自然語(yǔ)言分析——利用NLTK進(jìn)行文本預(yù)處理
本文作者:方 言
文字編輯:戴 雯
技術(shù)總編:張馨月
現(xiàn)如今的網(wǎng)絡(luò)信息豐富多樣,越來(lái)越多非結(jié)構(gòu)化的信息內(nèi)容得到廣泛傳播,所謂非結(jié)構(gòu)化的信息就是一些新聞報(bào)道、社交媒體文章等,一般涉及到這類(lèi)信息分析時(shí)都會(huì)用到NLP,也就是自然語(yǔ)言處理,在NLP中有很多工具可以用來(lái)分析非結(jié)構(gòu)化的信息內(nèi)容,今天我們就來(lái)簡(jiǎn)單的介紹一下在NLP中比較常用的自然語(yǔ)言處理工具——NLTK。NLTK的全稱(chēng)是natural language toolkit,是基于python用來(lái)處理自然語(yǔ)言的工具集,主要用來(lái)處理英文的相關(guān)數(shù)據(jù)。今天我們就來(lái)介紹一下NLTK庫(kù)的安裝和一些簡(jiǎn)單的文本分析操作。
一、安裝
NLTK的安裝可以直接通過(guò)pip完成:
pip install nltk
NLTK中包含非常多的語(yǔ)料和模型,我們可以通過(guò)NLTK Downloader進(jìn)行下載:
import nltk
nltk.download()
運(yùn)行上方的代碼可以獲取NLTK Downloader窗口

點(diǎn)擊Download,如果出現(xiàn)報(bào)錯(cuò),可以通過(guò)點(diǎn)擊File里的Change Server Index將service index改為http://nltk.org/nltk_data/,再點(diǎn)擊Download。
如果這種方法依然報(bào)錯(cuò),我們可以先輸入下面這行代碼查看nltk_data文件可以存放的路徑:
nltk.data.find(".")

接下來(lái),到官網(wǎng)https://github.com/nltk/nltk_data/tree/gh-pages下載packages文件到相應(yīng)的路徑,并對(duì)nltk_data進(jìn)行解壓(文件里很多個(gè)壓縮包,注意要全部解壓完成),我們可以測(cè)試一下是否安裝成功:
from nltk.book import *
如果運(yùn)行結(jié)果如下所示,則表明安裝成功:

但是,在測(cè)試運(yùn)行中還可能出現(xiàn)錯(cuò)誤,比如這里利用NLTK進(jìn)行分詞,運(yùn)行代碼后出現(xiàn)如下報(bào)錯(cuò):
import nltk
from nltk import word_tokenize
text = "NLTK is a great text analysis tool. We can make use of it."
sentence = nltk.sent_tokenize(text)
print(sentence)

這時(shí)是因?yàn)镹LTK路徑下的tokenizers\punkt里多了個(gè)PY3文件夾,將這個(gè)文件夾的內(nèi)容放置到punkt文件夾中,刪除PY3文件夾即可。
完成了NLTK的安裝以后,我們來(lái)進(jìn)行一下簡(jiǎn)單的操作。
二、常用功能(以句子為例)
1.分詞
在分詞時(shí),由于NLTK是先分句再分詞的,我們需要先通過(guò)nltk.sent_tokenize(text)將文本按照句子進(jìn)行劃分,然后通過(guò)nltk.word_tokenize(sent)實(shí)現(xiàn)對(duì)每個(gè)句子進(jìn)行分詞。下面我們來(lái)舉個(gè)例子:
import nltk
text = "NLTK is a great text analysis tool. We can make use of it."
sentence = nltk.sent_tokenize(text)
print(sentence)
運(yùn)行結(jié)果如下所示,這里將text分成了兩句話,結(jié)果以單引號(hào)進(jìn)行分隔

在寫(xiě)這個(gè)程序的時(shí)候一定要注意的是,每個(gè)英文句號(hào)的后面一定要加一個(gè)空格,否則在進(jìn)行分句的時(shí)候是無(wú)法將句子進(jìn)行分離的。
然后再對(duì)分離的每句話進(jìn)行分詞:
words = []
for sent in sentence :
words.append(nltk.word_tokenize(sent))
print(words)
結(jié)果如下所示,NLTK將每句話的每個(gè)單詞都進(jìn)行了拆分,拆分后的每個(gè)單詞都用單引號(hào)標(biāo)識(shí),但是這里有一個(gè)問(wèn)題,標(biāo)點(diǎn)符號(hào)也被作為一個(gè)單詞單獨(dú)進(jìn)行拆分了,那么怎么解決這個(gè)問(wèn)題呢?往下看就知道啦~

2.去除停用詞和標(biāo)點(diǎn)符號(hào)
所謂停用詞,就是在理解一個(gè)句子的時(shí)候沒(méi)什么必要去理解的單詞,它們的意思對(duì)理解整個(gè)句子的語(yǔ)義沒(méi)有太大影響。尤其是在英文中,"a","the",“to",“their”等冠詞,借詞,代詞等,這些詞語(yǔ)對(duì)文本分析起不到任何的幫助,因此我們?cè)谧鑫谋痉治龅臅r(shí)候希望將這些單詞去掉。想要去除停用詞,就要知道NLTK庫(kù)中有哪些停用詞,我們可以直接用NLTK中提供的英文停用詞表。
from nltk.corpus import stopwords
stop = set(stopwords.words('english'))
print(stop)
如下展示的就是NLTK詞庫(kù)中的停用詞,由于NLTK庫(kù)只支持英文的停用詞庫(kù),因此在進(jìn)行中文分詞的時(shí)候還需要構(gòu)造中文的停用詞詞庫(kù),這個(gè)會(huì)在以后的推文中進(jìn)行介紹~

在了解了NLTK的停用詞庫(kù)后,我們把句子中的停用詞去掉,結(jié)果運(yùn)行如圖所示:
filter_text = [word for word in sentence.split(' ') if word not in stopwords.words('english') ]
print(filter_text)

對(duì)于標(biāo)點(diǎn)符號(hào)的去除,其實(shí)大可不必利用NLTK去除,在Python中的re.sub()函數(shù)就可以實(shí)現(xiàn)標(biāo)點(diǎn)符號(hào)的全部去除,程序如下,這里我們需要用到正則表達(dá)式的相關(guān)內(nèi)容:
import re
filter_text = re.sub(r'[^a-zA-Z0-9\s]','',string= text1)
print(filter_text)
運(yùn)行結(jié)果如圖所示,可以看到所有的標(biāo)點(diǎn)符號(hào)都被刪除了:

在進(jìn)行分詞的時(shí)候,我們是希望將標(biāo)點(diǎn)符號(hào)以及停用詞都去除的,因此直接替換掉所有的標(biāo)點(diǎn)符號(hào)并進(jìn)行停用詞去除的程序如下所示,在進(jìn)行文本整理以后,去除不必要的符號(hào)可以讓我們?cè)谖谋痉治鰰r(shí)更能突出重點(diǎn)。
import re
stop = set(stopwords.words('english'))
filter_text = re.sub(r'[^a-zA-Z0-9\s]','',string= text)
filter_text = [word for word in filter_text.split(' ') if word not in stop]
print(filter_text)
結(jié)果如圖,可以看到結(jié)果只針對(duì)有用的單詞進(jìn)行了分詞:

3.詞頻統(tǒng)計(jì)
詞頻統(tǒng)計(jì)有利于我們?cè)谧鑫谋痉治鰰r(shí)了解文本的重點(diǎn)和核心,我們可以使用NLTK中的FreqDist()函數(shù)幫助我們對(duì)去除停用詞后的文本進(jìn)行詞頻統(tǒng)計(jì)。
from nltk import FreqDist
fdist = FreqDist(filter_text)
print(fdist)
for a,b in fdist.items():
print(str(a)+":"+str(b))
[圖片上傳失敗...(image-7214e9-1599102492408)]
上圖的運(yùn)行結(jié)果顯示出當(dāng)前文本中有8個(gè)樣本和8個(gè)結(jié)果,因?yàn)槊總€(gè)樣本都只出現(xiàn)了一次,因此8個(gè)樣本出現(xiàn)的頻數(shù)也就是8。
4.詞性標(biāo)注
在分詞過(guò)程中,對(duì)詞性進(jìn)行分析有助于我們更好的把握文本的核心和重點(diǎn)。這一功能可以通過(guò)NLTK中的pos_tag()函數(shù)實(shí)現(xiàn),下面我們來(lái)操作一下:
from nltk import pos_tag
text = "NLTK is a great text analysis tool.We can make use of it."
tokens = nltk.word_tokenize(text)
tags = pos_tag(tokens)

在上面的結(jié)果中我們看到輸出的結(jié)果是一些大寫(xiě)字母的組合,這些組合就是NLTK庫(kù)中的相關(guān)詞性,這里列舉一下,如下圖所示:

三、簡(jiǎn)單應(yīng)用(以NLTK自帶的古騰堡語(yǔ)料庫(kù)為例)
通過(guò)第二部分我們掌握了比較簡(jiǎn)單的句子的分析,那么我們利用第二部分介紹的內(nèi)容來(lái)簡(jiǎn)單以NLTK自帶的古騰堡語(yǔ)料庫(kù)應(yīng)用一下。
首先,我們需要調(diào)用NLTK的古騰堡語(yǔ)料庫(kù),并在該語(yǔ)料庫(kù)中獲取一個(gè)文本對(duì)象。在進(jìn)入應(yīng)用之前,先簡(jiǎn)單介紹一下古騰堡語(yǔ)料庫(kù)。古騰堡項(xiàng)目大約有36000本免費(fèi)電子圖書(shū),NLTK中只包含了其中的一小部分,NLTK的古騰堡語(yǔ)料庫(kù)收集的都是不同作家的書(shū),并且都是英文的,通過(guò)下述命令可以查看NLTK中包含的相關(guān)文本文檔:
from nltk.corpus import gutenberg
gutenberg.fileids()
運(yùn)行結(jié)果如圖,這里展示的就是NLTK古騰堡語(yǔ)料庫(kù)包含的所有文檔:

這里以莎士比亞的著作《哈姆雷特》為例進(jìn)行簡(jiǎn)單的文本分析,首先,我們需要先獲取《哈姆雷特》的文本內(nèi)容,鍵入以下命令即可獲取語(yǔ)料庫(kù)中的文本內(nèi)容:
hamlet = gutenberg.words('shakespeare-hamlet.txt') # 獲取shakespeare-hamlet.txt這個(gè)文件的單詞
print(hamlet)
hamlets = gutenberg.sents('shakespeare-hamlet.txt') # 獲取shakespeare-hamlet.txt這個(gè)文件的句子
print(hamlets)
運(yùn)行結(jié)果如圖所示:

通過(guò)運(yùn)行的結(jié)果可以看到,直接引用語(yǔ)料庫(kù)的文本內(nèi)容,不同于自己構(gòu)建的文本內(nèi)容,原因是NLTK的古騰堡語(yǔ)料庫(kù)已經(jīng)將這些作品分好詞、分好句,因此我們直接對(duì)語(yǔ)料庫(kù)中的內(nèi)容進(jìn)行后續(xù)文本處理,去停用詞、去標(biāo)點(diǎn)、詞頻統(tǒng)計(jì)以及詞性標(biāo)注:
(1)去停用詞
#去除停用詞
from nltk.corpus import stopwords
filter_text = [word for word in hamlet if word not in stopwords.words('english') ]
print(filter_text)
運(yùn)行結(jié)果如圖所示:

由于《哈姆雷特》的內(nèi)容較長(zhǎng),所以在前面沒(méi)辦法完全展開(kāi)顯示,但是從圖中可以明顯看到,《哈姆雷特》的第一句話中of這個(gè)單詞被去除掉了,這也說(shuō)明我們這個(gè)去除停用詞是成功實(shí)現(xiàn)了的。
(2)去標(biāo)點(diǎn)
在去除停用詞的基礎(chǔ)上,對(duì)標(biāo)點(diǎn)進(jìn)行去除,可以鍵入以下命令:
import re
filter_texts = re.sub(r'[^a-zA-Z0-9\s]','',str(filter_text))
print(filter_texts)
運(yùn)行結(jié)果如圖所示:

這就是一個(gè)干干凈凈的文本內(nèi)容,即沒(méi)有停用詞,也沒(méi)有標(biāo)點(diǎn)符號(hào)的文本,是不是看上去特別清爽!
(3)進(jìn)行詞頻統(tǒng)計(jì)
由于詞頻統(tǒng)計(jì)必須要在分詞的基礎(chǔ)上進(jìn)行,所以我們需要對(duì)去除標(biāo)點(diǎn)符號(hào)以后的清爽的文本內(nèi)容再進(jìn)行分詞,可以鍵入以下命令:
text=nltk.word_tokenize(filter_texts)
print(text)
運(yùn)行結(jié)果如圖所示:

在分詞之后,我們就可以進(jìn)行詞頻統(tǒng)計(jì)啦,鍵入以下命令:
from nltk import FreqDist
fdist = FreqDist(text)
print(fdist)
for a,b in fdist.items():
print(str(a)+":"+str(b))
運(yùn)行結(jié)果如圖所示:

可以看到結(jié)果中顯示了《哈姆雷特》中共有18814個(gè)單詞,剔除重復(fù)的單詞后,共用到了5324個(gè)單詞。
(4)詞性標(biāo)注
同詞頻統(tǒng)計(jì)一樣,詞性標(biāo)注也是必須在分句和分詞的基礎(chǔ)上才能進(jìn)行的,因此我們也是可以直接對(duì)分詞后的文本進(jìn)行詞性標(biāo)注:
from nltk import pos_tag
print(nltk.pos_tag(text))
結(jié)果如圖:

以上就是我們今天給大家簡(jiǎn)單介紹的自然語(yǔ)言處理工具NLTK以及進(jìn)行簡(jiǎn)單的文本預(yù)處理,NLTK還有很多語(yǔ)料庫(kù)可以供大家使用,詳情可以繼續(xù)關(guān)注我們后續(xù)的推文內(nèi)容哦~