腳本之家
你與百萬(wàn)開發(fā)者在一起
來(lái)源 | 異步
“認(rèn)知”的核心技術(shù)是自然語(yǔ)言處理,這是人工智能領(lǐng)域中的一個(gè)重要方向,研究各種理論和方法,涉及的領(lǐng)域較多,主要包括機(jī)器翻譯、閱讀理解、智能寫作、對(duì)話系統(tǒng)、基礎(chǔ)技術(shù)和語(yǔ)義計(jì)算等。
計(jì)算機(jī)能“理解并開口說(shuō)話”,意味著與人類可進(jìn)行更廣泛的交流,從而一步步逼近并超越“圖靈測(cè)試”,讓人工智能掀開新的篇章。
《Python和NLTK自然語(yǔ)言處理》
作者
[印度] 尼天·哈登尼亞(Nitin Hardeniya)雅各布·帕金斯(Jacob Perkins)迪蒂·喬普拉(Deepti Chopra) 尼什·斯喬希(Nisheeth Joshi) 伊提·摩突羅(Iti Mathur)
語(yǔ)言是我們?nèi)粘I畹暮诵牟糠?,處理與語(yǔ)言相關(guān)的任何問(wèn)題都是非常有趣的。我希望此書能夠讓你一嗅NLP的芬芳,激勵(lì)你去了解更令人驚奇的NLP概念,并鼓勵(lì)你開發(fā)一些具有挑戰(zhàn)性的NLP應(yīng)用。
研究人類語(yǔ)言的過(guò)程稱為NLP。深入研究語(yǔ)言的人稱為語(yǔ)言學(xué)家,而“計(jì)算語(yǔ)言學(xué)家”這個(gè)專有名詞適用于應(yīng)用計(jì)算研究語(yǔ)言處理的人。從本質(zhì)上講,計(jì)算語(yǔ)言學(xué)家是深入了解語(yǔ)言的計(jì)算機(jī)科學(xué)家,計(jì)算語(yǔ)言學(xué)家可以運(yùn)用計(jì)算技能,對(duì)語(yǔ)言的不同方面進(jìn)行建模。計(jì)算語(yǔ)言學(xué)家解決的是語(yǔ)言理論方面的問(wèn)題,NLP只不過(guò)是計(jì)算語(yǔ)言學(xué)的應(yīng)用。
NLP更多探討的是應(yīng)用計(jì)算機(jī),處理不同語(yǔ)言的細(xì)微差別,以及使用NLP技術(shù)構(gòu)建現(xiàn)實(shí)世界的應(yīng)用。在實(shí)際情景下,NLP類似于教孩子學(xué)語(yǔ)言。一些最常見(jiàn)的任務(wù)(如理解單詞和句子,形成在語(yǔ)法和結(jié)構(gòu)上正確的句子)對(duì)人類而言是很自然。在NLP領(lǐng)域,把這樣的一些任務(wù)轉(zhuǎn)化為標(biāo)記解析(tokenization)、組塊(chunking)、詞性標(biāo)注(part of speech tagging)、解析(parsing)、機(jī)器翻譯(machine translation)、語(yǔ)音識(shí)別(speech recognition),這些任務(wù)中的大部分依然是計(jì)算機(jī)所面臨的最嚴(yán)峻的挑戰(zhàn)。
本文主要內(nèi)容如下。
NLP及其相關(guān)概念。
安裝Python、NLTK和其他庫(kù)的方法。
編寫一些非?;镜腜ython和NLTK代碼片段的方法。
如果你從來(lái)沒(méi)有聽說(shuō)過(guò)NLP這個(gè)詞,那么請(qǐng)花一些時(shí)間來(lái)閱讀這里提到的任何一本書籍,只要閱讀最初幾章即可。至少要快速閱讀一些與NLP相關(guān)的維基百科網(wǎng)頁(yè)。
由Daniel Jurafsky和James H. Martin合著的《Speech and Language Processing》。
由Christopher D. Manning和Hinrich Schütze合著的《Statistical Natural Language Processing》。
本節(jié)從Gartner的技術(shù)成熟度曲線開始討論,從這條曲線上,你可以清楚地看到NLP處在技術(shù)成熟度曲線的頂部。目前,NLP是行業(yè)所需的稀有技能之一。在大數(shù)據(jù)到來(lái)之后,NLP面臨的主要的挑戰(zhàn)是,NLP需要大量不但精通結(jié)構(gòu)化數(shù)據(jù)而且擅長(zhǎng)于處理半結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)的技術(shù)人員。我們正在生成拍字節(jié)量級(jí)的網(wǎng)絡(luò)博客、推特信息、臉書(Facebook)的推送信息、聊天記錄、電子郵件和評(píng)論。一些公司正在收集所有這些不同種類的數(shù)據(jù),以便更好地為客戶定位,并從中得到有意義的見(jiàn)解。為了處理這些非結(jié)構(gòu)化數(shù)據(jù)源,我們需要了解NLP的技術(shù)人員。
我們身處信息時(shí)代;我們甚至不能想象生活中沒(méi)有谷歌。我們使用Siri來(lái)處理大多數(shù)基本的語(yǔ)音功能。我們使用垃圾郵件過(guò)濾器過(guò)濾垃圾郵件。在Word文檔中,我們需要拼寫檢查器。在我們周圍,存在許多NLP在現(xiàn)實(shí)世界中應(yīng)用的例子。
(圖片來(lái)自gartner網(wǎng)站)
下面也提供一些你能夠使用但是沒(méi)有意識(shí)它們是建立在NLP上的令人贊嘆的NLP應(yīng)用的示例。
拼寫校正(微軟的Word/任何其他編輯器)
搜索引擎(谷歌、必應(yīng)、雅虎和WolframAlpha)
語(yǔ)音引擎(Siri和谷歌語(yǔ)音)
垃圾郵件分類(所有的電子郵件服務(wù))
新聞推送(谷歌和雅虎等)
機(jī)器翻譯(谷歌翻譯等)
IBM的沃森
構(gòu)建這些應(yīng)用需要一種非常特殊的技能集,你需要對(duì)語(yǔ)言非常了解,并具有可以有效處理語(yǔ)言的工具。因此,讓NLP成為最具優(yōu)勢(shì)的領(lǐng)域之一的原因不是廣告宣傳,而是可以使用NLP創(chuàng)建的這種應(yīng)用使得NLP成為必備的最獨(dú)特技能之一。
為了實(shí)現(xiàn)上述的一些應(yīng)用,以及其他基本的NLP預(yù)處理,我們有很多可用的開源工具。在這些工具中,有一些是某些組織為建立自己的NLP應(yīng)用而開發(fā)的,而有一些是開源的。這里是一張可用的NLP工具列表。
GATE
Mallet
Open NLP
UIMA
斯坦福工具包
Genism
自然語(yǔ)言工具包(NLTK)
大部分工具是用Java編寫的,具有相似的功能。其中一些工具非常健壯,可以獲得NLP工具的不同版本。但是,當(dāng)涉及易于使用和易于解釋這兩個(gè)概念的時(shí)候,NLTK得分最高。由于Python(NLTK的編碼語(yǔ)言)的學(xué)習(xí)曲線非??欤虼薔LTK也是非常易于學(xué)習(xí)的工具包。NLTK已經(jīng)將大部分的NLP任務(wù)納入籃中,非常優(yōu)雅,容易用于工作中。出于所有這些原因,NLTK已成為NLP界最流行的庫(kù)之一。
建議使用Anaconda和Canopy Python的發(fā)行版本。理由是,這些版本綁定了一些庫(kù),如scipy、numpy、scikit等,你可以使用這些庫(kù)進(jìn)行數(shù)據(jù)分析,開發(fā)出與NLP有關(guān)的應(yīng)用,以及把這些庫(kù)應(yīng)用于相關(guān)領(lǐng)域。即使NLTK也是這個(gè)發(fā)行版本的一部分。
下面測(cè)試所有功能。
請(qǐng)?jiān)谙鄳?yīng)的操作系統(tǒng)中,啟動(dòng)終端。然后運(yùn)行:
$ python
這應(yīng)該打開了Python解釋器。
1Python 2.6.6 (r266:84292, Oct 15 2013, 07:32:41)
2[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
3Type 'help', 'copyright', 'credits' or 'license' for more information.
4>>>
我希望你得到的輸出與這個(gè)類似。你有可能得到一個(gè)不同的輸出,但是在理想情況下,你獲得了Python的最新版本(建議的版本是2.7)信息、編譯器GCC的信息,以及操作系統(tǒng)的詳細(xì)信息。Python的最新版本是3.0+,但是,與任何其他開源的系統(tǒng)一樣,我們應(yīng)該試圖保持相對(duì)穩(wěn)定的版本,而不是跳躍到最新版本。如果你已經(jīng)使用了Python 3.0+,那么請(qǐng)從python網(wǎng)站了解新版本中又添加了哪些新特征。
基于UNIX的系統(tǒng)將Python作為默認(rèn)程序。Windows用戶可以設(shè)置路徑,讓Python正常運(yùn)行。下面檢查一下是否已經(jīng)正確安裝了NLTK。
1>>>import nltk
2>>>print 'Python and NLTK installed successfully'
3Python and NLTK installed successfully
我們準(zhǔn)備好了。
本節(jié)不會(huì)深入探討Python。然而,我們會(huì)讓你快速瀏覽一遍Python的基本知識(shí)。同樣,為了讀者的利益,我認(rèn)為應(yīng)該來(lái)一段5分鐘的Python之旅。接下來(lái)的幾節(jié)將談?wù)摂?shù)據(jù)結(jié)構(gòu)的基本知識(shí)、一些常用的函數(shù),以及Python的一般構(gòu)建方式。
列表 |
在Python中,列表是最常用的數(shù)據(jù)結(jié)構(gòu)之一。它們幾乎相當(dāng)于其他編程語(yǔ)言中的數(shù)組。下面從Python列表所提供的一些最重要的函數(shù)開始講述。
在Python控制臺(tái)中,嘗試輸入以下內(nèi)容。
11>>> lst=[1,2,3,4]
22>>> # mostly like arrays in typical languages
33>>>print lst
44[1, 2, 3, 4]
可以使用更加靈活的索引來(lái)訪問(wèn)Python列表。下面是一些例子。
>>>print 'First element' +lst[0]
你會(huì)得到這樣的錯(cuò)誤消息:
TypeError: cannot concatenate 'str' and 'int' objects
原因是Python是一種解釋性語(yǔ)言,我們?cè)诼暶髯兞繒r(shí),不需要初始化變量并聲明變量的類型,Python只有在計(jì)算表達(dá)式時(shí),才檢查變量類型。在列表中,對(duì)象是整數(shù)類型的,因此它們不能與print函數(shù)串接。這個(gè)函數(shù)只接受字符串對(duì)象。出于這個(gè)原因,我們需要將列表元素轉(zhuǎn)換為字符串。這個(gè)過(guò)程也稱為強(qiáng)制類型轉(zhuǎn)換(typecasting)。
1>>>print 'First element :' +str(lst[0])
2>>>print 'last element :' +str(lst[-1])
3>>>print 'first three elements :' +str(lst[0:2])
4>>>print 'last three elements :'+str(lst[-3:])
5First element :1
6last element :4
7first three elements :[1, 2,3]
8last three elements :[2, 3, 4]
自助 |
了解更多不同的數(shù)據(jù)類型和函數(shù)的最佳方法是使用幫助函數(shù),如help() 和 dir(lst)。
可以使用dir(Python對(duì)象)命令,列出給定Python對(duì)象的所有給定的屬性。如果傳入一個(gè)列表對(duì)象,那么這個(gè)函數(shù)會(huì)列出所有可以使用列表執(zhí)行的酷炫的操作。
1>>>dir(lst)
2>>>' , '.join(dir(lst))
3'__add__ , __class__ , __contains__ , __delattr__ , __delitem__ , __
4delslice__ , __doc__ , __eq__ , __format__ , __ge__ , __getattribute__
5, __getitem__ , __getslice__ , __gt__ , __hash__ , __iadd__ , __imul__
6, __init__ , __iter__ , __le__ , __len__ , __lt__ , __mul__ , __ne__ ,
7__new__ , __reduce__ , __reduce_ex__ , __repr__ , __reversed__ , __rmul__
8, __setattr__ , __setitem__ , __setslice__ , __sizeof__ , __str__ , __
9subclasshook__ , append , count , extend , index , insert , pop , remove
10, reverse , sort'
使用help(Python對(duì)象)命令,我們可以得到給定Python對(duì)象的詳細(xì)文檔,并且這個(gè)命令也給出一些示例,告訴我們?nèi)绾问褂肞ython對(duì)象。
1>>>help(lst.index)
2Help on built-in function index:
3index(...)
4 L.index(value, [start, [stop]]) -> integer -- return first index of value.
5This function raises a ValueError if the value is not present.
因此,在Python的任何數(shù)據(jù)類型上,都可以使用help和dir,并且這是一種非常不錯(cuò)的方式,可用于了解關(guān)于函數(shù)和對(duì)象的其他詳細(xì)信息。這也提供了一些基本示例,供你在工作中參考,在大部分情況下,這些示例非常有用。
在Python和其他語(yǔ)言中,字符串都非常相似,但是對(duì)字符串的操作是Python的主要特征之一。在Python中,使用字符串非常容易。在Java/C中,即使是一些很簡(jiǎn)單的操作(例如將字符串分割),我們也需要花很大的精力才能做到。然而,在Python中,你會(huì)發(fā)現(xiàn)這是多么容易。
在應(yīng)用任何Python對(duì)象和函數(shù)時(shí),你都可以從先前的help函數(shù)中獲得幫助。下面使用最常用的數(shù)據(jù)類型字符串給你提供更多的例子。
Split:這是基于一些分隔符分割字符串的方法。如果不提供任何參數(shù),這個(gè)方法默認(rèn)以空格作為分隔符。
1 >>> mystring='Monty Python ! And the holy Grail !
'
2 >>> print mystring.split()
3 ['Monty', 'Python', '!', 'and', 'the', 'holy', 'Grail', '!']
Strip:這個(gè)方法可以刪除字符串的尾隨空格,例如''和'R'。
1 >>> print mystring.strip()
2 >>>Monty Python ! and the holy Grail !
你是否發(fā)現(xiàn)''字符被移除了?還有其他方法(如lstrip()和rstrip())可以移除字符串左側(cè)和右側(cè)的尾隨空格。
Upper/Lower:使用這些方法,可以改變字符串中字母的大小寫。
1 >>> print (mystring.upper()
2 >>>MONTY PYTHON !AND THE HOLY GRAIL !
Repalce:這個(gè)方法可以替換字符串中的子字符串。
1 >>> print mystring.replace('!','''''')
2 >>> Monty Python and the holy Grail
剛才談到的是一些最常用的字符串函數(shù),函數(shù)庫(kù)中還存在大量的字符串函數(shù)。
提示:要了解更多函數(shù)和示例,請(qǐng)瀏覽Python網(wǎng)站。
正則表達(dá)式 |
NLP發(fā)燒友的另外一個(gè)重要技能是使用正則表達(dá)式工作。正則表達(dá)式描述了字符串的有效模式匹配。我們大量使用模式提取從眾多雜亂無(wú)章的文本數(shù)據(jù)中獲得有意義的信息。以下是讀者所需要的正則表達(dá)式。在我一生中,我所用的正則表達(dá)式都不會(huì)超過(guò)這個(gè)范圍。
(句點(diǎn)):這個(gè)表達(dá)式匹配除了換行符 n外的任意單個(gè)字符。
w:這個(gè)表達(dá)式匹配[a~z A~Z 0~9]中的某個(gè)字符或數(shù)字。
W:匹配任何非單詞字符。
s:這個(gè)表達(dá)式匹配單個(gè)空白字符——空格、換行符()、回車符()、制表符()、換頁(yè)符()。
S:這個(gè)表達(dá)式匹配任何非空白字符。
t:這個(gè)表達(dá)式執(zhí)行tab操作。
n:這個(gè)表達(dá)式用于換行符。
r:這個(gè)表達(dá)式用于回車符。
d:十進(jìn)制數(shù)字[0~9]。
^:這個(gè)表達(dá)式在字符串開始處使用。
$:這個(gè)表達(dá)式在字符串末尾處使用。
:這個(gè)表達(dá)式用于抵消特殊字符的特殊性。
例如,要匹配$符號(hào),可以在它前面加上。
在現(xiàn)行的例子(即mystring是相同的字符串對(duì)象)中,搜索一些內(nèi)容,并且試圖在此字符串對(duì)象上尋找一些模式。子字符串搜索是re模塊的其中一個(gè)通用用例。下面實(shí)現(xiàn)這一功能。
1>>># We have to import re module to use regular expression
2>>>import re
3>>>if re.search('Python',mystring):
4>>> print 'We found python '
5>>>else:
6>>> print 'NO '
一旦執(zhí)行代碼,得到的消息如下。
We found python
可以使用正則表達(dá)式進(jìn)行更多的模式查找。為了找到字符串中的所有模式,我們使用的其中一個(gè)普通的函數(shù)是findall。這個(gè)函數(shù)搜索字符串中特定的模式,并且會(huì)給出一個(gè)包含所有匹配對(duì)象的列表。
1>>>import re
2>>>print re.findall('!',mystring)
3['!', '!']
正如我們所見(jiàn),在mystring中,有兩個(gè)“!”實(shí)例,findall使用一個(gè)列表,返回了這兩個(gè)對(duì)象。
詞典 |
詞典是另一種最常用的數(shù)據(jù)結(jié)構(gòu),在其他編程語(yǔ)言中,這也稱為關(guān)聯(lián)數(shù)組/關(guān)聯(lián)記憶(associative array/memory)。詞典是使用鍵(key)進(jìn)行索引的數(shù)據(jù)結(jié)構(gòu),這些鍵可以是任何不可變的類型,如字符串和數(shù)字可以用作鍵。
詞典是非常方便的數(shù)據(jù)結(jié)構(gòu),廣泛應(yīng)用于各種編程語(yǔ)言中來(lái)實(shí)現(xiàn)多種算法。在眾多的編程語(yǔ)言中,Python詞典是其中一個(gè)優(yōu)雅地實(shí)現(xiàn)了散列表的詞典。在其他語(yǔ)言中,相同的任務(wù),可能需要花費(fèi)更多的時(shí)間進(jìn)行更繁重的編碼工作,但是使用詞典,工作就變得非常容易。最棒的事情是,程序員僅僅使用少量的代碼塊,就可以建立非常復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。這使得程序員擺脫了數(shù)據(jù)結(jié)構(gòu)本身,花更多時(shí)間專注于算法。
我使用詞典中一個(gè)很常見(jiàn)的用例,在給定的文本中,獲得單詞的頻率分布。使用以下幾行代碼,就可以得到單詞的頻率。你可試著使用任意其他的語(yǔ)言執(zhí)行相同的任務(wù),馬上就會(huì)明白Python是多么讓人贊嘆不已。
1>>># declare a dictionary
2>>>word_freq={}
3>>>for tok in string.split():
4>>> if tok in word_freq:
5>>> word_freq [tok]+=1
6>>> else:
7>>> word_freq [tok]=1
8>>>print word_freq
9{'!': 2, 'and': 1, 'holy': 1, 'Python': 1, 'Grail': 1, 'the': 1, 'Monty':
101}
編寫函數(shù) |
正如其他編程語(yǔ)言,Python也有其編寫函數(shù)的方式。在Python中,函數(shù)以關(guān)鍵字def開始,然后是函數(shù)名和圓括號(hào)()。這與其他編程語(yǔ)言相似,即任何參數(shù)和參數(shù)的類型都放在圓括號(hào)內(nèi)。實(shí)際的代碼以冒號(hào)(:)開頭。代碼的初始行通常是文檔字符串(注釋),然后才是代碼體,函數(shù)使用return語(yǔ)句結(jié)束。例如,在給定的例子中,函數(shù)wordfreq以def關(guān)鍵字開始,這個(gè)函數(shù)沒(méi)有參數(shù),并且以return語(yǔ)句結(jié)束。
1>>>import sys
2>>>def wordfreq (mystring):
3>>> '''
4>>> Function to generated the frequency distribution of the given text
5>>> '''
6>>> print mystring
7>>> word_freq={}
8>>> for tok in mystring.split():
9>>> if tok in word_freq:
10>>> word_freq [tok]+=1
11>>> else:
12>>> word_freq [tok]=1
13>>> print word_freq
14>>>def main():
15>>> str='This is my fist python program'
16>>> wordfreq(str)
17>>>if __name__ == '__main__':
18>>> main()
這與上一節(jié)中所寫的代碼是相同的,使用函數(shù)的形式進(jìn)行編寫的思想使得代碼可重用和可讀。雖然在編寫Python代碼時(shí)解釋器方式也很常見(jiàn),但是對(duì)于大型程序,使用函數(shù)/類是一種非常好的做法,這也是一種編程范式。我們也希望用戶能夠編寫和運(yùn)行第一個(gè)Python程序。你需要按照下列步驟來(lái)實(shí)現(xiàn)這一目標(biāo)。
(1)在首選的文本編輯器中,打開一個(gè)空的Python文件mywordfreq.py。
(2)編寫或復(fù)制以上代碼段中的代碼到文件中。
(3)在操作系統(tǒng)中,打開命令提示符窗口。
(4)運(yùn)行以下命令。
$ python mywordfreq,py 'This is my fist python program !!'
(5)輸出應(yīng)該為:
{'This': 1, 'is': 1, 'python': 1, 'fist': 1, 'program': 1, 'my': 1}
現(xiàn)在,對(duì)Python提供的一些常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),你有了一個(gè)非?;镜牧私?。你可以寫一個(gè)完整并且能夠運(yùn)行的Python程序。我認(rèn)為這些已經(jīng)足夠了,使用這些Python的入門知識(shí),你可以看懂本書前幾章。
提示:請(qǐng)觀看維基百科網(wǎng)站中的一些Python教程,學(xué)習(xí)更多的Python命令。
無(wú)須進(jìn)一步研究自然語(yǔ)言處理的理論,下面開始介紹NLTK。我們從一些NLTK的基本示例用例開始。你們中的一些人,可能已經(jīng)做過(guò)了類似的事情。首先,本節(jié)會(huì)給出一些典型Python程序員的做法,然后會(huì)轉(zhuǎn)到NLTK,尋找一個(gè)更加高效、更加強(qiáng)大和更加清晰的解決方案。
下面從某個(gè)示例文本內(nèi)容的分析開始。對(duì)于當(dāng)前的例子,從Python的主頁(yè)上獲得了一些內(nèi)容如下所示。
1>>>import urllib2
2>>># urllib2 is use to download the html content of the web link
3>>>response = urllib2.urlopen('http://python.org/')
4>>># You can read the entire content of a file using read() method
5>>>html = response.read()
6>>>print len(html)
747020
由于我們對(duì)在這個(gè)URL中所討論的主題類型沒(méi)有任何線索,因此從探索性數(shù)據(jù)分析(EDA)開始。一般來(lái)說(shuō),在文本領(lǐng)域,EDA具有多種含義,但是這里討論一種簡(jiǎn)單的情況,即在文檔中,何種術(shù)語(yǔ)占據(jù)了主導(dǎo)地位。主題是什么?它們出現(xiàn)的頻率有多大?這一過(guò)程將涉及某種層次的預(yù)處理步驟。我們首先使用純Python方式,嘗試執(zhí)行這個(gè)任務(wù),然后會(huì)使用NLTK執(zhí)行這個(gè)任務(wù)。
讓我們從清理HTML標(biāo)簽開始。完成這個(gè)任務(wù)的一種方式是僅僅選擇包括了數(shù)字和字符的標(biāo)記(token)。任何能夠使用正則表達(dá)式工作的人員應(yīng)該能夠?qū)TML字符串轉(zhuǎn)換成標(biāo)記列表。
1>>># Regular expression based split the string
2>>>tokens = [tok for tok in html.split()]
3>>>print 'Total no of tokens :'+ str(len(tokens))
4>>># First 100 tokens
5>>>print tokens[0:100]
6Total no of tokens :2860
7['', '', '', ''type='text/css'', 'media='not', 'print,', 'braille,'...]
8
正如你所看到的,使用前面的方法,存在過(guò)量的HTML標(biāo)簽和其他無(wú)關(guān)緊要的字符。執(zhí)行同一任務(wù)的相對(duì)清潔的版本,如下所示。
1>>>import re
2>>># using the split function
3>>>#https://docs.python.org/2/library/re.html
4>>>tokens = re.split('W+',html)
5>>>print len(tokens)
6>>>print tokens[0:100]
75787
8['', 'doctype', 'html', 'if', 'lt', 'IE', '7', 'html', 'class', 'no',
9'js', 'ie6', 'lt', 'ie7', 'lt', 'ie8', 'lt', 'ie9', 'endif', 'if',
10'IE', '7', 'html', 'class', 'no', 'js', 'ie7', 'lt', 'ie8', 'lt', 'ie9',
11'endif', 'if', 'IE', '8', 'msapplication', 'tooltip', 'content', 'The',
12'official', 'home', 'of', 'the', 'Python', 'Programming', 'Language',
13'meta', 'name', 'apple' ...]
現(xiàn)在,這看起來(lái)清爽多了。但是,你可以做更多的事情,使代碼變得更加簡(jiǎn)潔。這里將這項(xiàng)工作留給你,讓你嘗試移除盡可能多的噪聲。可以清除一些仍然彈出的HTML標(biāo)簽。在這個(gè)例子中,字長(zhǎng)為1的單詞(如7和8這樣的元素)僅僅是噪聲,你可能希望以字長(zhǎng)作為標(biāo)準(zhǔn),移除這些單詞?,F(xiàn)在,與其從頭開始編寫一些預(yù)處理步驟的代碼,不如將目光轉(zhuǎn)移到NLTK,使用NTLK執(zhí)行相同的任務(wù)。有一個(gè)函數(shù)clean_html(),這個(gè)函數(shù)可以執(zhí)行所需要的所有清潔工作。
1>>>import nltk
2>>># http://www.nltk.org/api/nltk.html#nltk.util.clean_html
3>>>clean = nltk.clean_html(html)
4>>># clean will have entire string removing all the html noise
5>>>tokens = [tok for tok in clean.split()]
6>>>print tokens[:100]
7['Welcome', 'to', 'Python.org', 'Skip', 'to', 'content', '▼',
8'Close', 'Python', 'PSF', 'Docs', 'PyPI', 'Jobs', 'Community', '▲',
9'The', 'Python', 'Network', '≡', 'Menu', 'Arts', 'Business' ...]
這很酷炫,對(duì)吧?這種方法絕對(duì)更加清潔,也更容易執(zhí)行。
下面嘗試獲得這些術(shù)語(yǔ)的頻率分布。首先,我們使用純Python的方式執(zhí)行這個(gè)任務(wù),然后,我將告訴你NLTK的秘訣。
1>>>import operator
2>>>freq_dis={}
3>>>for tok in tokens:
4>>> if tok in freq_dis:
5>>> freq_dis[tok]+=1
6>>> else:
7>>> freq_dis[tok]=1
8>>># We want to sort this dictionary on values ( freq inthis case )
9>>>sorted_freq_dist= sorted(freq_dis.items(), key=operator.itemgetter(1),
10reverse=True)
11>>> print sorted_freq_dist[:25]
12[('Python', 55), ('>>>', 23), ('and', 21), ('to', 18), (',', 18), ('the',
1314), ('of', 13), ('for', 12), ('a', 11), ('Events', 11), ('News', 11),
14('is', 10), ('2014-', 10), ('More', 9), ('#', 9), ('3', 9), ('=', 8),
15('in', 8), ('with', 8), ('Community', 7), ('The', 7), ('Docs', 6),
16('Software', 6), (':', 6), ('3:', 5), ('that', 5), ('sum', 5)]
自然而然地,由于這是Python主頁(yè),因此Python和(>>>)解釋器符號(hào)是最常見(jiàn)的術(shù)語(yǔ),這也展示了網(wǎng)站的第一感覺(jué)。
一個(gè)更好并且更有效的方法是使用NLTK的FreqDist()函數(shù)。為了進(jìn)行對(duì)比,我們可以觀察之前開發(fā)的執(zhí)行相同任務(wù)的代碼。
1>>>import nltk
2>>>Freq_dist_nltk=nltk.FreqDist(tokens)
3>>>print Freq_dist_nltk
4>>>for k,v in Freq_dist_nltk.items():
5>>> print str(k)+':'+str(v)
6>>': 23, 'and': 21, ',': 18, 'to': 18, 'the':
714, 'of': 13, 'for': 12, 'Events': 11, 'News': 11, ...>
8Python:55
9>>>:23
10and:21
11,:18
12to:18
13the:14
14of:13
15for:12
16Events:11
17News:11
18
現(xiàn)在,讓我們做一些更有趣的事情,畫出這些頻率分布。
1>>>Freq_dist_nltk.plot(50, cumulative=False)
2>>># below is the plot for the frequency distributions
可以看到,累積頻率持續(xù)增長(zhǎng),整體上,曲線有一條長(zhǎng)長(zhǎng)的尾巴。一些噪聲依然存在,一些單詞(如the、of、for和=)是毫無(wú)用處的。對(duì)于這些單詞(如the、a、an等),使用術(shù)語(yǔ)停用詞(stop word)來(lái)稱呼它們。由于在大部分文檔中不定代詞一般都會(huì)出現(xiàn),因此這些詞沒(méi)有什么判別力,不能傳達(dá)太多的信息。在大多數(shù)的NLP和信息檢索任務(wù)中,人們通常會(huì)刪除停用詞。讓我們?cè)俅位氐疆?dāng)前的示例中。
1>>>stopwords=[word.strip().lower() for word in open('PATH/english.stop.
2txt')]
3>>>clean_tokens=[tok for tok in tokens if len(tok.lower())>1 and (tok.
4lower() not in stopwords)]
5>>>Freq_dist_nltk=nltk.FreqDist(clean_tokens)
6>>>Freq_dist_nltk.plot(50, cumulative=False)
現(xiàn)在,這看起來(lái)干凈多了!在完成了這么多任務(wù)后,可以訪問(wèn)Wordle,將頻率分布轉(zhuǎn)換成CSV格式。你應(yīng)該能夠得到以下詞云。
《Python和NLTK自然語(yǔ)言處理》
書號(hào):978-7-115-50334-3
推薦理由:NLTK是自然語(yǔ)言處理領(lǐng)域中非常受歡迎和廣泛使用的Python庫(kù)。NLTK的優(yōu)點(diǎn)在于其簡(jiǎn)單性,其中大多數(shù)復(fù)雜的自然語(yǔ)言處理任務(wù)使用幾行代碼即可完成。本書旨在講述如何用Python和NLTK解決各種自然語(yǔ)言處理任務(wù)并開發(fā)機(jī)器學(xué)習(xí)方面的應(yīng)用。本書介紹了NLTK的基本模塊,講述了采用NLTK實(shí)現(xiàn)自然語(yǔ)言處理的大量技巧,討論了一些文本處理方法和語(yǔ)言處理技術(shù),展示了使用Python實(shí)現(xiàn)NLP項(xiàng)目的大量實(shí)踐經(jīng)驗(yàn)。本書主要內(nèi)容包括文本挖掘/NLP任務(wù)中所需的所有預(yù)處理步驟,如何使用Python 3的NLTK 3進(jìn)行文本處理,如何通過(guò)Python開展NLP項(xiàng)目。
本書適合NLP和機(jī)器學(xué)習(xí)領(lǐng)域的愛(ài)好者、Python程序員以及機(jī)器學(xué)習(xí)領(lǐng)域的研究人員閱讀。
- End -
聯(lián)系客服