Python 自然語言處理(基於Gensim)

本人新書《玩轉Python網絡爬蟲》,可在天貓、京東等商城搜索查閱或通過右側圖書鏈接購買,項目深入淺出,適合爬蟲初學者或者是已經有一些網絡爬蟲編寫經驗,但希望更加全面、深入理解Python爬蟲的開發人員。
歡迎加入學習交流QQ羣:657341423


Gensim是一款開源的第三方Python工具包,用於從原始的非結構化的文本中,無監督地學習到文本隱層的主題向量表達。它支持包括TF-IDF,LSA,LDA,和word2vec在內的多種主題模型算法,支持流式訓練,並提供了諸如相似度計算,信息檢索等一些常用任務的API接口。
簡單地說,Gensim主要處理文本數據,對文本數據進行建模挖掘。


語料(Corpus):一組原始文本的集合,用於無監督地訓練文本主題的隱層結構。語料中不需要人工標註的附加信息。在Gensim中,Corpus通常是一個可迭代的對象(比如列表)。每一次迭代返回一個可用於表達文本對象的稀疏向量。
向量(Vector):由一組文本特徵構成的列表。是一段文本在Gensim中的內部表達。
稀疏向量(Sparse Vector):通常,我們可以略去向量中多餘的0元素。此時,向量中的每一個元素是一個(key, value)的tuple。
模型(Model):是一個抽象的術語。定義了兩個向量空間的變換(即從文本的一種向量表達變換爲另一種向量表達)。


文件準備:
aa.txt。文件內容爲某新聞報道
這裏寫圖片描述

from gensim import corpora, models, similarities
import jieba
import re
from snownlp import SnowNLP
# 讀取文本內容
f = open('aa.txt','r',encoding='utf-8')
text = f.read()
f.close()
# 分句
s = SnowNLP(text)
text_list = s.sentences
seg_list = []
# 循環句子列表,對每個句子做分詞處理
for i in text_list:
    temp_list = jieba.cut(i,cut_all=False)
    results = re.sub('[()::?“”《》,。!()·、.\d ]+', ' ', ' '.join(temp_list))
    seg_list.append(results)
# 將分詞寫入文件
f = open('data.txt','w',encoding='utf-8')
f.write(' '.join(seg_list))
f.close()

#…………………我是分割線………………………#
# **********字典的使用**********

# gensim的字典是將分詞好的數據轉換成gensim能處理的數據格式
seg_dict = [x.split(' ') for x in seg_list]
dict1 = corpora.Dictionary(seg_dict,prune_at=2000000)
print(dict1.token2id)
# 手動添加字典
dict2 = corpora.Dictionary()
dict2.token2id = {'computer': 0, 'human': 1, 'response': 2, 'survey': 3}
print(dict2.token2id)
# 合併字典
dict2 = corpora.Dictionary(seg_dict,prune_at=2000000)
dict2_to_dict1 = dict1.merge_with(dict2)
# 獲取字典中某詞語的詞袋向量
new_doc = '生態環境 政府 非法'
new_vec = dict1.doc2bow(new_doc.split())
print(new_vec) # [(14, 1), (22, 1), (66, 1)] -> 14代表生態環境在字典dict1的ID,1代表出現次數
# 獲取整個dict1的詞袋向量
bow_corpus = [dict1.doc2bow(text) for text in seg_dict]
print(bow_corpus)

# **********字典的使用**********
#…………………我是分割線………………………#

#…………………我是分割線………………………#
# **********模型的使用**********
# 模型對象的初始化,實現詞向量化
tfidf = models.TfidfModel(bow_corpus)
# 計算new_vec的權重
string_tfidf = tfidf[new_vec]
print(string_tfidf)
# 基於Tf-Idf計算相似度,參考https://radimrehurek.com/gensim/tutorial.html
index = similarities.SparseMatrixSimilarity(bow_corpus, num_features=10)
sims = index[string_tfidf]
print(sims) # 輸出[(14, 0.5862218816946012), (22, 0.4809979876921243), (66, 0.6519086141926397)]
# 14代表生態環境在字典dict1的ID,0.5862218816946012代表相似性分數


# ****建模****
# 參考https://radimrehurek.com/gensim/tut2.html
# LSI建模,models.LsiModel(corpus=tfidf[bow_corpus], id2word=dict1, num_topics=50, chunksize=10000)
# HDP建模,models.HdpModel(corpus=tfidf[bow_corpus], id2word=dict1,chunksize=10000)
# RP建模,models.RpModel(corpus=tfidf[bow_corpus], id2word=dict1, num_topics=50)
lda = models.LdaModel(corpus=tfidf[bow_corpus], id2word=dict1, num_topics=50, update_every=1, chunksize=10000, passes=1)
for i in range(0, 3):
    print(lda.print_topics(i)[0])
# 利用模型獲取文檔的主題概率分佈
doc_lda = lda[new_vec]
print(doc_lda)
# 根據模型計算相似度
# 參考https://radimrehurek.com/gensim/tut3.html
index = similarities.MatrixSimilarity(bow_corpus)
sims = index[new_vec]
print(list(enumerate(sims)))

# ****建模****
# **********模型的使用**********
#…………………我是分割線………………………#

#…………………我是分割線………………………#
# **********word2vec的使用**********
# 通過word2vec的“skip-gram和CBOW模型”生成深度學習的單詞向量
# 讀取已分詞的文件
sentences = models.word2vec.LineSentence('data.txt')
# 建立模型,實現詞向量化,第一個參數是訓練語料,min_count是小於該數的單詞會被踢出,默認值爲5;size是神經網絡的隱藏層單元數,在保存的model.txt中會顯示size維的向量值。默認是100。默認window=5
model = models.word2vec.Word2Vec(sentences, size=100, window=25, min_count=5, workers=4)
# 根據語料,計算某個詞的相關詞列表
sim = model.wv.most_similar('生態環境', topn=10)
# 計算一個詞d(或者詞表),使得該詞的向量v(d)與v(a="政府")-v(c="生態環境")+v(b="街道")最近
# sim = model.most_similar(positive=['政府','街道'],negative=['生態環境'], topn=10)
for s in sim:
    print("word:%s,similar:%s " %(s[0],s[1]))

# 根據語料,計算兩個詞的相似度 / 相關程度
print(str(model.similarity('政府','生態環境')))

# 計算文本的相似度
similarity_matrix = model.wv.similarity_matrix(dict1)
# MatrixSimilarity:指數相似性(密集與餘弦距離)。
# SparseMatrixSimilarity:索引相似度(帶餘弦距離的稀疏)。
# SoftCosineSimilarity:指數相似性(具有軟餘弦距離)。
# WmdSimilarity:索引相似度(與字移動距離)。
index = similarities.SoftCosineSimilarity(bow_corpus, similarity_matrix, num_best=10)
sims = index[dict1.doc2bow(new_doc.split())]
print(sims)

# 保存模型方法一
model.save("test_01.model")
# 保存模型方法二
# model.wv.save_word2vec_format("test_01.model.bin",binary=True)
# model= models.KeyedVectors.load_word2vec_format("test_01.model.bin", binary=True)

# **********word2vec的使用**********
#…………………我是分割線………………………#

參考資料:官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章