矩阵分解

1.什么是矩阵分解?

矩阵分解就是预测出评分矩阵中的缺失值,然后根据预测值以某种方式向用户推荐。常见的矩阵分解方法有基本矩阵分解(basic MF),正则化矩阵分解)(Regularized MF),基于概率的矩阵分解(PMF)等。

\2. 矩阵分解的思想以及算法步骤?

此处我们只将用户—商品矩阵Rm×nRm×n分解为两个矩阵Pm×kPm×k和Qk×nQk×n,使得满足,

Rm×n≈Pm×k×Qk×n=R^m×n
Rm×n≈Pm×k×Qk×n=R^m×n
从而补全那些缺失值,进而为用户推荐那些可能感兴趣的商品。
我们将使用最小二乘法对那些非缺失的值进行损失评估,即
e2=(rij−r^ij)2=(rij−∑l=1kpil×qlj)2
e2=(rij−r^ij)2=(rij−∑l=1kpil×qlj)2
另外我们使用L2L2正则化,
L2=∑l=1k(p2il+q2lj)
L2=∑l=1k(pil2+qlj2)
其中i∈[1,m],j∈[1,n]i∈[1,m],j∈[1,n], k是我们所指定的大小,因此最终的损失函数为,
loss(pil,qlj)=e2+β2L2 其中pil,qlj即为分解的两个矩阵中的元素,也就是求解参数
loss(pil,qlj)=e2+β2L2 其中pil,qlj即为分解的两个矩阵中的元素,也就是求解参数
接下来我们就可以使用梯度下降算法求解Pm×kPm×k和Qk×nQk×n
∇ploss=∂ loss∂pil=−2(rij−r^ij)qlj+βpil=−2eijqlj+βpil
∇ploss=∂ loss∂pil=−2(rij−r^ij)qlj+βpil=−2eijqlj+βpil

∇qloss=∂ loss∂qlj=−2(rij−r^ij)pil+βqlj=−2eijpil+βqlj
∇qloss=∂ loss∂qlj=−2(rij−r^ij)pil+βqlj=−2eijpil+βqlj

So…,
pil=pil−∇ploss
pil=pil−∇ploss
qlj=qlj−∇qloss
qlj=qlj−∇qloss
这样我们就可以通过迭代(迭代次数,误差容忍度。。。)直到收敛。

\3. 什么是正则化?正则化的作用是什么?

设C是不可约平面代数曲线,S是C的奇点的集合。如果存在紧Riemann面C及全纯映射σ:C→PC^2,使得

(1) σ(C*)=C (2) σ^(-1)(S)是有限点集 (3) σ:C*\σ^(-1)(S)→C\S是一对一的映射

则称(C*,σ)为C的正则化。不至于混淆的时候,也可以称C*为C的正则化。

  1. 正则化就是对最小化经验误差函数上加约束,这样的约束可以解释为先验知识(正则化参数等价于对参数引入先验分布)。约束有引导作用,在优化误差函数的时候倾向于选择满足约束的梯度减少的方向,使最终的解倾向于符合先验知识(如一般的l-norm先验,表示原问题更可能是比较简单的,这样的优化倾向于产生参数值量级小的解,一般对应于稀疏参数的平滑解)。
  2. 同时,正则化解决了逆问题的不适定性,产生的解是存在,唯一同时也依赖于数据的,噪声对不适定的影响就弱,解就不会过拟合,而且如果先验(正则化)合适,则解就倾向于是符合真解(更不会过拟合了),即使训练集中彼此间不相关的样本数很少。

\4. 代码实现

from math import *
import numpy
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                 # .T操作表示矩阵的转置
    result=[]
    for step in range(steps): #梯度下降
        for i in range(len(R)):
            for j in range(len(R[i])):
                    eij=R[i][j]-numpy.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])   #增加正则化,并对损失函数求导,然后更新变量P
                        Q[k][j]=Q[k][j]+alpha*(2*eij*P[i][k]-beta*Q[k][j])   #增加正则化,并对损失函数求导,然后更新变量Q
        eR=numpy.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]-numpy.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为阈值
            break
    return P,Q.T,result

if __name__ == '__main__':   #主函数
    R=[                 #原始矩阵,无评分用0代替
        [5,3,0,1],
        [4,0,0,1],
        [1,1,0,5],
        [1,0,0,4],
        [0,1,5,4]
    ]
    R=numpy.array(R)    #创建一个array
    N=len(R)            #原矩阵R的行数
    M=len(R[0])         #原矩阵R的列数
    K=3                 #K值可根据需求改变
    P=numpy.random.rand(N,K) #随机生成一个 N行 K列的矩阵
    Q=numpy.random.rand(M,K) #随机生成一个 M行 K列的矩阵
    nP,nQ,result=matrix_factorization(R,P,Q,K)
    R_MF=numpy.dot(nP,nQ.T)
    print(R_MF)      #输出新矩阵
    #数据可视化(画出图像)
    plt.plot(range(len(result)),result)
    plt.xlabel("time")
    plt.ylabel("loss")            #loss  :损失函数
    plt.show()


运行结果:
[[4.98765298 2.95236783 4.35100489 0.99986468]
[3.97009465 2.32223303 3.5983697 0.99647856]
[1.05398001 0.8612008 5.3682779 4.9637146 ]
[0.97427659 0.89285051 4.5631002 3.97184612]
[1.62385446 1.17360362 4.923405 4.03090791]]

\5.什么是测试集 训练集k折交叉验证

测试集:作用:检验最终选择最优的模型的性能如何

主要是测试训练好的模型的分辨能力(识别率等)

交叉验证往往是对实际应用中数据不充足而采用的,基本目的就是重复使用数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值