协同过滤与矩阵分解推荐系统
本文最后更新于:2021年10月28日 晚上
协同过滤与矩阵分解
推荐系统
在如今的大数据时代,我们不断地在与推荐系统打交道。在音乐播放器中听几首喜欢的歌,不一会儿播放器就开始向你推荐类似的歌;打开B站刷几条视频,马上就有与之类似的视频出现在了你的首页。毫不夸张地说,我们已经处于一种广告效率最大化的环境之中,与之同来的是一个个的信息茧房,我们确实看到了当时我们喜欢的东西,但是不久之后我们也会为之感到无聊,于此同时我们对一些事物的偏见也会加深,人与人之间的隔阂也会加剧,推荐系统,我看还是随机点好(笑😂)。
影评推荐
今天我们来实现一个经典的推荐系统,该系统根据目标用户的影评(评分)情况来为他推荐他可能喜欢的电影。
协同过滤
我们很容易想到根据用户已经有的评价来找到与之相似的用户,然后根据相似用户的打分情况来推荐给目标用户。但是我们并不是总能找到这样的相似用户,而且按照协同滤波理论,我们需要维持一个 大小的矩阵。显然这里的和的数目都是非常巨大的,而且随着时间会不断增加。更不优雅的是这个矩阵显而易见是稀疏的,维持这样的矩阵会产生非常不必要的开销。
矩阵分解
矩阵分解的核心思想是将矩阵分解成两个矩阵的乘积,其中为用户矩阵,大小为;为物品矩阵,大小为,其中,为隐因子,我个人的理解就是用户之间、物品之间差异的表示。这样一来我们就将原来的平方空间复杂度转化成了线性空间复杂度,而且最为关键的,现在我们有了每个用户对所有物品评价的数据的近似值,有了这些数据,我们就能很方便的进行推荐了。
但是一般来讲我们是无法直接得到矩阵,我们只能对原数据进行拟合,使得在已有的数据集上尽可能地接近。这里我们使用SGD
算法进行拟合。
同时我们注意到对不同的用户,有些可能会偏好打低分,而有些喜欢打高分,对不同的物品也是如此,我们必须减去这些影响才能得到用户之间、物品之间的差距。
实验数据
输入:影评字典
1 |
|
目标,为Toby进行推荐。
我们进行模块化设计,以下为矩阵分解推荐系统的代码:
首先我们对要用的变量进行初始化:
1 |
|
定义添加数据集的函数,为了能多次添加数据,我们每次都会更新模型参数:
1 |
|
定义预测函数:
1 |
|
使用SGD的训练函数:
1 |
|
最后,定义推荐函数:
1 |
|
以上就是推荐系统的全部定义,下面我们来测试推荐系统性能:
1 |
|
在k=3、epoch=100、n=20、trainTestRate=0.7
的条件下我们得到了如下结果:
得到的Toby推荐评分矩阵为:
Snakes on a Plane | 4.369445 |
---|---|
Superman Returns | 3.865079 |
The Night Listener | 3.511469 |
Lady in the Water | 3.047306 |
Just My Luck | 2.428205 |
You, Me and Dupree | 1.211615 |
我们继续在不同k的情况下继续实验:
k = 5 | |
---|---|
k = 10 | |
k = 1 |
显然k越大数据变化越稳定,但是模型占据的空间就更大了,且模型更容易过拟合。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!