推荐系统之LFM模型

协同过滤算法是按照用户的相似度或者物品的相似度来进行推荐的。而LFM模型则是按照用户喜欢的分类来进行推荐。

但是这样就有一个问题,如何去进行分类,分类的颗粒度如何规定。这样的话,我们引进了LFM模型。

LEM不直接计算分类,而是计算每个物品在各个类别中的比重,从而进行计算。

在此,我们使用tensorflow进行模型的构建。

1.处理数据

ratings = pd.read_csv("C:/Users/jkx/Desktop/一些数据集/ml-latest-small/ratings.csv")
movies = pd.read_csv("C:/Users/jkx/Desktop/一些数据集/ml-latest-small/movies.csv")
movies['movies_row'] = movies.index
ratings = pd.merge(ratings, movies, how='left', on='movieId')
ratings = ratings[['userId', 'rating', 'movies_row']]
#因为每个人的评分标准不一样,比如A认为最好的电影应该给4分,B认为给5分,所以进行归一化
aggs = ratings.groupby('userId')['rating'].agg(['max'])
ratings = pd.merge(ratings, aggs, on='userId',how='left')
ratings['rating'] = ratings['rating']/ratings['max']

这是处理之后的数据
推荐系统之LFM模型_第1张图片
大部分max是5分,不过还是有不是5分的
推荐系统之LFM模型_第2张图片

2.构建评分矩阵

num_user = ratings['userId'].max()+1
num_movie = ratings['movies_row'].max()+1
rating = np.zeros((num_movie,num_user))
#标志位
flag = 0
#获取合并表中的列数
ratings_length = np.shape(ratings)[0]
#遍历矩阵,将电影的评分填入表中
for index,row in ratings.iterrows():
    rating[int(row['movies_row']), int(row['userId'])] = row['rating']
    flag += 1
    print('processed %d, %d left' %(flag,ratings_length-flag))

构建后的评分矩阵如下图:
推荐系统之LFM模型_第3张图片

3.构建模型

损失函数是:
在这里插入图片描述
Theta_parameters矩阵是一个[num_users, num_features]的矩阵,表示了每个用户所喜欢的分类所占的比重。
X_parameters矩阵是一个[num_movies,num_features]的矩阵,表示了每个电影所占分类的比重。

record = rating > 0
record = np.array(record, dtype = int)
rating_norm = rating
num_features = 10

X_parameters = tf.Variable(tf.random_normal([num_movie, num_features],stddev = 0.35))
Theta_parameters = tf.Variable(tf.random_normal([num_user, num_features],stddev = 0.35))

loss = 1/2 * tf.reduce_sum(((tf.matmul(X_parameters, Theta_parameters, transpose_b=True) - rating_norm) * record) ** 2) + 1/2 * (tf.reduce_sum(X_parameters ** 2) + tf.reduce_sum(Theta_parameters ** 2)) 
optimizer = tf.train.AdamOptimizer(1e-4)
train = optimizer.minimize(loss)

tf.summary.scalar('loss', loss)
summaryMerged = tf.summary.merge_all()
#merge_all 可以将所有summary全部保存到磁盘,以便tensorboard显示。
filename = './movie_tensorborad'
writer = tf.summary.FileWriter(filename)
#指定一个文件用来保存图。
sess = tf.Session()
#定义一个session
init = tf.global_variables_initializer()
sess.run(init)
#运行session

4.训练模型

for i in range(50000):
    _loss, _, movie_summary = sess.run([loss, train, summaryMerged])
    if i%500==0:
        print("step {} begins, loss is {}.".format(i,_loss))
    writer.add_summary(movie_summary, i)

5.计算errors

Current_X_parameters, Current_Theta_parameters = sess.run([X_parameters, Theta_parameters])
# Current_X_parameters为用户内容矩阵,Current_Theta_parameters用户喜好矩阵
predicts = np.dot(Current_X_parameters,Current_Theta_parameters.T)
errors = np.sqrt(np.sum((predicts - rating)**2))

6.进行推荐

userId = input('您要向哪位用户进行推荐呢?请输入用户编号:(smaller than 672)')
sortedResult = predicts[:, int(userId)].argsort()[::-1]
idx = 0
print('为该用户推荐的评分最高的20部电影是:'.center(80,'='))
for i in sortedResult:
    print('score: %.3f, movie name: %s' % (predicts[i, int(userId)], movies.iloc[i]['title']))
    idx += 1
    if idx == 20:break

推荐系统之LFM模型_第4张图片
数据来源

你可能感兴趣的:(算法,tensorflow,深度学习,推荐系统,python)