目录

item2vec

原理

item2item(itemCF):基于用户喜爱的item来寻找相似的item推荐给用户
user2item(UserCF,LFM,personal rank):基于用户(喜好、历史行为等)计算出item列表推荐给用户

背景

  1. item2item效果不错,所以给用户推荐其行为过item的相似item是可行的
  2. 神经网络具有更好的特征抽象能力

物理意义

  1. 将用户的行为序列转化成item组成的句子
  2. 模仿word2vec训练word embedding将item embedding
  3. 故word2vec训练的结果是word之间的距离,而item2vec训练出来的结果就是item之间的距离(或相似性)

缺点

  1. 用户的行为序列时序性丢失:用户对item的行为顺序体现不出来
  2. 用户行为序列中的item强度是无区分性的:用户的喜爱程度体现不出,如对一个视频观看了10分钟, 对另一个视频观看了30分钟是体现不出来的,只能知道用户点击了这两个视频

算法流程

  1. 从log中抽取用户行为序列
  2. 将行为序列当成语料训练word2vec得到item embedding
  3. 等到item的相似关系用于推荐

word2vec

链接 https://bingdong.site/2020/03/word2vec/

item2vec

CBOW:

/images/recommenderSystem/cbow.png

/images/recommenderSystem/cbow2.png

/images/recommenderSystem/cbow3.png

  1. 选取中心词w以及负采样出NEG(w)
  2. 分别获得损失函数对于$x_w$与$θ^u$的梯度
  3. 更新$θ^u$以及中心词对应的context(w)的每一个词的词向量

Skip Gram:

/images/recommenderSystem/Skip.png

/images/recommenderSystem/Skip2.png

  1. 对context(w)中任何一个词$w^c$,选取词w的正负样本
  2. 计算Loss对θ以及对$w^c$的偏导
  3. 更新$w^c$对应的词向量

负采样:

/images/recommenderSystem/negsample.png

import os
import numpy as np

def produce_train_data(input_file, out_file):
    if not os.path.exists(input_file):
        return
    record = {}
    score_thr = 4.0
    with open(input_file, 'r') as f:
        next(f)
        for line in f:
            item = line.strip().split(',')
            if len(item) < 4:
                continue
            userid, itemid, rating = item[0], item[1], float(item[2])
            if rating <  score_thr:
                continue
            if userid not in record:
                record[userid] = []
            record[userid].append(itemid)
    with open(out_file, 'w') as f:
        for userid in record:
            f.write(" ".join(record[userid]) + "\n")

# 加载训练生成的word2vec文件
def load_item_vec(input_file):
    if not os.path.exists(input_file):
        return
    item_vec = {}
    with open(input_file, 'r') as f:
        next(f)
        for line in f:
            item = line.strip().split()
            # 词向量维数为128
            if len(item) < 129:
                continue
            itemid = item[0]
            if itemid == "</s>":
                continue
            item_vec[itemid] = np.array([float(ele) for ele in item[1:]])
    return item_vec


def produce_item_sim():
    pass


if __name__ == "__main__":
    produce_train_data("D:/document/Python/ml-latest-small/ratings.csv", "D:/document/Python/ml-latest-small/data.txt")
    
    # 通过word2vec对输入的data.txt进行训练得到词向量
    # 代码下载链接:https://code.google.com/archive/p/word2vec/source/default/source

    # 获得相似度矩阵
    produce_item_sim()