zoukankan      html  css  js  c++  java
  • LFM矩阵分解

    对矩阵R的近似求解:

    1.

    其中,P矩阵维度:N*KQ矩阵维度:M*K。前者为UserK维潜因子空间的表示;后者为ItemK维潜因子空间的表示。

    2.预测评分,或者説近似评分为:

    3. 损失函数为平方误差+L2正则项:

    ,其中为真实评分。

    4.用梯度下降求解:

     其中是学习率,是正则化参数。

     5.代码如下,完整代码(预处理等,数据来自movielens, ml-100k)https://github.com/jiangnanboy/recommendation_methods/blob/master/com/sy/reco/recommendation/matrix_factorization/lfm.py

    import numpy as np
    import math
    import random
    
    '''
    LFM(latent factor model)隐语义推荐模型,利用矩阵分解来拟合原始评分矩阵,训练得到U,I矩阵
    对user-item评分矩阵进行分解为U、I矩阵,再利用随机梯度下降(函数值下降最快的方向)迭代求解出U,I矩阵,最后用U*I预测得出user对item的预测评分
    这里U矩阵是user对每个隐因子的偏好程度,I矩阵是item在每个隐因子中的分布
    最小化误差平方函数,加入正则化是为了减少过拟合
    '''
    class LFM():
        '''
        初始化ratingMatrix,F, alpha, λ
        ratingMatrix:评分矩阵
        F:隐因子数目
        alpha:学习速率
        λ:正则化参数,以防过拟合
        '''
        def __init__(self,ratingMatrix,F,alpha,λ):
            self.ratingMatrix=ratingMatrix
            self.F=F
            self.alpha=alpha
            self.λ=λ
    
        #对U,I矩阵初始化,随机填充,根据经验随机数与1/sqrt(F)成正比
        def __initPQ(self,userSum,itemSum):
            self.U=np.zeros((userSum,self.F))
            self.I=np.zeros((itemSum,self.F))
            for i in range(userSum):
                self.U[i]=[random.random()/math.sqrt(self.F) for x in range(self.F)]
            for i in range(itemSum):
                self.I[i]=[random.random()/math.sqrt(self.F) for x in range(self.F)]
    
        #预测打分,用户的行与项目的列
        def predict(self,user,item):
            I_T=self.I.T#项目矩阵转置
            pui=np.dot(self.U[user,:],I_T[:,item])
            return pui
    
        #迭代训练分解,max_iter:迭代次数
        def iteration_train(self,max_iter):
            userSum = len(self.ratingMatrix)  # 用户个数
            itemSum = len(self.ratingMatrix[0])  # 项目个数
            self.__initPQ(userSum,itemSum)#初始化U,I矩阵
            for step in range(max_iter):
                for user in range(userSum):
                    for item in range(itemSum):
                        if self.ratingMatrix[user,item]>0:#未评分的项目不参与计算
                            eui=self.ratingMatrix[user,item]-self.predict(user,item)#真实值减去预测的值
                            for f in range(self.F):
                                self.U[user,f]+=self.alpha*(self.I[item,f]*eui-self.λ*self.U[user,f])#更新
                                self.I[item,f]+=self.alpha*(self.U[user,f]*eui-self.λ*self.I[item,f])#更新
                #self.alpha*=0.9#对学习参数进行衰减,使用算法尽快收敛
            return np.round(np.dot(self.U,self.I.T),0)#返回全部,两个矩阵相乘
    
        #预测误差训练,convergence:误差收敛,小于这个误差
        def convergence_train(self,convergence):
            userSum = len(self.ratingMatrix)  # 用户个数
            itemSum = len(self.ratingMatrix[0])  # 项目个数
            self.__initPQ(userSum, itemSum)
            flag=True
            while flag:
                for user in range(userSum):
                    for item in range(itemSum):
                        if self.ratingMatrix[user,item]>0:#未评分的项目不参与计算
                            eui=self.ratingMatrix[user,item]-self.predict(user,item)#真实值减去预测的值
                            for f in range(self.F):
                                self.U[user,f]+=self.alpha*(self.I[item,f]*eui-self.λ*self.U[user,f])#更新
                                self.I[item,f]+=self.alpha*(self.U[user,f]*eui-self.λ*self.I[item,f])#更新
                #self.alpha*=0.9#对学习参数进行衰减,使用算法尽快收敛
    
                cost=0#误差
                for user in range(userSum):
                    for item in range(itemSum):
                        if self.ratingMatrix[user,item]>0:
                            cost+=(1/2)*math.pow(self.ratingMatrix[user,item]-np.dot(self.U[user],self.I.T[:,item]),2)
                            for f in range(self.F):
                                cost+=(1/2)*self.λ*(math.pow(self.U[user,f],2)+math.pow(self.I[item,f],2))
                if cost<convergence:
                    flag=False
            return np.dot(self.U,self.I.T)#返回全部,两个矩阵相乘
  • 相关阅读:
    Spring框架开发的三种模式
    IDEA 的Surround With快捷键
    Spring框架IOC和AOP的实现原理与详解
    mitmproxy 安装配置
    adb 使用
    小象代理
    requests 模块查看请求的ip地址
    smtplib 邮件模块
    淘宝直播数据爬取 + 淘宝模拟登陆
    postgresql基础操作
  • 原文地址:https://www.cnblogs.com/little-horse/p/12489619.html
Copyright © 2011-2022 走看看