博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LFM 隐语义模型
阅读量:4979 次
发布时间:2019-06-12

本文共 3230 字,大约阅读时间需要 10 分钟。

隐语义模型:

物品       表示为长度为k的向量q(每个分量都表示  物品具有某个特征的程度)
用户兴趣 表示为长度为k的向量p(每个分量都表示  用户对某个特征的喜好程度)
用户u对物品i的兴趣可以表示为
  
其损失函数定义为-
      
使用随机梯度下降,获得参数p,q
 
负样本生成:
对于只有正反馈信息(用户收藏了,关注了xxx)的数据集,需要生成负样本,原则如下
1.生成的负样本要和正样本数量相当
2.物品越热门(用户没有收藏该物品),越有可能是负样本
 
实现:
# coding=gbk'''实现隐语义模型,对隐式数据进行推荐1.对正样本生成负样本  -负样本数量相当于正样本  -物品越热门,越有可能成为负样本2.使用随机梯度下降法,更新参数'''import numpy as npimport pandas as pdimport randomfrom sklearn import cross_validationclass LFM():        '''    初始化隐语义模型    参数:    *F  隐特征的个数    *N  迭代次数    *data 训练数据,要求为pandas的dataframe    *alpha 随机梯度下降的学习速率    *r 正则化参数    *ratio 负样本/正样本比例    '''    def __init__(self,data,F=100,N=1000,alpha=0.02,r=0.01,ratio=1):        self.F=F        self.N=N        self.alpha=alpha        self.r=r        self.data=data        self.ratio=ratio        '''    初始化物品池,物品池中物品出现的次数与其流行度成正比    '''        def InitItemPool(self):        self.itemPool=[]        groups = self.data.groupby([1])        for item,group in groups:            for i in range(group.shape[0]):                self.itemPool.append(item)        '''    获取每个用户对应的商品(用户购买过的商品)列表,如    {用户1:[商品A,商品B,商品C],     用户2:[商品D,商品E,商品F]...}    '''     def user_item(self,data):        ui = dict()        groups = data.groupby([0])        for item,group in groups:            ui[item]=set(group.ix[:,1])                return ui        '''    初始化隐特征对应的参数    numpy的array存储参数,使用dict存储每个用户(物品)对应的列    '''    def initParam(self):        users=set(self.data.ix[:,0])        items=set(self.data.ix[:,1])                self.Pdict=dict()        self.Qdict=dict()        for user in users:            self.Pdict[user]=len(self.Pdict)                for item in items:            self.Qdict[item]=len(self.Qdict)                self.P=np.random.rand(self.F,len(users))/10        self.Q=np.random.rand(self.F,len(items))/10        '''    使用随机梯度下降法,更新参数    '''    def stochasticGradientDecent(self):        alpha=self.alpha        for i in range(self.N):            for user,items in self.ui.items():                ret=self.RandSelectNegativeSamples(items)                for item,rui in ret.items():                   p=self.P[:,self.Pdict[user]]                   q=self.Q[:,self.Qdict[item]]                   eui=rui-sum(p*q)                   tmp=p+alpha*(eui*q-self.r*p)                   self.Q[:,self.Qdict[item]]+=alpha*(eui*p-self.r*q)                   self.P[:,self.Pdict[user]]=tmp            alpha*=0.9            print i                def Train(self):        self.InitItemPool()        self.ui = self.user_item(self.data)        self.initParam()        self.stochasticGradientDecent()        def Recommend(self,user,k):        items=self.ui[user]        p=self.P[:,self.Pdict[user]]                rank = dict()        for item,id in self.Qdict.items():            if item in items:                continue            q=self.Q[:,id];            rank[item]=sum(p*q)        return sorted(rank.items(),lambda x,y:cmp(x[1],y[1]),reverse=True)[0:k-1];    '''    生成负样本    '''    def RandSelectNegativeSamples(self,items):        ret=dict()        for item in items:            #所有正样本评分为1            ret[item]=1        #负样本个数,四舍五入        negtiveNum = int(round(len(items)*self.ratio))                N = 0        while N

 

转载于:https://www.cnblogs.com/porco/p/4412114.html

你可能感兴趣的文章
产品设计的经验分享
查看>>
IIS Media Service: Channel 小结
查看>>
安全防护与配置
查看>>
ANDROID SHAPE画圆形背景_ANDROID实现角标布局
查看>>
[Computer Netword] Tcp Udp 区别
查看>>
获取上一行记录lag
查看>>
配置ftp服务器
查看>>
【面试】二维数组中找数字
查看>>
在eclipse启动tomcat时遇到超时45秒问题的解决方法
查看>>
iReport报表的简单函数及部分操作
查看>>
bean 解析、注册、实例化流程源码剖析
查看>>
压缩、解压缩及归档工具
查看>>
Windows环境下Apache的reverse proxy报OS 10048的原因和解决办法
查看>>
调用CRM自己的Dialogue
查看>>
SAP服务开不起来:disp+work.EXE进程绿色变黄色的解决办法
查看>>
SpringMVC系列(十一)把后台返回的数据转换成json、文件下载、文件上传
查看>>
如何禁用OneDrive与Win10的集成
查看>>
EL表达式不解析
查看>>
预测出现代码问题及解决方法
查看>>
协作图(Collaboration Diagram)—UML图(七)
查看>>