【火爐煉AI】機器學習042-NLP文字的主題建模
【火爐煉AI】機器學習042-NLP文字的主題建模
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3)
文字的主題建模時用NLP來識別文字文件中隱藏的某種模式的過程,可以發現該文件的隱藏主題,以便對文件進行分析。主題建模的實現過程是,識別出某文字文件中最有意義,最能表徵主題的詞來實現主題分類,即尋找文字文件中的關鍵詞,通過關鍵詞就可以識別出某文件的隱藏主題。
1. 準備資料集
本次所用的資料集存放在一個txt文件中,故而需要從txt文件中載入該文字內容,然後再對這些文字進行預處理。由於預處理的步驟比較多,故而此處建立一個class來完成資料的載入和預處理過程,也使得程式碼看起來更簡潔,更通用。
# 準備資料集,建一個class來載入資料集,對資料進行預處理 from nltk.tokenize import RegexpTokenizer from nltk.corpus import stopwords from nltk.stem.snowball import SnowballStemmer from gensim import models, corpora class DataSet: def __init__(self,txt_file_path): self.__txt_file=txt_file_path def __load_txt(self): # 從txt文件中載入文字內容,逐行讀入 with open(self.__txt_file,'r') as file: content=file.readlines() # 一次性將所有的行都讀入 return [line[:-1] for line in content] # 去掉每一行末尾的\n def __tokenize(self,lines_list): # 預處理之一:對每一行文字進行分詞 tokenizer=RegexpTokenizer('\w+') # 此處用正則表示式分詞器而不用word_tokenize的原因是:排除帶有標點的單詞 return [tokenizer.tokenize(line.lower()) for line in lines_list] def __remove_stops(self,lines_list): # 預處理之二:對每一行取出停用詞 # 我們要刪除一些停用詞,避免這些詞的噪聲干擾,故而需要一個停用詞表 stop_words_list=stopwords.words('english') # 獲取英文停用詞表 return [[token for token in line if token not in stop_words_list] for line in lines_list] # 這兒有點難以理解,lines_list含有的元素也是list,這一個list就是一行文字, # 而一行文字內部有N個分片語成,故而lines_list可以看出二維陣列,需要用兩層generator def __word_stemm(self,lines_list): # 預處理之三:對每個分詞進行詞幹提取 stemmer=SnowballStemmer('english') return [[stemmer.stem(word) for word in line] for line in lines_list] def prepare(self): '''供外部呼叫的函式,用於準備資料集''' # 先從txt檔案中載入文字內容,再進行分詞,再去除停用詞,再進行詞幹提取 stemmed_words=self.__word_stemm(self.__remove_stops(self.__tokenize(self.__load_txt()))) # 後面的建模需要用到基於dict的詞矩陣,故而先用corpora構建dict在建立詞矩陣 dict_words=corpora.Dictionary(stemmed_words) matrix_words=[dict_words.doc2bow(text) for text in stemmed_words] return dict_words, matrix_words # 以下函式主要用於測試上面的幾個函式是否執行正常 def get_content(self): return self.__load_txt() def get_tokenize(self): return self.__tokenize(self.__load_txt()) def get_remove_stops(self): return self.__remove_stops(self.__tokenize(self.__load_txt())) def get_word_stemm(self): return self.__word_stemm(self.__remove_stops(self.__tokenize(self.__load_txt())))
這個類是否執行正常,是否能夠得到我們預期的結果了?可以用下面的程式碼來測試
# 檢驗上述DataSet類是否執行正常 dataset=DataSet("E:\PyProjects\DataSet\FireAI\data_topic_modeling.txt") # 以下測試load_txt()函式是否正常 content=dataset.get_content() print(len(content)) print(content[:3]) # 以下測試__tokenize()函式是否正常 tokenized=dataset.get_tokenize() print(tokenized) # 一下測試__remove_stops()函式是否正常 removed=dataset.get_remove_stops() print(removed) # 以下測試__word_stemm()函式是否正常 stemmed=dataset.get_word_stemm() print(stemmed) # 以下測試prepare函式是否正常 _,prepared=dataset.prepare() print(prepared)
輸出的執行結果比較長,可以看我的github原始碼。
2. 構建模型,訓練資料集
我們用LDA模型(Latent Dirichlet Allocation, LDA)做主題建模,如下:
# 獲取資料集
dataset=DataSet("E:\PyProjects\DataSet\FireAI\data_topic_modeling.txt")
dict_words, matrix_words =dataset.prepare()
# 使用LDAModel建模
lda_model=models.ldamodel.LdaModel(matrix_words,num_topics=2,
id2word=dict_words,passes=25)
# 此處假設原始文件有兩個主題
上面的程式碼會建立LDAModel並對模型進行訓練,需要注意,LDAModel位於gensim模組中,這個模組需要自己用pip install gensim來安裝,安裝之後才能使用。
LDAModel會計算每個單詞的重要性,然後建立重要性計算方程,依靠此方程來給出預測主題。
如下程式碼可以打印出該重要性方程:
# 檢視模型中最重要的N個單詞
print('Most important words to topics: ')
for item in lda_model.print_topics(num_topics=2,num_words=5):
# 此處只打印最重要的5個單詞
print('Topic: {}, words: {}'.format(item[0],item[1]))
-------------------------------------輸---------出--------------------------------
Most important words to topics:
Topic: 0, words: 0.075"need" + 0.053"order" + 0.032"system" + 0.032"encrypt" + 0.032"work"
Topic: 1, words: 0.037"younger" + 0.037"develop" + 0.037"promot" + 0.037"talent" + 0.037"train"
--------------------------------------------完-------------------------------------
########################小**********結###############################
1,一般機器學習專案需要我們自己處理的內容都是資料集方面,可以將資料集處理過程寫成一個專門的class,比如上面我把文字預處理過程寫在class裡面,每一個函式代表一種預處理方式,這樣條理清楚,具有一定通用性。
2,此處我們使用gensim模組中的LDAModel來做主題建模,gensim模組是一個非常有用的NLP處理工具,在文字內容分析中應用較多。
#################################################################
注:本部分程式碼已經全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯