天天看點

《Python自然語言處理》——第1章 語言處理與Python 1.1 語言計算:文本和詞彙

本節書摘來自異步社群《python自然語言處理》一書中的第1章,第1.1節,作者[美]steven bird,ewan klein,edward loper, 陳濤,張旭,崔楊,劉海平 譯,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

我們能夠很容易地得到數百萬數量級的文本。假設我們會寫一些簡單的程式,那可以用它來做些什麼?本章将解決以下幾個問題。

(1)通過将技術性較簡單的程式與大規模文本結合起來,我們能實作什麼?

(2)如何自動地提取出關鍵字和詞組,用來總結文本的風格和内容?

(3)python程式設計語言為上述工作提供了哪些工具和技術?

(4)自然語言進行中有哪些有趣的挑戰呢?

我們都對文本非常熟悉,因為我們每天都在進行閱讀和寫作。在本書中,把文本視為編寫程式的原始資料,并通過很多有趣的程式設計方式來處理和分析文本。但在能寫這些程式之前,必須得從了解python解釋器開始。

python入門

python與使用者友好互動的方式之一包括你可以在互動式解釋器直接輸入代碼——解釋器将運作你的python代碼的程式。你可以通過一個叫做互動式開發環境(interactive development environment,idle)的簡單圖形接口來通路python解釋器。在mac上,你可以在“applications→macpython”中找到;在windows中,你可以在“程式→python”中找到。在unix下,你可以在shell輸入“idle”來運作python(如果沒有安裝,嘗試輸入python)。解釋器将會輸入關于你的python的版本簡介,請檢查你是否運作在python 2.4或2.5(這裡是2.5.1)。

提示符>>>表示python解釋器正在等待輸入。複制這本書的例子時,自己不要鍵入>>>。現在,把python當作電腦使用。

一旦解釋器完成計算并顯示出答案,提示符就會重新出現。這表示python解釋器在等待另一個指令。

前面的例子展示了如何使用python互動式解釋器,體驗python語言中各種表達式,看看它們能做些什麼。現在讓我們嘗試一個無意義的表達式,看看解釋器将如何處理。

結果産生了一個文法錯誤。在python中,指令以加号結尾是沒有意義的。python解釋器會指出發生錯誤的行(的第1行,表示“标準輸入”)。

現在我們學會使用python解釋器了,已經準備好開始處理語言資料了。

nltk入門

一旦安裝完成,便可像前面那樣啟動python解釋器。在python提示符後面輸入下面兩行指令來安裝本書所需的資料,然後選擇book,如圖1-1所示。

《Python自然語言處理》——第1章 語言處理與Python 1.1 語言計算:文本和詞彙

一旦資料被下載下傳到你的機器,你就可以使用python解釋器加載其中的一些了。第一步是在python提示符後輸入一個特殊的指令,告訴解釋器去加載一些我們要用的文本:from nltk.book import * 。這條語句是說“從nltk的book子產品中加載所有的條目”。book子產品包含你閱讀本章時所需的所有資料。在輸出歡迎資訊之後,将會加載一些書的文本(這将需要幾秒鐘)。下面就是你需要輸入的指令及輸出的結果,注意拼寫和标點符号的正确性,記住不要輸入>>>。

無論什麼時候想要找到這些文本,隻需要在python提示符後輸入它們的名字即可。

現在我們可以使用python解釋器和這些資料,準備開始了。

搜尋文本

除了簡單地閱讀文本之外,還有很多方法可以用來檢視文本内容。詞語索引視圖可以顯示指定單詞的出現情況,同時還可以顯示一些上下文。下面我們輸入text1并在後面跟一個點,再輸入函數名concordance,然後将monstrous放在括号裡,用來查找《白鲸記》中的詞monstrous。

通過一段時間對這些文本的研究,我們希望你能對語言的豐富性和多樣性有一個新的認識。在下一章中,你将學習如何擷取更廣泛的文本,包括英語以外其他語言的文本。

關鍵詞索引讓我們可以看到上下文中的詞。例如:我們看到monstrous出現在文章中,如the___pictures和the____ size。還有哪些詞出現在相似的上下文中?我們可以通過在被查詢的文本名後添加函數名similar,然後在括号中插入相關詞的方法來查找到。

可以發現從不同的文本中能夠得到不同的結果。austen(奧斯丁,英國女小說家)在詞彙的使用上與melville完全不同。對于她來說,monstrous是正面的意思,有時它的功能像詞very一樣用作強調成分。

我們可以使用函數common_contexts研究共用兩個或兩個以上詞彙的上下文,如monstrous和very。使用方括号和圓括号将這些詞括起來,中間用逗号分割。

自動檢測出現在文本中的特定的詞,并顯示同一上下文中出現的其他詞。我們也可以判斷詞在文本中的位置:從文本開頭算起有多少詞出現。這個位置資訊可以用離散圖表示。每一列代表一個單詞,每一行代表整個文本。在圖1-2中,我們看到在過去220年中的一些顯著的詞語用法模式(在一個由就職演說語料首尾相連組合的人工文本中)。可以利用下面的方法畫出離散圖。你也許會想嘗試更多的單詞(如:liberty,constitution)和不同的文本。你能在看到這幅圖之前預測一個單詞的分布嗎?如前所述,保證引号、逗号、中括号及小括号的使用完全正确。

《Python自然語言處理》——第1章 語言處理與Python 1.1 語言計算:文本和詞彙

現在輕松一下,嘗試以上述不同風格産生一些随機文本。要做到這一點,我們需要輸入後面跟着函數名generate的文本名稱。(需要帶括号,但括号裡什麼也沒有。)

請注意,第一次運作此指令時,由于要搜集單詞序列的統計資訊,因而執行速度比較慢。每次運作後,輸出的文本都會不同。現在嘗試産生就職演說風格或網際網路聊天室風格的随機文本。雖然文本是随機的,但它重複使用了源文本中常見的單詞和短語,進而使我們能感覺到它的風格和内容。

計數詞彙

在前面例子中出現的文本中,最明顯的地方在于它們所使用的詞彙不同。在本節中,我們将看到如何使用計算機并以各種有用的方式來計數詞彙。像以前一樣,你可以馬上開始使用python解釋器進行試驗,即使你可能還沒有系統地研究過python。修改這些例子并測試一下你對它們的了解程度,嘗試一下本章結尾的練習題。

首先,讓以文本中出現的單詞和标點符号為機關算出文本從頭到尾的長度。使用函數len擷取長度,參考《創世紀》中使用的例子。

《創世紀》有44764個單詞和标點符号,也被稱作“辨別符”。辨別符是表示一組字元序列——如:hairy、his或者:)——的術語。當計算文本中辨別符的個數時,如to be or not to be這句話,我們計算的是這些序列出現的次數。是以,例句中出現了to和be各兩次,or和not各一次。然而在例句中隻有4個不同的單詞。《創世紀》中有多少不同的單詞?如果要用python來回答這個問題,就不得不稍微改變一下提出的問題。因為一個文本詞彙表隻是它用到的辨別符的集合,在集合中所有重複的元素都隻算一個。在python中可以使用指令:set(text3)來獲得text3的詞彙表。這樣做之後,螢幕上的很多詞就會被掠過。現在嘗試以下操作。

用sorted()包裹python表達式set(text3)①,得到一個詞彙條目的排序表,這個表以各種标點符号開始,然後接着是以a開頭的詞彙。大寫單詞排在小寫單詞前面。通過求集合中項目的個數,可以間接地獲得詞彙表的大小。再次使用指令len來獲得這個數值②。盡管書中有44764個辨別符,但隻有2789個不同的詞彙或“詞類型”。詞類型是指一個詞在一個文本中獨一無二的出現或拼寫形式。也就是說,這個單詞在詞彙表中是唯一的。計數的2789個項目中包括标點符号,是以把它們稱作唯一項目類型而不是詞類型。

現在,開始對文本詞彙豐富度進行測量。下面的例子展示的結果含義為每個詞平均被使用了16次(應該確定python使用的是浮點除法)。

接下來,專注于特定的詞。計數一個單詞在文本中出現的次數,再計算一個特定詞在文本中占據的百分比。

也許你想要對幾個文本重複進行這些計算,但重新輸入公式是很乏味的。方法是可以自己命名一個任務,如“lexical_diversity”或“percentage”,然後用一個代碼塊關聯它。這樣,你隻需輸入一個很短的名字就可以代替一行或多行python代碼,而且想用多少次就用多少次。執行一個任務的代碼段叫做函數。使用關鍵字def給函數定義一個簡短的名字。下面的例子示範的是如何定義兩個新的函數,lexical_diversity()和percentage()。

在lexical_diversity()1的定義中,指定了一個text參數。這個參數是計算文本詞彙多樣性時的一個“占位符”,并在使用函數時,重制在運作的代碼段中2。類似地,percentage()3定義了兩個參數:count和total。

隻要python知道了lexical_diversity()和percentage()是指定代碼段的名字,我們就可以繼續使用這些函數了。

簡要重述一下,使用或者說是調用一個如lexical_diversity()這樣的函數時,隻要輸入它的名字并在後面跟一個左括号,再輸入文本名字,然後是右括号即可。這些括号經常出現,它們的作用是将任務名——如:lexical_diversity()——與任務将要處理的資料——如:text3分割開。調用函數時放在參數位置的資料值叫做函數的實參。

在本章中,你已經遇到了一些函數,如:len(),set()和sorted()。通常會在函數名後面加一對空括号,例如len(),這隻是為了表明這是一個函數而不是其他的python表達式。函數是程式設計中的一個重要概念,我們隻是在一開始提到了它們,為了是讓新手體會到程式設計的強大和它的創造力。如果你現在覺得有點混亂,請不要擔心。

稍後将學習如何使用函數清單顯示資料,見表1-1。表中每一行包含了不同資料相同的計算,将使用函數進行這種重複性的工作。

《Python自然語言處理》——第1章 語言處理與Python 1.1 語言計算:文本和詞彙