1. 程式人生 > >ML/NLP入門教程Python版(第一部分:文字處理)

ML/NLP入門教程Python版(第一部分:文字處理)

第一部分:文字處理

歡迎來到機器學習和自然語言處理原型編碼教程系列的第一部分。 Thoughtly正在製作一個著重於理解機器學習基礎的系列教程,著重關注於在自然語言處理中的應用。

這一系列教程的目標是提供有據可查的可用程式碼,附加留言部分的深入探討。程式碼將被放到GitHub上,在一個開放的許可證下,允許你任意修改或使用——不必署名(註明來源)。這裡的程式碼為了明白起見以犧牲效能為代價寫的比較冗長。如果你有大量的資料要處理,這些工具的可擴充套件性很可能無法達到完成你目的的要求。幸運的是,我們正在計劃通過研究此處討論的演算法在當下最新的實現,來更好地對這個系列進行深入探索。這些內容都是黑盒子,是我們在初始系列中有意避免(到實用的程度)提到的內容。我們相信,在能使用這些黑盒子之前,在機器學習方面打下一個堅實的基礎是至關重要的。

第一部分的重點是如何從文字語料庫提取出資訊來。我們有意用介紹性的水平來開始教程,但是它涉及到很多不同的技巧和測量標準,這些方法都會在之後應用到更深入的機器學習任務上。

文字提取

下文介紹的以及此處程式碼中用到的工具,都假設我們將所選的語料當作一袋單詞。這是你在處理文字文件的時候常常會看到的一個基本概念。將語料當作一袋單詞是將文件向量化中的一個典型步驟,以供機器學習演算法進一步處理。把文件轉換成可處理向量通常還需要採取一些額外步驟,我們將在後面的課程中對此進行討論。本課程中介紹的概念和工具將作為後面工具的構建模組。也許更重要的是,這些工具可以幫助你通過快速檢查一個文字語料庫,從而對它所包含的內容有一個基本的瞭解。

本課程中我們所研究的程式碼及示例都是使用Python實現的。這些程式碼能夠從NLTK(Python的自然語言工具包)所提供的不同的文字語料庫中提取資料。這是個包括了ABC新聞的文字、聖經的創世紀、從古滕堡計劃中選取的部分文字、總統就職演說、國情諮文和從網路上擷取的部分文字所組成的語料庫。另外,使用者還能從他們自己提供的語料庫來提取文字。從NLTK匯入的程式碼並不是特別有趣,但我們想指出的是,要從NLTK文字語料庫中提取資料是非常簡單方便的。

Python
12345678910111213141516171819202122232425262728293031323334353637383940414243 defload_text_corpus(args):ifargs["abc"]:logging.debug("Loading the ABC corpus.")name="ABC"words=nltk.corpus.abc.words()elifargs["genesis"]:logging.debug("Loading the ABC corpus.")name="Genesis"words=nltk.corpus.genesis.words()elifargs["gutenberg"]:logging.debug("Loading the Gutenberg corpus.")name="Gutenberg"words=nltk.corpus.gutenberg.words()elifargs["inaugural"]:logging.debug("Loading the Inaugural Address corpus.")name="Inaugural"words=nltk.corpus.inaugural.words()elifargs["stateUnion"]:logging.debug("Loading the State of the Union corpus.")name="Union"words=nltk.corpus.state_union.words()elifargs["webtext"]:logging.debug("Loading the webtext corpus.")name="Web"words=nltk.corpus.webtext.words()elifargs["custom"]!=None:logging.debug("Loading a custom corpus from "+args["custom"])name="Custom"words=load_custom_corpus(args["custom"])else:words=""name="None"logging.debug("Read "+str(len(words))+" words: "+str(words[0:20]))returnwords,name

上面的大部分程式碼只是日誌。有意思的部分在357行、362行、367行等。基於使用者選擇,每部分載入不同的語料庫。 NLTK對從現有語料庫中提取文字提供了一些非常便利的方法。這包括一些簡單的、純文字的語料庫,也包括一些已經用各種方式被標記過的語料庫 —— 語料庫中的每個文件可能被標記過類別或是語料庫中有的語音已被加過標籤,如此等等。在本課程中,我們對NLTK的使用僅限於語料庫的匯入、詞彙的切分,以及我們下面將討論兩個操作,詞根和詞形還原。雖然不會總是如此,但現在為止足夠我們需要的所有功能。值得注意的是,您還可以在指令碼中使用-custom引數匯入自定義語料庫。這應該是含有.txt檔案的資料夾。該資料夾是遞迴讀入的,所以含有.txt檔案的子資料夾也能被處理。

詞彙切分

詞彙切分是切分語料庫,使之變成各個獨立部分——通常指單詞,的行為。我們這樣做是因為大多數ML演算法無法處理任意長的文字字串。相反,他們會假設你已經分割你的語料庫為單獨的,演算法可處理的詞塊(token)。雖然我們將在後面的課程詳細討論這個話題,演算法不一定限於一次只處理一個詞塊(token)。事實上,許多演算法只在處理短序列(n-grams)時有用。本課程中我們將情況限定於一序列(1-grams),或者叫,單序列(unigram)。

對文字語料庫做詞彙切分的最簡單的方法就是僅基於空白字元。這種方法確實非常簡單,但它也有缺點。例如,它會導致位於句尾的文字包含有句尾標點符號,而一般不需要這樣。在另一方面,類似can’t和e.g.這樣帶有詞內標點的單詞就沒法被正確提取出來了。我們可以新增一步操作來刪除所有非字母數字的字元。這將解決句尾標點符號的問題,同時也能將can’t和e.g.這樣的單詞提取出來,儘管是以丟掉了他們的標點符號的方式被提取出來的。然而,這也引入了一個新的問題。對於某些應用,我們還是希望保留標點符號。在建立語言模型的時候,句尾標點能區分一個單詞是否是結尾單詞,從這方面來說,額外的標點資訊是有價值的。

對於這個任務,我們要將一些標點符號(句號)作為一個詞,使用NLTK word_tokenizer(它是基於TreebankWordTokenizer來實現的)來做詞彙切分。這個分詞器有很多針對各式各樣的詞彙做切分的規則。舉例來說,“can’t”這樣的縮寫實際上被分成了兩個詞(token) – ca和n’t。有趣的是,這意味著我們最後會得到ca這樣的詞,它理想地匹配了can(在某些任務中)。這樣的錯誤匹配是這種符號化演算法帶來的不幸後果。NLTK支援多種分詞器。這是一個及其冗長的檔案,http://www.nltk.org/api/nltk.tokenize.html,但在裡面可以找到它所支援的分詞器的細節。

詞幹提取和詞形還原

一旦取到了文字我們就可以開始處理它。指令碼提供了許多簡單的工具,它們會幫助我們檢視我們所選擇的內容。之後我們會深入談到這些工具。首先,讓我們思考一下該用什麼方法來操作我們取到的文字。通常我們需要為ML演算法提供從語料庫提取的原始文字詞彙(單詞)。在其他情況下,將這些單詞轉成原始內容的各種變形也是有道理的。

具體來說,我們經常要將原始單詞截斷到它的詞根。那麼,什麼是一個詞根呢?英語單詞有從原始單詞延伸出的通用字尾。就拿單詞”run”為例。有很多的擴充套件它的詞 – “runner”,”runs”,”running”等,即對基本定義的進一步闡述。詞幹提取是從”runner”,”runs”以及“running”中去除所有和”run”不一致的部分的過程。請注意,在上述列表中不包含”ran” —— 後面我們再對此進行闡述。下面是一個被提取詞幹的句子的具體例項。

Python
1 stem(Jim isrunning to work.)=>Jim isrun to work.

我們已經丟失了”吉姆在跑步”這個資訊,儘管此處的上下文隱含的所有其他資訊都說不通。我們不可能完全扭轉這一點 —— 我們可以猜測那裡曾經是什麼詞,但我們很可能會弄錯。

此處提供的程式碼可以讓你對你的語料庫進行詞幹提取。實際的詞幹提取是微不足道的,因為我們會使用NLTK來進行這部分工作。我們只需通過輸入陣列迭代,並返回使用NLTK Porter Stemmer所得到的各種提取後的詞幹變體。有許多不同的詞幹分析器可供選擇,還包括非英語語言的選項。Porter Stemmer常用於英語。

Python
1234567 defstem_words_array(words_array):stemmer=nltk.PorterStemmer();stemmed_words_array=[];forword inwords_array:stem=stemmer.stem(word);stemmed_words_array.append(stem);returnstemmed_words_array;

詞形還原類似於詞幹提取,但又有著重要的區別。與使用一系列簡單的規則將一個單詞截斷成它的詞根不同,詞形還原嘗試對輸入的單詞確定一個恰當的詞根。本質上,詞形還原試圖找到一個單詞的字典項,也稱為單詞的基本形(base term)。為了使這種查詢能正確的工作,詞形還原器必須知道您尋找的這個詞在句子中的詞性。生成語料庫的詞條與詞幹提取的程式碼基本上是相同的(儘管這段程式碼有上文略為提及的缺點,我們將在下面進一步對此進行討論)。這裡我們用了WordNetLemmatizer,它使用WordNet的資料庫作為其查詢指定詞條的字典。

Python
1234567 deflemmatize_words_array(words_array):lemmatizer=nltk.stem.WordNetLemmatizer()lemmatized_words_array=[];forword inwords_array:lemma=lemmatizer.lemmatize(word)lemmatized_words_array.append(lemma)returnlemmatized_words_array;

正如上文所述,詞形還原知道單詞的詞性。NLTK WordNetLemmatizer天真地假設,所有傳入的單詞都是名詞。這種假設意味著你必須告訴詞形還原器要傳遞的詞不是一個名詞,否則它會錯誤的地將其視為一個名詞。這個行為,加上對未知的單詞(特別是當它混在一段文字中的時候)不做任何處理直接輸出的行為,使得詞形還原器處理效果很差。舉例來說,如果讓詞形還原器處理”ran”這個詞,在不指出”ran”屬於一段文字的情況下,它將直接輸出”ran”。它不知道的作為名詞的”ran”,因為很明顯”ran”不是一個名詞。但是,如果你正確地指出”ran”是動詞,那麼詞形還原器就能輸出”run”。與相對,此處詞幹分析器就會輸出”ran”。因此,如果我們要有效地利用詞形還原器,我們也必須付出在原始碼中對詞性進行標註的代價,我們將在後面的課程中對詞性標註的部分進行討論。標記單詞詞性的額外成本也是詞形還原器不像詞幹分析器那樣應用廣泛的原因之一 —— 所新增的功能抵不上所花的成本。

詞彙量

現在,使用詞幹提取或詞形還原的方法,我們已經拉取了一個語料庫並且(視情況)對它做了變形,終於可以開始檢視它的內容了。下面不是一個詳盡的清單,但作為審查文字的技術參考。有些是立刻會用到的,其他則會在以後討論到。

第一項測量是最簡單的——詞彙計數。這個指標是語料庫內所有唯一字的計數。正如你所期望的,程式碼很容易實現。唯一一個你之後還會再遇到的技巧,是我們決定使用Python裡dictionary的唯一性。即任一字典的條目在字典中不能出現超過一次。

Python
12345 defcollect_unique_terms(corpus):unique_vocabulary={}forterm incorpus:unique_vocabulary[term]=1;returnunique_vocabulary;

這種方法可以讓我們對我們的資料有所認知。思考我們使用詞幹提取及詞形還原來考察ABC語料庫後的如下輸出。

首先是原始語料文字:

Python
12345 >python words.py-vv-abc-s-vsLoading the ABCcorpus.Read766811words:[u'PM', u'denies', u'knowledge', u'of', u'AWB', u'kickbacks', u'The', u'Prime', u'Minister', u'has', u'denied', u'he', u'knew', u'AWB', u'was', u'paying', u'kickbacks', u'to', u'Iraq', u'despite']The corpus contains766811elements after processingThe corpus hasatotal vocabulary of31885unique tokens.

其次是詞形還原後的語料庫:

Python
12345 >python words.py-vv-abc-l-vsLoading the ABCcorpus.Read766811words:[u'PM', u'denies', u'knowledge', u'of', u'AWB', u'kickbacks', u'The', u'Prime', u'Minister', u'has', u'denied', u'he', u'knew', u'AWB', u'was', u'paying', u'kickbacks', u'to', u'Iraq', u'despite']The corpus contains766811elements after processingThe corpus hasatotal vocabulary of28699unique tokens.

最後,是詞幹提取後的語料庫:

Python
12345 >python words.py-vv-abc-vsLoading the ABCcorpus.Read766811words:[u'PM', u'denies', u'knowledge', u'of', u'AWB', u'kickbacks', u'The', u'Prime', u'Minister', u'has', u'denied', u'he', u'knew', u'AWB', u'was', u'paying', u'kickbacks', u'to', u'Iraq', u'despite']The corpus contains766811elements after processingThe corpus hasatotal vocabulary of22162unique tokens.

可以看到,從原始資料到詞形還原到詞幹提取後,語料庫中唯一字計數值總體在減少,從31K至28K到22K。這個模式重複於每個語料庫。在每個例項中,原始語料庫的字數統計大於詞幹提取後的,而詞幹提取後的字數統計則大於詞形還原後的。

上面的圖表是使用我們共享工程的Python程式碼生成。它對非定製語料庫列表進行遍歷,並分別計算原始、詞幹提取後、詞形還原後的唯一字數量。你可以用命令列重現這個圖表。你還可以得到一份同樣內容的文字轉儲。

Python
123456 >python words.py-v--stemVsLemma2015-02-0219:49:22,255(INFO):Corpora:['ABC', 'Genesis', 'Gutenberg', 'Inaugural', 'Union', 'Web']2015-02-0219:49:22,255(INFO):Word Counts:[31885,25841,51156,9754,14591,21538]2015-02-0219:49:22,255(INFO):Lemmatized Word Counts:[28699,25444,46456,8763,13111,20056]2015-02-0219:49:22,255(INFO):Stemmed Word Counts:[22162,23542,33521,6135,9533,16599]2015-02-0219:49:22,466

相關推薦

ML/NLP入門教程Python第一部分文字處理

第一部分:文字處理 歡迎來到機器學習和自然語言處理原型編碼教程系列的第一部分。 Thoughtly正在製作一個著重於理解機器學習基礎的系列教程,著重關注於在自然語言處理中的應用。 這一系列教程的目標是提供有據可查的可用程式碼,附加留言部分的深入探討。程式碼將被放到GitHub

RabbitMQ官方中文入門教程(PHP) 第三部分:釋出/訂閱Publish/Subscribe

1 $exchange->setName('logs'); 2 $exchange->setType(AMQP_EX_TYPE_FANOUT); 3 $exchange->declare(); fanout交換器很簡單,你可能從名字上就能猜測出來,它把訊息傳送給它所知道

《SQL入門經典》筆記第一歡迎進入SQL世界

想刷刷書,順便做個筆記~ 下列內容大部分都是直接抄書,侵刪 1. 什麼是ANSI SQL? “美國國家標準化組織(ANSI)是一個核準多種行業標準的組織”。1987年,ISO吧ANSI SQL作為國標標準,目前最新的標準是SQL-2008。   2. SQL-2008:

RabbitMQ官方中文入門教程(PHP) 第四部分:路由(Routing)

路由(Routing) 在前面的教程中,我們實現了一個簡單的日誌系統。可以把日誌訊息廣播給多個接收者。 本篇教程中我們打算新增一個功能——使得它能夠只訂閱訊息的一個字集。例如,我們只需要把嚴重的錯誤日誌資訊寫入日誌檔案(儲存到磁碟),但同時仍然把所有的日誌資訊輸出到控制檯中

Axis2/C入門教程之二服務端實現詳細分析

本文承接Axis2/C入門教程之一,詳細分析服務端程式碼hello_svc.c的實現。hello_svc.c程式碼如下:#include <axis2_svc_skeleton.h> #include <axutil_log_default.h> #i

RabbitMQ學習筆記第一Rabbit簡介

處理機制 有用 都在 參數 ket 統一 宋體 interface 自己 RabbitMQ是目前非常熱門的一款消息中間件,不管是互聯網行業還是傳統行業都在大量地使用。RabbitMQ憑借其高可靠、易擴展、高可用及豐富的功能特性受到了越來越多的企業的青睞。 (一)什麽是消息中

三步學會用spring開發OSGI——第一環境篇

cli led 新版 pan 活性 time 加強 管理 tro Spring-DM是什麽 Spring-DM 指的是Spring Dynamic Modules. dm Server 是一個完全模塊化部署的,基於OSGi的Java服務器

robot framework rf自動化測試例項第一啟動應用

1. 啟動手機用USB連線電腦,注意手機需要開啟開發者模式,開啟USB除錯功能(或者啟動電腦上的手機模擬器) 2. 啟動命令列cmd, 用命令檢視手機裝置名稱:adb devices (如下圖): 3. 啟動appium, 看到以下介面無報錯,則為啟動成功 4. 啟動r

第一部分處理的專用命令

分隔符 pause exe call pat sage 設置環境變量 定義 順序 批處理文件是將一系列命令按一定的順序集合為一個可執行的文本文件,其擴展名為BAT。這些命令統稱批處理命令,下面我就來給大家介紹一下批處理的命令。 1、 REM REM 是個註釋命令一般是用來給

【CC2530入門教程-增強】基礎技能綜合實訓案例基礎-題目需求

情況 led 興趣 題目 嵌入式開發 廣東 難點 在一起 參數 【CC2530入門教程-增強版】基礎技能綜合實訓案例(基礎版)-題目需求 廣東職業技術學院 歐浩源 一、引用 不管是簡單的單片機應用,還是復雜的嵌入式系統,在我看來它們的本質結構是差不多的,都離不開“

Python核心程式設計第三練習參考第一正則表示式

1-1 識別後續的字串:“bat”、“bit”、“but”、“hat”、“hit”或者“hut”。 答:'[bh][aiu]t' 1-2 匹配由單個空格分隔的任意單詞對,也就是姓和名。 答:'\w+\s\w+' 1-3 匹配由單個逗號和單個空白符分隔的任何單詞和單個字

RabbitMQ官方中文入門教程(PHP) 第一部分:Hello World

RabbitMQ是一個訊息代理。它的核心原理非常簡單:接收和傳送訊息。你可以把它想像成一個郵局:你把信件放入郵箱,郵遞員就會把信件投遞到你的收件人處。在這個比喻中,RabbitMQ是一個郵箱、郵局、郵遞員。RabbitMQ和郵局的主要區別是,它處理的不是紙,而是接收、儲存和

Python NLP入門教程

本文簡要介紹Python自然語言處理(NLP),使用Python的NLTK庫。NLTK是Python的自然語言處理工具包,在NLP領域中,最常使用的一個Python庫。 什麼是NLP? 簡單來說,自然語言處理(NLP)就是開發能夠理解人類語言的應用程式或服務。 這裡討論一些自然

Spark英中對照翻譯(PySpark中文版新手快速入門-Quick Start)-中文指南,教程(Python)-20161115

This program just counts the number of lines containing ‘a’ and the number containing ‘b’ in a text file. Note that you’ll need to replace YOUR_SPARK_HOME

Python學習第一

logs 完全 python3 兩個 ges tex pytho 格式 代碼 說明:筆者所用的版本是python3.6 首先,說一下python的三種格式輸出。第一種用到了格式化操作符%,格式化字符串時,Python使用一個字符串作為模板。模板中有格式符,這些格式符為真實值

python第一1.4 數字和表達式

python以下內容是我學習《Python基礎教程》第2版 這本書所寫的筆記 轉載請註明出處1.>>> 2.75%.50.25【不同】C語言中取余運算必須為整數,不能是浮點型2.>>>(-3)**29【不同】C語言中pow (double x,double n);(將返回

紅米1線刷救磚教程V5移動聯通適用,線刷包永久有效

裏的 警告 大全 磚頭 中國 民間 png 技術 關機 紅米1線刷救磚教程V5版(移動聯通適用,線刷包永久有效) 原文來自:http://www.miui.com/thread-1890972-1-1.html?mobile=2 ,加了些自己的經驗。 (我用這個方法救活

Python練習第一: 編寫登陸認證程序

用戶鎖定 用戶輸入 文件 提示 print 基礎 else 再次 分享圖片 基礎需求: 讓用戶輸入用戶名密碼 認證成功後顯示歡迎信息 輸錯三次後退出程序 升級需求: 可以支持多個用戶登錄 (提示,通過列表存多個賬戶信息) 用戶3次認證失敗後,退出程序,再次啟動程序嘗試登錄

一看就懂的ReactJs入門教程-精華-轉載

角度 ice ets perf date 入門實例 view 此外 map 傳送門:http://www.cnblogs.com/yunfeifei/p/4486125.html   現在最熱門的前端框架有AngularJS、React、Bootstrap等。自從接觸了R

Python學習第一

left cccccc tro 告訴 str pad 初始設置 所在 自動補全 1. Tab鍵 可以對命令自動補全 2. 查看Python的內置函數bif ,用help(int)查看內置函數用法 dir(__builtins__) 3. Pycharm拓展: >1