python电影推荐算法_基于Python的电影推荐算法

原标题:基于Python的电影推荐算法

第一步:收集和清洗数据

数据链接:https://grouplens.org/datasets/movielens/

下载文件:ml-latest-small

import pandas as pd import numpy as np import tensorflow as tf

导入ratings.csv文件ratings_df = pd.read_csv('./ml-latest-small/ratings.csv') ratings_df.tail() #tail命令用于输入文件中的尾部内容。tail命令默认在屏幕上显示指定文件的末尾5行。

结果:

userId

movieId

rating

timestamp

99999

671

6268

2.5

1065579370

100000

671

6269

4.0

1065149201

100001

671

6365

4.0

1070940363

100002

671

6385

2.5

1070979663

100003

671

6565

3.5

1074784724

导入movies.csv文件

movies_df = pd.read_csv('./ml-latest-small/movies.csv') movies_df.tail()

结果:

movieId

title

genres

9120

162672

Mohenjo Daro (2016)

Adventure|Drama|Romance

9121

163056

Shin Godzilla (2016)

Action|Adventure|Fantasy|Sci-Fi

9122

163949

The Beatles: Eight Days a Week - The Touring Y...

Documentary

9123

164977

The Gay Desperado (1936)

Comedy

9124

164979

Women of '69, Unboxed

Documentary

将movies_df中的movieId替换为行号

movies_df[ 'movieRow'] = movies_df. index #生成一列‘movieRow’,等于索引值 index movies_df.tail()

结果:

movieId

title

genres

movieRow

9120

162672

Mohenjo Daro (2016)

Adventure|Drama|Romance

9120

9121

163056

Shin Godzilla (2016)

Action|Adventure|Fantasy|Sci-Fi

9121

9122

163949

The Beatles: Eight Days a Week - The Touring Y...

Documentary

9122

9123

164977

The Gay Desperado (1936)

Comedy

9123

9124

164979

Women of '69, Unboxed

Documentary

9124

筛选movies_df中的特征

movies_df = movies_df[[ 'movieRow', 'movieId', 'title']] #筛选三列出来 movies_df.to_csv( './ml-latest-small/moviesProcessed.csv', index= False, header= True, encoding= 'utf-8') #生成一个新的文件moviesProcessed.csv movies_df.tail()

结果:

movieRow

movieId

title

9120

9120

162672

Mohenjo Daro (2016)

9121

9121

163056

Shin Godzilla (2016)

9122

9122

163949

The Beatles: Eight Days a Week - The Touring Y...

9123

9123

164977

The Gay Desperado (1936)

9124

9124

164979

Women of '69, Unboxed

根据movieId,合并rating_df和movie_df

ratings_df = pd.merge(ratings_df, movies_df, on= 'movieId') ratings_df.head()

结果:

userId

movieId

rating

timestamp

movieRow

title

0

1

31

2.5

1260759144

30

Dangerous Minds (1995)

1

7

31

3.0

851868750

30

Dangerous Minds (1995)

2

31

31

4.0

1273541953

30

Dangerous Minds (1995)

3

32

31

4.0

834828440

30

Dangerous Minds (1995)

4

36

31

3.0

847057202

30

Dangerous Minds (1995)

筛选ratings_df中的特征

ratings_df = ratings_df[[ 'userId', 'movieRow', 'rating']] #筛选出三列 ratings_df.to_csv( './ml-latest-small/ratingsProcessed.csv', index= False, header= True, encoding= 'utf-8') #导出一个新的文件ratingsProcessed.csv ratings_df.head()

结果:

userId

movieRow

rating

0

1

30

2.5

1

7

30

3.0

2

31

30

4.0

3

32

30

4.0

4

36

30

3.0 第二步:创建电影评分矩阵rating和评分纪录矩阵record

userNo = ratings_df['userId'].max() + 1 #userNo的最大值 movieNo = ratings_df['movieRow'].max() + 1 #movieNo的最大值 rating = np.zeros((movieNo,userNo)) #创建一个值都是0的数据 flag = 0 ratings_df_length = np.shape(ratings_df)[0] #查看矩阵ratings_df的第一维度是多少 for index,row in ratings_df.iterrows(): #interrows(),对表格ratings_df进行遍历 rating[int(row['movieRow']),int(row['userId'])] = row['rating'] #将ratings_df表里的'movieRow'和'userId'列,填上row的‘评分’ flag += 1 record = rating > 0 record record = np.array(record, dtype = int) #更改数据类型,0表示用户没有对电影评分,1表示用户已经对电影评分 record

结果:

array([[ 0, 0, 0, ..., 0, 1, 1], [ 0, 0, 0, ..., 0, 0, 0], [ 0, 0, 0, ..., 0, 0, 0], ..., [ 0, 0, 0, ..., 0, 0, 0], [ 0, 0, 0, ..., 0, 0, 0], [ 0, 0, 0, ..., 0, 0, 0]])

第三步:构建模型 def normalizeRatings(rating, record): m, n =rating.shape #m代表电影数量,n代表用户数量 rating_mean = np.zeros((m, 1)) #每部电影的平均得分 rating_norm = np.zeros((m,n)) #处理过的评分 for i in range(m): idx = record[i,:] != 0 #每部电影的评分,[i,:]表示每一行的所有列 rating_mean[i] = np.mean(rating[i,idx]) #第i行,评过份idx的用户的平均得分; #np.mean() 对所有元素求均值 rating_norm[i,idx] -= rating_mean[i] #rating_norm = 原始得分-平均得分 return rating_norm, rating_mean rating_norm, rating_mean = normalizeRatings(rating, record)

结果:/root/anaconda2/envs/python3/lib/python3. 6/site-packages/numpy/core/fromnumeric.py: 2957: RuntimeWarning: Mean of empty slice. out= out, **kwargs) /root/anaconda2/envs/python3/lib/python3. 6/site-packages/numpy/core/_methods.py: 80: RuntimeWarning: invalid value encountered in double_scalars ret = ret.dtype. type(ret / rcount)

注:如果数据出现较多的NaNN,对后面的运算影响较大rating_norm =np.nan_to_num(rating_norm) #对值为NaNN进行处理,改成数值0 rating_norm

结果:array([[ 0. , 0. , 0. , ..., 0. , - 3.87246964, - 3.87246964], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], ..., [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ]])

-rating_mean =np.nan_to_num(rating_mean) #对值为NaNN进行处理,改成数值0 rating_mean

结果: array( [[3.87246964], [3.40186916], [3.16101695], ..., [3. ], [0. ], [5. ]])

构建模型 num_features = 10 X_parameters = tf.Variable(tf.random_normal([movie No, num_features],stddev = 0.35)) Theta_parameters = tf.Variable(tf.random_normal([user No, num_features],stddev = 0.35)) #tf.Variables()初始化变量 #tf.random_normal()函数用于从服从指定正太分布的数值中取出指定个数的值,mean: 正态分布的均值。stddev: 正态分布的标准差。dtype: 输出的类型 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)) #基于内容的推荐算法模型

# 函数解释: # reduce_sum() 就是求和,reduce_sum( input_tensor, axis=None, keep_dims=False, name=None, reduction_indices=None) # reduce_sum() 参数解释: # 1) input_tensor:输入的张量。 # 2) axis:沿着哪个维度求和。对于二维的input_tensor张量,0表示按列求和,1表示按行求和,[0, 1]表示先按列求和再按行求和。 # 3) keep_dims:默认值为Flase,表示默认要降维。若设为True,则不降维。 # 4) name:名字。 # 5) reduction_indices:默认值是None,即把input_tensor降到 0维,也就是一个数。对于2维input_tensor,reduction_indices=0时,按列;reduction_indices=1时,按行。 # 6) 注意,reduction_indices与axis不能同时设置。 # tf.matmul(a,b),将矩阵 a 乘以矩阵 b,生成a * b # tf.matmul(a,b)参数解释: # 1) a:类型为 float16,float32,float64,int32,complex64,complex128 和 rank > 1的张量。 # 2) b:与 a 具有相同类型和 rank。 # 3) transpose_a:如果 True,a 在乘法之前转置。 # 4) transpose_b:如果 True,b 在乘法之前转置。 # 5) adjoint_a:如果 True,a 在乘法之前共轭和转置。 # 6) adjoint_b:如果 True,b 在乘法之前共轭和转置。 # 7) a_is_sparse:如果 True,a 被视为稀疏矩阵。 # 8) b_is_sparse:如果 True,b 被视为稀疏矩阵。 # 9) name:操作名称(可选)

优化算法

optimizer = tf.train.AdamOptimizer( 1e- 4) # https://blog.csdn.net/lenbow/article/details/52218551 train = optimizer.minimize(loss) # Optimizer.minimize对一个损失变量基本上做两件事 # 它计算相对于模型参数的损失梯度。 # 然后应用计算出的梯度来更新变量。

第四步:训练模型 # tf.summary的用法 https://www.cnblogs.com/lyc-seu/p/8647792.html 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() #https://www.cnblogs.com/wuzhitj/p/6648610.html init = tf.global_variables_initializer() sess.run(init) #运行 for i in range(5000): _, movie_summary = sess.run([train, summaryMerged]) # 把训练的结果summaryMerged存在movie里 writer.add_summary(movie_summary, i) # 把训练的结果保存下来

查看训练结果: 在终端输入 tensorboard --logir=./

第五步:评估模型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) + rating_mean # dot函数是np中的矩阵乘法,np.dot(x,y) 等价于 x.dot(y) errors = np.sqrt(np.sum((predicts - rating)**2)) # sqrt(arr) ,计算各元素的平方根 errors

结果:4037.9002717628305 第六步:构建完整的电影推荐系统user_id = input('您要想哪位用户进行推荐?请输入用户编号:') sortedResult = predicts[:, int(user_id)].argsort()[::-1] # argsort()函数返回的是数组值从小到大的索引值; argsort()[::-1] 返回的是数组值从大到小的索引值 idx = 0 print('为该用户推荐的评分最高的20部电影是:'.center(80,'=')) # center() 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串。默认填充字符为空格。 for i in sortedResult: print('评分: %.2f, 电影名: %s' % (predicts[ i,int(user_id)],movies_df.iloc[ i][ 'title'])) # .iloc的用法:https://www.cnblogs.com/harvey888/p/6006200.html idx += 1 if idx == 20:break

结果:您要想哪位用户进行推荐?请输入用户编号:123 ==============================为该用户推荐的评分最高的20部电影是:=============================== 评分: 5.03, 电影名: Fireworks Wednesday (Chaharshanbe-soori) (2006) 评分: 4.88, 电影名: Woman on the Beach (Haebyeonui yeoin) (2006) 评分: 4.73, 电影名: Mummy's Ghost, The (1944) 评分: 4.66, 电影名: Maborosi (Maboroshi no hikari) (1995) 评分: 4.63, 电影名: Boiling Point (1993) 评分: 4.60, 电影名: Mala Noche (1985) 评分: 4.49, 电影名: All-Star Superman (2011) 评分: 4.47, 电影名: Bill Hicks: Relentless (1992) 评分: 4.45, 电影名: Something Borrowed (2011) 评分: 4.37, 电影名: Box of Moon Light (1996) 评分: 4.37, 电影名: Kwaidan (Kaidan) (1964) 评分: 4.35, 电影名: Sacrifice, The (Offret - Sacraficatio) (1986) 评分: 4.29, 电影名: Hotel de Love (1996) 评分: 4.27, 电影名: Aria (1987) 评分: 4.23, 电影名: Querelle (1982) 评分: 4.22, 电影名: Rocky VI (1986) 评分: 4.21, 电影名: Little Lord Fauntleroy (1936) 评分: 4.19, 电影名: Hardcore (1979) 评分: 4.16, 电影名: Three of Hearts (1993) 评分: 4.15, 电影名: White Stripes Under Great White Northern Lights, The (2009)

作者:Kervin_Chan 源自:https://juejin.im/post/5afbfe316fb9a07aa5427d73 #heading-5

转发此文到朋友圈并截图到后台,

获得20G

python入门视频课

往期实战及福利

关注本公众号,牧原小主 送您

2.7G 380份最新数据分析报告

40G 人工智能算法课

已关注的小伙伴,直接回复数据分析报告、人工智能算法

关注后,回复 PM2.5 获得 Python分析北京PM2.5,原来每年的值都在变少...所有源代码

关注后,回复“python3.7”,获得python 3.7官方最新pdf 文档

关注后,回复 世界杯, 获得 2018世界杯来了,利用Python预测冠军(附全部代码和数据集)所有源代码

关注后,回复“豆瓣电影“,获得 Python实战 | 手把手教你爬取豆瓣电影 Top 250(附全部代码及福利哦)所有源代码

关注后,回复“python可视化”,获得 利用python“三步”实现数据可视化,炫的不要不要的!所有源代码

长按二维码,关注我们

责任编辑:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值