自然語言處理 | (二)Python對文本的簡單處理
大家好,我是廈門大學王亞南經濟研究院的一名本科生。今天將為大家介紹一些用Python處理文本的方法。
注:非商業轉載注明作者即可,商業轉載請聯系作者授權并支付稿費。本專欄已授權“維權騎士”網站( http:// rightknights.com )對我在知乎發布文章的版權侵權行為進行追究與維權。
---------------------------------------------------------------------------------------------------------------------------
NLP主要是對文本的處理。在更深的應用中,我們可以根據我們的需要,去處理我們想要處理的文本(比如上次提到的“購物網站中的買家評論”)。而在開始的時候,我們一般使用NLTK中提供的語料進行練習;NLTK不僅提供文本處理的工具,而且提供了一些文本材料。
在我們已經下載的\nltk-3.2.1\nltk文件夾中,有一個book.py的模塊。在Python命令窗口使用“from nltk.book import *”命令,可以導入該模塊提供的文本;包括9本名著和9個句子。如下所示:
>>> from nltk.book import *
*** Introductory Examples for the NLTK Book ***
Loading text1, ..., text9 and sent1, ..., sent9
Type the name of the text or sentence to view it.
Type: 'texts()' or 'sents()' to list the materials.
text1: Moby Dick by Herman Melville 1851
text2: Sense and Sensibility by Jane Austen 1811
text3: The Book of Genesis
text4: Inaugural Address Corpus
text5: Chat Corpus
text6: Monty Python and the Holy Grail
text7: Wall Street Journal
text8: Personals Corpus
text9: The Man Who Was Thursday by G . K . Chesterton 1908
>>>
從結果中我們可以看到,9本名著的名字分別是text1~text9,9個句子的名字分別是sent1~sent9。在操作命令中,我們將使用這些名字來指代相應的文本,以對其進行處理。
下面的內容是對一些方法或函數的介紹,分為兩個層面:文本層面和詞匯層面。首先,在文本層面,哪些方法可以完成以下任務:
1. 在一段文本中,找出某個詞語所在的上下文;
2. 找出與某個詞有著類似用法的詞,并確定它們在文本中出現的語境;
3. 在整個文本中,某個詞或某些詞在文本中是怎樣分布的;
在2. 和3. 中,我們要處理的可能是多個詞語(“它們”“某些詞”)。如果有一定Python基礎,那么不難猜到,我們可以用一個 字符串 來表示單個詞語;對多個詞語,我們需要用一個 鏈表 來表示。一個鏈表由一個英文方括號“[]”界定,方括號內的內容為有限個(可以為零個)有序的字符串(詞語或其他符號),各個字符串之間用逗號分隔。可以試著執行:
>>> print sent1
['Call', 'me', 'Ishmael', '.']
>>>
得到的就是一個鏈表。
下面來介紹這些任務的意義。
某一些詞匯的上下文可能能夠給我們提供一些有價值的信息。text3是《創世紀》( The Book of Genesis ),如果我們想知道《創世紀》中的一些角色活了多久,那么我們可以通過對“lived”這個詞進行1. 操作,以得到相關信息。操作如下:
>>> text3.concordance('lived')
Displaying 25 of 38 matches:
ay when they were created . And Adam lived an hundred and thirty years , and be
ughters : And all the days that Adam lived were nine hundred and thirty yea and
nd thirty yea and he died . And Seth lived an hundred and five years , and bega
ve years , and begat Enos : And Seth lived after he begat Enos eight hundred an
welve years : and he died . And Enos lived ninety years , and begat Cainan : An
years , and begat Cainan : And Enos lived after he begat Cainan eight hundred
ive years : and he died . And Cainan lived seventy years and begat Mahalaleel :
rs and begat Mahalaleel : And Cainan lived after he begat Mahalaleel eight hund
years : and he died . And Mahalaleel lived sixty and five years , and begat Jar
s , and begat Jared : And Mahalaleel lived after he begat Jared eight hundred a
and five yea and he died . And Jared lived an hundred sixty and two years , and
o years , and he begat Eno And Jared lived after he begat Enoch eight hundred y
and two yea and he died . And Enoch lived sixty and five years , and begat Met
; for God took him . And Methuselah lived an hundred eighty and seven years ,
, and begat Lamech . And Methuselah lived after he begat Lamech seven hundred
nd nine yea and he died . And Lamech lived an hundred eighty and two years , an
ch the LORD hath cursed . And Lamech lived after he begat Noah five hundred nin
naan shall be his servant . And Noah lived after the flood three hundred and fi
xad two years after the flo And Shem lived after he begat Arphaxad five hundred
at sons and daughters . And Arphaxad lived five and thirty years , and begat Sa
ars , and begat Salah : And Arphaxad lived after he begat Salah four hundred an
begat sons and daughters . And Salah lived thirty years , and begat Eber : And
y years , and begat Eber : And Salah lived after he begat Eber four hundred and
begat sons and daughters . And Eber lived four and thirty years , and begat Pe
y years , and begat Peleg : And Eber lived after he begat Peleg four hundred an
>>>
“concordance”是text類(可參考Python中“類”的概念)的一個 方法 (或 函數 ;這里不對二者作區分),在后面的括號中以字符串的形式輸入我們想要查找的詞語,就可以得到其上下文。
相似地,可以用如下代碼完成2. 任務:
>>> text2.similar('monstrous')
very exceedingly so heartily a great good amazingly as sweet
remarkably extremely vast
>>> text2.common_contexts(['monstrous', 'very'])
a_pretty is_pretty a_lucky am_glad be_glad
>>>
執行第一行代碼得到的結果是在text2這個文本——《理智與情感》( Sense and Sensibility )——中,與“monstrous”這個詞有著相似用法的詞;在第二行代碼中,我們使用了“common_contexts”這個 方法 (中間的“_”符號相當于函數名中出現的連字符),得到的是圓括號中的詞鏈表中兩個詞語共同的上下文。
第3. 個任務看起來更實用;我們可以將結果以分布圖的形式輸出。這時我們需要用到兩個程序包:NumPy和Matplotlib。(可以到 http://www. nltk.org/ 上進行安裝,也可以到 http:// pan.baidu.com/s/1slSsSs H 直接下載。)
通過執行代碼(以由人名組成的鏈表為參數):
>>> text2.dispersion_plot(['Elinor', 'Marianne', 'Edward', 'Willoughby'])
我們可以得到,整部小說中,這四位主人公大致的出場分布。現在,如果告訴你,四個人中有兩人是夫妻,那么沒有讀過這部小說的讀者也可以根據得到的分布圖猜一下,這兩個人是誰。
接下來介紹一些詞匯層面的處理方法。這里簡單說三種:len(), set(), sorted(), count()。(明確一下:這里講“詞匯層面”并不意味著這三種方法處理的對象是詞匯,而是指應用這三種方法時,我們的目的與整個文本的語境基本無關。)
len()的參數可以是text或sent(或鏈表;下同),處理得到的結果是這段文本或這個鏈表的長度,即所含詞語及其它符號的數量(詞語或其它符號若重復出現,將被重復計數;區別于“詞匯量”)。需要注意的是,在計數過程中,標點符號(如逗號’,’)會被單獨計數;而’.”’這樣“句號加右雙引號”的組合,會被計為一個符號。例:
>>> len(text1)
260819
>>> len(sent1)
4
>>>
set()和sorted()的參數同樣是text或sent。set()可將作為參數的文本(text或sent;下同)中出現的所有詞語或其他字符不重復地以鏈表的形式輸出,相當于輸出一個亂序的詞匯表;而sorted()經常與set()搭配使用,相信你已經猜到它的作用了:將作為參數的文本按默認順序排列。
這樣,使用如下代碼,就可得到一個文本所用的詞匯表了(以text2,《理智與情感》為例;詞匯表中包含除字母單詞外的其他符號):
>>> sorted(set(text2))
將以上三種函數配合使用,可以開發出更多考查文本屬性的函數。可以想想,如何計算一段文本的詞匯多樣性?(提示:可以用每個詞匯出現的平均次數來衡量。)
count()方法的參數是字符串形式的詞語,如:
>>> text2.count('monstrous')
11
>>>
得到的是“monstrous”這個詞在text2中出現的頻次。
結合前面的介紹,不難算出這個詞在該文本中出現的頻率。當然,對頻次和頻率的統計,我們有更加方便的方法(nltk內置的FreqDist()函數),在這里暫不作介紹,在得到更豐富的文本材料后,我們將用這個函數和另一個有關頻率分布的函數,完成更多有意義的操作。
---------------------------------------------------------------------------------------------------------------------------
備注:對text1~9和sent1~9,我們可以像操作 序列 那樣,進行索引、切片和遍歷。具體概念可參考Python教程中的相關內容。參見之前的文章:
代碼舉例:
>>> text2.count('monstrous')
11
>>> text2[173]#得到text2中第172個詞語或其他符號
u'nephew'
>>> text2.index('monstrous')#得到該詞第一次出現時對應的索引
38430
>>> text2[173:177]#text2中第172個詞到第176個詞,不包括第176個詞
[u'nephew', u'and', u'niece', u',']
>>> for word in text2:
print word, #得到整篇《理智與情感》(需要一定時間才能輸出全部文本)
-----------------------------------------------------END------------------------------------------------------
更多項目介紹,請關注我們的項目專欄: China's Prices Project - 知乎專欄
項目聯系方式:
- 項目郵箱(@iGuo 的郵箱):zhangguocpp@163.com
- 申請加入項目,請聯系人事負責人@Suri :liuxiaomancpp@163.com
- 知乎:@iGuo@Suri(項目負責人)@林行健@Dementia (技術負責人)@張土不 (財務負責人)
作者:CPP
鏈接: https:// zhuanlan.zhihu.com/p/21 511857
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
來自:https://zhuanlan.zhihu.com/p/22059714