前言 在對文本做數(shù)據(jù)分析時,一大半的時間都會花在文本預(yù)處理上,而中文和英文的預(yù)處理流程稍有不同,本文對中文文本挖掘的預(yù)處理流程做一個總結(jié)。 中文文本挖掘預(yù)處理特點 首先看中文文本挖掘預(yù)處理與英文文本挖掘預(yù)處理的不同點。 首先,中文文本是沒有像英文的單詞空格那樣隔開的,因此不能直接像英文一樣可以直接用最簡單的空格和標點符號完成分詞。所以一般需要用分詞算法來完成分詞,在(干貨 | 自然語言處理(1)之聊一聊分詞原理)已經(jīng)講到了中文的分詞原理。 第二,中文的編碼不是utf8,而是unicode。這樣會導(dǎo)致在分詞時,需要處理編碼的問題。 上述兩點構(gòu)成了中文分詞相比英文分詞的一些不同點,后面也會重點講述這部分的處理。了解了中文預(yù)處理的一些特點后,通過實踐總結(jié)下中文文本挖掘預(yù)處理流程。 1. 數(shù)據(jù)收集 在文本挖掘之前,需要得到文本數(shù)據(jù),文本數(shù)據(jù)的獲取方法一般有兩種:使用別人做好的語料庫和自己用爬蟲去在網(wǎng)上去爬自己的語料數(shù)據(jù)。 對于第一種方法,常用的文本語料庫在網(wǎng)上有很多,如果大家只是學(xué)習,則可以直接下載下來使用,但如果是某些特殊主題的語料庫,比如“機器學(xué)習”相關(guān)的語料庫,則這種方法行不通,需要我們自己用第二種方法去獲取。 對于第二種使用爬蟲的方法,開源工具有很多,通用的爬蟲我一般使用beautifulsoup。但是我們需要某些特殊的語料數(shù)據(jù),比如上面提到的“機器學(xué)習”相關(guān)的語料庫,則需要用主題爬蟲(也叫聚焦爬蟲)來完成,一般使用ache。 ache允許我們用關(guān)鍵字或者一個分類算法來過濾出我們需要的主題語料,比較強大。 2. 除去數(shù)據(jù)中非中文部分 這一步主要是針對用爬蟲收集的語料數(shù)據(jù),由于爬下來的內(nèi)容中有很多html的一些標簽,需要去掉。少量的非文本內(nèi)容的可以直接用Python的正則表達式(re)刪除, 復(fù)雜的則可以用beautifulsoup來去除。去除掉這些非文本的內(nèi)容后,就可以進行真正的文本預(yù)處理了。 3. 處理中文編碼問題 由于Python2.x不支持unicode的處理,因此使用Python2.x做中文文本預(yù)處理時需要遵循的原則是,存儲數(shù)據(jù)都用utf8,讀出來進行中文相關(guān)處理時,使用GBK之類的中文編碼,在下一節(jié)的分詞再用例子說明這個問題。 4. 中文分詞 常用的中文分詞軟件有很多,比較推薦結(jié)巴分詞。安裝也很簡單,比如基于Python的,用'pip install jieba'就可以完成。下面我們就用例子來看看如何中文分詞。 首先準備兩段文本,內(nèi)容分別如下: nlp_test0.txt 沙瑞金贊嘆易學(xué)習的胸懷,是金山的百姓有福,可是這件事對李達康的觸動很大。易學(xué)習又回憶起他們?nèi)朔珠_的前一晚,大家一起喝酒話別,易學(xué)習被降職到道口縣當縣長,王大路下海經(jīng)商,李達康連連賠禮道歉,覺得對不起大家,他最對不起的是王大路,就和易學(xué)習一起給王大路湊了5萬塊錢,王大路自己東挪西撮了5萬塊,開始下海經(jīng)商。沒想到后來王大路竟然做得風生水起。沙瑞金覺得他們?nèi)?,在困難時期還能以沫相助,很不容易。 nlp_test2.txt 沙瑞金向毛婭打聽他們家在京州的別墅,毛婭笑著說,王大路事業(yè)有成之后,要給歐陽菁和她公司的股權(quán),她們沒有要,王大路就在京州帝豪園買了三套別墅,可是李達康和易學(xué)習都不要,這些房子都在王大路的名下,歐陽菁好像去住過,毛婭不想去,她覺得房子太大很浪費,自己家住得就很踏實。 首先將文本從第一個文件中讀取進來,并使用中文GBK編碼,再調(diào)用結(jié)巴分詞,最后把分詞結(jié)果用uft8格式存在另一個文本nlp_test1.txt中。代碼如下: # -*- coding: utf-8 -*- import jieba with open('./nlp_test0.txt') as f: document = f.read()
document_decode = document.decode('GBK') document_cut = jieba.cut(document_decode) result = ' '.join(document_cut) result = result.encode('utf-8') with open('./nlp_test1.txt', 'w') as f2: f2.write(result) f.close() f2.close() 輸出的文本內(nèi)容如下: nlp_test1.txt 沙 瑞金 贊嘆 易 學(xué)習 的 胸懷 , 是 金山 的 百姓 有福 , 可是 這件 事對 李達康 的 觸動 很大 。 易 學(xué)習 又 回憶起 他們 三人 分開 的 前一晚 , 大家 一起 喝酒 話別 , 易 學(xué)習 被 降職 到 道口 縣當 縣長 , 王 大路 下海經(jīng)商 , 李達康 連連 賠禮道歉 , 覺得 對不起 大家 , 他 最 對不起 的 是 王 大路 , 就 和 易 學(xué)習 一起 給 王 大路 湊 了 5 萬塊 錢 , 王 大路 自己 東挪西撮 了 5 萬塊 , 開始 下海經(jīng)商 。 沒想到 后來 王 大路 竟然 做 得 風生水 起 。 沙 瑞金 覺得 他們 三人 , 在 困難 時期 還 能 以沫 相助 , 很 不 容易 。 可以發(fā)現(xiàn)對于一些人名和地名,jieba處理不好,不過可以幫jieba加入詞匯如下: jieba.suggest_freq('沙瑞金', True) 現(xiàn)在再重新進行讀文件,編碼,分詞,編碼和寫文件,代碼如下: with open('./nlp_test0.txt') as f: document = f.read()
document_decode = document.decode('GBK') document_cut = jieba.cut(document_decode) result = ' '.join(document_cut) result = result.encode('utf-8') with open('./nlp_test1.txt', 'w') as f2: f2.write(result) f.close() f2.close() 輸出的文本內(nèi)容如下: nlp_test1.txt 沙瑞金 贊嘆 易學(xué)習 的 胸懷 , 是 金山 的 百姓 有福 , 可是 這件 事對 李達康 的 觸動 很大 。 易學(xué)習 又 回憶起 他們 三人 分開 的 前一晚 , 大家 一起 喝酒 話別 , 易學(xué)習 被 降職 到 道口 縣當 縣長 , 王大路 下海經(jīng)商 , 李達康 連連 賠禮道歉 , 覺得 對不起 大家 , 他 最 對不起 的 是 王大路 , 就 和 易學(xué)習 一起 給 王大路 湊 了 5 萬塊 錢 , 王大路 自己 東挪西撮 了 5 萬塊 , 開始 下海經(jīng)商 。 沒想到 后來 王大路 竟然 做 得 風生水 起 。 沙瑞金 覺得 他們 三人 , 在 困難 時期 還 能 以沫 相助 , 很 不 容易 。 以同樣的方法對第二段文本nlp_test2.txt進行分詞和寫入文件nlp_test3.txt。 with open('./nlp_test2.txt') as f: document2 = f.read()
document2_decode = document2.decode('GBK') document2_cut = jieba.cut(document2_decode) #print ' '.join(jieba_cut) result = ' '.join(document2_cut) result = result.encode('utf-8') with open('./nlp_test3.txt', 'w') as f2: f2.write(result) f.close() f2.close() 輸出的文本內(nèi)容如下: nlp_test3.txt 沙瑞金 向 毛婭 打聽 他們 家 在 京州 的 別墅 , 毛婭 笑 著 說 , 王大路 事業(yè)有成 之后 , 要 給 歐陽 菁 和 她 公司 的 股權(quán) , 她們 沒有 要 , 王大路 就 在 京州 帝豪園 買 了 三套 別墅 , 可是 李達康 和 易學(xué)習 都 不要 , 這些 房子 都 在 王大路 的 名下 , 歐陽 菁 好像 去 住 過 , 毛婭 不想 去 , 她 覺得 房子 太大 很 浪費 , 自己 家住 得 就 很 踏實 。 5. 引入停用詞 上面解析的文本中有很多無效的詞,比如“著”,“和”,還有一些標點符號,這些我們不想在文本分析時引入,因此需要去掉,這些詞就是停用詞。常用的中文停用詞表是1208個(下載地址:https://pan.baidu.com/s/1gfMXMl9)。 現(xiàn)在將停用詞表從文件讀出,并切分成一個數(shù)組備用: #從文件導(dǎo)入停用詞表 stpwrdpath = 'stop_words.txt' stpwrd_dic = open(stpwrdpath, 'rb') stpwrd_content = stpwrd_dic.read() #將停用詞表轉(zhuǎn)換為list stpwrdlst = stpwrd_content.splitlines() stpwrd_dic.close() 6. 特征處理 現(xiàn)在可以用scikit-learn來對文本特征進行處理,在()中講到了兩種特征處理的方法,向量化與Hash Trick。而向量化是最常用的方法,因為它可以接著進行TF-IDF的特征處理。在()中也講到了TF-IDF特征處理的方法,這里使用scikit-learn的TfidfVectorizer類來進行TF-IDF特征處理。 TfidfVectorizer類可以完成向量化,TF-IDF和標準化三步。當然,還可以處理停用詞。現(xiàn)在把上面分詞好的文本載入內(nèi)存: with open('./nlp_test1.txt') as f3: res1 = f3.read() print res1 with open('./nlp_test3.txt') as f4: res2 = f4.read() print res2 現(xiàn)在可以進行向量化,TF-IDF和標準化三步處理(這里引入了上面的停用詞表)。 from sklearn.feature_extraction.text import TfidfVectorizer print tfidf 部分輸出如下: (0, 44)0.154467434933 看看每個詞與TF-IDF的對應(yīng)關(guān)系: wordlist = vector.get_feature_names()#獲取詞袋模型中的所有詞 # tf-idf矩陣 元素a[i][j]表示j詞在i類文本中的tf-idf權(quán)重 weightlist = tfidf.toarray() #打印每類文本的tf-idf詞語權(quán)重,第一個for遍歷所有文本,第二個for便利某一類文本下的詞語權(quán)重 for i in range(len(weightlist)): print '-------第',i,'段文本的詞語tf-idf權(quán)重------' for j in range(len(wordlist)): print wordlist[j],weightlist[i][j] 部分輸出如下: -------第 0 段文本的詞語tf-idf權(quán)重------ 7. 建立分析模型 有了每段文本的TF-IDF的特征向量,就可以利用這些數(shù)據(jù)建立分類或者聚類模型了,或者進行主題模型的分析。此時的分類聚類模型和之前講的非自然語言處理的數(shù)據(jù)分析沒有什么兩樣。因此對應(yīng)的算法都可以直接使用。 小結(jié) 本文對中文文本挖掘預(yù)處理的過程做了一個總結(jié),希望可以幫助到大家。需要注意的是這個流程主要針對一些常用的文本挖掘,并使用了詞袋模型,對于某一些自然語言處理的需求則流程需要修改。比如我們涉及到詞上下文關(guān)系的一些需求,此時不能使用詞袋模型。而有時候我們對于特征的處理有自己的特殊需求,因此這個流程僅供自然語言處理入門者參考。 |
|
來自: 長沙7喜 > 《智能技術(shù)》