实战基于矩阵分解的推荐系统

简介: 基于矩阵分解算法的图书推荐系统实战

推荐系统


推荐系统,可以根据用户的喜好来推荐给用户不同的事物。

推荐系统类型:

  1. 纯手工设置推荐内容
  2. 根据物品的销量,曝光率等来排序物品,并推荐给用户
  3. 根据不同的算法,整合不同维度的数据,来智能的推荐物品


简单的推荐系统模型


设:

U 为所有用户集合

P 为所有物品集合

R 为用户对物品的喜好程度

模型 Model(R) = U * P

算法核心:

通过用户对不同物品的打分,来预测用户对其他物品的喜好程度。此处并没有考虑用户和物品的属性,如:用户年龄,性别,学历,工作等,物品价格,品类,外观等。

通过用户对物品的打分,可以建立一个推荐值矩阵,之后就可以通过运算该矩阵来预测用户喜好,即为矩阵分解算法!


矩阵分解:

将推荐值矩阵 R 分解为矩阵 U 和 矩阵 P,使得 U 和 P 的乘积得到的新矩阵 R* 中的元素与 R 中的已知元素的值非常接近,那么 R* 中对应于 R 中的未知元素的值就是预测值。

推荐值矩阵:


时间简史 万历三十年 大秦帝国 红楼梦 数学简史
小明 1
4
1
小王
2
2 4
小李 4
1
4
小张
5 1 4

推荐值矩阵关键性问题:

  1. 初始值获取,数据的收集
  2. 从推荐值矩阵中已知数据预测未知数据
  3. 建立评价系统,用于检验推荐系统的效果


收集数据

一般可以采取网络爬虫的方式,比如对于数据的评分,可以爬取豆瓣读书上的数据,也可以在自己可以控制的网站上做埋点等来收集用户信息。


预测未知数据

关键挑战:

  • 当用户和物品的数量都比较大时,推荐之矩阵通常会是一个稀疏矩阵(在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵),说明大多数用户可能并没有对大多数物品表达喜好。
  • 冷启动问题,是每一个推荐系统都需要面对的问题。

矩阵分解实例:

image.png

即:

image.png

对比最左侧的元素矩阵和最右侧的预测矩阵,预测矩阵中位于原始矩阵缺失数值位置的元素值,即为预测值。

同时也可以得到

image.png

即:对于在 ij 位置上的物品的喜好数据,可以通过第 i 个用户的画像向量和第 j 个物品的画像向量代表。

使用图形表示如下:

image.png

其中 k 在数学上的意义为矩阵分解的秩,在业务上的意义为 影响用户给物品评分的 k 个影响因子,当前我们无法直接知道 k 的值,在模型训练时,一般采取交叉验证的方式来寻找最优的 k 值。

我们可以使用“和方差”来作为损失函数

image.png

这里通过已知的{r(ij)},计算“和方差”,使之达到最小,即预测值越接近真实值。以此得出的 U 和 P 的值就是我们需要的值。

损失函数的梯度

单独取出误差

image.png

对误差 L 分别在 U 和 P 上求导可得

image.png


现在我们已经知道了损失函数的梯度(导数),下面就可以使用梯度下降法来求解 U 和 P 的值。

梯度下降法

image.png

随机选取一个起始点,然后在负梯度的方向上持续训练,直到损失函数的梯度越来越接近零,此时即可取得最优解。

引入正则化

为了防止过拟合的发生,对损失函数加入正则化参数

image.png

λ>0

这样,当 U 和 P 都保证比较小的情况下,U 或者 P 的数值剧烈变化时,U 和 P 的点积也不会有太大的变化。

最终的损失函数为:

image.png 

最终损失函数的梯度为:

image.png


运用梯度下降法求最优解

设定梯度下降的速率 γ(学习速率)和 k 值,并随机初始化 U 和 P,重复训练,直到误差满意为止。

image.png


评估推荐系统

  • 最基本的就是,通过训练集训练模型,通过测试集测试模型,如果模型在测试集上的表现达到我们的预期,则该模型可以上线部署。
    一般采用平均绝对离差来验证模型预测值的好坏
    image.png

n:测试集中推荐值的总数量

r(up):真实的用户 u 对物品 p 的推荐值

r*(up):预测的用户 u 对物品 p 的推荐值

  • 在线的 A/B 测试


项目实战


数据集格式如下:

1    1119    9.000000
1    167 8.000000
1    6265    8.000000
1    1440    9.000000
1    1427    9.000000
1    5404    8.000000
1    259 7.000000
1    4156    8.000000
2    419 9.000000
2    415 10.000000
2    2834    9.000000
2    228 10.000000
2    107 10.000000
2    440 9.000000
2    44  10.000000
2    455 10.000000

第一列为用户 ID,第二列为物品 ID,第三列为对应的打分(1-10)


总体代码基于 surprise 库,可以先安装

pip install scikit-surprise


下面导入相关库和数据集

import numpy as np
import surprise
from surprise import BaselineOnly
from surprise import Dataset
from surprise import Reader
from surprise import accuracy
from surprise.model_selection import cross_validate
from surprise.model_selection import train_test_split
reader = Reader(line_format='user item rating', sep='\t', rating_scale=(1, 10))
data = Dataset.load_from_file('book_ratings.dat.txt', reader=reader)
# 将数据随机分为训练和测试数据集
trainset, testset = train_test_split(data, test_size=.25)


根据公式,定义算法函数

class MatrixFactorization(surprise.AlgoBase):
    def __init__(self, lr, n_epochs, n_factors, lmd):
        self.lr = lr  # 梯度下降法的学习速率
        self.n_epochs = n_epochs  # 梯度下降法的迭代次数
        self.n_factors = n_factors  # 分解的矩阵的秩,即影响用户打分的隐藏因子
        self.lmd = lmd  # 正则化参数
    def fit(self, trainset):
        print("Fitting data...")
        # 随机初始化 u 和 p 矩阵
        u = np.random.normal(0, .1, (trainset.n_users, self.n_factors))  # 均值为0,方差为0.1,(行数,列数)
        p = np.random.normal(0, .1, (trainset.n_items, self.n_factors))
        # 梯度下降法
        for _ in range(self.n_epochs):
            print("Round:", _)
            for i, j, r_ij in trainset.all_ratings():
                # 这里就是套用上面得到的公式
                # u_old[i] = u[i]
                err = r_ij - np.dot(u[i], p[j])
                u[i] -= -self.lr * err * p[j] + self.lr * self.lmd * u[i]
                p[j] -= -self.lr * err * u[i] + self.lr * self.lmd * p[j]
        self.u, self.p = u, p
        self.trainset = trainset
        print("End fitting!")
    def estimate(self, i, j):
        if self.trainset.knows_user(i) and self.trainset.knows_item(j):
            return np.dot(self.u[i], self.p[j])
        else:
            return self.trainset.global_mean  # 返回平均值


最后再训练、预测,评估

algo = MatrixFactorization(0.005, 60, 3, 0.2)
algo.fit(trainset)
predictions = algo.test(testset)
accuracy.mae(predictions)

可以调整学习速率,迭代次数,隐藏因子个数和正则化参数等来训练不同的模型,并评估结果,获取满意的模型。

相关文章
|
4月前
|
数据采集 搜索推荐 算法
实战基于矩阵分解的推荐系统
实战基于矩阵分解的推荐系统
|
搜索推荐 算法 数据挖掘
# 【推荐系统入门到项目实战】(三):矩阵分解和ALS算法
# 【推荐系统入门到项目实战】(三):矩阵分解和ALS算法
# 【推荐系统入门到项目实战】(三):矩阵分解和ALS算法
|
12月前
|
机器学习/深度学习 并行计算 搜索推荐
推荐系统总结(交替最小二乘法、LightFM、神经网络矩阵分解和神经协同过滤)
在社交媒体网络上,有大量的半结构化数据。该任务的数据集是从在线照片共享社交媒体网络 Flickr 收集的。Flickr 允许用户分享照片并相互交流(朋友)。目标是向访问此社交媒体平台的大量数据的每个用户推荐对象(图片)列表。训练数据集包含一组用于构建推荐系统的用户和项目(照片)之间的交互,包含评分基本事实的验证数据用于决定最终模型。除测试数据外,其余数据集不用于分析。
380 0
|
机器学习/深度学习 搜索推荐 算法
# 【推荐系统入门到项目实战】(五):SVD矩阵分解 -
# 【推荐系统入门到项目实战】(五):SVD矩阵分解
# 【推荐系统入门到项目实战】(五):SVD矩阵分解 -
|
机器学习/深度学习 自然语言处理 搜索推荐
推荐系统[八]算法实践总结V2:排序学习框架(特征提取标签获取方式)以及京东推荐算法精排技术实战
推荐系统[八]算法实践总结V2:排序学习框架(特征提取标签获取方式)以及京东推荐算法精排技术实战
推荐系统[八]算法实践总结V2:排序学习框架(特征提取标签获取方式)以及京东推荐算法精排技术实战
|
机器学习/深度学习 人工智能 算法
【推荐系统】矩阵分解MF利用BASIC-SVD分解
【推荐系统】矩阵分解MF利用BASIC-SVD分解
111 0
【推荐系统】矩阵分解MF利用BASIC-SVD分解
|
机器学习/深度学习 人工智能 自然语言处理
【推荐系统】隐语义模型(LFD)与矩阵分解(Matrix Factorization)
【推荐系统】隐语义模型(LFD)与矩阵分解(Matrix Factorization)
153 0
【推荐系统】隐语义模型(LFD)与矩阵分解(Matrix Factorization)
|
数据采集 搜索推荐 PyTorch
推荐系统基础:使用PyTorch进行矩阵分解进行动漫的推荐
推荐系统基础:使用PyTorch进行矩阵分解进行动漫的推荐
253 0
推荐系统基础:使用PyTorch进行矩阵分解进行动漫的推荐
|
机器学习/深度学习 搜索推荐 算法
推荐系统的PMF - 概率矩阵分解和协同过滤(三)
推荐系统的PMF - 概率矩阵分解和协同过滤(三)
168 0
推荐系统的PMF - 概率矩阵分解和协同过滤(三)
|
监控 搜索推荐 Python
推荐系统的PMF - 概率矩阵分解和协同过滤(二)
推荐系统的PMF - 概率矩阵分解和协同过滤(二)
121 1
推荐系统的PMF - 概率矩阵分解和协同过滤(二)