
之前我们手动构建了一个小型的神经网络,解决了机器学习的分类问题,本次我们利用深度学习框架Tensorflow2.11构建一套基于神经网络协同过滤模型(NCF的视频推荐系统,解决预测问题,完成一个真正可以落地的项目。
推荐系统发展历程
大约20年前,在北京中关村的街头,一位抱着婴儿的中年大妈兴奋地拽着笔者的胳臂,手舞足蹈地推荐着她的“产品”,大概这就是最原始的推荐系统雏形了。
所以推荐系统解决的痛点应该是用户的兴趣需求,给用户推荐喜欢的内容,才是推荐系统的核心。
启发式推荐算法易于实现,并且推荐结果的可解释性强。启发式推荐算法又可以分为两类:
基于物品的协同过滤(Item-based collaborative filtering):主要考虑的是物品和物品之间的相似度,只有找到了目标用户对某些物品的评分,那么就可以对相似度高的类似物品进行预测,将评分最高的若干个相似物品推荐给用户。举个例子,如果用户A、B、C给书籍X,Y的评分都是5分,当用户D想要买Y书籍的时候,系统会为他推荐X书籍,因为基于用户A、B、C的评分,系统会认为喜欢Y书籍的人在很大程度上会喜欢X书籍。
然而,启发式协同过滤算法也存在一些缺陷:
对数据稀疏性敏感:如果数据集中存在大量的缺失值,启发式协同过滤算法的预测准确率会受到影响,因为它需要依赖于完整的评分数据来进行预测。
受限于启发式规则的质量:启发式协同过滤算法的预测准确率受到启发式规则的质量影响,如果启发式规则得不到有效的优化和更新,算法的性能可能会受到影响。
为了解决上面的问题,基于神经网络的协同过滤算法诞生了,神经网络的协同过滤算法可以通过将用户和物品的特征向量作为输入,来预测用户对新物品的评分,从而解决冷启动问题。
更好的预测准确率:神经网络的协同过滤算法可以通过多层非线性变换来学习用户和物品之间的复杂关系,从而能够提高预测准确率。
所以基于神经网络协同过滤模型是目前推荐系统的主流形态。
基于稀疏矩阵的视频完播数据
User,Video 1,Video 2,Video 3,Video 4,Video 5,Video 6
User1,10,3,,,,
User2,,10,,10,5,1
User3,,,9,,,
User4,6,1,,8,,9
User5,1,,1,,10,4
User6,1,4,1,,10,1
User7,,2,1,2,,8
User8,,,,1,,
User9,1,,10,,3,1
这里横轴是视频数据,纵轴是用户,对应的数据是用户对于视频的完播程度,10代表看完了,1则代表只看了百分之十,留空的代表没有看。
import pandas as pd
# set pandas to show all columns without truncation and line breaks
pd.set_option('display.max_columns', 1000
pd.set_option('display.width', 1000
# data = np.loadtxt('data/test-data.csv', delimiter=',', dtype=int, skiprows=1,
data = pd.read_csv('data/test-data.csv'
print(data
程序返回:
User Video 1 Video 2 Video 3 Video 4 Video 5 Video 6
0 User1 10.0 3.0 NaN NaN NaN NaN
1 User2 NaN 10.0 NaN 10.0 5.0 1.0
2 User3 NaN NaN 9.0 NaN NaN NaN
3 User4 6.0 1.0 NaN 8.0 NaN 9.0
4 User5 1.0 NaN 1.0 NaN 10.0 4.0
5 User6 1.0 4.0 1.0 NaN 10.0 1.0
6 User7 NaN 2.0 1.0 2.0 NaN 8.0
7 User8 NaN NaN NaN 1.0 NaN NaN
8 User9 1.0 NaN 10.0 NaN 3.0 1.0
一目了然。
矩阵拆解算法
有一种推荐算法是基于矩阵拆解,通过假设的因素去“猜”稀疏矩阵的空缺数据,猜出来之后,再通过反向传播的逆运算来反推稀疏矩阵已存在的数据是否正确,从而判断“猜”出来的数据是否正确:
但是这套逻辑过于线性,也就是因素过于单一,比如我喜欢黑色的汽车,那么就会给我推所有黑色的东西,其实可能黑色的因素仅局限于汽车,是多重因素叠加导致的,所以矩阵拆解并不是一个非常好的解决方案。
基于神经网络
# reset the column.index to be numeric
user_index = data[data.columns[0]]
book_index = data.columns
data = data.reset_index(drop=True
data[data.columns[0]] = data.index.astype('int'
# print(data
# print(data
scaler = 10
# data = pd.DataFrame(data.to_numpy(, index=range(0,len(user_index, columns=range(0,len(book_index
df_long = pd.melt(data, id_vars=[data.columns[0]],
ignore_index=True,
var_name='video_id',
value_name='rate'.dropna(
df_long.columns = ['user_id', 'video_id', 'rating']
df_long['rating'] = df_long['rating'] / scaler
# replace the user_id to user by match user_index
df_long['user_id'] = df_long['user_id'].apply(lambda x: user_index[x]
# data = df_long.to_numpy(
print(df_long
程序返回:
user_id vide
编程笔记 » 构建基于深度学习神经网络协同过滤模型(NCF)的视频推荐系统(Python3.10/Tensorflow2.11)