基於gensim TFIDF模型 的文章推薦演算法
阿新 • • 發佈:2018-12-29
1. gensim.similarities.SparseMatrixSimilarity 的三個方法
2. TFIDF 原始碼淺析
一 訓練階段 輸入資料格式:一個列表,列表中的每個元素(也是列表)代表一個文字。每個文字分詞後的詞語組成的一個列表代表該文字。 生成的模型、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)