Python,余弦相似度与调整后的余弦相似度

标签 python numpy scikit-learn similarity cosine-similarity

我想改造Collaborative Filtering with Python通过余弦相似度到调整后的余弦相似度。

基于余弦相似度的实现如下所示:

import pandas as pd
import numpy as np
from scipy.spatial.distance import cosine
from scipy.spatial.distance import pdist, squareform

data = pd.read_csv("C:\\Sample.csv")
data_germany = data.drop("Name", 1)
data_ibs = pd.DataFrame(index=data_germany.columns,columns=data_germany.columns)

for i in range(0,len(data_ibs.columns)) :
    for j in range(0,len(data_ibs.columns)) :
      data_ibs.ix[i,j] = 1-cosine(data_germany.ix[:,i],data_germany.ix[:,j])

data_neighbours = pd.DataFrame(index=data_ibs.columns,columns=range(1,6))

for i in range(0,len(data_ibs.columns)):
    data_neighbours.ix[i,:] = data_ibs.ix[0:,i].sort_values(ascending=False)[:5].index

df = data_neighbours.head().ix[:,2:6]
print df

正在使用的Sample.csv看起来像:

Sample.csv

其中1表示用户购买了特定水果,反之0表示用户未购买特定水果

当我运行上面的代码时,我得到的是:

results1

其中行是水果,列是相似度排名(按降序排列)。在此示例中,PearApple 最相似,Melon 是第二相似的,依此类推。

我遇到了this post关于调整余弦相似度,我尝试将该方法集成到我的代码中。在本例中,数据是用户对水果给出的评分:

ratings

这是我的尝试:

data_ibs = pd.DataFrame(index=data_germany.columns,columns=data_germany.columns)
M_u = data_ibs.mean(axis=1)
M = np.asarray(data_ibs)
item_mean_subtracted = M - M_u[:, None]

for i in range(0,len(data_ibs.columns)) :
    for j in range(0,len(data_ibs.columns)) :
      data_ibs.ix[i,j]  = 1 - squareform(pdist(item_mean_subtracted.T, "cosine")) ### error

data_neighbours = pd.DataFrame(index=data_ibs.columns,columns=range(1,6))

for i in range(0,len(data_ibs.columns)):
    data_neighbours.ix[i,:] = data_ibs.ix[0:,i].sort_values(ascending=False)[:5].index

df = data_neighbours.head().ix[:,2:6]

但我被困住了。我的问题是:如何将调整后的余弦相似度成功应用于此示例?

最佳答案

这是针对您的问题的基于 NumPy 的解决方案。

首先我们将评分数据存储到一个数组中:

fruits = np.asarray(['Apple', 'Orange', 'Pear', 'Grape', 'Melon'])
M = np.asarray(data.loc[:, fruits])

然后我们计算调整后的余弦相似度矩阵:

M_u = M.mean(axis=1)
item_mean_subtracted = M - M_u[:, None]
similarity_matrix = 1 - squareform(pdist(item_mean_subtracted.T, 'cosine'))

最后我们按照相似度降序对结果进行排序:

indices = np.fliplr(np.argsort(similarity_matrix, axis=1)[:,:-1])
result = np.hstack((fruits[:, None], fruits[indices]))

演示

In [49]: M
Out[49]: 
array([[ 0, 10,  0,  1,  0],
       [ 6,  0,  0,  0,  2],
       [ 1,  0, 20,  0,  1],
       [ 0,  3,  6,  0, 18],
       [ 3,  0,  2,  0,  0],
       [ 0,  2,  0,  5,  0]])

In [50]: np.set_printoptions(precision=2)

In [51]: similarity_matrix
Out[51]: 
array([[ 1.  ,  0.01, -0.41,  0.48, -0.44],
       [ 0.01,  1.  , -0.57,  0.37, -0.26],
       [-0.41, -0.57,  1.  , -0.56, -0.19],
       [ 0.48,  0.37, -0.56,  1.  , -0.51],
       [-0.44, -0.26, -0.19, -0.51,  1.  ]])

In [52]: result
Out[52]: 
array([['Apple', 'Grape', 'Orange', 'Pear', 'Melon'],
       ['Orange', 'Grape', 'Apple', 'Melon', 'Pear'],
       ['Pear', 'Melon', 'Apple', 'Grape', 'Orange'],
       ['Grape', 'Apple', 'Orange', 'Melon', 'Pear'],
       ['Melon', 'Pear', 'Orange', 'Apple', 'Grape']], 
      dtype='|S6')

关于Python,余弦相似度与调整后的余弦相似度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42898466/

相关文章:

python - 我应该如何解决这个 DeprecationWarning?

python - 如何在 pandas 中将一组行洗牌在一起(行具有唯一的 id)

python - 如何在 Python 中打印棋盘格图案?

python - 将具有非固定长度元素的列表转换为张量

python:numpy数组的矩阵列表?

python - numpy 数组的顺序如何影响乘法速度?

machine-learning - scikit learn如何实现输出层

python - 如果 yticks 太多,Seaborn 会自动隐藏 yticks

python - Unicode 字符串适用于 python2,但不适用于 python3

python - 使用 SciPy 最小化受线性等式约束的二次函数