根据兴趣匹配人

时间:2019-01-22 14:26:47

标签: python data-science matching recommender-systems

以下问题:通过填写表明个性,生活方式,兴趣等的个人资料所提供的数据,根据兼容性得分来匹配用户

每个属性均为真(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+)增加时。有什么建议可以加快速度,使代码更容易吗?

2 个答案:

答案 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%