我調用了結巴分詞做中文處理远寸,所以同樣
import jieba
手工寫個文本列表
sentences = ["我喜歡吃土豆","土豆是個百搭的東西","我不喜歡今天霧霾的北京"]
回到過程中來,將范例的語句分詞
words=[]
for doc in sentences:
words.append(list(jieba.cut(doc)))
print words
輸出:
[[u'\u6211', u'\u559c\u6b22', u'\u5403', u'\u571f\u8c46'], [u'\u571f\u8c46', u'\u662f', u'\u4e2a', u'\u767e', u'\u642d', u'\u7684', u'\u4e1c\u897f'], [u'\u6211', u'\u4e0d', u'\u559c\u6b22', u'\u4eca\u5929', u'\u96fe', u'\u973e', u'\u7684', u'\u5317\u4eac']]
得到的分詞結果構造詞典
dic = corpora.Dictionary(words)
print dic
print dic.token2id
為了方便看冻河,我給了個循環(huán)輸出:
for word,index in dic.token2id.iteritems():
print word +" 編號為:"+ str(index)
輸出:
北京 編號為:12
搭 編號為:6
的 編號為:9
喜歡 編號為:1
不 編號為:10
東西 編號為:4
土豆 編號為:2
霾 編號為:14
是 編號為:7
個 編號為:5
霧 編號為:13
百 編號為:8
今天 編號為:11
我 編號為:3
吃 編號為:0
詞典生成好之后原环,就開始生成語料庫了
corpus = [dic.doc2bow(text) for text in words]
print corpus
輸出:
[[(0, 1), (1, 1), (2, 1), (3, 1)], [(2, 1), (4, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1)], [(1, 1), (3, 1), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1)]]
此時,得到了語料庫键畴,接下來做一個TF-IDF變換
可以理解成 將用詞頻向量表示一句話 變換成為用 詞的重要性向量表示一句話
(TF-IDF變換:評估一字詞對于一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨著它在文件中出現的次數成正比增加突雪,但同時會隨著它在語料庫中出現的頻率成反比下降起惕。)
tfidf = models.TfidfModel(corpus)
vec = [(0, 1), (4, 1)]
print tfidf[vec]
corpus_tfidf = tfidf[corpus]
for doc in corpus_tfidf:
print doc
輸出:
[(0, 0.7071067811865475), (4, 0.7071067811865475)]
[(0, 0.8425587958192721), (1, 0.3109633824035548), (2, 0.3109633824035548), (3, 0.3109633824035548)]
[(2, 0.16073253746956623), (4, 0.4355066251613605), (5, 0.4355066251613605), (6, 0.4355066251613605), (7, 0.4355066251613605), (8, 0.4355066251613605), (9, 0.16073253746956623)]
[(1, 0.1586956620869655), (3, 0.1586956620869655), (9, 0.1586956620869655), (10, 0.42998768831312806), (11, 0.42998768831312806), (12, 0.42998768831312806), (13, 0.42998768831312806), (14, 0.42998768831312806)]
vec是查詢文本向量,比較vec和訓練中的三句話相似度
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=14)
sims = index[tfidf[vec]]
print list(enumerate(sims))
輸出:
[(0, 0.59577906), (1, 0.30794966), (2, 0.0)]
表示和第1句話相似度為59.578%咏删,和第二句話的相似度位30.79%惹想,第三句沒有相似度,
我們看看vec這句話是什么:0為吃督函,4為東西嘀粱,所以vec這句話可以是["吃東西"]或者["東西吃"]
而第一句話"我喜歡吃土豆","土豆是個百搭的東西"明顯有相似度,而第三句話"我不喜歡今天霧霾的北京"辰狡,相似度幾乎為0锋叨,至于為什么第一句比第二句更相似,就需要考慮TfIdf document representation和cosine similarity measure了
回到tfidf轉換宛篇,接著訓練LSI模型娃磺,假定三句話屬于2個主題,
lsi = models.LsiModel(corpus_tfidf, id2word=dic, num_topics=2)
lsiout=lsi.print_topics(2)
print lsiout[0]
print lsiout[1]
輸出:
0.532*"吃" + 0.290*"喜歡" + 0.290*"我" + 0.258*"土豆" + 0.253*"霾" + 0.253*"霧" + 0.253*"北京" + 0.253*"今天" + 0.253*"不" + 0.166*"東西"
0.393*"百" + 0.393*"搭" + 0.393*"東西" + 0.393*"是" + 0.393*"個" + -0.184*"霾" + -0.184*"霧" + -0.184*"北京" + -0.184*"今天" + -0.184*"不"
這就是基于SVD建立的兩個主題模型內容
將文章投影到主題空間中
corpus_lsi = lsi[corpus_tfidf]
for doc in corpus_lsi:
print doc
輸出:
[(0, -0.70861576320682107), (1, 0.1431958007198823)]
[(0, -0.42764142348481798), (1, -0.88527674470703799)]
[(0, -0.66124862582594512), (1, 0.4190711252114323)]
因此第一三兩句和主題一相似叫倍,第二句和主題二相似
同理做個LDA
lda = models.LdaModel(corpus_tfidf, id2word=dic, num_topics=2)
ldaOut=lda.print_topics(2)
print ldaOut[0]
print ldaOut[1]
corpus_lda = lda[corpus_tfidf]
for doc in corpus_lda:
print doc
得到的結果每次都變偷卧,給一次的輸出:
0.077*吃 + 0.075*北京 + 0.075*霧 + 0.074*今天 + 0.073*不 + 0.072*霾 + 0.070*喜歡 + 0.068*我 + 0.062*的 + 0.061*土豆
0.091*吃 + 0.073*搭 + 0.073*土豆 + 0.073*個 + 0.073*是 + 0.072*百 + 0.071*東西 + 0.066*我 + 0.065*喜歡 + 0.059*霾
[(0, 0.31271095988105352), (1, 0.68728904011894654)]
[(0, 0.19957991735916861), (1, 0.80042008264083142)]
[(0, 0.80940337254233863), (1, 0.19059662745766134)]
第一二句和主題二相似,第三句和主題一相似
輸入一句話吆倦,查詢屬于LSI得到的哪個主題類型听诸,先建立索引:
index = similarities.MatrixSimilarity(lsi[corpus])
query = "霧霾"
query_bow = dic.doc2bow(list(jieba.cut(query)))
print query_bow
query_lsi = lsi[query_bow]
print query_lsi
輸出:
[(13, 1), (14, 1)]
[(0, 0.50670602027401368), (1, -0.3678056037187441)]
與第一個主題相似
比較和第幾句話相似,用LSI得到的索引接著做蚕泽,并排序輸出
sims = index[query_lsi]
print list(enumerate(sims))
sort_sims = sorted(enumerate(sims), key=lambda item: -item[1])
print sort_sims
輸出:
[(0, 0.90161765), (1, -0.10271341), (2, 0.99058259)]
[(2, 0.99058259), (0, 0.90161765), (1, -0.10271341)]
可見和第二句話相似度很高晌梨,因為只有第二句話出現了霧霾兩個詞,可是驚訝的是和第一句話的相似度也很高,這得益于LSI模型的算法:在A和C共現仔蝌,B和C共現的同時砸逊,可以找到A和B的相似度