Du co-filtrage, j'ai implémenté le co-filtrage basé sur les éléments le plus simple en python, alors exposons-le à Qiita. (Il s'agit probablement de la première implémentation, donc s'il y a des erreurs, veuillez préciser mm)
Utilisez MovieLens 100K Dataset comme sujet recommandé. Je laisserai l'explication détaillée à la destination du lien, mais en gros, ce sont les données qui ont évalué le film avec une note de 1 à 5.
En anglais, le co-filtrage est un filtrage collaboratif, que l'on peut appeler un «système de recommandation basé sur le bouche-à-oreille basé sur l'évaluation des autres».
Le co-filtrage peut être classé comme suit, et le co-filtrage basé sur les éléments est positionné comme l'un d'entre eux.
Pour plus de détails, veuillez lire Commentaire du système de recommandation / matériel de conférence du professeur Kamishima. Cette classification est également basée sur le matériau ci-dessus.
J'ai écrit que le co-filtrage est un système de recommandation qui "utilise l'évaluation des autres", mais le co-filtrage basé sur les éléments est basé sur les deux hypothèses suivantes.
Hypothèse 1: Parmi les éléments que M. A n'a pas évalués (= candidats recommandés), ceux qui sont susceptibles d'être appréciés sont similaires aux éléments que M. A évalue fortement. </ i>
Hypothèse 2: Les éléments peuvent être considérés comme similaires si leurs modèles d'évaluation sont similaires. </ i>
Pour obtenir une image, l'explication à la page 36 ~ de Construction d'un système de recommandation utilisant le filtrage coopératif est facile à comprendre.
Il est exprimé par une formule mathématique comme suit.
r'_{u,y} = \frac{\sum _{j \in Y_u} {s_{y,j}r_{u,j}}}{\sum _{j \in Y_u} {\mid s_{y,j} \mid}}
\scriptsize r'_{u,y}La prédiction d'évaluation pour l'élément y de l'utilisateur u\\
\scriptsize S_{y,j}La similitude entre l'élément y et l'élément j\\
\scriptsize Y_{u}Est un ensemble d'éléments que l'utilisateur u a évalué\\
\scriptsize r_{u,j}La note de l'utilisateur u pour l'élément j
Le numérateur est la somme pondérée des items évalués par similarité, ce qui correspond à l'hypothèse 1. Le dénominateur est la normalisation.
Premièrement, nous devons calculer la similitude des éléments qui correspondent à l'hypothèse 2.
Convertir les données csv et tsv en une matrice avec MovieLens utilisant python comme exemple suppose qu'elle a déjà été chargée dans la matrice R.
>>> print(R)
[[ 5. 3. 4. ..., 0. 0. 0.]
[ 4. 0. 0. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 0. 0. 0.]
...,
[ 5. 0. 0. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 0. 0. 0.]
[ 0. 5. 0. ..., 0. 0. 0.]]
Cette fois, nous utiliserons le cosinus pour calculer la similitude des éléments. Il semble que la corrélation de Pearson soit également utilisée.
def compute_item_similarities(R):
# n: movie counts
n = R.shape[1]
sims = np.zeros((n,n))
for i in range(n):
for j in range(i, n):
if i == j:
sim = 1.0
else:
# R[:, i]Est un vecteur de colonne répertoriant toutes les évaluations utilisateur pour l'élément i
sim = similarity(R[:,i], R[:,j])
sims[i][j] = sim
sims[j][i] = sim
return sims
def similarity(item1, item2):
#Un ensemble d'utilisateurs qui ont évalué à la fois item1 et item2
common = np.logical_and(item1 != 0, item2 != 0)
v1 = item1[common]
v2 = item2[common]
sim = 0.0
#Le nombre d'évaluateurs communs est limité à 2 ou plus.
if v1.size > 1:
sim = 1.0 - cosine(v1, v2)
return sim
sims = compute_item_similarities(R)
>>> print(sims)
[[ 1. 0.94873739 0.91329972 ..., 0. 0. 0. ]
[ 0.94873739 1. 0.90887971 ..., 0. 0. 0. ]
[ 0.91329972 0.90887971 1. ..., 0. 0. 0. ]
...,
[ 0. 0. 0. ..., 1. 0. 0. ]
[ 0. 0. 0. ..., 0. 1. 0. ]
[ 0. 0. 0. ..., 0. 0. 1. ]]
Puisque la similitude S de la formule suivante a été obtenue à l'ÉTAPE 1, la valeur prédite peut être obtenue en obtenant la somme pondérée et en la normalisant.
r'_{u,y} = \frac{\sum _{j \in Y_u} {s_{y,j}r_{u,j}}}{\sum _{j \in Y_u} {\mid s_{y,j} \mid}}
def predict(u, sims):
#Non classé est 0,Evalué est un vecteur qui devient 1. Pour le calcul des normalisateurs.
x = np.zeros(u.size)
x[u > 0] = 1
scores = sims.dot(u)
normalizers = sims.dot(x)
prediction = np.zeros(u.size)
for i in range(u.size):
#La valeur prédite est 0 pour les cas où le dénominateur est 0 et les éléments évalués
if normalizers[i] == 0 or u[i] > 0:
prediction[i] = 0
else:
prediction[i] = scores[i] / normalizers[i]
#Prédiction de l'évaluation de l'utilisateur u pour l'élément i
return prediction
Pour confirmation, je l'ai essayé avec un exemple simple et j'ai obtenu le résultat.
u = np.array([5, 0, 1])
sims = np.array([ [1, 0.2, 0], [0.2, 1, 0.1], [0, 0.1, 1] ])
>> print(predict(u, sims))
[ 0. 3.66666667 0. ]
Implémentation d'un co-filtrage basé sur les éléments basé sur les données MovieLens Les matériaux à partir desquels cet article est basé sont les suivants.
Recommended Posts