個性化召回算法實踐(五)——item2vec


item2vec將用戶的行為序列轉化成item組成的句子,模仿word2vec訓練word embedding將item embedding。基本思想是把原來高維稀疏的表示方式(one_hot)映射到低維稠密的向量空間中,這樣我們就可以用這個低維向量來表示該項目(電影),進而通過計算兩個低維向量之間的相似度來衡量兩個項目之間的相似性。
embedding就是用一個低維的向量表示一個物體,可以是一個詞,或是一個商品,或是一個電影等等。這個embedding向量的性質是能使距離相近的向量對應的物體有相近的含義
類似於Word2vec,item2vec有兩種方式:CBOW和skip-gram模型。
CBOW使用的是詞袋模型,模型的訓練輸入是某一個特征詞的上下文相關的詞對應的詞向量,而輸出就是這特定的一個詞的詞向量。Skip-Gram模型和CBOW的思路是反着來的,即輸入是特定的一個詞的詞向量,而輸出是特定詞對應的上下文詞向量。

主流程:

  • 從log中抽取用戶行為序列
  • 將行為序列當成預料訓練word2Vec得到item embedding
  • 得到item sim關系用於推薦

在代碼中,我們直接用gensim庫實現。在gensim中,word2vec 相關的API都在包gensim.models.word2vec中。和算法有關的參數都在類gensim.models.word2vec.Word2Vec中。算法需要注意的參數有:

  1. sentences: 我們要分析的語料,可以是一個列表,或者從文件中遍歷讀出。
  2. size: 詞向量的維度,默認值是100。這個維度的取值一般與我們的語料的大小相關,如果是不大的語料,比如小於100M的文本語料,則使用默認值一般就可以了。如果是超大的語料,建議增大維度。
  3. window:即詞向量上下文最大距離,window越大,則和某一詞較遠的詞也會產生上下文關系。默認值為5。在實際使用中,可以根據實際的需求來動態調整這個window的大小。如果是小語料則這個值可以設的更小。對於一般的語料這個值推薦在[5,10]之間。
  4. sg: 即我們的word2vec兩個模型的選擇了。如果是0, 則是CBOW模型,是1則是Skip-Gram模型,默認是0即CBOW模型。
  5. hs: 即我們的word2vec兩個解法的選擇了,如果是0, 則是Negative Sampling,是1的話並且負采樣個數negative大於0, 則是Hierarchical Softmax。默認是0即Negative Sampling。
  6. negative:即使用Negative Sampling時負采樣的個數,默認是5。推薦在[3,10]之間。這個參數在我們的算法原理篇中標記為neg。
  7. cbow_mean: 僅用於CBOW在做投影的時候,為0,則算法中的\(x_w\)為上下文的詞向量之和,為1則為上下文的詞向量的平均值。在我們的原理篇中,是按照詞向量的平均值來描述的。默認值也是1,不推薦修改默認值。
  8. min_count:需要計算詞向量的最小詞頻。這個值可以去掉一些很生僻的低頻詞,默認是5。如果是小語料,可以調低這個值。
  9. iter: 隨機梯度下降法中迭代的最大次數,默認是5。對於大語料,可以增大這個值。
  10. alpha: 在隨機梯度下降法中迭代的初始步長。算法原理篇中標記為ηη,默認是0.025。
  11. min_alpha: 由於算法支持在迭代的過程中逐漸減小步長,min_alpha給出了最小的迭代步長值。隨機梯度下降中每輪的迭代步長可以由iter,alpha, min_alpha一起得出。對於大語料,需要對alpha, min_alpha,iter一起調參,來選擇合適的三個值。

訓練完模型后,常見的用法如下:

#找出某一個詞向量最相近的詞集合
model.wv.similar_by_word('沙瑞金'.decode('utf-8'), topn =100)
#看兩個詞向量的相近程度
model.wv.similarity('沙瑞金'.decode('utf-8'), '高育良'.decode('utf-8'))
#找出不同類的詞
model.wv.doesnt_match(u"沙瑞金 高育良 李達康 劉慶祝".split())

全部代碼如下所示:

#-*-coding:utf-8-*-
"""
author:jamest
date:20190405
CBOW function
"""
import pandas as pd
from gensim.models import Word2Vec
import multiprocessing
import os

class CBOW:
    def __init__(self,input_file):
        self.model = self.get_train_data(input_file)

    def get_train_data(self,input_file,L=100):
        if not os.path.exists(input_file):
            return
        score_thr = 4.0
        ratingsDF = pd.read_csv(input_file, index_col=None, sep='::', header=None,
                                names=['user_id', 'movie_id', 'rating', 'timestamp'])
        ratingsDF = ratingsDF[ratingsDF['rating']>score_thr]
        ratingsDF['movie_id'] = ratingsDF['movie_id'].apply(str)
        movie_list = ratingsDF.groupby('user_id')['movie_id'].apply(list).values
        print('training...')
        model = Word2Vec(movie_list, size=L, window=5, sg=0, hs=0, min_count=1, workers=multiprocessing.cpu_count(),iter=10)
        return model

    def recommend(self,movieID,K):
        """
         Args:
             movieID:the movieID to find similar
             K:recom item num
         Returns:
             a dic,key:itemid ,value:sim score
         """
        movieID = str(movieID)
        rank = self.model.most_similar(movieID,topn=K)
        return rank

if __name__ == '__main__':
    moviesPath = '../data/ml-1m/movies.dat'
    ratingsPath = '../data/ml-1m/ratings.dat'
    usersPath = '../data/ml-1m/users.dat'

    rank = CBOW(ratingsPath).recommend(movieID=1,K=30)
    print('CBOW result',rank)

參考:
推薦系統概述(一)
Github


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM