哈嘍铝噩,大家好。
我們現(xiàn)在做數(shù)據分析的時候窿克,不可避免地會與文本數(shù)據打交道骏庸,今天跟大家分享在數(shù)據分析中,如何挖掘出相似的文本年叮。
本文從提出問題具被,到解決問題,再到算法原理三個方面來介紹只损。
1. 提出問題
假設在一個電商APP里一姿,我們想要找出某款商品評價里,關于“快遞很差” 的評論跃惫,該怎么做叮叹?
如果只用字符串匹配的方式,你可能會遍歷所有的評論爆存,判斷每條評論里是否包含“快遞很差”字符串蛉顽。
但這種做法對下面幾條評論就失效了
快遞真差勁
快遞一點不好
物流真差
所以,單純的字符串匹配會漏掉很多評論先较。
2. 解決問題
要解決上面的問題携冤,需要借助?潛在語義索引(Latent Semantic Indexing, 以下簡稱LSI)?算法悼粮。
LSI 算法可以挖掘相似文本,因此曾棕,通過 LSI 算法可以找到與“快遞很差”相似的評論扣猫。
下面我們以之前一篇文章《挖掘張同學視頻評論主題》為例,實踐 LSI 算法睁蕾。
2.1 構建 LSI 模型
張同學視頻評論
上篇文章抓取了張同學抖音視頻 1.2w 條評論,對應上圖 text 列债朵。
首先子眶,對評論分詞,并去掉停用詞序芦。
origin_docs?=?df['text'].values
documents?=?[jieba.lcut(doc)fordocinorigin_docs]
texts?=?[[wordforwordindocifwordnotinfilter_wrods]fordocindocuments]
texts變量
然后臭杰,用gensim構建評論詞典,并統(tǒng)計每條評論中每個詞出現(xiàn)的次數(shù)(詞頻)谚中。
from?gensim?import?corpora,?models,?similarities
#?構建詞典渴杆,給每個詞編號
dictionary?=?corpora.Dictionary(texts)
#?每條評論里每個詞的出現(xiàn)頻次
corpus?=?[dictionary.doc2bow(text)fortextintexts]
corpus變量
dictionary將texts變量中的文本變成了數(shù)字編號。如:熱好?的編號為 0宪塔,飯?的編號為 1磁奖。
doc2bow()中的 bow 是?Bag-of-Words的縮寫,代表詞袋模型某筐,該模型用來統(tǒng)計評論中的詞頻比搭。
corpus變量與texts變量相對應。corpus[0]中的第一個元組(0, 1)代表第一條評論中熱好一詞的出現(xiàn)的次數(shù)是1南誊,第二個元組(1, 1)代表飯出現(xiàn)的次數(shù)是1身诺。
接著,構建 LSI 模型
lsi?=?models.LsiModel(
corpus,
id2word=dictionary,
power_iters=100,
num_topics=10
)
num_topics是評論的主題數(shù)抄囚,上篇文章我們挖掘出來8個主題比較好霉赡, 這里我們設置的主題數(shù)是10個,稍微大一些對后面挖掘相似文本更好幔托。
最后穴亏,構建每條評論向量的索引,方便后面查詢重挑。
#?lsi[corpus]?是所有評論對應的向量
index?=?similarities.MatrixSimilarity(lsi[corpus])
2.2 查詢相似文本
張同學的視頻評論中迫肖,很多人都對“喂狗”鏡頭印象深刻。
下面我們來查詢與“以為自己吃攒驰,結果喂狗”相似的評論蟆湖。
query?='以為自己吃,結果喂狗'
#?詞袋模型玻粪,統(tǒng)計詞頻
vec_bow?=?dictionary.doc2bow(jieba.lcut(query))
#?計算?query?對應的向量
vec_lsi?=?lsi[vec_bow]
#?計算每條評論與query的相似度
sims?=?index[vec_lsi]
經過 LSI 處理后隅津,每條評論都可以用向量表示诬垂,同樣的,query也可以用向量表示伦仍。
所以结窘,index[vec_lsi]其實是計算向量之間的相似度,這里用的方法是余弦相似度充蓝。結果越靠近1說明query與該評論越相似隧枫。
下面按照相似度倒排,輸出與query相似的評論谓苟。
#?輸出(原始文檔官脓,相似度)二元組
result?=?[(origin_docs[i[0]],i[1])foriinenumerate(sims)]
#?按照相似度逆序排序
sorted(result?,key=lambda?x:?-x[1])
相似文本
可以看到,效果還是不錯的涝焙,能夠挖掘出很多相似的文本卑笨。
3. LSI 算法原理
LSI 與我們之前講的 LDA 類似,都能用來計算每篇文本的主題仑撞。
LSI 是基于奇異值分解(SVD)的方法來得到文本的主題的赤兴。SVD 的近似公式為:
其中,m代表所有評論中詞的數(shù)量隧哮,n代表評論的條數(shù)桶良,k代表分解后得到的主題數(shù)。
矩陣??對應n篇評論沮翔,每篇評論下有m個詞艺普。
矩陣??對應k個主題,每個主題下鉴竭,m個詞的概率分布歧譬。
矩陣??轉置后是?n*k?的矩陣,對應 n 篇文檔搏存,每篇文檔下瑰步,k 個主題的概率分布。
因此璧眠,?中每行其實就是每條評論的向量缩焦,該矩陣對應到上述代碼中,是lsi[corpus]责静。
上面我們提到用余弦相似度計算向量相似度袁滥。在高中數(shù)學中,兩個向量的余弦相似度其實就是兩個向量的夾角
夾角0度時灾螃,兩向量重合(相等)题翻,相似度為1
夾角90度時,兩向量垂直(不相關)腰鬼,相似度為0
夾角180度時嵌赠,兩向量反向塑荒,相似度為-1
到這里,基于 LSI 的相似文本挖掘就介紹完了姜挺。經過本篇的學習齿税,你可以發(fā)現(xiàn) LSI 不僅可以挖掘相似文本,甚至還可以做文本推薦炊豪、搜索引擎之類的事凌箕。
當然它也有缺點,有興趣的朋友可以繼續(xù)深入研究词渤。