1. 程式人生 > >基於gensim TFIDF模型 的文章推薦演算法

基於gensim TFIDF模型 的文章推薦演算法

1. gensim.similarities.SparseMatrixSimilarity 的三個方法

2. TFIDF 原始碼淺析

3.  gensim使用之一 tfidf 和lsi

一  訓練階段     輸入資料格式:一個列表,列表中的每個元素(也是列表)代表一個文字。每個文字分詞後的詞語組成的一個列表代表該文字。 生成的模型、tfidf矩陣、文章item_id列表,字典,語料分別儲存。

gensim版本的TFIDF模型的建立分為一下5步:

1. 生成字典 dictionary = corpora.Dictionary(train)
2. 生成語料 corpus = [dictionary.doc2bow(text) for text in train]
3. 定義TFIDF模型 tfidf_model = models.TfidfModel(corpus, dictionary=dictionary)
4. 用語料訓練模型並生成TFIDF矩陣 corpus_tfidf = tfidf_model[corpus]
5. 生成餘弦相似度索引 index = similarities.SparseMatrixSimilarity(corpus_tfidf, num_features=featurenum) 使用SparseMatrixSimilarity(),可以佔用更少的記憶體和磁碟空間。
from gensim import corpora,similarities,models
import jieba
import pandas as pd
import pickle
stopwords = [line.strip() for line in open('./doc/stopword.txt', 'r',encoding='utf-8').readlines()]
def chinese_word_cut(mytext):
    seg_list = []
    seg_text = jieba.cut(mytext)
    for word in seg_text:
        if word not in stopwords:
            seg_list.append(word)
    return " ".join(seg_list)
df = pd.read_csv("./doc/corpora.csv",sep='\t',encoding='utf-8')
t = pd.DataFrame(df['content'].astype(str))
df["content"] = t['content'].apply(chinese_word_cut)
train = []
train_item_id = []
for i in range(len(df["content"])):
    line = df["content"][i]
    line = line.split()
    train.append([w for w in line])
    train_item_id.append(df["item_id"][i])
    #print(len(train))
    #print(train)
print(len(train))
dictionary = corpora.Dictionary(train)
corpus = [dictionary.doc2bow(text) for text in train]
# corpus是一個返回bow向量的迭代器。下面程式碼將完成對corpus中出現的每一個特徵的IDF值的統計工作
tfidf_model = models.TfidfModel(corpus, dictionary=dictionary)
corpus_tfidf = tfidf_model[corpus]
dictionary.save('train_dictionary.dict')  # 儲存生成的詞典
tfidf_model.save('train_tfidf.model')
corpora.MmCorpus.serialize('train_corpuse.mm', corpus)
featurenum = len(dictionary.token2id.keys())  # 通過token2id得到特徵數
# 稀疏矩陣相似度,從而建立索引,我們用待檢索的文件向量初始化一個相似度計算的物件
index = similarities.SparseMatrixSimilarity(corpus_tfidf, num_features=featurenum)
index.save('train_index.index')
pickle.dump(train_item_id,'item_id.pkl')

二  測試階段   模型對測試集進行operation;求餘弦相似度。對於給定的新文字,找到訓練集中最相似的五篇文章作為推薦。

程式碼說明

1 import warnings   warnings.filterwarnings(action='ignore',category=UserWarning,module='gensim') 為了不報警告。
2 pickle.dump() 報錯,需要有wirite屬性。改為 from sklearn.externals import joblib。其dump 和load 方式和pickle一致。
3 index.get_similarities(test_vec) 返回test_vec 和訓練語料中所有文字的餘弦相似度。返回結果是個numpy陣列 
4 related_doc_indices = sim.argsort()[:-6:-1] 完成對numpy陣列的排序並獲取其top5最大值。

 

import jieba
from sklearn.externals import joblib
import warnings
warnings.filterwarnings(action='ignore',category=UserWarning,module='gensim')
from gensim import corpora,similarities,models


stopwords = [line.strip() for line in open('./doc/stopword.txt', 'r',encoding='utf-8').readlines()]
def chinese_word_cut(mytext):
    seg_list = []
    seg_text = jieba.cut(mytext)
    for word in seg_text:
        if word not in stopwords:
            seg_list.append(word)
    return seg_list

 # 讀取文章
def readfile(path):
    fp = open(path, "r", encoding="utf-8")
    content = fp.read()
    fp.close()
    return content

doc = readfile('doc/re0.txt')
test = chinese_word_cut(doc)
dictionary = corpora.Dictionary.load("train_dictionary.dict")
tfidf = models.TfidfModel.load("train_tfidf.model")
index = similarities.SparseMatrixSimilarity.load('train_index.index')
item_id_list = joblib.load('item_id.pkl')
corpus = corpora.MmCorpus('train_corpuse.mm')
print('模型載入完成')
# 產生BOW向量
vec = dictionary.doc2bow(test)
#生成tfidf向量
test_vec = tfidf[vec]
# 計算相似度
sim = index.get_similarities(test_vec)
related_doc_indices = sim.argsort()[:-6:-1]
print(related_doc_indices)
idlist = [] # 儲存item_id
for i in related_doc_indices:
    idlist.append(item_id_list[i])
print(idlist)