文本挖掘预处理流程总结(1)— 中文
目錄
1. 中文文本挖掘預處理特點
2.??中文文本挖掘預處理
2.1 預處理一:數據收集
2.2? 預處理二:除去數據中非文本部分
2.3 預處理三:處理中文編碼問題
2.4?預處理四:中文分詞
2.5 預處理五:引入停用詞
2.6 預處理六:特征處理
2.7 預處理七:建立分析模型
3. 中文文本挖掘預處理總結
? ? ? ?在對文本做數據分析時,我們一大半的時間都會花在文本預處理上,而中文和英文的預處理流程稍有不同,本文就對中文文本挖掘的預處理流程做一個總結。
文本挖掘預處理基本步驟:
? ? ? 分詞——向量化(詞袋模型)——Hash Trick(特征的降維,若詞匯量極大,內存不夠時)——TF-TDF(特征的權重修正)——使用各個文本的詞特征向量作為文本的特征,進行分類或者聚類分析。
? ? ? 注:TF-IDF是常用的文本挖掘預處理基本步驟,但是如果預處理中使用了Hash Trick,則一般就無法使用TF-IDF了
1. 中文文本挖掘預處理特點
首先我們看看中文文本挖掘預處理和英文文本挖掘預處理相比的一些特殊點。
? ? (1)第一,中文文本是沒有像英文的單詞空格那樣隔開的,因此不能直接像英文一樣可以直接用最簡單的空格和標點符號完成分詞。所以一般我們需要用分詞算法來完成分詞,在文本挖掘的分詞原理中,講到了中文的分詞原理,這里就不多說。
(2)第二,中文的編碼不是utf-8,而是unicode。這樣會導致在分詞的時候,和英文相比,我們要處理編碼的問題。
這兩點構成了中文分詞相比英文分詞的一些不同點,當然,英文分詞也有自己的煩惱。了解了中文預處理的一些特點后,我們就言歸正傳,通過實踐總結下中文文本挖掘預處理流程。
2.??中文文本挖掘預處理
2.1 預處理一:數據收集
在文本挖掘之前,我們需要得到文本數據,文本數據的獲取方法一般有兩種:
(1)使用別人做好的語料庫。常用的文本語料庫在網上有很多,如果只是學習,則可以直接下載下來使用,但如果是某些特殊主題的語料庫,比如“機器學習”相關的語料庫,則這種方法行不通,需要我們自己用第二種方法去獲取。
NLTK包含了許多語料庫:
? ? ? ? ? ? ? ? (1)古滕堡語料庫?
? ? ? ? ? ? ? ? (2)網絡和聊天文本
? ? ? ? ? ? ? ? (3)布朗語料庫
? ? ? ? ? ? ? ? (4)路透社語料庫
? ? ? ? ? ? ? ? (5)就職演講語料庫
? ? ? ? ? ? ? ? (6)標注文本語料庫?
(2)用爬蟲去在網上去爬自己的語料數據:對于使用爬蟲的方法,開源工具有很多,通用的爬蟲一般使用beautifulsoup。但是我們需要某些特殊的語料數據,比如上面提到的“機器學習”相關的語料庫,則需要用主題爬蟲(也叫聚焦爬蟲)來完成。這個我一般使用ache。 ache允許用關鍵字或者一個分類算法來過濾出我們需要的主題語料,比較強大。
2.2? 預處理二:除去數據中非文本部分
這一步主要是針對用爬蟲收集的語料數據,由于爬下來的內容中有很多html的一些標簽,需要去掉。少量的非文本內容可以直接用Python的正則表達式(re)刪除,復雜的則可以用beautifulsoup來去除。去除掉這些非文本的內容后,我們就可以進行真正的文本預處理了。
2.3 預處理三:處理中文編碼問題
由于Python2不支持unicode的處理,因此使用Python2做中文文本預處理時需要遵循的原則是:
? ? ?(1)存儲數據都用utf-8;
? ? ?(2)讀出來進行中文相關處理時,使用GBK之類的中文編碼。
? ? ?下面一節的分詞,用例子說明這個問題。
2.4?預處理四:中文分詞
常用的中文分詞軟件有很多,個人比較推薦結巴分詞。安裝也很簡單,比如基于Python的,用"pip install jieba"就可以完成。下面我們就用例子來看看如何中文分詞。
完整代碼參見:github:?https://github.com/ljpzzz/machinelearning/blob/master/natural-language-processing/chinese_digging.ipynb
首先,準備了兩段文本,這兩段文本在兩個文件中。兩段文本的內容分別是nlp_test0.txt和nlp_test1.txt:
? ? ? ? 沙瑞金贊嘆易學習的胸懷,是金山的百姓有福,可是這件事對李達康的觸動很大。易學習又回憶起他們三人分開的前一晚,大家一起喝酒話別,易學習被降職到道口縣當縣長,王大路下海經商,李達康連連賠禮道歉,覺得對不起大家,他最對不起的是王大路,就和易學習一起給王大路湊了5萬塊錢,王大路自己東挪西撮了5萬塊,開始下海經商。沒想到后來王大路竟然做得風生水起。沙瑞金覺得他們三人,在困難時期還能以沫相助,很不容易。
沙瑞金向毛婭打聽他們家在京州的別墅,毛婭笑著說,王大路事業有成之后,要給歐陽菁和她公司的股權,她們沒有要,王大路就在京州帝豪園買了三套別墅,可是李達康和易學習都不要,這些房子都在王大路的名下,歐陽菁好像去住過,毛婭不想去,她覺得房子太大很浪費,自己家住得就很踏實。
先講文本從第一個文件中讀取,并使用中文GBK編碼,再調用結巴分詞,最后把分詞結果用uft-8格式存在另一個文本nlp_test1.txt中。代碼如下:
import jiebawith open('./input/nlp_test0.txt',encoding='GBK') as f: # 讀入文件時用GBK解碼document = f.read()document_cut = jieba.cut(document)# print ' '.join(jieba_cut) //如果打印結果,則分詞效果消失,后面的result無法顯示result = ' '.join(document_cut) with open('./input/nlp_test2.txt', 'w', encoding='utf-8') as f2: # 存儲時用utf-8編碼f2.write(result)輸出的文本內容如下:
沙 瑞金 贊嘆 易 學習 的 胸懷 , 是 金山 的 百姓 有福 , 可是 這件 事對 李達康 的 觸動 很大 。 易 學習 又 回憶起 他們 三人 分開 的 前一晚 , 大家 一起 喝酒 話別 , 易 學習 被 降職 到 道口 縣當 縣長 , 王 大路 下海經商 , 李達康 連連 賠禮道歉 , 覺得 對不起 大家 , 他 最 對不起 的 是 王 大路 , 就 和 易 學習 一起 給 王 大路 湊 了 5 萬塊 錢 , 王 大路 自己 東挪西撮 了 5 萬塊 , 開始 下海經商 。 沒想到 后來 王 大路 竟然 做 得 風生水 起 。 沙 瑞金 覺得 他們 三人 , 在 困難 時期 還 能 以沫 相助 , 很 不 容易 。?可以發現對于一些人名和地名,jieba處理的不好,不過我們可以幫jieba加入詞匯如下:suggest_freq(segment, tune=True)?
import jiebawith open('./input/nlp_test0.txt',encoding='GBK') as f: # 讀入文件時用GBK解碼document = f.read()document_cut = jieba.cut(document)# 使用 suggest_freq(segment, tune=True) 可調節單個詞語的詞頻,使其(或不能)被分出來jieba.suggest_freq('沙瑞金', True)jieba.suggest_freq('易學習', True)jieba.suggest_freq('王大路', True)jieba.suggest_freq('京州', True)# print ' '.join(jieba_cut) //如果打印結果,則分詞效果消失,后面的result無法顯示result = ' '.join(document_cut)with open('./input/nlp_test2.txt', 'w', encoding='utf-8') as f2: # 存儲時用utf-8編碼f2.write(result)?輸出的文本內容如下:
沙瑞金 贊嘆 易學習 的 胸懷 , 是 金山 的 百姓 有福 , 可是 這件 事對 李達康 的 觸動 很大 。 易學習 又 回憶起 他們 三人 分開 的 前一晚 , 大家 一起 喝酒 話別 , 易學習 被 降職 到 道口 縣當 縣長 , 王大路 下海經商 , 李達康 連連 賠禮道歉 , 覺得 對不起 大家 , 他 最 對不起 的 是 王大路 , 就 和 易學習 一起 給 王大路 湊 了 5 萬塊 錢 , 王大路 自己 東挪西撮 了 5 萬塊 , 開始 下海經商 。 沒想到 后來 王大路 竟然 做 得 風生水 起 。 沙瑞金 覺得 他們 三人 , 在 困難 時期 還 能 以沫 相助 , 很 不 容易 。基本已經可以滿足要求。同樣的方法我們對第二段文本nlp_test1.txt進行分詞和寫入文件nlp_test3.txt。?輸出的文本內容如下:
沙瑞金 向 毛婭 打聽 他們 家 在 京州 的 別墅 , 毛婭 笑 著 說 , 王大路 事業有成 之后 , 要 給 歐陽 菁 和 她 公司 的 股權 , 她們 沒有 要 , 王大路 就 在 京州 帝豪園 買 了 三套 別墅 , 可是 李達康 和 易學習 都 不要 , 這些 房子 都 在 王大路 的 名下 , 歐陽 菁 好像 去 住 過 , 毛婭 不想 去 , 她 覺得 房子 太大 很 浪費 , 自己 家住 得 就 很 踏實 。2.5 預處理五:引入停用詞
在上面我們解析的文本中有很多無效的詞,比如“著”,“和”,還有一些標點符號,這些我們不想在文本分析的時候引入,因此需要去掉,這些詞就是停用詞。常用的中文停用詞表是1208個,下載地址。當然也有其他版本的停用詞表,不過這個1208詞版是我常用的。
? ?在我們用scikit-learn做特征處理的時候,可以通過參數stop_words來引入一個數組作為停用詞表。
? 現在我們將停用詞表從文件讀出,并切分成一個數組備用:
# 從文件導入停用詞表stpwrdpath = "./input/stop_words.txt"with open(stpwrdpath, 'rb') as f:stpwrd_content = f.read()# 將停用詞表轉換為liststpwrdlst = stpwrd_content.splitlines()??stpwrdlst的結果為:
[b',', b'?', b'\xa1\xa2', b'\xa1\xa3', b'\xa1\xb0', b'\xa1\xb1', b'\xa1\xb6', b'\xa1\xb7', b'\xa3\xa1', b'\xa3\xac', b'\xa3\xba', b'\xa3\xbb', b'\xa3\xbf', b'\xc8\xcb\xc3\xf1', b'\xc4\xa9##\xc4\xa9', b'\xb0\xa1', b'\xb0\xa2', b'\xb0\xa5', b'\xb0\xa5\xd1\xbd', b'\xb0\xa5\xd3\xb4',...]
? ? ? ?NLTK的語料庫中有一個停用詞,用戶必須從切詞列表中把停用詞去掉,請參考。
2.6 預處理六:特征處理
現在就可以用scikit-learn來對文本特征進行處理了,在文本挖掘預處理之向量化與Hash Trick中,我們講到了兩種特征處理的方法,向量化與Hash Trick。而向量化是最常用的方法,因為它可以接著進行TF-IDF的特征處理。在文本挖掘預處理之TF-IDF中,我們也講到了TF-IDF特征處理的方法。這里我們就用scikit-learn的TfidfVectorizer類來進行TF-IDF特征處理。
TfidfVectorizer類可以幫助完成向量化、TF-IDF和標準化三步。當然,還可以幫我們處理停用詞。(相當于word2vec)
現在我們把上面分詞好的文本載入內存:
with open('./input/nlp_test2.txt','rb') as f3:res1 = f3.read() with open('./input/nlp_test3.txt','rb') as f4:res2 = f4.read()? ? ? ?這里的輸出還是我們上面分完詞的文本。現在我們可以進行向量化、TF-IDF和標準化三步處理了。注意,這里引入了上面的停用詞表。?
from sklearn.feature_extraction.text import TfidfVectorizer corpus = [res1, res2] vector = TfidfVectorizer(stop_words=stpwrdlst) tfidf = vector.fit_transform(corpus) print(tfidf)部分輸出如下:
? (0, 44)?? ?0.15446743493280246
? (0, 59)?? ?0.10854929506851102
? (0, 39)?? ?0.3089348698656049
? (0, 53)?? ?0.10854929506851102
? (0, 65)?? ?0.10854929506851102
? (0, 49)?? ?0.10854929506851102
? ?......
? (1, 29)?? ?0.13989105965823861
? (1, 5)?? ?0.13989105965823861
? (1, 27)?? ?0.13989105965823861
? (1, 47)?? ?0.13989105965823861
? (1, 30)?? ?0.13989105965823861
? (1, 60)?? ?0.13989105965823861
? ? ? ?再來看看每個詞和TF-IDF的對應關系:
wordlist = vector.get_feature_names() # 獲取詞袋模型中的所有詞 # tf-idf矩陣 元素a[i][j]表示j詞在i類文本中的tf-idf權重 weightlist = tfidf.toarray() #打印每類文本的tf-idf詞語權重,第一個for遍歷所有文本,第二個for遍歷某一類文本下的詞語權重 for i in range(len(weightlist)):print("-------第",i,"段文本的詞語tf-idf權重------")for j in range(len(wordlist)):print(wordlist[j], weightlist[i][j])''' wordlist:['一起','萬塊','三人','三套','下海經商','不想','不要','東挪西撮',...]weightlist:array([[0.21709859, 0.21709859, 0.21709859, 0. , 0.21709859,0. , 0. , 0.1085493 , 0. , 0. ,...][0. , 0. , 0. , 0.13989106, 0. ,0.13989106, 0.13989106, 0. , 0.13989106, 0.13989106,]] '''部分輸出如下:
-------第 0 段文本的詞語tf-idf權重------
一起 0.21709859013702204
萬塊 0.21709859013702204
三人 0.21709859013702204
三套 0.0
下海經商 0.21709859013702204
不想 0.0?
...
-------第 1 段文本的詞語tf-idf權重------
一起 0.0
萬塊 0.0
三人 0.0
三套 0.13989105965823861
下海經商 0.0
不想 0.13989105965823861
不要 0.13989105965823861
...??
2.7 預處理七:建立分析模型
有了每段文本的TF-IDF的特征向量,就可以利用這些數據建立分類模型,或者聚類模型了,或者進行主題模型的分析。比如上面的兩段文本,就可以是兩個訓練樣本了。此時的分類聚類模型和之前講的非自然語言處理的數據分析沒有什么兩樣。因此對應的算法都可以直接使用。而主題模型是自然語言處理比較特殊的一塊。
3. 中文文本挖掘預處理總結
上面對中文文本挖掘預處理的過程做了一個總結,需要注意的是這個流程主要針對一些常用的文本挖掘,并使用了詞袋模型,對于某一些自然語言處理的需求則流程需要修改。比如涉及到詞上下文關系的一些需求,此時不能使用詞袋模型。而有時候對于特征的處理有自己的特殊需求,因此這個流程僅供自然語言處理入門參考。
總結
以上是生活随笔為你收集整理的文本挖掘预处理流程总结(1)— 中文的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: word2vec原理(二):基于Hier
- 下一篇: 文本挖掘预处理流程总结(2)— 英文