参考地址:

贪心学院:https://github.com/GreedyAIAcademy/Machine-Learning

1矩阵分解概述

1.1用在什么地方

推荐系统:最著名的就那个烂大街的啤酒和尿布的故事,还有现在头条的投喂用户使用的也是推荐系统。就不多说了。

1.2推荐的原理

设,矩阵R代表3个用户对4部影片的评分,矩阵U和P是通过算法分解出来的矩阵,R是预测出来的矩阵。

此时我们可以看出, 矩阵R
中的值很接近原始矩阵R中的值,这样填补之后的值就是我们要的数字。

2矩阵分解的原理

2.1目标函数

如1.2所示,我们希望的结果就是R*中的结果与R中的结果差值最小。

因此我们可以得到目标函数:

\[arg \min_{U,P} \sum_{(i,j) \in Z}(R_{ij}-U_{i}P_{j}^{T})^2 \\
\\
Z = \{(i,j):r_{ij} 已知\}
\]

\(U_i P_j\)为行向量,分别来自于矩阵U和矩阵P的第i行和第j行;分别代表了第i个用户的画像向量,和第j个物品的画像向量。

2.2 损失函数

为了方便求导,我们乘个1/2,结果如下:

\[arg \min_{U,P} \sum_{(i,j) \in Z}\frac{1}{2}(R_{ij}-U_{i}\cdot P_{j})^2 \\
\\
Z = \{(i,j):r_{ij} 已知\}
\]

继续计算结果如下:

\[L_{ij} = \frac{1}{2}(R_{ij}-U_{i}\cdot P_{j})^2 \\
\]

得到损失梯度如下:

\[\frac{\partial L_{ij}}{\partial U_{i}}= \frac{\partial }{\partial U_{i}} [\frac{1}{2}(R_{ij}-U_{i}\cdot P_{j})^2] = -P_j(R_{ij}-U_{i}\cdot P_{j}) \\
\\
\frac{\partial L_{ij}}{\partial P_{j}}= \frac{\partial }{\partial P_{j}} [\frac{1}{2}(R_{ij}-U_{i}\cdot P_{j})^2] = -U_i(R_{ij}-U_{i}\cdot P_{j})
\]

为了防止过拟合和训练过程中的误差,加入正则项

\[arg \min_{U,P} \sum_{(i,j) \in Z}\frac{1}{2}(R_{ij}-U_{i}\cdot P_{j})^2 + \lambda [ \sum_{i=1}^{m}\left \| U_i \right \|^2 + \sum_{i=1}^{n}\left \| P_j \right \|^2]
\]

再求偏导可得:

\[\frac{\partial L_{ij}}{\partial U_{i}}=-P_{j}(R_{ij}-U_{i}\cdot P_{j}) + \lambda U_{i} \\
\\
\frac{\partial L_{ij}}{\partial P_{j}}=-U_{i}(R_{ij}-U_{i}\cdot P_{j}) + \lambda P_{j} \\
\]

2.3 通过梯度下降的方法求得结果

设定k的值,设定学习步长\(\gamma\)(learning rate),初始化U和P,重复以下步骤直到均方差满意为止:

遍历Z中的(i,j),Z={(i,j):\(r_{ij}\)已知}

\[U_{i}\leftarrow U_{i} - \gamma \frac{\partial L_{ij}}{\partial U_{i}} \\
P_{j}\leftarrow P_{j} - \gamma \frac{\partial L_{ij}}{\partial P_{j}} \\
\]

3 代码实现

看了上面的公式肯定是一知半解的,但看了矩阵分解函数,就会对梯度下降问题的解决方法豁然开朗

代码:

# 导入 nunpy 和 surprise 辅助库
import numpy as np
import surprise # 计算模型
class MatrixFactorization(surprise.AlgoBase):
'''基于矩阵分解的推荐.''' def __init__(self, learning_rate, n_epochs, n_factors, lmd): self.lr = learning_rate # 梯度下降法的学习率
self.n_epochs = n_epochs # 梯度下降法的迭代次数
self.n_factors = n_factors # 分解的矩阵的秩(rank)
self.lmd = lmd # 防止过拟合的正则化的强度 def fit(self, trainset):
'''通过梯度下降法训练, 得到所有 u_i 和 p_j 的值''' print('Fitting data with SGD...') # 随机初始化 user 和 item 矩阵.
u = np.random.normal(0, .1, (trainset.n_users, self.n_factors))
p = np.random.normal(0, .1, (trainset.n_items, self.n_factors)) # 梯度下降法
for _ in range(self.n_epochs):
for i, j, r_ij in trainset.all_ratings():
err = r_ij - np.dot(u[i], p[j])
# 利用梯度调整 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]
# 注意: 修正 p_j 时, 按照严格定义, 我们应该使用 u_i 修正之前的值, 但是实际上差别微乎其微 self.u, self.p = u, p
self.trainset = trainset def estimate(self, i, j):
'''预测 user i 对 item j 的评分.''' # 如果用户 i 和物品 j 是已知的值, 返回 u_i 和 p_j 的点积
# 否则使用全局平均评分rating值(cold start 冷启动问题)
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 # 应用
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
import os # 数据文件
file_path = os.path.expanduser('./ml-100k/u.data') # 数据文件的格式如下:
# 'user item rating timestamp', 使用制表符 '\t' 分割, rating值在1-5之间.
reader = Reader(line_format='user item rating timestamp', sep='\t', rating_scale=(1, 5))
data = Dataset.load_from_file(file_path, reader=reader) # 将数据随机分为训练和测试数据集
trainset, testset = train_test_split(data, test_size=.25) # 初始化以上定义的矩阵分解类.
algo = MatrixFactorization(learning_rate=.005, n_epochs=60, n_factors=2, lmd = 0.2) # 训练
algo.fit(trainset) # 预测
predictions = algo.test(testset) # 计算平均绝对误差
accuracy.mae(predictions) #结果:0.7871327139440717 # 使用 surpise 内建的基于最近邻的方法做比较
algo = surprise.KNNBasic()
algo.fit(trainset)
predictions = algo.test(testset)
accuracy.mae(predictions) #结果:0.7827160139309475 # 使用 surpise 内建的基于 SVD 的方法做比较
algo = surprise.SVD()
algo.fit(trainset)
predictions = algo.test(testset)
accuracy.mae(predictions) #结果:0.7450633876817936

机器学习笔记7:矩阵分解Recommender.Matrix.Factorization的更多相关文章

  1. 矩阵分解(matrix factorization)

    1. 基本概念 针对高维空间中的数据集,矩阵分解通过寻找到一组基及每一个数据点在该基向量下的表示,可对原始高维空间中的数据集进行压缩表示. 令 X=[x1,⋯,xm]∈Rm×n 为数据矩阵,矩阵分解的 ...

  2. Matrix Factorization SVD 矩阵分解

    Today we have learned the Matrix Factorization, and I want to record my study notes. Some kownledge ...

  3. 简单的基于矩阵分解的推荐算法-PMF, NMF

    介绍: 推荐系统中最为主流与经典的技术之一是协同过滤技术(Collaborative Filtering),它是基于这样的假设:用户如果在过去对某些项目产生过兴趣,那么将来他很可能依然对其保持热忱.其 ...

  4. Non-negative Matrix Factorization 非负矩阵分解

    著名的科学杂志<Nature>于1999年刊登了两位科学家D.D.Lee和H.S.Seung对数学中非负矩阵研究的突出成果.该文提出了一种新的矩阵分解思想――非负矩阵分解(Non-nega ...

  5. 关于NMF(Non-negative Matrix Factorization )

    著名的科学杂志<Nature>于1999年刊登了两位科学家D.D.Lee和H.S.Seung对数学中非负矩阵研究的突出成果.该文提出了一种新的矩阵分解思想――非负矩阵分解(Non-nega ...

  6. 吴恩达机器学习笔记59-向量化:低秩矩阵分解与均值归一化(Vectorization: Low Rank Matrix Factorization & Mean Normalization)

    一.向量化:低秩矩阵分解 之前我们介绍了协同过滤算法,本节介绍该算法的向量化实现,以及说说有关该算法可以做的其他事情. 举例:1.当给出一件产品时,你能否找到与之相关的其它产品.2.一位用户最近看上一 ...

  7. 【RS】Matrix Factorization Techniques for Recommender Systems - 推荐系统的矩阵分解技术

    [论文标题]Matrix Factorization Techniques for Recommender Systems(2009,Published by the IEEE Computer So ...

  8. 推荐系统(recommender systems):预测电影评分--构造推荐系统的一种方法:低秩矩阵分解(low rank matrix factorization)

    如上图中的predicted ratings矩阵可以分解成X与ΘT的乘积,这个叫做低秩矩阵分解. 我们先学习出product的特征参数向量,在实际应用中这些学习出来的参数向量可能比较难以理解,也很难可 ...

  9. 论文笔记: Matrix Factorization Techniques For Recommender Systems

    Recommender system strategies 通过例子简单介绍了一下 collaborative filtering 以及latent model,这两个方法在之前的博客里面介绍过,不累 ...

随机推荐

  1. 网络协议 17 - HTTPDNS

    全球统一的 DNS 是很权威,但是我们都知道“适合自己的,才是最好的”.很多时候,标准统一化的 DNS 并不能满足我们定制的需求,这个时候就需要 HTTPDNS 了.     上一节我们知道了 DNS ...

  2. nlp语义理解的一点儿看法

    nlp领域里,语义理解仍然是难题! 给你一篇文章或者一个句子,人们在理解这些句子时,头脑中会进行上下文的搜索和知识联想.通常情况下,人在理解语义时头脑中会搜寻与之相关的知识.知识图谱的创始人人为,构成 ...

  3. .net core 运行不需命令行

    1.问题情景: 需要保证已安装.net core SDK,并且命令提示符下运行“dotnet --version”,有反应. 如果之前运行良好,现在却不行了,查看安装程序中存在.net core SD ...

  4. 【IntelliJ IDEA学习之三】IntelliJ IDEA常用快捷键

    版本:IntelliJIDEA2018.1.4 按场景列举一.打开设置CTRL + ALT + S:打开设置(File-->Settings...)Ctrl + Shift + Alt + S: ...

  5. 《Linux就该这么学》培训笔记_ch17_使用iSCSI服务部署网络存储

    <Linux就该这么学>培训笔记_ch17_使用iSCSI服务部署网络存储 文章最后会post上书本的笔记照片. 文章主要内容: iSCSI技术介绍 创建RAID磁盘阵列 配置iSCSI服 ...

  6. Spring JDBC最佳实践(3)

    原文地址:https://my.oschina.net/u/218421/blog/38598 spring jdbc包提供了JdbcTemplate和它的两个兄弟SimpleJdbcTemplate ...

  7. ssh密码登录+ Google Authenticator 实现双向认证

    通常我们直接通过ssh输入密码连接服务器,但这样很容易出现暴力破解情况,所以我们可以结合google的动态认证+ssh密码,这样能够大大的提升登陆的安全. 简单来说,就是当用户通过ssh登陆系统时,先 ...

  8. [转帖]Centos7防火墙配置rich-rule实现IP端口限制访问

    Centos7防火墙配置rich-rule实现IP端口限制访问 2019-02-18 18:05:35 sunny05296 阅读数 2143  收藏 更多 分类专栏: Linux   版权声明:本文 ...

  9. 乘法器——Wallace树型乘法器

    博主最近在看乘法器相关的知识,发现现在用的比较多的是booth编码的乘法器和Wallace树型乘法器,当然两者并不是互斥的关系,他们也可以结合使用.在这里给大家介绍一下Wallace树型乘法器,希望能 ...

  10. 【Python爬虫案例学习】Python爬取天涯论坛评论

    用到的包有requests - BeautSoup 我爬的是天涯论坛的财经论坛:'http://bbs.tianya.cn/list.jsp?item=develop' 它里面的其中的一个帖子的URL ...