以下问题:通过填写表明个性,生活方式,兴趣等的个人资料所提供的数据,根据兼容性得分来匹配用户
每个属性均为真(1)或假(0)的标签(例如,对个性保持冷静的属性)。假设我们想找到两个用户的兼容性。
Extract from panda DataFrame for personality
从用户3中减去用户2,对差异进行平方,然后将差异的总和与最大可能偏差(类别等属性的数量)相关。这样,倒数就是相似度。 所有类别(例如生活方式)的操作都一样
def similarityScore (pandaFrame, name1, name2):
profile1 = pandaToArray(pandaFrame, name1)#function changing DataFrane to array
profile2 = pandaToArray(pandaFrame, name2)
newArray = profile1 - profile2
differences = 0
for element in newArray:
element = (element)**2
differences += element
maxDifference = len(profile1)
similarity = 1 - (differences/maxDifference)
return similarity
将每个用户与DataFrame中的每个其他用户进行比较:
def scorecalc(fileName):
data = csvToPanda(fileName)
scorePanda = pd.DataFrame([], columns=userList, index=userList)
for user1 in userList:
firstUser = user1
for user2 in userList:
secondUser = user2
score = similarityScore(data, firstUser, secondUser)
scorePanda.iloc[[userList.index(firstUser)],[userList.index(secondUser)]] = score
return(scorePanda)
根据特定类别对用户的相似性对用户的重要性,通过将相似性得分乘以偏好数据框来加权相似性得分:
def weightedScore (personality, lifestyle,preferences):
personality = personality.multiply(preferences['personality'])
lifestyle = lifestyle.multiply(preferences['lifestyle'])
weightscore = (personality + lifestyle)
return(weightscore)
结果将是一个介于0到1之间的兼容性评分。
一切正常,但是运行它需要花费很多时间,尤其是当所比较的用户数(100+)增加时。有什么建议可以加快速度,使代码更容易吗?
答案 0 :(得分:0)
希望我的问题陈述正确无误:
我有二进制指示符变量的DataFrameX。 (0,1) 对于X的每一行(代表不同的用户),我想在其他用户/行中查找最相似的用户/行。
我将在sklearn中使用NearestNeighbors类,from here:
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from sklearn.neighbors import NearestNeighbors
X = np.array([[0,0,0,0,1],
[0,0,0,0,1],
[1,1,1,0,0],
[1,0,0,1,1]])
看看X,我们可以看到idx = 1和idx = 2是最相似的。它们完美匹配。他们应该相互匹配,“最相似”。
# two nbrs since first match is self match
nbrs = NearestNeighbors(n_neighbors=2, metric='dice').fit(X)
distances, indices = nbrs.kneighbors(X)
print(indices)
#remember first val in this array per line is self match
[[0 1]
[0 1]
[2 3]
[3 1]]
要确定您的加权分数,我不确定。我的第一个想法是获取您的二进制数据数组,乘以“这对我有多重要”,然后在最近的邻居搜索中使用不同的指标,例如"euclidean"
或其他。此类需要更多有关这些其他数据框中包含的内容的详细信息。
因此,假设用户1和2(按其索引位置)指示第三列是非常重要的(0-10处为“ 10”),第三列按如下方式填写:>
X = np.array([[0,0,0,0,1],
[0,0,1,0,1],
[1,1,1,0,0],
[1,0,0,1,1]])
# notice they match now on that 3rd col, but disagree elsewhere
#ugly hack for replacing two vals
np.put(X[1], [2], [10]) # grab second row, third col, place [10]
np.put(X[2], [2], [10])
print(X)
[[ 0 0 0 0 1]
[ 0 0 10 0 1]
[ 1 1 10 0 0]
[ 1 0 0 1 1]]
现在,他们俩都同意这个问题非常重要。 现在尝试使用其他指标计算邻居calc:
nbrs = NearestNeighbors(n_neighbors=2, metric='euclidean').fit(X)
d, i = nbrs.kneighbors(X)
print(d)
print(i)
[[0. 1.41421356]
[0. 1.73205081]
[0. 1.73205081]
[0. 1.41421356]]
[[0 3]
[1 2]
[2 1]
[3 0]]
其中[1,2]
和[2,1]
表示第二行和第三行现在彼此最近。 (记住数组i
中的第一个val是自匹配项)
我在这里详细介绍了一些细节,可能会使最近的邻居不合适,但是您可以阅读有关them in other various places的信息
答案 1 :(得分:0)
@Dylan 我对NearestNeighbours的唯一问题是,它将使我采用的方法产生不同的结果。例子:
from sklearn.neighbors import NearestNeighbors
import numpy as np
X = np.array([[0,0,0,0,1],
[0,0,1,1,0]])
nbrs = NearestNeighbors(n_neighbors=2, metric = 'euclidean').fit(X)
distances, indices = nbrs.kneighbors(X)
print(distances)
print(1/ (1+distances)) # returns a similarity score between 0 and 1
相似度得分为0.366,应该为40%,因为它们的绝对偏差为5个变量中的3个-> 60%