/ / Python, Cosine подібність до налагодженої косинуса подібність - python, numpy, scikit-learn, подібність, косинусна подібність

Пітон, козинальне схожості з налагодженою подібністю косинуса - python, numpy, scikit-learn, подібність, косинусоподібність

Я хочу перетворити a Спільна фільтрація з 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

a Sample.csv використовується:

Sample.csv

де 1 означає, що користувач придбав конкретний фрукт і навпаки 0 означає, що користувач не придбав певний фрукт

Коли я запускаю код вище, це я отримую:

Результати1

де рядки - плоди, а стовпці - ряди подібності (у порядку спадання). У цьому прикладі Pear є найбільш подібним Apple, Melonє другим найбільш подібним і так далі.

Я зіткнувся цей пост на налаштованому Косинусі подібності, і я намагався інтегрувати цей підхід у свій код. У цьому випадку дані є рейтинговими оцінками, наданими користувачами:

рейтинги

Ось моя спроба:

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]

Але я застряг. Моє запитання: як можна скоригувати подібність косинуса в цьому зразку?

Відповіді:

1 для відповіді № 1

Ось рішення 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]))

DEMO

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")