基于python和TensorFlow的电影推荐系统

电影推荐系统

这门课感觉挺有意思,而且老师讲的也很好,便决定为代码添上注释自己做一下总结。
代码地址
课程地址
第一步:数据准备
打开网址
电影数据集
找到下图所示数据集进行下载解压。
在这里插入图片描述
第二步:数据准备
读取ratings.csv和movies.csv文件,观察一下两个数据集的内容。
会用到的函数:
tail():查看后几行的数据,默认5行
head():查看前几行的数据,默认5行

ratings数据集:
在这里插入图片描述
movies数据集:
在这里插入图片描述
对数据进行一些处理

#增加行号信息
movies_df['movieRow'] = movies_df.index
# movies_df.tail()

##筛选movies_df中的特征
movies_df = movies_df[['movieRow', 'movieId', 'title']]
movies_df.to_csv('movieProcessed.csv', index=False, header=True, encoding='utf-8')
# movies_df.tail()

#moviesId远大于行号,将ratings_df中的movieId替换为行号
ratings_df = pd.merge(ratings_df, movies_df, on='movieId')
#使用head查看前几行数据,默认前5行
# ratings_df.head()

ratings_df = ratings_df[['userId', 'movieRow', 'rating']]
#处理后的数据保存到文件中
ratings_df.to_csv('ratingsProcessed.csv', index=False, header=True, encoding='utf-8')
# ratings_df.head()

接着创建电影评分矩阵rating和评分记录矩阵record,即用户是否对电影进行了评分,评分则1,未评分则为0。

userNo = ratings_df['userId'].max() + 1
movieNo = ratings_df['movieRow'].max() + 1

rating = np.zeros((movieNo, userNo))

flag = 0
ratings_df_length = np.shape(ratings_df)[0]  #ratings_df的样本个数

利用pycharm中的脚本,可以观察到用户样本数,电影样本数,rating矩阵,ratings_df样本个数.
在这里插入图片描述
填写rating

#填写rating
for index, row in ratings_df.iterrows():
    #将rating当中对应的电影编号及用户编号填上row当中的评分
    rating[int(row['movieRow']), int(row['userId'])] = row['rating']
    flag += 1
    print('processed %d, %d left' % (flag, ratings_df_length - flag))

在电影评分表中,>0表示电影被用户评分,等于0表示未被用户评分。
将布尔值的矩阵转换为0 1表示,即可生成record矩阵。如下三图:

#电影评分表中,>0表示已经评分,=0表示未被评分
record = rating > 0
#bool值转换为0和1
record = np.array(record, dtype=int)

布尔值的record矩阵转变为0 1的record矩阵
在这里插入图片描述
有了这两个矩阵,便可以开始构建模型。
第三步:构建模型
先定义一个对评分取值范围进行缩放的函数,这样能使评分系统性能好一些。

def normalizeRatings(rating, record):
    m, n = rating.shape
    rating_mean = np.zeros((m, 1))  #初始化对于每部电影每个用户的平均评分
    rating_norm = np.zeros((m, n))  #保存处理后的数据
    #原始评分-平均评分,最后将计算结果和平均评分返回。
    for i in range(m):
        idx = record[i, :] != 0  #获取已经评分的电影的下标
        rating_mean[i] = np.mean(rating[i,  idx])  #计算平均值,右边式子代表第i行已经评分的电影的平均值
        rating_norm[i, idx] = rating[i, idx] - rating_mean[i]
    return rating_norm, rating_mean
    
rating_norm, rating_mean = normalizeRatings(rating, record)

rating_norm = np.nan_to_num(rating_norm)
rating_mean = np.nan_to_num(rating_mean)

注1:慕课网课程中的rating_norm[i, idx] 的计算代码有问题,感谢在评论下解惑的大牛们( ̄▽ ̄)~*
注2:如果不对rating_norm,rating_mean进行处理,会报RuntimeWarning: Mean of empty slice.

初始化电影矩阵、用户喜好矩阵,便可以开始计算损失,代价函数即为理论课定义的函数,如图。
注:初始化矩阵产生的参数都是随机数,且服从正态分布:random_normal()
在这里插入图片描述
代码如下:

#假设有10中类型的电影
num_features = 10
#初始化电影矩阵X,用户喜好矩阵Theta,这里产生的参数都是随机数,并且是正态分布
X_parameters = tf.Variable(tf.random_normal([movieNo, num_features], stddev=0.35))
Theta_paramters = tf.Variable(tf.random_normal([userNo, num_features], stddev=0.35))
#理论课定义的代价函数
#tf.matmul(X_parameters, Theta_paramters, transpose_b=True)代表X_parameters和Theta_paramters的转置相乘
loss = 1/2 * tf.reduce_sum(((tf.matmul(X_parameters, Theta_paramters, transpose_b=True)
                             - rating_norm) * record) ** 2) \
       + 1/2 * (tf.reduce_sum(X_parameters**2)+tf.reduce_sum(Theta_paramters**2))  #正则化项,这里λ=1,可以调整来观察模型性能变化。

#创建优化器和优化目标
optimizer = tf.train.AdamOptimizer(1e-4)
train = optimizer.minimize(loss)

第四步:训练模型
使用TensorFlow中的tf.summary模块,它用于将TensorFlow的数据导出,从而变得可视化,因为loss是标量,所以使用scalar函数。
代码如下:

#Step4:训练模型
#使用TensorFlow中的tf.summary模块,它用于将TensorFlow的数据导出,从而变得可视化,因为loss是标量,所以使用scalar函数
tf.summary.scalar('loss', loss)
#将所有summary信息汇总
summaryMerged = tf.summary.merge_all()
#定义保存信息的路径
filename = 'F:\datasets\慕课电影推荐系统数据集\ml-latest-small\movie_tensorboard'
#把信息保存在文件当中
writer = tf.summary.FileWriter(filename)

#创建tensorflow绘画
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

接下来便开始训练模型,设置10000次迭代,训练过程时间有点长,如果只是想看一下结果,设几十次就好了,但是误差就会比较大。

#开始训练模型
for i in range(10000):
    #不重要的变量可用下划线表示,每次train的结果都会保存到"_",summaryMerged的训练结果保存到"movie_summary"
    _, movie_summary = sess.run([train, summaryMerged])
    writer.add_summary(movie_summary, i)
    #记录一下次数,有没有都无所谓,只是看看还有多久
    print('i=', i, 'loss=', loss)

之前提到可视化,所以接着就是利用可视化观察运行的结果。
进入cmd命令,进入文件位置后,输入"tensorboard --logdir=./ --host=127.0.0.1"
运行后,在浏览器输入127.0.0.1:6006,即可打开可视化TensorFlow的页面观察代价函数

在这里插入图片描述
详细步骤可以看这篇
《TensorBoard返回的网址打不开的问题》

第五步:评估模型

Current_X_paramters, Current_Theta_parameters = sess.run([X_parameters, Theta_paramters])
#将电影内容矩阵和用户喜好矩阵相乘,再加上每一行的均值,便得到一个完整的电影评分表
predicts = np.dot(Current_X_paramters, Current_Theta_parameters.T) + rating_mean
#计算预测值与真实值的残差平方和的算术平方根,将它作为误差error,随着迭代次数增加而减少
errors = np.sqrt(np.sum((predicts - rating)**2))

这是为了赶时间看一下结果,所设置训练50次生成的结果,不出所料,误差很大,但是暂时先忽略⑧
在这里插入图片描述
最后一步:构建完整系统
获取对该用户的电影评分的列表,predicts[:, int(user_id)]是该用户对应的所有电影的评分,即系统预测的用户对于电影的评分。
推荐系统需要从高分开始,所以采用argsort()[::-1]从大到小排序

sortedResult = predicts[:, int(user_id)].argsort()[::-1]

idx用于保存已经推荐了多少部电影

idx = 0
#后边的center函数只是为了美观一点点,不重要
print('为该用户推荐的评分最高的20部电影是:'.center(80, '='))
for i in sortedResult:
    print('评分: %.2f, 电影名: %s' % (predicts[i, int(user_id)], movies_df.iloc[i]['title']))
    idx += 1
    if idx == 20:
        break

以下就是运行后的结果:
在这里插入图片描述
可以看到,为用户推荐的电影已经从高评分到低排列并显示了出来。
一个电影推荐系统便完成了。

注:

#假设有10中类型的电影
num_features = 10
1/2 * (tf.reduce_sum(X_parameters**2)+tf.reduce_sum(Theta_paramters**2))  
#正则化项,这里λ=1,可以调整来观察模型性能变化。
#开始训练模型
for i in range(1000):

这些都是影响系统性能的重要因素,可以修改这些参数来调整系统性能。

  • 26
    点赞
  • 164
    收藏
    觉得还不错? 一键收藏
  • 30
    评论
基于Python电影推荐系统可以通过以下步骤来设计和实现: 1. 数据获取和处理:使用Python的数据处理库(如pandas)从公开的电影数据库或API获取电影数据。可以获取电影的特征信息(如类型、演员、导演等)以及用户的历史观影记录和评分数据。 2. 推荐算法选择:根据需求选择合适的推荐算法,如基于内容的推荐、协同过滤推荐、深度学习推荐等。可以使用Python机器学习和深度学习库(如scikit-learn、TensorFlow)来实现这些算法。 3. 模型训练和优化:根据用户的历史观影记录、评分和电影的特征,使用选择的推荐算法进行模型的训练和优化。可以使用Python机器学习和深度学习库来实现这一步骤。 4. 用户界面开发:使用Python的Web框架(如Django、Flask)或GUI库(如PyQt、Tkinter)开发用户界面,提供用户友好的交互体验。用户可以通过界面输入自己的观影记录和评分,系统根据这些信息进行推荐。 5. 推荐结果展示:将推荐结果以列表或其他形式展示给用户,用户可以根据推荐结果选择自己感兴趣的电影。 以下是一个基于Python电影推荐系统的示例代码: ```python import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import linear_kernel # 1. 数据获取和处理 movies = pd.read_csv('movies.csv') ratings = pd.read_csv('ratings.csv') # 2. 推荐算法选择 # 基于内容的推荐算法 tfidf = TfidfVectorizer(stop_words='english') movies['overview'] = movies['overview'].fillna('') tfidf_matrix = tfidf.fit_transform(movies['overview']) cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix) # 3. 模型训练和优化 # 根据用户的历史观影记录和评分,计算电影之间的相似度 def get_recommendations(movie_title, cosine_sim=cosine_sim): idx = movies[movies['title'] == movie_title].index[0] sim_scores = list(enumerate(cosine_sim[idx])) sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True) sim_scores = sim_scores[1:11] movie_indices = [i[0] for i in sim_scores] return movies['title'].iloc[movie_indices] # 4. 用户界面开发 # 使用Flask框架开发Web界面,用户可以输入观影记录和评分 from flask import Flask, request, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/recommend', methods=['POST']) def recommend(): movie_title = request.form['movie_title'] recommendations = get_recommendations(movie_title) return render_template('recommendations.html', recommendations=recommendations) if __name__ == '__main__': app.run() ```
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值