潜在语义分析原理以及python实现代码!!!!
在Wiki上看到的LSA的詳細介紹,感覺挺好的,遂翻譯過來,有翻譯不對之處還望指教。
原文地址:http://en.wikipedia.org/wiki/Latent_semantic_analysis
前言
淺層語義分析(LSA)是一種自然語言處理中用到的方法,其通過“矢量語義空間”來提取文檔與詞中的“概念”,進而分析文檔與詞之間的關系。LSA的基本假設是,如果兩個詞多次出現在同一文檔中,則這兩個詞在語義上具有相似性。LSA使用大量的文本上構建一個矩陣,這個矩陣的一行代表一個詞,一列代表一個文檔,矩陣元素代表該詞在該文檔中出現的次數,然后再此矩陣上使用奇異值分解(SVD)來保留列信息的情況下減少矩陣行數,之后每兩個詞語的相似性則可以通過其行向量的cos值(或者歸一化之后使用向量點乘)來進行標示,此值越接近于1則說明兩個詞語越相似,越接近于0則說明越不相似。
LSA最早在1988年由?Scott Deerwester,?Susan Dumais,?George Furnas,?Richard Harshman,?Thomas Landauer,?Karen Lochbaum?and?Lynn Streeter提出,在某些情況下,LSA又被稱作潛在語義索引(LSI)。
概述
詞-文檔矩陣(Occurences Matrix)
LSA 使用詞-文檔矩陣來描述一個詞語是否在一篇文檔中。詞-文檔矩陣式一個稀疏矩陣,其行代表詞語,其列代表文檔。一般情況下,詞-文檔矩陣的元素是該詞在文檔中的出現次數,也可以是是該詞語的tf-idf(term frequency–inverse document frequency)。
詞-文檔矩陣和傳統的語義模型相比并沒有實質上的區別,只是因為傳統的語義模型并不是使用“矩陣”這種數學語言來進行描述。
降維
在構建好詞-文檔矩陣之后,LSA將對該矩陣進行降維,來找到詞-文檔矩陣的一個低階近似。降維的原因有以下幾點:
- 原始的詞-文檔矩陣太大導致計算機無法處理,從此角度來看,降維后的新矩陣式原有矩陣的一個近似。
- 原始的詞-文檔矩陣中有噪音,從此角度來看,降維后的新矩陣式原矩陣的一個去噪矩陣。
- 原始的詞-文檔矩陣過于稀疏。原始的詞-文檔矩陣精確的反映了每個詞是否“出現”于某篇文檔的情況,然而我們往往對某篇文檔“相關”的所有詞更感興趣,因此我們需要發掘一個詞的各種同義詞的情況。
可以看到,每一行代表一個詞的向量,該向量描述了該詞和所有文檔的關系。
相似的,一列代表一個文檔向量,該向量描述了該文檔與所有詞的關系。
詞向量的點乘可以表示這兩個單詞在文檔集合中的相似性。矩陣?包含所有詞向量點乘的結果,元素(i,p)和元素(p,i)具有相同的值,代表詞p和詞i的相似度。類似的,矩陣包含所有文檔向量點乘的結果,也就包含了所有文檔那個的相似度。
現在假設存在矩陣的一個分解,即矩陣可分解成正交矩陣U和V,和對角矩陣的乘積。
這種分解叫做奇異值分解(SVD),即:
因此,詞與文本的相關性矩陣可以表示為:
因為與是對角矩陣,因此肯定是由的特征向量組成的矩陣,同理是特征向量組成的矩陣。這些特征向量對應的特征值即為中的元素。綜上所述,這個分解看起來是如下的樣子:
?被稱作是奇異值,而??和則叫做左奇異向量和右奇異向量。通過矩陣分解可以看出,原始矩陣中的?只與U矩陣的第i行有關,我們則稱第i行為?。同理,原始矩陣中的只與中的第j列有關,我們稱這一列為。與并非特征值,但是其由矩陣所有的特征值所決定。
當我們選擇k個最大的奇異值,和它們對應的U與V中的向量相乘,則能得到一個X矩陣的k階近似,此時該矩陣和X矩陣相比有著最小誤差(即殘差矩陣的Frobenius范數)。但更有意義的是這么做可以將詞向量和文檔向量映射到語義空間。向量與含有k個奇異值的矩陣相乘,實質是從高維空間到低維空間的一個變換,可以理解為是一個高維空間到低維空間的近似。同理,向量?也存在這樣一個從高維空間到低維空間的變化。這種變換用公式總結出來就是這個樣子:
有了這個變換,則可以做以下事情:
- 判斷文檔??與??在低維空間的相似度。比較向量??與向量?(比如使用余弦夾角)即可得出。
- 通過比較?與?可以判斷詞和詞的相似度。?
- 有了相似度則可以對文本和文檔進行聚類。
- 給定一個查詢字符串,算其在語義空間內和已有文檔的相似性。
其中對角矩陣?的逆矩陣可以通過求其中非零元素的倒數來簡單的得到。 同理,對于查詢字符串,得到其對應詞的向量后,根據公式?將其映射到語義空間,再與文檔進行比較。 應用
低維的語義空間可以用于以下幾個方面:
- 在低維語義空間可對文檔進行比較,進而可用于文檔聚類和文檔分類。
- 在翻譯好的文檔上進行訓練,可以發現不同語言的相似文檔,可用于跨語言檢索。
- 發現詞與詞之間的關系,可用于同義詞、歧義詞檢測。.
- 通過查詢映射到語義空間,可進行信息檢索。
- 從語義的角度發現詞語的相關性,可用于“選擇題回答模型”(multi choice qustions answering model)。
(原文還說了一些其它方面,感覺不是很重要,不翻譯了,放上原文)
Synonymy and polysemy are fundamental problems in?natural language processing:
- Synonymy is the phenomenon where different words describe the same idea. Thus, a query in a search engine may fail to retrieve a relevant document that does not contain the words which appeared in the query. For example, a search for "doctors" may not return a document containing the word "physicians", even though the words have the same meaning.
- Polysemy is the phenomenon where the same word has multiple meanings. So a search may retrieve irrelevant documents containing the desired words in the wrong meaning. For example, a botanist and a computer scientist looking for the word "tree" probably desire different sets of documents.
Commercial applications[edit]
LSA has been used to assist in performing?prior art?searches for?patents.[5]
Applications in human memory[edit]
The use of Latent Semantic Analysis has been prevalent in the study of human memory, especially in areas of?free recall?and memory search. There is a positive correlation between the semantic similarity of two words (as measured by LSA) and the probability that the words would be recalled one after another in free recall tasks using study lists of random common nouns. They also noted that in these situations, the inter-response time between the similar words was much quicker than between dissimilar words. These findings are referred to as the?Semantic Proximity Effect.[6]
When participants made mistakes in recalling studied items, these mistakes tended to be items that were more semantically related to the desired item and found in a previously studied list. These prior-list intrusions, as they have come to be called, seem to compete with items on the current list for recall.[7]
Another model, termed?Word Association Spaces?(WAS) is also used in memory studies by collecting free association data from a series of experiments and which includes measures of word relatedness for over 72,000 distinct word pairs.[8]
算法局限性
LSA的一些缺點如下:
- 新生成的矩陣的解釋性比較差.比如
- LSA無法撲捉一詞多以的現象。在原始詞-向量矩陣中,每個文檔的每個詞只能有一個含義。比如同一篇文章中的“The Chair of Board"和"the chair maker"的chair會被認為一樣。在語義空間中,含有一詞多意現象的詞其向量會呈現多個語義的平均。相應的,如果有其中一個含義出現的特別頻繁,則語義向量會向其傾斜。
- LSA具有詞袋模型的缺點,即在一篇文章,或者一個句子中忽略詞語的先后順序。
- LSA的概率模型假設文檔和詞的分布是服從聯合正態分布的,但從觀測數據來看是服從泊松分布的。因此LSA算法的一個改進PLSA使用了多項分布,其效果要好于LSA。
教你在Python中實現潛在語義分析
介紹
你有沒有去過那種運營良好的圖書館?我總是對圖書館館員通過書名、內容或其他主題保持一切井井有條的方式印象深刻。但是如果你給他們數千本書,要求他們根據書的種類整理出來,他們很難在一天內完成這項任務,更不用說一小時!
但是,如果這些書以電子的形式出現,就難不倒你了,對吧?所有的整理會在幾秒之間完成,并且不需要任何人工勞動。自然語言處理(NLP)萬歲!
看看下面這段話:
你可以從高亮的詞語中總結出,這段話有三個主題(或概念)——主題1、主題2和主題3。一個良好的主題模型可以識別出相似的詞語并將它們放在一組或一個主題下。上述示例中最主要的主題是主題2,表明這段文字主要關于虛假視頻。
是不是很好奇?太好了!在本文中,我們將學習一種叫做主題建模的文本挖掘方法。這是一種非常有用的提取主題的技術,在面對NLP挑戰時你會經常使用到它。
注意:我強烈建議您通讀這篇文章了解SVD和UMAP等定義。它們在本文中經常出現,因此對它們有基本的理解有助于鞏固這些概念。
目錄
1.?什么是主題模型?
2.?何時使用主題建模?
3.?潛在語義分析(LSA)概述
4.?在Python中實現LSA
數據讀取和檢查
數據預處理
文檔-詞項矩陣(Document-Term Matrix)
主題建模
主題可視化
5. ?LSA的優缺點
6. ?其他主題建模技術
什么是主題模型?
主題模型可定義為一種在大量文檔中發現其主題的無監督技術。這些主題本質上十分抽象,即彼此相關聯的詞語構成一個主題。同樣,在單個文檔中可以有多個主題。我們暫時將主題模型理解為一個如下圖所示的黑盒子:
這個黑盒子(主題模型)將相似和相關的詞語聚集成簇,稱為主題。這些主題在文檔中具有特定的分布,每個主題都根據它包含的不同單詞的比例來定義。
何時使用主題建模?
回想一下剛才提到的將相似的書籍整理到一起的例子。現在假設你要對一些電子文檔執行類似的任務。只要文檔的數量不太多,你就可以手動完成。但是如果這些文檔的數量非常多呢?
這就是NLP技術脫穎而出的地方。對于這個任務而言,主題建模非常適用。
主題建模有助于挖掘海量文本數據,查找詞簇,文本之間的相似度以及發現抽象主題。如果這些理由還不夠引人注目,主題建模也可用于搜索引擎,判斷搜索字段與結果的匹配程度。越來越有趣了,是不是?那么,請繼續閱讀!
潛在語義分析(LSA)概述
所有語言都有自己的錯綜復雜和細微差別,比如一義多詞和一詞多義,這對機器而言很難捕捉(有時它們甚至也被人類誤解了!)。
例如,如下兩個句子:
1.?I liked his last novel quite a lot.
2.?We?would like to go for a novel?marketing campaign.
在第一個句子中,'novel' 指一本書,而在第二個句子中,它的含義是新奇的、新穎的。
我們能夠輕松地區分這些單詞,是因為我們可以理解這些詞背后的語境。但是,機器并不能捕捉到這個概念,因為它不能理解單詞的上下文。這就是潛在語義分析(LSA)發揮作用的地方,它可以利用單詞所在的上下文來捕捉隱藏的概念,即主題。
因此,簡單地將單詞映射到文檔并沒有什么用。我們真正需要的是弄清楚單詞背后的隱藏概念或主題。LSA是一種可以發現這些隱藏主題的技術。現在我們來深入探討下LSA的內部工作機制。
LSA的實施步驟
假設我們有m篇文檔,其中包含n個唯一詞項(單詞)。我們希望從所有文檔的文本數據中提取出k個主題。主題數k,必須由用戶給定。
生成一個m×n維的文檔-詞項矩陣(Document-Term Matrix),矩陣元素為TF-IDF分數
然后,我們使用奇異值分解(SVD)把上述矩陣的維度降到k(預期的主題數)維
SVD將一個矩陣分解為三個矩陣。假設我們利用SVD分解矩陣A,我們會得到矩陣U,矩陣S和矩陣VT(矩陣V的轉置)
矩陣Uk(document-term matrix)的每個行向量代表相應的文檔。這些向量的長度是k,是預期的主題數。代表數據中詞項的向量可以在矩陣Vk(term-topic matrix)中找到。
因此,SVD為數據中的每篇文檔和每個詞項都提供了向量。每個向量的長度均為k。我們可以使用余弦相似度的方法通過這些向量找到相似的單詞和文檔。
在Python中實現LSA
是時候啟動Python并了解如何在主題建模問題中應用LSA了。開啟Python環境后,請按照如下步驟操作。
數據讀取和檢查
在開始之前,先加載需要的庫。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
pd.set_option("display.max_colwidth", 200)
在本文中,我們使用sklearn中的"20 Newsgroup"數據集,可從這里下載,然后按照代碼繼續操作。
from sklearn.datasets import fetch_20newsgroups
dataset = fetch_20newsgroups(shuffle=True, random_state=1, remove=('header','footers',quotes'))
documents = dataset.data
len(documents)
Output: 11,314
Dataset.target_names
?['alt.atheism',
'comp.graphics',
'comp.os.ms-windows.misc',
'comp.sys.ibm.pc.hardware',
'comp.sys.mac.hardware',
'misc.forsale',
'rec.autos',
'rec.motorcycles',
'rec.sport.baseball',
'rec.sport.hockey',
'sci.crypt',
'sci.electronics',
'sci.med',
'sci.space',
'soc.religion.christian',
'talk.politics.guns',
'talk.politics.mideast',
'talk.politics.misc',
'talk.religion.misc']
該數據集包含分布在20個不同新聞組中的11314篇文檔。
數據預處理
?首先,我們嘗試盡可能地清理文本數據。我們的想法是,使用正則表達式replace("[^a-zA-Z#]", " ")一次性刪除所有標點符號、數字和特殊字符,這個正則表達式可以替換除帶空格的字母之外的所有內容。然后刪除較短的單詞,因為它們通常并不包含有用的信息。最后,將全部文本變為小寫,使得大小寫敏感失效。
news_df = pd.DataFrame({'document':documents})
?
#?removing everything except alphabets
news_df['clean_doc'] = news_df['document'].str.replace("[^a-zA-Z#]", " ")
?
# removing short words
news_df['clean_doc'] = news_df['clean_doc'].apply(lambda x: ' '.join([w for w in x.split() if len(w)>3]))
?
#?make all the lowercase
news_df['clean_doc'] = news_df['clean_doc'].apply(lambda x: x.lower())
最好將文本數據中的停止詞刪除,因為它們十分混亂,幾乎不攜帶任何信息。停止詞是指'it', 'they', 'am', 'been', 'about', 'because', 'while'之類的詞匯。
?要從文檔中刪除停止詞,我們必須對文本進行標記,將文本中的字符串拆分為單個的標記或單詞。刪除完停止詞后,我們將標記重新拼接到一起。
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
?
# tokenization
tokenized_doc = news_df['clean_doc'].apply(lambda x: x.split())
?
# remove stop-words
tokenized_doc = tokenized_doc.apply(lambda x: [item for item in x ifitem not in stop_words])
?
#?de-tokenization
detokenized_doc = []
for i in range(len(news_df)):
?t = ' '.join(tokenized_doc[i])
? ? detokenized_doc.append(t)
?
news_df['clean_doc'] = detokenized_doc
文檔-詞項矩陣(Document-Term Matrix)
?這是主體建模的第一步。我們將使用sklearn的TfidfVectorizer來創建一個包含1000個詞項的文檔-詞項矩陣。
from sklearn.feature_extraction.text import TfidfVectorizer
?
vectorizer = TfidfVectorizer(stop_words='english',
max_features =1000, # keep top 1000 terms
max_df = 0.5,
smooth_idf = True)
?
X?= vectorizer.fit_transform(news_df['clean_doc'])
?
X.shape ?# check shape of the document-term matrix
(11314, 1000)
我們也可以使用全部詞項來創建這個矩陣,但這回需要相當長的計算時間,并占用很多資源。因此,我們將特征的數量限制為1000。如果你有計算能力,建議嘗試使用所有詞項。
主題建模
下一步是將每個詞項和文本表示為向量。我們將使用文本-詞項矩陣,并將其分解為多個矩陣。我們將使用sklearn的TruncatedSVD來執行矩陣分解任務。
由于數據來自20個不同的新聞組,所以我們打算從文本數據中提取出20個主題。可以使用n_components參數來制定主題數量。
from sklearn.decomposition import TruncatedSVD
?
#?SVD represent documents and terms in vectors
svd_model = TruncatedSVD(n_components=20, algorithm='randomized', n_iter=100, random_state=122)
?
svd_model.fit(X)
?
len(svd_model.components_)
?
20
svd_model的組成部分即是我們的主題,我們可以通過svd_model.components_來訪問它們。最后,我們打印出20個主題中前幾個最重要的單詞,看看我們的模型都做了什么。
terms = vectorizer.get_feature_names()
?
for i, comp in enumerate(svd_model.components_):
terms_comp = zip(terms, comp)
sorted_terms = sorted(terms_comp, key=lambda x:x[1], reverse=True)[:7]
print("Topic "+str(i)+": ")
for t in sorted_terms:
print(t[0])
print(" ")
Topic 0: like know people think good time thanks
Topic 0: like know people think good time thanks
Topic 1: thanks windows card drive mail file advance
Topic 2: game team year games season players good
Topic 3: drive scsi disk hard card drives problem
Topic 4: windows file window files program using problem
Topic 5: government chip mail space information encryption data
Topic 6: like bike know chip sounds looks look
Topic 7: card sale video offer monitor price jesus
Topic 8: know card chip video government people clipper
Topic 9: good know time bike jesus problem work
Topic 10: think chip good thanks clipper need encryption
Topic 11: thanks right problem good bike time window
Topic 12: good people windows know file sale files
Topic 13: space think know nasa problem year israel
Topic 14: space good card people time nasa thanks
Topic 15: people problem window time game want bike
Topic 16: time bike right windows file need really
Topic 17: time problem file think israel long mail
Topic 18: file need card files problem right good
Topic 19: problem file thanks used space chip sale
主題可視化
為了找出主題之間的不同,我們將其可視化。當然,我們無法可視化維度大于3的數據,但有一些諸如PCA和t-SNE等技術可以幫助我們將高維數據可視化為較低維度。在這里,我們將使用一種名為UMAP(Uniform Manifold Approximation and Projection)的相對較新的技術。
import umap
?
X_topics = svd_model.fit_transform(X)
embedding = umap.UMAP(n_neighbors=150, min_dist=0.5, random_state=12).fit_transform(X_topics)
plt.figure(figsize=(7,5))
plt.scatter(embedding[:, 0], embedding[:, 1],
c?= dataset.target,
s?= 10, # size
edgecolor='none'
)
plt.show()
如上所示,結果非常漂亮。每個點代表一個文檔,顏色代表20個新聞組。我們的LSA模型做得很好。可以任意改變UMAP的參數來觀察其對圖像的影響。
可在此找到本文的完整代碼。
LSA的優缺點
?如上所述,潛在語義分析非常有用,但是確實有其局限性。因此,對LSA的優缺點都有充分的認識十分重要,這樣你就知道何時需要使用LSA,以及何時需要嘗試其他方法。
?優點:
LSA快速且易于實施。
它的結果相當好,比簡單的向量模型強很多。
?缺點:
因為它是線性模型,因此在具有非線性依賴性的數據集上可能效果不佳。
LSA假設文本中的詞項服從正態分布,這可能不適用于所有問題。
LSA涉及到了SVD,它是計算密集型的,當新數據出現時難以更新。
?其他主題建模技術
?除了LSA,還有其他一些先進并有效的主題建模技術,如LDA(Latent Dirichlet Allocation)和Ida2Vec。我們有一篇關于LDA的精彩文章,你可以在這里查看。Ida2vec是一個基于word2vec單詞嵌入的更先進的主題建模技術。如果你想對它有更多了解,可以在下方的評論中留言,我們很樂意回答你的問題。
?尾記
本文意于與大家分享我的學習經驗。主題建模是個非常有趣的話題,當你在處理文本數據集時會用到許多技巧和方法。因此,我敦促大家使用本文中的代碼,并將其應用于不同的數據集。如果您對本文有任何疑問或反饋,請與我們聯系。快樂地去挖掘文本吧!
原文標題:
Text Mining 101: A Stepwise Introduction to Topic Modeling using Latent Semantic Analysis (using Python)
原文鏈接:
https://www.analyticsvidhya.com/blog/2018/10/stepwise-guide-topic-modeling-latent-semantic-analysis/
總結
以上是生活随笔為你收集整理的潜在语义分析原理以及python实现代码!!!!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用flask部署模型
- 下一篇: Python-接口开发入门