當前位置:
首頁 > 科技 > 文本挖掘入門課:主題模型讓文本數據處理更幸福

文本挖掘入門課:主題模型讓文本數據處理更幸福

全文共3480字,預計閱讀時長7分鐘

在解決自然語言處理的問題上,有一種文本挖掘的方法叫做主題模型,這是提取主題時一項極其有用的技術,那麼什麼是主題模型?何時使用主題模型?在Python中利用潛在語義分析來解決主題模型時,又應該注意哪些問題?讀完了本文,相信你一定會有最實在的收穫!

前言

你有沒有去過維護得相當完善的圖書館?那些圖書管理員非常讓人佩服,他們把圖書按照名稱、內容或主題進行歸類,一切都管理得井井有條。但是如果你扔給他們上千本圖書,然後讓他們按照書本的類型來整理好,他們可能一天都做不完,更不必說在一個小時之內了。

但是,如果這些書都是電子文本的話,整理工作可能就是幾秒鐘的事情,無需任何人力。自然語言處理萬歲!

先來看一下下面的文本片段:

參照有底色的文本,可以看到一共有三個主題(或者概念)——主題1、主題2和主題3。一個好的主題模型能夠辨別相似的片語,並把它們歸為一類。上面的例子中最明顯的主題是主題2,主要講偽造影像的內容。

有意思吧?好!本文介紹了一個叫做主題模型的文本挖掘方法。這是提取主題時一項極其有用的技術,在應對自然語言處理問題的時候也非常常見。

提示:強烈建議你閱讀這篇文章以對奇異值分解(SVD)和UMAP等概念進行了解(https://www.analyticsvidhya.com/blog/2018/08/dimensionality-reduction-techniques-python/)。本文是建立在這些概念之上的,因此先學習它們有利於鞏固我們對基礎概念的理解。

目錄

什麼是主題模型?

何時使用主題模型?

潛在語義分析(Latent Semantic Analysis, LSA)

在Python使用LSA

4.1 數據讀取和檢視

4.2 數據預處理

4.3 文本—詞語矩陣

4.4主題模型

4.5 主題可視化

LSA的優缺點

主題模型的其他技術

1.什麼是主題模型?

主題模型是一種無監督技術,用來發現各種文本文檔中的主題。這些主題本質上是抽象的,也就是說彼此相關的單詞會形成主題。 與此同時,單個文檔中可以有多個主題。本文中暫時將主題模型理解為黑盒子,如下圖所示:

這個黑盒子(也就是主題模型)把相關的片語劃分為不同的類群,稱之為主題。這些主題在文本中有特定的分布,每個主題都可以用不同比例的單片語合來定義。

2.何時使用主題模型?

回想一下之前提到的整理圖書的任務。現在想像一下,你需要對電子文檔來進行分類。當然,如果文檔比較少的話,你可以手動完成這個任務。但是如果文檔特別多的話怎麼辦?

這時候就要用自然語言處理技術了。而對於這個任務來說,將使用主題模型來完成。

主題模型可以幫助我們對海量的文本數據進行探索,對片語進行聚類,找到文本之間的相似性,並發現抽象的主題。如果你覺得這些任務還不夠有挑戰的話,主題模型還可以在搜索引擎中找到與搜索文本匹配的結果。是不是有點意思了?讓我們繼續深入探討!

3.潛在語義分析(Latent Semantic Analysis, LSA)

所有語言都會有自身的複雜性和微妙特徵,機器是難以捕捉這些內容的(有的時候人類自己也難以分辨)。比方說,不同的單詞可能會有相同的含義,而同樣的單詞又可能有不同的含義。

讓我們來看下面兩個句子:

1. I liked his last novel quite a lot.

2. We would like to go for a novel marketing campaign.

第一句話中,「novel」指代的是一本書,而第二句話中它表示新奇的、新穎的。

我們可以通過上下文輕易地推斷這兩個詞的含義,但是機器就捕捉不到這個概念因為它不能理解單詞所使用的語境。這時候就需要用到潛在語義分析了,它可以基於片語之間的上下文來揣摩背後的意思,也就是我們說的主題。

因此,單純地把片語映射到文檔中不一定有效果,我們需要的是搞懂詞語背後的概念和主題。潛在語義分析就是能夠找到隱藏主題的一種方法,現在讓我們來深入探討潛在語義分析的內部工作機制。

潛在語義分析的實現步驟

比方說我們有m個文檔,文檔中一共有n個唯一的詞,我們要從所有文檔中提取出k個主題。這裡k表示主題的數量,是由用戶自己定義的。

構造一個形如m * n的文檔—詞語矩陣,其中包含有TF-IDF分值。

然後,我們會把上述的矩陣用奇異值分解(SVD)的方法降到k維。

奇異值分解(SVD)把矩陣分解為三個矩陣。比如我們想要用奇異值分解(SVD)來降解矩陣A,那麼我們會得到矩陣U、矩陣S和矩陣VT(矩陣V的轉置矩陣)。矩陣Uk(文檔—片語矩陣)的每一行都是文檔的向量表示。這些向量的長度為k,也就是我們設定的主題數量。片語的向量表示可以在Vk(詞語—主題矩陣)中找到。

這樣一來,奇異值分解(SVD)把我們數據中的每個文檔和片語都進行了向量化,每個向量的長度都是k。我們可以結合餘弦相似度的方法,利用這些向量來找相似的片語和文檔。

4.在Python中使用潛在語義分析

下面我們介紹如何在Python中利用潛在語義分析來解決主題模型的問題。打開Python之後,可以按照我下面提到的步驟開始運行代碼。

4.1 數據讀取和檢視

首先要載入下面的包:

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=("headers", "footers", "quotes"))

documents = dataset.data

len(documents)

輸出: 11,314

dataset.target_names

["alt.atheism",

"comp.graphics",

"comp.os.ms-windows.misc",

"comp.sys.ibm.pc.hardware",

"comp.sys.mac.hardware",

"comp.windows.x",

"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個不同新聞媒體的11,314份文本文檔。

4.2 數據預處理

開始,我們要儘可能對文本數據進行清洗。基本原則就是利用正則表達式,用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 text 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 if item 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

4.3 文本—詞語矩陣

這是創建主題模型的第一步。我們會用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。如果你有足夠的計算資源,我建議你可以把所有的詞語都涵蓋進去。

4.4 主題模型

下一步是把每個詞語和文檔用向量表示。我們會用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的要素(components)就是我們的主題,我們可以利用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 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

4.5 主題可視化

要知道我們的主題是否有特色,就需要進行可視化。當然,我們無法對三個維度以上的信息進行可視化。但是利用主成分分析(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的參數,看看圖片會有什麼變化。

文中所有代碼都可以在GitHub中找到。

(https://github.com/prateekjoshi565/latent_semantic_analysis)

5.LSA的優缺點

上面的例子中我們可以看到潛在語義分析的威力,但是它還是有自身局限性的。我們需要了解LSA的優缺點,這樣我們才知道什麼時候選用它,什麼時候應該嘗試別的方法。

優點:

LSA速度快,容易實現。

效果好,比平面向量空間模型要好得多。

缺點:

它是一個線性模型,因此在非線性依賴關係的數據集中表現不佳。

LSA假設詞語在文檔中呈正態分布,但不是所有問題都滿足這個假設。

LDA需要用到SVD,這是計算密集型的運算,在新數據加入後難以進行更新。

6.主題模型的其他技術

除了LSA之外,還有其他高級有效的主題模型技術,比如LDA和lda2Vec。我們還寫過一篇介紹LDA的好文章,可以給大家提供參考。Lda2vec是一個高級得多的主題模型方法,它是基於word2vec單詞嵌入的。

結束語

這篇文章中我分享了自己的學習收穫。主題模型是一個非常有意思的東西,它能幫助你處理許多文本數據集。因此,我建議大家利用本文的代碼來解決其他數據集的問題。享受文本挖掘吧!

留言 點贊 發個朋友圈

我們一起分享AI學習與發展的乾貨

編譯組: 黃天元、胡婷

相關鏈接:

https://www.analyticsvidhya.com/blog/2018/10/stepwise-guide-topic-modeling-latent-semantic-analysis/

如需轉載,請後台留言,遵守轉載規範


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 讀芯術 的精彩文章:

周末AI課堂:深度學習中的熵 理論篇
今日芯聲 | 拒絕大眾化!不整容也能讓你得到一張獨一無二的臉

TAG:讀芯術 |