自然語言處理 | (二)Python對文本的簡單處理

osa46z67 8年前發布 | 12K 次閱讀 自然語言處理 Python 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教程中的相關內容。參見之前的文章:

https:// zhuanlan.zhihu.com/p/21 360064?refer=xmucpphttps://zhuanlan.zhihu.com/p/21360064?refer=xmucpp

代碼舉例:

>>> 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

 

 本文由用戶 osa46z67 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!