实战智能推荐系统(10)-- 隐语义模型 LFM (Funk-SVD)

关于隐语义模型,其中之一就是本专栏第(2)节讲过的 -- SVD矩阵分解及其正则化 。LFM 模型通过如下公式计算用户 u 对物品 i 的兴趣:

其中P 和 Q 的解释同第(2)节,不再累述。但可以解释一下隐类 K:

假如用户喜欢看电影,但是兴趣比较广泛。如果采用协同过滤的算法,那么很难满足用户广泛的兴趣及其比重。假如用户80%的时间喜欢看科幻电影,20% 的时间喜欢看动画片。那么协同过滤无法考虑到这种兴趣的比重并合理推荐。我们就将 K 设定为2,定义两个隐类,将用户与隐类的联系设成矩阵 P;同理,将隐类与物品的联系设成矩阵 Q,形成了隐语义模型 LFM。

如何通过隐反馈数据获得 SVD 的 UI 矩阵?

在 SVD 中,UI 矩阵的行代表用户U,列代表物品I,其中的数字代表用户 U 对 I 的评分。但是在隐反馈数据中,只有正样本,没有负样本,要得到 UI 矩阵,必须要有负样本。因此要进行负样本采样,采样原则如下:

(1)对每个用户,从他没有行为的物品中采样一些物品作为负样本。
(2)要保证正负样本的数量相当。

(3)对每个用户采样负样本时,选择那些很热门,用户却没有行为的物品比冷门用户没有行为的物品更佳。

负样本采样代码如下:

def RandomSelectNegativeSample(items):
    ret = dict()
    for i in items.keys():
        ret[i] = 1 #已有的物品为 1 代表正样本
    n = 0 
    for i in xrange(len(items) * 3):
        #items_pool 维护了一个候选物品表,在这个列表中
        #物品 i 出现的次数和物品 i 的流行度成正比
        item = items_pool[random.randint(0,len(items_pool) - 1)]
        if item in ret:continue
        ret[item] = 0 #负样本
        n += 1
        if n > len(items):break #保证正负平衡
    return ret

梯度下降求解 SVD 

直接引入第(2)节的结果,加入了正则化的 SVD 矩阵的梯度下降公式为:

将其中的2 设成 alpha ,称之为学习率,则如下:

下面的代码实现了这一梯度下降过程:

def LatenFactorModel(user_items, K, N, alpha, lambda):
    [P,Q] = InitModel(user_items,K) #生成 K 个隐类的 P,Q 矩阵
    for step in range(0,N):
        for user,items in user_items.items():
            samples = RandomSelectNegativeSample(items)
            for item,rui in samples.items():
                eui = rui - Predict(user,item) #Predict 根据 P,Q 矩阵计算 ^rui
                for k in range(0,K):
                    P[user][k] += alpha * (eui * Q[k][item] - lambda * P[user][k])
                    Q[k][item] += alpha * (eui * P[user][k] - lambda * Q[k][item])
        
        alpha *= 0.9 #学习率衰减

得到 P, Q 矩阵后生成推荐

通过梯度下降算法获得 P, Q 矩阵后,我们就可以根据矩阵生成推荐,代码如下:

def Recommend(user, P, Q):
    rank = dict()
    for u,puk in P[user].items():
        for i,qki in Q[u].items():
            if i not in rank:
                rank[i] = puk * qki #矩阵乘法
    return rank

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值