J'ai implémenté la factorisation matricielle, qui est la base du modèle recommandé, en python.
C'est un système qui prédit la préférence pour un article et présente l'article le plus approprié à un utilisateur spécifique. Des exemples de mise en œuvre en tant que service incluent les "Produits recommandés pour vous" d'Amazon et les "Vidéos recommandées" de Youtube.
Un algorithme souvent utilisé dans les recommandations.
Sur la base des informations de valeur d'évaluation pour l'élément de l'utilisateur, la valeur d'évaluation de l'élément qui n'a pas été évalué est prédite, et celle qui est susceptible d'avoir une valeur d'évaluation élevée est recommandée.
Premièrement, il existe une matrice (A) constituée de m utilisateurs et de n éléments, et chaque valeur qu'elle contient est une valeur d'évaluation pour un élément par un certain utilisateur. Cette matrice (A) est décomposée en une matrice utilisateur (U) composée d'utilisateurs et de variables latentes (P) et une matrice d'items (I) constituée d'items et de variables latentes (Q).
La valeur obtenue en prenant le produit interne de la matrice utilisateur et de la matrice d'éléments est utilisée comme valeur prédite. Le paramètre est mis à jour plusieurs fois jusqu'à ce que l'erreur entre la valeur prédite et la valeur de réponse correcte tombe en dessous de la valeur de seuil ou que le nombre de répétitions dépasse un certain nombre.
Nous avons adopté https://grouplens.org/datasets/movielens/100k/ comme ensemble de données.
import numpy as np
import random
import pandas as pd
import math
class MFx(object):
#Définir chaque variable
def __init__(self,K=20,alpha=1e-6,beta=0.0):
self.K=K
self.alpha=alpha
self.beta=beta
def fit(self,X,n_user,n_item,n_iter=100):
self.R=X.copy()
self.samples=X.copy()
#Définir la valeur initiale de la variable de facteur latent
self.user_factors = np.random.rand(n_user,self.K)
self.item_factors = np.random.rand(n_item,self.K)
#stochastic gradient descent
self.loss=[]
for i in range(n_iter):
self.sgd()
mse=self.mse()
self.loss.append((i,mse))
def sgd(self):
np.random.shuffle(self.samples)
for user,item,rating in self.samples:
err=rating-self.predict_pair(user,item)
#update parameter
self.user_factors[user] += self.alpha*(err*self.item_factors[item]-self.beta*self.user_factors[user])
self.item_factors[item] += self.alpha*(err*self.user_factors[user]-self.beta*self.item_factors[item])
def mse(self):
predicted = self.predict(self.R)
error=np.hstack((self.R,np.array(predicted).reshape(-1,1)))
error=np.sqrt(pow((error[:,2]-error[:,3]),2).mean())
return error
#Prédiction de la valeur d'évaluation pour un certain élément par un certain utilisateur (interne est le produit interne des vecteurs)
def predict_pair(self,user,item):
return np.inner(self.user_factors[user],self.item_factors[item])
def predict(self,X):
rate=[]
for row in X:
rate.append(self.predict_pair(row[0],row[1]))
return rate
def get_full_matrix(self):
return np.inner(self.user_factors,self.item_factors)
#Lecture des données
def load_ml100k():
samples=pd.read_csv('data/ml-100k/u.data',sep='\t',header=None)
samples=samples.iloc[:,:3]
samples.columns=['user','item','rate']
samples['user']=samples['user']-1
samples['item']=samples['item']-1
return samples
#Jeu de données au type de tableau
df = np.array(load_ml100k())
#Supprimer la même valeur et compter le nombre d'utilisateurs et d'éléments
n_user=np.unique(df[:,0]).max()+1
n_item=np.unique(df[:,1]).max()+1
n_rate=np.unique(df[:,2]).max()
#Ordre aléatoire
random.shuffle(df)
#80% de la taille totale est destinée à la formation, le reste est destiné aux tests
train_size=int(df.shape[0]*0.8)
train_df=df[:train_size]
test_df=df[train_size:]
#MF
MF=MFx(K=20,alpha=0.01,beta=0.5)
MF.fit(train_df,n_user,n_item,n_iter=10)
Les deux évaluations suivantes ont été faites pour l'exactitude des recommandations. --Evaluation de la valeur prédite
Trouvez l'erreur quadratique entre la valeur prédite et la valeur de réponse correcte et calculez la moyenne. Plus la valeur est basse, plus la recommandation est précise.
#Prédire la valeur d'évaluation de l'élément dans les données de test
pre=MF.predict(test_df)
#f=np.array(pre)
#print(type(test_df))
#Créer une matrice avec la valeur prédite après la valeur d'évaluation des données de test
ret1=np.hstack((test_df, np.array(pre).reshape(-1, 1)))
#Calculer l'erreur quadratique moyenne entre la valeur prédite et la valeur d'évaluation réelle
print("pred")
print(np.sqrt(pow((ret1[:,2]-ret1[:,3]),2).mean()))
NDCG Créez un classement basé sur la valeur de réponse correcte et un classement basé sur la valeur prédite. Comparez les deux classements et mesurez à quel point le classement prévu est proche du classement correct. La plage de valeurs NDCG va de 0 à 1, et plus elle est proche de 1, meilleur est le classement généré.
def get_dcg(f):
dcg=0.0
s=1
if type(f[0])==float:
f=[f]
for i in f:
if s==1:
dcg+=i[0]
s+=1
else:
dcg+=i[0]/math.log2(s)
s+=1
return dcg
def get_ndcgs(pre):
user=[]
x=[]
for i in np.argsort(pre[:,0]):
user.append(pre[i][0])
x.append(pre[i])
users=list(set(user))
columns=['user','item','real','pred']
y=pd.DataFrame(data=pre, columns=columns, dtype='float')
y.set_index("user",inplace=True)
y_real=y.sort_values(['user','real'],ascending=[True, False])
y_pred=y.sort_values(['user','pred'],ascending=[True, False])
ndcg=0
fff=users
for ii in fff:
fr=y_real.loc[ii,"real":"pred"].values.tolist()
fp=y_pred.loc[ii,"real":"pred"].values.tolist()
ndcg+=get_dcg(fp)/get_dcg(fr)
return ndcg/len(fff)
print("NDCG")
print(get_ndcgs(ret1[:,:4]))
Recommended Posts