gensim和jieba分詞進行主題分析,文本類似度

參考連接:https://blog.csdn.net/whzhcahzxh/article/details/17528261算法

 

demo1:結巴分詞:app

# 構造分詞庫,格式以下:

'''

[['樓下', '買', '水果', '這家', '店', '價格比', '店要', '高', '', '', '%', '價格', '過高', '老闆', '說', '老闆', '您好', '家', '水果', '很漂亮', '新鮮', '進貨', '價格', '挺', '高', '我剛', '搬', '喜歡', '吃水果', '購買', '老闆', '迴應', '說', '價格', '優惠', '一點', '更好', '老闆', '微笑', '說', '長期', '購買', '', '', '折', '說', '老闆', '真', '大方', '就常', '買', '', '', '折', '老闆', '聽後', '計算機', '算了', '', '', '折', '再少', '開心', '', '', '折', '價格', '購買', '水果'], 
['工做', '作', '行政助理', '跟着', '老闆', '一年', '工資', '變化', '', '', '有次', '老闆', '聊天', '問', '一年', '表現', '有沒有', '批評', '指導', '一年', '表現', '幫', '加', '工資', '老闆', '', '', '幫', '工資', '提升']]
'''

stopwords = [line.strip() for line in codecs.open('./data/stopwords.txt', 'r', encoding = 'utf-8').readlines()]

train = []
fp = codecs.open('./result/demo5_sheet1_1.csv','r',encoding='utf8')
for line in fp.readlines():
    line = line.strip()
    if not len(line):#判斷是否爲空行
        continue
    outstr = ' '
    seg_list =jieba.cut(line,cut_all=False)#採用精確模式分詞,效果最好
    for word in seg_list:
        if word not in stopwords:
            if word != '\t':
                outstr += word
                outstr += " "
    train.append(outstr.strip().split(" "))#字符串轉列表
fp.close()

 

 

詳細實例:spa

# coding=utf-8         
import codecs
import gensim
import jieba 
from gensim import corpora,models,similarities
from gensim.models import LdaModel
from gensim.corpora import Dictionary



# 構造分詞庫,格式以下:

'''

[['樓下', '買', '水果', '這家', '店', '價格比', '店要', '高', '', '', '%', '價格', '過高', '老闆', '說', '老闆', '您好', '家', '水果', '很漂亮', '新鮮', '進貨', '價格', '挺', '高', '我剛', '搬', '喜歡', '吃水果', '購買', '老闆', '迴應', '說', '價格', '優惠', '一點', '更好', '老闆', '微笑', '說', '長期', '購買', '', '', '折', '說', '老闆', '真', '大方', '就常', '買', '', '', '折', '老闆', '聽後', '計算機', '算了', '', '', '折', '再少', '開心', '', '', '折', '價格', '購買', '水果'], 
['工做', '作', '行政助理', '跟着', '老闆', '一年', '工資', '變化', '', '', '有次', '老闆', '聊天', '問', '一年', '表現', '有沒有', '批評', '指導', '一年', '表現', '幫', '加', '工資', '老闆', '', '', '幫', '工資', '提升']]
'''

stopwords = [line.strip() for line in codecs.open('./data/stopwords.txt', 'r', encoding = 'utf-8').readlines()]

train = []
fp = codecs.open('./result/demo5_sheet1_1.csv','r',encoding='utf8')
for line in fp.readlines():
    line = line.strip()
    if not len(line):#判斷是否爲空行
        continue
    outstr = ' '
    seg_list =jieba.cut(line,cut_all=False)#採用精確模式分詞,效果最好
    for word in seg_list:
        if word not in stopwords:
            if word != '\t':
                outstr += word
                outstr += " "
    train.append(outstr.strip().split(" "))#字符串轉列表
fp.close()
# print(type(train))
# print(train)
# exit()


#各個詞或詞組在字典中的編號

'''
北京 編號爲:12
搭 編號爲:6
的 編號爲:9
喜歡 編號爲:1
不 編號爲:10
東西 編號爲:4
土豆 編號爲:2
霾 編號爲:14
是 編號爲:7
個 編號爲:5
霧 編號爲:13
百 編號爲:8
今天 編號爲:11
我 編號爲:3
吃 編號爲:0
'''
dic = corpora.Dictionary(train)
for name,index in dic.token2id.items():
    print(name+":"+str(index))
    break#執行一次

# 詞典生成好以後,就開始生成語料庫了
'''
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)]]
每一箇中括號表明一句話,用逗號隔開,(0,1)表明詞典中編號爲0的詞出現了一次,以此類推,很好理解
'''
corpus = [ dic.doc2bow(text) for text in train ]
# print(corpus)
# exit()

'''
獲得了語料庫,接下來作一個TF-IDF變換

能夠理解成 將用詞頻向量表示一句話 變換成爲用 詞的重要性向量表示一句話
(TF-IDF變換:評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨着它在文件中出現的次數成正比增長,但同時會隨着它在語料庫中出現的頻率成反比降低。)
vec是查詢文本向量,比較vec和文檔中的文本的類似度
執行結果:
[(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)]
'''
tfidf = models.TfidfModel(corpus)
vec =[(0,1),(4,1)]
corpus_tfidf = tfidf[corpus]
for doc in corpus_tfidf:
    print(doc)
    break#執行一次

# exit()
'''
獲得比較結果:
[(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了
'''
# index = similarities.SparseMatrixSimilarity(tfidf[corpus],num_features=3)
# sims =index[tfidf[vec]]
# print(list(enumerate(sims)))#報錯待調試


'''
回到tfidf轉換,接着訓練LSI模型,假定文檔屬於10個主題,
'''
lsi =  models.LsiModel(corpus_tfidf,id2word=dic,num_topics=10)
lsiout =lsi.print_topics(10)
print(lsiout[0])
# exit()
'''
基於SVD創建的兩個主題模型內容,將文章投影到主題空間中
輸出:

[(0, -0.70861576320682107), (1, 0.1431958007198823)]
[(0, -0.42764142348481798), (1, -0.88527674470703799)]
[(0, -0.66124862582594512), (1, 0.4190711252114323)]

所以第一三兩句和主題一類似,第二句和主題二類似
'''
corpus_lsi = lsi[corpus_tfidf]
for doc in corpus_lsi:
    print(doc)
    break


'''
LDA
獲得的結果每次都變,給一次的輸出:

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不同,我估計這和樣本數目太少,區別度不高有關,畢竟讓我來區分把第一句和哪一句分在一個主題,我也不肯定
'''

lda = models.LdaModel(corpus_tfidf, id2word=dic, num_topics=10)
ldaOut=lda.print_topics(10)
print (ldaOut[0])
print (ldaOut[1])
corpus_lda = lda[corpus_tfidf]
for doc in corpus_lda:
    print (doc)
    break

'''
輸入一句話,查詢屬於LSI獲得的哪一個主題類型,先創建索引:
輸出:

[(13, 1), (14, 1)]
[(0, 0.50670602027401368), (1, -0.3678056037187441)]

與第一個主題類似
'''
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)
'''
比較和第幾句話類似,用LSI獲得的索引接着作,並排序輸出
[(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的類似度
'''
相關文章
相關標籤/搜索