【火爐煉AI】機器學習042-NLP文本的主題建模

【火爐煉AI】機器學習042-NLP文本的主題建模

(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3)git

文本的主題建模時用NLP來識別文本文檔中隱藏的某種模式的過程,能夠發現該文檔的隱藏主題,以便對文檔進行分析。主題建模的實現過程是,識別出某文本文檔中最有意義,最能表徵主題的詞來實現主題分類,即尋找文本文檔中的關鍵詞,經過關鍵詞就能夠識別出某文檔的隱藏主題。github


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]))

-------------------------------------輸---------出--------------------------------code

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著,陶俊傑,陳小莉譯

相關文章
相關標籤/搜索