矩阵分解及其代码实现
目录
1.问题引入
2.矩阵运算:
2.1矩阵相乘:
2.2矩阵转置
2.3矩阵分解:
2.4 预测矩阵的表示:
3.损失函数:
3.1. 首先
3.2如何构造损失函数
3.损失函数求解:
4.正则化:
5.python代码实现:
1.问题引入
个人认为学习这个内容需要掌握四大块:1.掌握矩阵的一些运算,2.了解损失函数的意思,3.了解正则化,4,最后看懂代码,进行一定程度上的代码实现。
下面对矩阵分解的学习会用上面的图片 ,Ui代表不同的用户,Di代表不同的物品,下面的数字代表每个用户对每个物品的评分(假设满分为5分)。
2.矩阵运算:
2.1矩阵相乘:
矩阵相乘的特点:
(1)当矩阵A的列数等于矩阵B的行数时,A与B才可以相乘。
(2)乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和。
(3)矩阵C的行数等于矩阵A的行数,C的列数等于B的列数
若有一个矩阵R,矩阵R可以近似表示为P和Q的乘积,即:R(n,m)≈ P(n,K)*Q(K,m)
2.2矩阵转置
把矩阵A的行换成同序数的列得到的新矩阵,叫做A的转置矩阵(Transpose of a Matrix),记作ATAT。
因此,转置矩阵的特点:
(1)转置矩阵的行数是原矩阵的列数,转置矩阵的列数是原矩阵的行数;
(2)转置矩阵下标(i,j)的元素对应于原矩阵下标(j,i)的元素
2.3矩阵分解:
矩阵分解的过程中,将原始矩阵
分解成两个矩阵
和
的乘积:
2.4 预测矩阵的表示:
在这个例子中我们将会用到矩阵分解和矩阵相乘
3.损失函数:
损失函数对我们来说并不陌生,我在线性回归的里面写到过这个内容,现在在写一遍:
损失函数定义:
损失函数是机器学习里最基础也是最为关键的一个要素,通过对损失函数的定义、优化,就可以衍生到我们现在常用的机器学习等算法中。
损失函数的作用:衡量模型模型预测的好坏。再简单一点说就是:损失函数就是用来表现预测与实际数据的差距程度。损失函数越小越好。
3.1. 首先
3.2如何构造损失函数
我认为就是求出原来的值与预测的值的差,然后再进行平方。
以上面的评分为例来说明:使用原有的评分矩阵Rm×n与重新构建的评分矩阵R^m×n进行相减求的误差的平方作为损失函数,即为
最后需要求的所有非负项的损失函数的最小值,在运用梯度下降算法时,也会用损失函数的值作为迭代的一个限制条件,还有一个限制条件就是迭代的次数(cnt)
3.损失函数求解:
对于损失函数求解我们可以利用梯度下降进行求导,对不同的变量进行求导,梯度下降法的核心步骤是:
- 求解损失函数的负梯度
因为e=
所以:
- 根据负梯度的方向更新变量:
通过不断迭代,不断更新值,和
,可以通过迭代次数和阈值作为限制条件
4.正则化:
为了防止过拟合,增加正则化项。
加入正则化的损失函数求解:
4.1.第一步和没有使用正则化是一样的
4.2. 加入正则化后的损失函数为:
即:
4.3.使用梯度下降法获得修正的p和q分量:
- 求解损失函数的负梯度:
- 根据负梯度的方向更新变量:
然后就通过不断迭代以此来不断更新值,直到遇到限制条件。
预测
5.python代码实现:
加正则化: 其中矩阵Q是新生成的一个M行K列矩阵,矩阵P是N行K列的矩阵,之后传入函数defmatrix_factorization(R,P,Q,K,steps=5000,alpha=0.0002,beta=0.02):中,在函数里面,Q=Q.T是为了得到转置,这样Q就变成了K行M列,这样就可以与P进行相乘得到最后的预测结果。
from math import *
import numpy as np
import matplotlib.pyplot as plt
def matrix_factorization(R,P,Q,K,steps=5000,alpha=0.0002,beta=0.02): #矩阵因子分解函数,steps:梯度下降次数;alpha:步长;beta:β。Q=Q.T#新生成的Q的转置矩阵 # .T操作表示矩阵的转置result=[]#用于储存加入正则化后的损失函数求和后的值for step in range(steps): #梯度下降,steps迭代次数for i in range(len(R)):#len(R)代表矩阵的行数for j in range(len(R[i])):#取每一行的列数eij=R[i][j]-np.dot(P[i,:],Q[:,j]) # .DOT表示矩阵相乘for k in range(K):if R[i][j]>0: #限制评分大于零P[i][k]=P[i][k]+alpha*(2*eij*Q[k][j]-beta*P[i][k]) #增加正则化,并对损失函数求导,然后更新变量PQ[k][j]=Q[k][j]+alpha*(2*eij*P[i][k]-beta*Q[k][j]) #增加正则化,并对损失函数求导,然后更新变量QeR=np.dot(P,Q)e=0#用来保存损失函数求和后的值for i in range(len(R)):#每一行循环for j in range(len(R[i])):#每一列循环if R[i][j]>0:e=e+pow(R[i][j]-np.dot(P[i,:],Q[:,j]),2) #损失函数求和for k in range(K):e=e+(beta/2)*(pow(P[i][k],2)+pow(Q[k][j],2)) #加入正则化后的损失函数求和result.append(e)if e<0.001: #判断是否收敛,0.001为阈值breakreturn P,Q.T,resultif __name__ == '__main__': #主函数R=[ #原始矩阵[5,3,0,1],[4,0,0,1],[1,1,0,5],[1,0,0,4],[0,1,5,4]]R=np.array(R)N=len(R) #原矩阵R的行数M=len(R[0]) #原矩阵R的列数K=3 #K值可根据需求改变P=np.random.rand(N,K) #随机生成一个 N行 K列的矩阵Q=np.random.rand(M,K) #随机生成一个 M行 K列的矩阵nP,nQ,result=matrix_factorization(R,P,Q,K)#nP=P,nQ=nQ.T,result=resultprint("输出原矩阵:")print(R) #输出原矩阵R_MF=np.dot(nP,nQ.T)#矩阵的乘积print("输出新矩阵:")print(R_MF) #输出新矩阵#画图plt.plot(range(len(result)),result)plt.xlabel("time")plt.ylabel("loss")plt.show()
输出结果:
输出原矩阵:
[[5 3 0 1][4 0 0 1][1 1 0 5][1 0 0 4][0 1 5 4]]
输出新矩阵:
[[4.98067845 2.9761162 2.84953808 1.00359896][3.97858746 1.78290637 3.12381968 1.00229724][1.00184528 0.9931711 2.78202187 4.97058181][0.99909932 0.85761773 2.38753953 3.98254216][3.32404613 1.00984832 4.98333193 3.98733355]]
python画图:
无正则化:在上面的基础上,通过修改写出未加入正则化的python代码:
from math import *
import numpy as np
import matplotlib.pyplot as plt
def matrix_factorization(R,P,Q,steps=5000,alpha=0.0002,beta=0.02): #矩阵因子分解函数,steps:梯度下降次数;alpha:步长;beta:β。Q=Q.T#新生成的Q的转置矩阵 # .T操作表示矩阵的转置result=[]#用于储存加入正则化后的损失函数求和后的值for step in range(steps): #梯度下降,steps迭代次数for i in range(len(R)):#len(R)代表矩阵的行数for j in range(len(R[i])):#取每一行的列数eij=R[i][j]-np.dot(P[i,:],Q[:,j]) # .DOT表示矩阵相乘for k in range(K):if R[i][j]>0: #限制评分大于零P[i][k]=P[i][k]+alpha*2*eij*Q[k][j] #没加入正则化,并对损失函数求导,然后更新变量PQ[k][j]=Q[k][j]+alpha*2*eij*P[i][k] #没加入正则化,并对损失函数求导,然后更新变量QeR=np.dot(P,Q)e=0#用来保存损失函数求和后的值for i in range(len(R)):#每一行循环for j in range(len(R[i])):#每一列循环if R[i][j]>0:e=e+pow(R[i][j]-np.dot(P[i,:],Q[:,j]),2) #损失函数求和result.append(e)if e<0.001: #判断是否收敛,0.001为阈值breakreturn P,Q.T,resultif __name__ == '__main__': #主函数R=[ #原始矩阵[5,3,0,1],[4,0,0,1],[1,1,0,5],[1,0,0,4],[0,1,5,4]]R=np.array(R)N=len(R) #原矩阵R的行数M=len(R[0]) #原矩阵R的列数,在这里求列数和行数,是为了P和Q相乘后与原矩阵具有相同的行和列K=3P=np.random.rand(N,K) #随机生成一个 N行 K列的矩阵Q=np.random.rand(M,K) #随机生成一个 M行 K列的矩阵nP,nQ,result=matrix_factorization(R,P,Q)#nP=P,nQ=nQ.T,result=resultprint("输出原矩阵:")print(R) #输出原矩阵R_MF=np.dot(nP,nQ.T)#矩阵的乘积print("输出新矩阵:")print(R_MF) #输出新矩阵#画图plt.plot(range(len(result)),result)plt.xlabel("time")plt.ylabel("loss")plt.show()
结果代码:
输出原矩阵:
[[5 3 0 1][4 0 0 1][1 1 0 5][1 0 0 4][0 1 5 4]]
输出新矩阵:
[[5.05012796 2.85469134 5.80052834 0.99533487][3.95534029 2.22271651 4.66029473 0.99616947][1.10372258 0.7124859 3.8909487 4.99555685][0.94579615 0.6751661 3.18376022 3.99414936][2.57938868 1.39377654 4.8865643 4.03595907]]
图示:
矩阵分解及其代码实现相关推荐
- 推荐系统之矩阵分解MF原理及Python实现
矩阵分解(Matrix Factorization) 矩阵分解基本原理 用户矩阵U与物品矩阵V求解 矩阵分解详解好文 实现矩阵分解Python代码 参考 矩阵分解基本原理 将mn维的共现矩阵R分解为m ...
- python 怎么取对数_概率矩阵分解(PMF)及MovieLens上的Python代码
首先对Probabilistic Matrix Factorization这篇论文的核心公式进行讲解和推导:然后用Python代码在Movielens数据集上进行测试实验. 一. 背景知识 文中作者提 ...
- python实现推荐系统代码_推荐系统之矩阵分解及其Python代码实现
有如下R(5,4)的打分矩阵:("-"表示用户没有打分) 其中打分矩阵R(n,m)是n行和m列,n表示user个数,m行表示item个数 那么,如何根据目前的矩阵R(5,4)如何对 ...
- 矩阵分解及用Python代码实现
对于一个打分的二维矩阵,一些没有打分,我们就可以通过矩阵分解的方法来解出那些没有打分的近似数值.所谓分解矩阵就是将矩阵分解为两个矩阵的乘积.矩阵分解的过程中,将原始的评分矩阵 分解成两个矩阵 矩阵P( ...
- 布尔矩阵分解 代码实现(BMF)--MEBF论文阅读
文章目录 关于布尔矩阵分解 布尔矩阵分解的思路 MEBF思路 MEBF算法流程及分析 代码实现 布尔矩阵分解测试 参考文献 关于布尔矩阵分解 最近在做有关布尔矩阵分解方面的研究,因为自己的方向需要,找 ...
- 推荐系统之矩阵分解(MF)没废话,有代码
前言 本文章,适合零基础学习MF(个人认为)数据集很小,只是简单但详细的讲解了矩阵分解,并给出了一个简单的代码 推荐系统中最为主流与经典的技术之一是协同过滤技术(Collaborative Filte ...
- 推荐系统入门(三):矩阵分解MF因子分解机FM(附代码)
推荐系统入门(三):矩阵分解MF&因子分解机FM(附代码) 目录 推荐系统入门(三):矩阵分解MF&因子分解机FM(附代码) 一. 矩阵分解MF 1. 隐含语义分析技术 1.1 隐语义 ...
- 矩阵分解(rank decomposition)文章代码汇总
矩阵分解(rank decomposition) 本文收集了现有矩阵分解的几乎所有算法和应用,原文链接:https://sites.google.com/site/igorcarron2/matrix ...
- 统计学习方法第十五章作业:SVD矩阵分解 代码实现 及其在推荐的应用和矩阵压缩意义
SVD矩阵分解 import numpy as npclass SVD:def __init__(self,x):self.x = np.array(x)def get_r_rv(self,x):x ...
最新文章
- 海归技术大佬:硅谷科技公司到底牛在哪里?讲透“奈飞文化”8个原则!
- delphi pdf 转换 html5,Delphi使用Word ActiveX将doc转换为pdf
- Django(part37)--session
- element-ui之dialog组件title插槽的使用
- 2. python 参数个数可变的函数
- linux 命令行模式下,浏览网页方法
- Storm精华问答 | 如何处理常见故障?
- LeetCode 题 - 58. 最后一个单词的长度 python解答
- 设计模式之不简单的工厂模式(一)
- nginx配置文件注释说明
- luajit官方性能优化指南和注解
- FreeMarker(七)Html转义
- 微信或者QQ如何制作请用右上角打开浏览器
- Softmax回归求导公式推导
- 微信企业支付 服务器根证书,微信支付服务器证书根ca证书有什么用
- Java项目:SSH自驾游管理系统
- 仿微博、微信、qq 点击缩略图, 查看高清图 UI 组件
- 文本识别(自然语言处理,NLP)
- 2019年中国在线酒店预订行业发展分析报告
- 蓝桥杯单片机串口通信学习提升笔记
热门文章
- Java基础篇-笔记 p1-p75
- 视频教程-从零开始开发3D跑酷游戏教程-Unity3D
- 苹果:Kindle Fire与Android平板鹬蚌相争,iPad渔翁得利
- vue的随意拖拽插件
- pks服务器清除归档文件路径,霍尼韦尔PKS系统备份及恢复
- sap服务器查看系统日志目录,服务器怎么看操作日志
- 数据库性能调优的10个方法介绍
- 解决Android Studio编译时INSTALL_FAILED_MISSING_SHARED_LIBRARY错误,提示 unavailable shared library wearable的问题
- 2023年6月29日DevOps国际峰会北京站大会报告
- 单片机与PLD(可编程逻辑器件)的联系与区别