推荐系统3——隐语义分析(LFM)

在之前我也看了很多人写的推荐系统的博客,理论的、算法的都有,多是个人的理解和感悟,虽然很深刻,但是对于自己而言还是不成系统,于是我参考大牛项亮编著的《推荐系统实践》将该领域知识系统整理一遍,与大家一起学习。
本系列对应的代码请查看https://github.com/wangyuyunmu/Recommended-system-practice
上一篇总结了基于用户行为数据的推荐方法——协同过滤,本篇继续总结基于用户行为数据的相关推荐方法——隐语义。



如何给用户userA推荐item?
1)UserCF通过寻找userA相关的user,找到topN的tems
2)ItemCF找到userA喜欢的item对应的topN的item
3)找到userA对item的兴趣关系(隐语义)以及兴趣与item的关系,来确定user与item的关系。
隐语义分析的核心思想:通过隐含特征(latent factor)联系用户和数据。

1,隐语义分析

对基于兴趣分类的方法,需要解决三个问题:
1)如何对物品进行分类?
2)如何确定用户对哪些类的物品感兴趣,以及感兴趣的程度?
3)对于给定的一个类,选择哪些属于这个类的物品给用户,以及他们的权重?
第一个分类问题可以人工进行处理,但是人分类的主观性、有限性,容易带来偏差和不全面。因此需要从数据出发,自动的进行物品分类,然后进行个性化推荐。

2,LFM(latent factor model)算法

LFM算法的兴趣指标公式如下:
p r e f e r e n c e ( u , i ) = r u i = p u t q i = ∑ k = 1 K p u , k q i , k preference(u,i)=r_{ui}=p_u^tq_i=\sum_{k=1}^Kp_{u,k}q_{i,k} preference(u,i)=rui=putqi=k=1Kpu,kqi,k

r表示用户u对物品i的兴趣,是用户u与隐含类k的关系和物品i与隐含类k的关系决定的。所以需要求得用户对每个类别的关系参数p、每个item与类别的关系参数q,这两个参数。测试的时候只要给定user,计算所有item对应的兴趣指标r,根据r的大小可以判定用户u对item的喜好程度。

C = ∑ ( u , i ) ( r u i − r ^ u i ) 2 = ∑ u , i ( r u i − ∑ k = 1 K p u , k q i , k ) 2 + λ ∥ p u ∥ 2 + λ ∥ q i ∥ 2 C=\sum_{(u,i)}(r_{ui}-\hat r_{ui})^2=\sum_{u,i}(r_{ui}-\sum_{k=1}^Kp_{u,k}q_{i,k})^2+\lambda\Vert p_{u} \Vert^2+\lambda\Vert q_{i} \Vert^2 C=(u,i)(ruir^ui)2=u,i(ruik=1Kpu,kqi,k)2+λpu2+λqi2

C表示loss,是目标喜好程度与预测喜好程度的方差。

2.1 负样本

1)那么目标r是多少呢?
对于显性反馈数据集,r表示用户的评分。
2)对于隐语义数据集,没有负样本怎么办?
对于隐反馈数据集,数据没有评分,没有正负样本的区别,这里就需要自定义训练集的正负样本,正样本为1,负样本为0。负样本可以采样获得。对于user没有标记为喜好的item中采样,得到与正样本相似大小的数据集,保证样本平衡性(这一点很重要);作为负样本集,其中尽量选取热门的item。

这里书中是分步随机选取的负样本,其速度要比下面一种方法快一点(大概24s一次),但是并没有按照流行度采样,如果按照流行度逐个采样,速度太慢(3.5m一次)。所以还是选择一次性多个随机采样的方法,虽然采集的样本数目不是特别准确,但是误伤大雅,速度也可以(30s一次)。

# # 分步按照流行度采集负样本
        # for user in new_data:
        #     seen = set(new_data[user])
        #     pos_num = len(seen)
        #     n = 0
        #     for i in range(pos_num*3):
        #         # temp = items[np.random.randint(0,len(items)-1)]
        #         temp = np.random.choice(items, 1, pops)[0]
        #         if temp in new_data[user]:
        #             continue
        #         new_data[user][temp] = 0
        #         n += 1
        #         if n > pos_num*ratio:
        #             break

        # 负样本
        for user in new_data:
            seen = set(new_data[user])
            pos_num = len(seen)
            item = np.random.choice(items, int(pos_num * ratio * 3), pops)
            item = [x for x in item if x not in seen][:int(pos_num * ratio)]
            new_data[user].update({x: 0 for x in item})

2.2 算法优化

那么通过梯度下降算法,对loss两个参数求导,就可以获得梯度,优化即可。

∂ C ∂ p u k = − 2 q i k ( r u i − ∑ k = 1 K p u , k q i , k ) + 2 λ p u k \frac {\partial C}{\partial p_{uk}}=-2q_{ik}(r_{ui}-\sum_{k=1}^Kp_{u,k}q_{i,k})+2\lambda p_{uk} pukC=2qik(ruik=1Kpu,kqi,k)+2λpuk
∂ C ∂ q i k = − 2 p u k ( r u i − ∑ k = 1 K p u , k q i , k ) + 2 λ q i k \frac {\partial C}{\partial q_{ik}}=-2p_{uk}(r_{ui}-\sum_{k=1}^Kp_{u,k}q_{i,k})+2\lambda q_{ik} qikC=2puk(ruik=1Kpu,kqi,k)+2λqik

# 训练
    P, Q = {}, {}
    for user in train:
        P[user] = np.random.random(K)
    for item in items:
        Q[item] = np.random.random(K)

    for s in trange(step):
        data = nSample(train, ratio)
        for user in data:
            for item in data[user]:
                eui = data[user][item] - (P[user] * Q[item]).sum()
                P[user] += lr * (Q[item] * eui - lmbda * P[user])
                Q[item] += lr * (P[user] * eui - lmbda * Q[item])
        lr *= 0.9  # 调整学习率

由此看来,LFM算法需要维护两个表p、q,参数共有k*(u+i)个,其受类别k的影响,要比CF算法保存的相关性表格小的多。
推荐过程:训练好p、q之后,给定一个user,遍历所有item,计算r,排序得到topN个items。

 # 获取接口函数
    def GetRecommendation(user):
        seen_items = set(train[user])
        recs = {}
        for item in items:
            if item not in seen_items:
                recs[item] = (P[user] * Q[item]).sum()
        recs = list(sorted(recs.items(), key=lambda x: x[1], reverse=True))[:N]
        return recs

训练结果如下:

#M=8取平均,top-n=10,ratio=5,负样本5倍
Metric: {'Precision': 25.9, 'Recall': 12.44, 'Coverage': 26.5, 'Popularity': 7.10661}

2.3 LFM与CF对比

LFM方法与基于邻域的方法(CF)比较:
1,LFM是一种学习方法,CF是统计方法
2,LFM空间复杂度O(F*(M+N)),CF的空间复杂度O(MM)或者O(NN)
3,离线时间复杂度差不多
4,CF可以在内存中保存一个表,进行实时推荐。LFM在推荐时需要遍历每一个物品然后进行排名,当item很多时,时间复杂度很高,不太适用于物品非常多的系统;LFM在生成用户推荐表时太慢,不能实时计算。
5,解释性不强,无法用语言描述解释推荐原因。

2.4 其他模型

隐语义模型(LFM,latent factor model),相关的有LSI、pLSA、LDA和topic model。隐含类别模型(latent class model)、隐含主题模型(latent topic model)、矩阵分解(MF)。

以上模型将会在其他专栏中总结。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值