轉 --天然語言工具包(NLTK)小結

 

原做者:http://www.cnblogs.com/I-Tegulia/category/706685.htmlphp

1.天然語言工具包(NLTK)
NLTK 建立於2001 年,最初是賓州大學計算機與信息科學系計算語言學課程的一部分。從那之後,在數十名貢獻者的幫助下不斷髮展壯大。現在,它已被幾十所大學的課程所採納,並做爲許多研究項目的基礎。表P -2 列出了NLTK 的一些最重要的模塊。
 
這本書提供天然語言處理領域很是方便的入門指南。它能夠用來自學,也能夠做爲天然語言處理或計算語言學課程的教科書,或是人工智能、文本挖掘、語料庫語言學課程的補充讀物。本書的實踐性很強,包括幾百個實際可用的例子和分級練習。

本書基於Python 編程語言及其上的一個名爲天然語言工具包(Natural Language Toolkit ,簡稱NLTK)的開源庫。NLTK 包含大量的軟件、數據和文檔,全部這些均可以從http://www.nltk.org/免費下載。NLTK 的發行版本支持Windows、Macintosh 和Unix 平臺。
2. 得到文本語料和詞彙語料
2.1 獲取文本語料庫
    經過nltk.download()下載配套的數據,本文文本語料庫包括如下:
  • 古騰堡語料庫(Gutenberg)
    • NLTK 包含古騰堡項目(Project Gutenberg)電子文本檔案的通過挑選的一小部分文本。該項目大約有25,000(如今是36,000 了)本免費電子圖書。
  • 網絡和聊天文本
    • NLTK 的網絡文本小集合的內容包括Firefox 交流論壇,在紐約無心聽到的對話,《加勒比海盜》的電影劇本,我的廣告和葡萄酒的評論等
  • 布朗語料庫
    • 布朗語料庫是第一個百萬詞級的英語電子語料庫的,由布朗大學於1961 年建立。這個語料庫包含500 個不一樣來源的文本,按照文體分類,如:新聞、社論等。
  • 路透社語料庫
    • 路透社語料庫包含10,788 個新聞文檔,共計130 萬字。這些文檔分紅90 個主題,按照「訓練」和「測試」分爲兩組。這樣分割是爲了訓練和測試算法的,這種算法自動檢測文檔的主題。
  • 就任演說語料庫
    • 就任演說語料庫,其實是55 個文本的集合,每一個文本都是一個總統的演說。這個集合的一個有趣特性是它的時間維度
  • 標註文本語料庫
    • 包含語言學標註,有詞性標註、命名實體、句法結構、語義角色等。NLTK 中提供了很方便的方式來訪問這些語料庫中的幾個,還有一個包含語料庫和語料樣本的數據包。
  • 其餘語言的語料庫
    NLTK 包含多國語言語料庫。
 
文本語料庫的結構:語料庫結構最簡單的一種沒有任何結構,僅僅是一個文本集合。一般,文本會按照其可能對應的文體、來源、做者、語言等分類。有時,這些類別會重疊,尤爲是在按主題分類的狀況下,由於一個文本可能與多個主題相關。偶爾的,文本集有一個時間結構,新聞集合是最多見的例子。NLTK 語料庫閱讀器支持高效的訪問大量語料庫,而且能用於處理新的語料庫。
表2-3 NLTK中定義的基本語料庫函數
 
載入你本身的語料庫:若是你有本身收集的文本文件,而且想使用前面討論的方法訪問它們,你能夠很容易地
在NLTK 中的PlaintextCorpusReader 幫助下載入它們。
 
2.2 條件頻率分佈
條件頻率分佈是頻率分佈的集合,每一個頻率分佈有一個不一樣的「條件」,這個條件一般是文本的類別。當語料文本被分爲幾類(文體、主題、做者等)時,咱們能夠計算每一個類別獨立的頻率分佈。這將容許咱們研究類別之間的系統性差別。
 
條件頻率分佈是一個對許多NLP 任務都有用的數據結構。
表2-4 NLTK中條件機率分佈: 定義、訪問和可視化一個計數的條件機率分佈的經常使用方法和習慣用法
2.3 詞典資源
詞典或者詞典資源是一個詞和/或短語以及一些相關信息的集合,例如:詞性和詞意定義等相關信息。詞典資源附屬於文本,一般在文本的幫助下建立和豐富。複雜的詞典資源包括在詞彙項內和跨詞彙項的複雜的結構。
 
NLTK包括的詞典資源:
  • 詞彙列表語料庫
    NLTK 包括一些僅僅包含詞彙列表的語料庫。詞彙語料庫是Unix 中的/usr/dict/words 文件,被一些拼寫檢查程序使用。咱們能夠用它來尋找文本語料中不尋常的或拼寫錯誤的詞彙。
  • 還有一個停用詞語料庫,就是那些高頻詞彙,如:the,to,咱們有時在進一步的處理以前想要將它們從文檔中過濾。停用詞一般幾乎沒有什麼詞彙內容,而它們的出現會使區分文本變困難。
  • 發音的詞典
    • 一個稍微豐富的詞典資源是一個表格(或電子表格),在每一行中含有一個詞加一些性質。NLTK 中包括美國英語的CMU 發音詞典,它是爲語音合成器使用而設計的。
    • 對每個詞,這個詞典資源提供語音的代碼——不一樣的聲音不一樣的標籤——叫作音素。
      請看fire 有兩個發音(美國英語中):單音節F AY1 R 和雙音節F AY1 ER0。
  • 比較詞表
    • 表格詞典的另外一個例子是比較詞表。NLTK 中包含了所謂的斯瓦迪士核心詞列表(Swadesh wordlists),幾種語言中約200 個經常使用詞的列表。
    • 咱們能夠經過在entries()方法中指定一個語言鏈表來訪問多語言中的同源詞。
  • 詞彙工具:Toolbox
    • 可能最流行的語言學家用來管理數據的工具是Toolbox,之前叫作Shoebox,由於它用滿滿的檔案卡片佔據了語言學家的舊鞋盒。一個Toolbox 文件由一個大量條目的集合組成,其中每一個條目由一個或多個字段組成。大多數字段都是可選的或重複的,這意味着這個詞彙資源不能做爲一個表格或電子表格來處理。
  • WordNet
    • 是面向語義的英語詞典,相似與傳統辭典,但具備更豐富的結構。NLTK 中包括英語WordNet,共有155,287 個詞和117,659 個同義詞集合。
 
2.4 WordNet
WordNet的層次結構:WordNet 的同義詞集對應於抽象的概念,它們並不老是有對應的英語詞彙。這些概念在層次結構中相互聯繫在一塊兒。一些概念也很通常,如實體、狀態、事件;這些被稱爲獨一無二的根同義詞集。其餘的,如:油老虎和有倉門式後背的汽車等就比較具體的多。圖2-8 展現了一個概念層次的一小部分。
圖2-8. WordNet 概念層次片斷:每一個節點對應一個同義詞集;邊表示上位詞/下位詞關係,即上級概念與從屬概念的關係。
 
更多的詞彙關係:上位詞和下位詞被稱爲詞彙關係,由於它們是同義集之間的關係。這個關係定位上下爲「是一個」層次。WordNet 網絡另外一個重要的漫遊方式是從物品到它們的部件(部分)或到它們被包含其中的東西(總體)。例如:一棵樹的部分是它的樹幹,樹冠等;這些都是part_meronyms()。一棵樹的實質是包括心材和邊材組成的,即substance_meronyms()。樹木的集合造成了一個森林,即member_holonyms()。
 
語義類似度:咱們已經看到同義詞集之間構成複雜的詞彙關係網絡。給定一個同義詞集,咱們能夠遍歷WordNet 網絡來查找相關含義的同義詞集。知道哪些詞是語義相關的,對索引文本集合很是有用,當搜索一個通常性的用語——例如:車輛——時就能夠匹配包含具體用語——例如豪華轎車——的文檔。回想一下每一個同義詞集都有一個或多個上位詞路徑鏈接到一個根上位詞。鏈接到同一個根的兩個同義詞集可能有一些共同的上位詞。若是兩個同義詞集共用一個很是具體的上位詞——在上位詞層次結構中處於較低層的上位詞——它們必定有密切的聯繫。
 
2.5 小結
􀁺 文本語料庫是一個大型結構化文本的集合。NLTK 包含了許多語料庫,如:布朗語料庫nltk.corpus.brown。
􀁺 有些文本語料庫是分類的,例如經過文體或者主題分類;有時候語料庫的分類會相互重疊。
􀁺 條件頻率分佈是一個頻率分佈的集合,每一個分佈都有一個不一樣的條件。它們能夠用於經過給定內容或者文體對詞的頻率計數。
􀁺 行數較多的Python 程序應該使用文本編輯器來輸入,保存爲.py 後綴的文件,並使用import 語句來訪問。
􀁺 Python 函數容許你將一段特定的代碼塊與一個名字聯繫起來,而後重用這些代碼想用多少次就用多少次。
􀁺 一些被稱爲「方法」的函數與一個對象聯繫在起來,咱們使用對象名稱跟一個點而後跟方法名稱來調用它,就像:x.funct(y)或者word.isalpha()。
􀁺 要想找到一些關於變量v 的信息,能夠在Pyhon 交互式解釋器中輸入help(v)來閱讀這一類對象的幫助條目。
􀁺 WordNet 是一個面向語義的英語詞典,由同義詞的集合—或稱爲同義詞集(synsets)—組成,而且組織成一個網絡。
􀁺 默認狀況下有些函數是不能使用的,必須使用Python 的import 語句來訪問。
3.加工原料文本
 
3.1 字符串:最底層的文本處理
咱們側重於將文本做爲一個詞鏈表。經過使用NLTK 中的語料庫接口,咱們能夠忽略這些文本所在的文件。一個詞的內容,一個文件的內容在編程語言中是由一個叫作字符串的基本數據類型來表示的。
 
3.2使用Unicode進行文字處理
Unicode 支持超過一百萬種字符。每一個字符分配一個編號,稱爲編碼點。在Python 中,編碼點寫做\uXXXX 的形式,其中XXXX 是四位十六進制形式數。在一個程序中,咱們能夠像普通字符串那樣操縱Unicode 字符串。然而,當Unicode 字符被存儲在文件或在終端上顯示,它們必須被編碼爲字節流。一些編碼(如ASCII 和Latin-2)中每一個編碼點使用單字節,因此它們能夠只支持Unicode 的一個小的子集就足夠一種語言使用了。
 
文件中的文本都是有特定編碼的,因此咱們須要一些機制來將文本翻譯成Unicode——翻譯成Unicode 叫作解碼。相對的,要將Unicode 寫入一個文件或終端,咱們首先須要將Unicode 轉化爲合適的編碼——這種將Unicode 轉化爲其它編碼的過程叫作編碼。
 
3.3 使用正則表達式檢測詞組搭配
許多語言處理任務都涉及模式匹配。例如:咱們可使用endswith('ed')找到以「ed」結尾的詞。
 
正則表達式給咱們一個更增強大和靈活的方法描述咱們感興趣的字符模式,在Python 中使用正則表達式,須要使用import re 導入re 函數庫。還須要一個用於搜索的詞彙鏈表;咱們再次使用詞彙語料庫,對它進行預處理消除某些名稱。
>>> import re
>>> wordlist = [w for w in nltk.corpus.words.words('en') if w.islower()]
 
3.4 正則表達式的有益應用
使用re.search(regexp, w)匹配一些正則表達式regexp 來搜索詞w。除了檢查一個正則表達式是否匹配一個單詞外,咱們還可使用正則表達式從詞彙中提取的特徵或以特殊的方式來修改詞。
  • 提取字符塊
    • 經過re.findall() (「find all」即找到全部)方法找出全部(無重疊的)匹配指定正則表達式的。讓咱們找出一個詞中的元音,再計數它們:
  • 查找詞幹
    • 在使用網絡搜索引擎時,咱們一般不介意(甚至沒有注意到)文檔中的詞彙與咱們的搜索條件的後綴形式是否相同。查詢「laptops」會找到含有「laptop」的文檔,反之亦然。事實上,「laptop」與「laptops」只是字典中的同一個詞(或詞條)的兩種形式。對於一些語言處理任務,咱們想忽略詞語結尾,只是處理詞幹。抽出一個詞的詞幹的方法有不少種。
  • 搜索已分詞文本
    • 你可使用一種特殊的正則表達式搜索一個文本中多個詞(這裏的文本是一個標識符列表)。例如:「<a> <man>」找出文本中全部「a man」的實例。尖括號用於標記標識符的邊界,尖括號之間的全部空白都被忽略(這隻對NLTK 中的findall()方法處理文本有效)。
3.5 規範化文本
  • 詞幹提取器
    • NLTK 中包括了一些現成的詞幹提取器,若是你須要一個詞幹提取器,你應該優先使用它們中的一個,而不是使用正則表達式製做本身的詞幹提取器,由於NLTK 中的詞幹提取器能處理的不規則的狀況很普遍。
  • 詞性歸併
    • 詞形歸併
      WordNet 詞形歸併器刪除詞綴產生的詞都是在它的字典中的詞。這個額外的檢查過程使詞形歸併器比剛纔提到的詞幹提取器要慢。
3.6 用正則表達式爲文本分詞
分詞是將字符串切割成可識別的構成一塊語言數據的語言單元。許多語料庫已經分過詞了,也由於NLTK中包括一些分詞器。如今你已經熟悉了正則表達式,你能夠學習如何使用它們來爲文本分詞,並對此過程當中有更多的掌控權。
 
NLTK 的正則表達式分詞器:函數nltk.regexp_tokenize()與re.findall()相似(咱們一直在使用它進行分詞)。然
而,nltk.regexp_tokenize()分詞效率更高,且不須要特殊處理括號。爲了加強可讀性,咱們將正則表達式分幾行寫,每行添加一個註釋。特別的「(?x)」「verbose 標誌」告訴Python 去掉嵌入的空白字符和註釋。
 
>>> text = 'That U.S.A. poster-print costs $12.40...'
>>> pattern = r'''(?x) # set flag to allow verbose regexps
... ([A-Z]\.)+ # abbreviations, e.g. U.S.A.
... | \w+(-\w+)* # words with optional internal hyphens
... | \$?\d+(\.\d+)?%? # currency and percentages, e.g. $12.40, 82%
... | \.\.\. # ellipsis
... | [][.,;"'?():-_`] # these are separate tokens
... '''
>>> nltk.regexp_tokenize(text, pattern)
['That', 'U.S.A.', 'poster-print', 'costs', '$12.40', '...']
 
分詞是一個比你可能預期的要更爲艱鉅的任務。沒有單一的解決方案能在全部領域都行之有效,咱們必須根據應用領域的須要決定那些是標識符。在開發分詞器時,訪問已經手工標註好的原始文本是有益的,這可讓你的分詞器的輸出結果與高品質(或稱「黃金標準」)的標註進行比較。NLTK 語料庫集合包括賓州樹庫的數據樣本,包括《華爾街日報》原始文本(nltk.corpus.treebank_raw.raw())和分好詞的版本(nltk.corpus.treebank.words())。

3.7 分割
分詞是一個更廣泛的分割問題的一個實例。在本節中,咱們將看到這個問題的另外兩個實例。
 
  • 分句
    • 在詞級水平處理文本一般假定可以將文本劃分紅單個句子。一些語料庫已經提供在句子級別的訪問。在其餘狀況下,文本可能只是做爲一個字符流。在將文本分詞以前,咱們須要將它分割成句子。NLTK 經過包含Punkt 句子分割器(Kiss & Strunk, 2006)簡化了這些。
  • 分詞
    • 對於一些書寫系統,因爲沒有詞邊界的可視表示這一事實,文本分詞變得更加困難。咱們的第一個挑戰僅僅是:咱們須要找到一種方法來分開文本內容與分詞標誌。咱們能夠給每一個字符標註一個布爾值來指示這個字符後面是否有一個分詞標誌(這個想法將在第7 章「分塊」中大量使用)。讓咱們假設說話人會給語言學習者一個說話時的停頓,這每每是對應一個延長的暫停。這裏是一種表示方法,包括初始的分詞和最終分詞目標。
    • 如今分詞的任務變成了一個搜索問題:找到將文本字符串正確分割成詞彙的字位串。咱們假定學習者接收詞,並將它們存儲在一個內部詞典中。給定一個合適的詞典,是可以由詞典中的詞的序列來重構源文本的。讀過(Brent & Cart-wright, 1995)以後,咱們能夠定義一個目標函數,一個打分函數,咱們將基於詞典的大小和從詞典中重構源文本所需的信息量盡力優化它的值。
    • 如圖計算目標函數:給定一個假設的源文本的分詞(左),推導出一個詞典和推導表,它能讓源文本重構,而後合計每一個詞項(包括邊界標誌)與推導表的字符數,做爲分詞質量的得分;得分值越小代表分詞越好。
圖3-6. 計算目標函數:給定一個假設的源文本的分詞(左),推導出一個詞典和推導表,它能讓源文本重構,而後合計每一個詞項(包括邊界標誌)與推導表的字符數,做爲分詞質量的得分;得分值越小代表分詞越好。
 
 
4 分類和標註詞彙
 
1. 什麼是詞彙分類,在天然語言處理中它們是如何使用?
2. 一個好的存儲詞彙和它們的分類的Python 數據結構是什麼?
3. 咱們如何自動標註文本中詞彙的詞類?

咱們將介紹NLP 的一些基本技術,包括序列標註、N-gram 模型、回退和評估。這些技術在許多方面都頗有用,標註爲咱們提供了一個表示它們的簡單的上下文。咱們還將看到標註爲什麼是典型的NLP 流水線中繼分詞以後的第二個步驟。將詞彙按它們的詞性(parts-of-speech,POS)分類以及相應的標註它們的過程被稱爲 詞性標註(part-of-speech tagging, POS tagging)或乾脆簡稱標註。詞性也稱爲詞類或詞彙範疇。用於特定任務的標記的集合被稱爲一個標記集。咱們在本章的重點是利用標記和自動標註文本。
 
4.1 使用詞性標註器
一個詞性標註器(part-of-speech tagger 或POS tagger)處理一個詞序列,爲每一個詞附加一個詞性標記。
>>> text = nltk.word_tokenize("And now for something completely different")
>>> nltk.pos_tag(text)
[('And', 'CC'), ('now', 'RB'), ('for', 'IN'), ('something', 'NN'),('completely', 'RB'), ('different', 'JJ')]
 
4.2 標註語料庫
  • 表示已標註的標識符:按照NLTK 的約定,一個已標註的標識符使用一個由標識符和標記組成的元組來表示。
    • 咱們可使用函數str2tuple()從表示一個已標註的標識符的標準字符串建立一個這樣的特殊元組:
      >>> tagged_token = nltk.tag.str2tuple('fly/NN')
      >>> tagged_token
      ('fly', 'NN')
  • 讀取已標註的語料庫:NLTK 中包括的若干語料庫已標註了詞性。
    • 用文本編輯器打開一個布朗語料庫的文件就能看到的例子:
      The/at Fulton/np-tl County/nn-tl Grand/jj-tl Jury/nn-tl said/vbd Friday/nr an/at investigation/
      nn of/in Atlanta’s/np$ recent/jj primary/nn election/nn produced/vbd / no/at
      evidence/nn ''/'' that/cs any/dti irregularities/nns took/vbd place/nn ./.
      其餘語料庫使用各類格式存儲詞性標記。NLTK 中的語料庫閱讀器提供了一個統一的接口,使你沒必要理會這些不一樣的文件格式。與剛纔提取並顯示的上面的文件不一樣,布朗語料庫的語料庫閱讀器按以下所示的方式表示數據。注意:部分詞性標記已轉換爲大寫的;自從布朗語料庫發佈以來,這已成爲標準的作法。
  • 簡化的詞性標記集:已標註的語料庫使用許多不一樣的標記集約定來標註詞彙。
    • 爲了幫助咱們開始,咱們將看一看一個簡化的部分標記集(表所示)。
  • 未簡化的標記
    讓咱們找出每一個名詞類型中最頻繁的名詞。
    • 例 中的程序找出全部以NN 開始的標記,併爲每一個標記提供了幾個示例詞彙。你會看到有許多名詞的變種;最重要的含有$的名詞全部格,含有S 的複數名詞(由於複數名詞一般以s 結尾),以及含有P 的專有名詞。此外,大多數的標記都有後綴修飾符:-NC 表示引用,-HL 表示標題中的詞,-TL 表示標題(布朗標記的特徵)。
    • 找出最頻繁的名詞標記的程序
      def findtags(tag_prefix, tagged_text):
      cfd = nltk.ConditionalFreqDist((tag, word) for (word, tag) in tagged_text
      if tag.startswith(tag_prefix))
      return dict((tag, cfd[tag].keys()[:5]) for tag in cfd.conditions())
      >>> tagdict = findtags('NN', nltk.corpus.brown.tagged_words(categories='news'))
      >>> for tag in sorted(tagdict):
      ... print tag, tagdict[tag]
      ...
      NN ['year', 'time', 'state', 'week', 'man']
      NN$ ["year's", "world's", "state's", "nation's", "company's"]
      NN$-HL ["Golf's", "Navy's"]
      NN$-TL ["President's", "University's", "League's", "Gallery's", "Army's"]
      NN-HL ['cut', 'Salary', 'condition', 'Question', 'business'] ...
  • 探索已標註的語料庫
    • 讓咱們簡要地回過來探索語料庫,咱們在前面的章節中看到過,此次咱們探索POS 標記。
    • 假設咱們正在研究詞often,想看看它是如何在文本中使用的。咱們能夠試着看看跟在often 後面的詞彙:
      >>> brown_learned_text = brown.words(categories='learned')
      >>> sorted(set(b for (a, b) in nltk.ibigrams(brown_learned_text) if a == 'often'))
      [',', '.', 'accomplished', 'analytically', 'appear', 'apt', 'associated', 'assuming',
      'became', 'become', 'been', 'began', 'call', 'called', 'carefully', 'chose', ...]
      然而,它使用tagged_words()方法查看跟隨詞的詞性標記可能更有指導性。
      >>> brown_lrnd_tagged = brown.tagged_words(categories='learned', simplify_tags=True)
      >>> tags = [b[1] for (a, b) in nltk.ibigrams(brown_lrnd_tagged) if a[0] == 'often']
      >>> fd = nltk.FreqDist(tags)
      >>> fd.tabulate()
      VN V VD DET ADJ ADV P CNJ , TO VG WH VBZ .
      15 12 8 5 5 4 4 3 3 1 1 1 1 1
      請注意often 後面最高頻率的詞性是動詞。名詞歷來沒有在這個位置出現(在這個特別的語料中)。
 
4.3 自動標註
咱們將看到一個詞的標記依賴於這個詞和它在句子中的上下文。
  • 默認標註器:
    • 最簡單的標註器是爲每一個標識符分配一樣的標記。這彷佛是一個至關平庸的一步,但它創建了標註器性能的一個重要的底線。爲了獲得最好的效果,咱們用最有可能的標記標註每一個詞。讓咱們找出哪一個標記是最有可能的(如今使用未簡化標記集):
      >>> tags = [tag for (word, tag) in brown.tagged_words(categories='news')]
      >>> nltk.FreqDist(tags).max()
      'NN'
    • 默認的標註器給每個單獨的詞分配標記,即便是以前從未遇到過的詞。碰巧的是,一旦咱們處理了幾千詞的英文文本以後,大多數新詞都將是名詞。正如咱們將看到的,這意味着,默認標註器能夠幫助咱們提升語言處理系統的穩定性。
  • 正則表達式標註器:基於匹配模式分配標記給標識符。
    • 例如:咱們可能會猜想任一以ed結尾的詞都是動詞過去分詞,任一以's 結尾的詞都是名詞全部格。能夠用一個正則表達式的列表表示這些:
      >>> patterns = [
      ... (r'.*ing$', 'VBG'), # gerunds
      ... (r'.*ed$', 'VBD'), # simple past
      ... (r'.*es$', 'VBZ'), # 3rd singular present
      ... (r'.*ould$', 'MD'), # modals
      ... (r'.*\'s$', 'NN$'), # possessive nouns
      ... (r'.*s$', 'NNS'), # plural nouns
      ... (r'^-?[0-9]+(.[0-9]+)?$', 'CD'), # cardinal numbers
      ... (r'.*', 'NN') # nouns (default)
      ... ]
      >>> regexp_tagger = nltk.RegexpTagger(patterns)
      >>> regexp_tagger.tag(brown_sents[3])
      [('``', 'NN'), ('Only', 'NN'), ('a', 'NN'), ('relative', 'NN'), ('handful', 'NN'),
      ('of', 'NN'), ('such', 'NN'), ('reports', 'NNS'), ('was', 'NNS'), ('received', 'VBD'),
      ("''", 'NN'), (',', 'NN'), ('the', 'NN'), ('jury', 'NN'), ('said', 'NN'), (',', 'NN'),
      ('``', 'NN'), ('considering', 'VBG'), ('the', 'NN'), ('widespread', 'NN'), ...]
      >>> regexp_tagger.evaluate(brown_tagged_sents)
      0.20326391789486245
    • 最終的正則表達式«.*»是一個全面捕捉的,標註全部詞爲名詞。除了做爲正則表達式標註器的一部分從新指定這個,這與默認標註器是等效的(只是效率低得多)。有沒有辦法結合這個標註器和默認標註器呢?咱們將很快看到如何作到這一點。
  • 查詢標註器
    不少高頻詞沒有NN 標記。讓咱們找出100 個最頻繁的詞,存儲它們最有可能的標記。而後咱們可使用這個信息做爲「查找標註器」(NLTK UnigramTagger)的模型:
    • >>> fd = nltk.FreqDist(brown.words(categories='news'))
      >>> cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories='news'))
      >>> most_freq_words = fd.keys()[:100]
      >>> likely_tags = dict((word, cfd[word].max()) for word in most_freq_words)
      >>> baseline_tagger = nltk.UnigramTagger(model=likely_tags)
      >>> baseline_tagger.evaluate(brown_tagged_sents)
      0.45578495136941344
    • 如今應該並不奇怪,僅僅知道100 個最頻繁的詞的標記就使咱們能正確標註很大一部分
      標識符(近一半,事實上)。讓咱們來看看它在一些未標註的輸入文本上作的如何:
      >>> sent = brown.sents(categories='news')[3]
      >>> baseline_tagger.tag(sent)
      [('``', '``'), ('Only', None), ('a', 'AT'), ('relative', None),
      ('handful', None), ('of', 'IN'), ('such', None), ('reports', None),
      ('was', 'BEDZ'), ('received', None), ("''", "''"), (',', ','),
      ('the', 'AT'), ('jury', None), ('said', 'VBD'), (',', ','),
      ('``', '``'), ('considering', None), ('the', 'AT'), ('widespread', None),
      ('interest', None), ('in', 'IN'), ('the', 'AT'), ('election', None),
      (',', ','), ('the', 'AT'), ('number', None), ('of', 'IN'),
      ('voters', None), ('and', 'CC'), ('the', 'AT'), ('size', None),
      ('of', 'IN'), ('this', 'DT'), ('city', None), ("''", "''"), ('.', '.')]
    • 許多詞都被分配了一個None 標籤,由於它們不在100 個最頻繁的詞之中。在這些狀況下,咱們想分配默認標記NN。換句話說,咱們要先使用查找表,若是它不能指定一個標記就使用默認標註器,這個過程叫作回退。咱們能夠作到這個,經過指定一個標註器做爲另外一個標註器的參數,以下所示。如今查找標註器將只存儲名詞之外的詞的詞-標記對,只要它不能給一個詞分配標記,它將會調用默認標註器。
      >>> baseline_tagger = nltk.UnigramTagger(model=likely_tags,
      ... backoff=nltk.DefaultTagger('NN'))
  • 評估
    • 事實上,這些工具的性能評估是NLP 的一箇中心主題。咱們對比專家分配的標記來評估一個標註器的性能。因爲咱們一般很難得到專業和公正的人的判斷,因此使用黃金標準測試數據來代替。這是一個已經手動標註並做爲自動系統評估標準而被接受的語料庫。當標註器對給定詞猜想的標記與黃金標準標記相同,標註器被視爲是正確的。
    • 固然,設計和實施原始的黃金標準標註的也是人,更深刻的分析可能會顯示黃金標準中的錯誤,或者可能最終會致使一個修正的標記集和更復雜的指導方針。然而,黃金標準就目前有關的自動標註器的評估而言被定義成「正確的」。
    • 開發一個已標註語料庫是一個重大的任務。除了數據,它會產生複雜的工具、文檔和實踐,爲確保高品質的標註。標記集和其餘編碼方案不可避免地依賴於一些理論主張,不是全部的理論主張都被共享。然而,語料庫的創做者每每竭
      盡全力使他們的工做盡量理論中立,以最大限度地提升其工做的有效性。
4.4 N-gram標註
  • 一元標註(Unigram Tagging)
    • 一元標註器基於一個簡單的統計算法:對每一個標識符分配這個獨特的標識符最有可能的標記。例如:它將分配標記JJ 給詞frequent 的全部出現,由於frequent 用做一個形容詞(例如:a frequent word)比用做一個動詞(例如:I frequent this cafe)更常見。一個一元標註器的行爲就像一個查找標註器,除了有一個更方便的創建它的技術,稱爲訓練。
    • 在下面的代碼例子中,咱們訓練一個一元標註器,用它來標註一個句子,而後評估:
      >>> from nltk.corpus import brown
      >>> brown_tagged_sents = brown.tagged_sents(categories='news')
      >>> brown_sents = brown.sents(categories='news')
      >>> unigram_tagger = nltk.UnigramTagger(brown_tagged_sents)
      >>> unigram_tagger.tag(brown_sents[2007])
      [('Various', 'JJ'), ('of', 'IN'), ('the', 'AT'), ('apartments', 'NNS'),
      ('are', 'BER'), ('of', 'IN'), ('the', 'AT'), ('terrace', 'NN'), ('type', 'NN'),
      (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'), ('ground', 'NN'),
      ('floor', 'NN'), ('so', 'QL'), ('that', 'CS'), ('entrance', 'NN'), ('is', 'BEZ'),
      ('direct', 'JJ'), ('.', '.')]
      >>> unigram_tagger.evaluate(brown_tagged_sents)
      0.9349006503968017
    • 咱們訓練一個UnigramTagger,經過在咱們初始化標註器時指定已標註的句子數據做爲參數。訓練過程當中涉及檢查每一個詞的標記,將全部詞的最可能的標記存儲在一個字典裏面,這個字典存儲在標註器內部。
  • 通常的 N-gram的標註
    • 一個n-gram標註器是一個 unigram 標註器的通常化,它的上下文是當前詞和它前面n-1 個標識符的詞性標記。要選擇的標記是圓圈裏的tn,灰色陰影的是上下文。在圖 所示的n-gram 標註器的例子中,咱們讓n= 3,也就是說,咱們考慮當前詞的前兩個詞的標記。一個n-gram 標註器挑選在給定的上下文中最有可能的標記。
    • 1-gram 標註器是一元標註器(unigram tagger)另外一個名稱:即用於標註一個標識符的上下文的只是標識符自己。2-gram 標註器也稱爲二元標註器(bigram taggers),3-gram 標註器也稱爲三元標註器(trigram taggers)。
    • NgramTagger 類使用一個已標註的訓練語料庫來肯定對每一個上下文哪一個詞性標記最有可能。在這裏,咱們看到一個n-gram 標註器的特殊狀況,即一個bigram 標註器。首先,咱們訓練它,而後用它來標註未標註的句子:
      >>> bigram_tagger = nltk.BigramTagger(train_sents)
      >>> bigram_tagger.tag(brown_sents[2007])
      [('Various', 'JJ'), ('of', 'IN'), ('the', 'AT'), ('apartments', 'NNS'),
      ('are', 'BER'), ('of', 'IN'), ('the', 'AT'), ('terrace', 'NN'),
      ('type', 'NN'), (',', ','), ('being', 'BEG'), ('on', 'IN'), ('the', 'AT'),
      ('ground', 'NN'), ('floor', 'NN'), ('so', 'CS'), ('that', 'CS'),
      ('entrance', 'NN'), ('is', 'BEZ'), ('direct', 'JJ'), ('.', '.')]
      >>> unseen_sent = brown_sents[4203]
      >>> bigram_tagger.tag(unseen_sent)
      [('The', 'AT'), ('population', 'NN'), ('of', 'IN'), ('the', 'AT'), ('Congo', 'NP'),
      ('is', 'BEZ'), ('13.5', None), ('million', None), (',', None), ('divided', None),
      ('into', None), ('at', None), ('least', None), ('seven', None), ('major', None),
      ('``', None), ('culture', None), ('clusters', None), ("''", None), ('and', None),
      ('innumerable', None), ('tribes', None), ('speaking', None), ('400', None),
      ('separate', None), ('dialects', None), ('.', None)]
    • 請注意,bigram 標註器可以標註訓練中它看到過的句子中的全部詞,但對一個沒見過的句子表現不好。只要遇到一個新詞,就沒法給它分配標記。它不能標註下面的詞(如:million),即便是在訓練過程當中看到過的,只是由於在訓練過程當中歷來沒有見過它前面有一個None 標記的詞。所以,標註器標註句子的其他部分也失敗了。它的總體準確度
      得分很是低:
      >>> bigram_tagger.evaluate(test_sents)
      0.10276088906608193
    • 當n 越大,上下文的特異性就會增長,咱們要標註的數據中包含訓練數據中不存在的上下文的概率也增大。這被稱爲數據稀疏問題,在NLP 中是至關廣泛的。所以,咱們的研究結果的精度和覆蓋範圍之間須要有一個權衡(這與信息檢索中的精度/召回權衡有關)。
    • 注意:
      N-gram 標註器不該考慮跨越句子邊界的上下文。所以,NLTK 的標註器被設計用於句子鏈表,一個句子是一個詞鏈表。在一個句子的開始,tn-1和前面的標記被設置爲None。
  • 組合標註器:解決精度和覆蓋範圍之間的權衡的一個辦法是儘量的使用更精確的算法,但卻在不少時候落後於具備更廣覆蓋範圍的算法。例如:咱們能夠按以下方式組合bigram 標註器、unigram 標註器和一個默認標註器:
    • 1. 嘗試使用bigram 標註器標註標識符。
      2. 若是bigram 標註器沒法找到一個標記,嘗試unigram 標註器。
      3. 若是unigram 標註器也沒法找到一個標記,使用默認標註器。
    • 大多數NLTK 標註器容許指定一個回退標註器。回退標註器自身可能也有一個回退標註器:
      >>> t0 = nltk.DefaultTagger('NN')
      >>> t1 = nltk.UnigramTagger(train_sents, backoff=t0)
      >>> t2 = nltk.BigramTagger(train_sents, backoff=t1)
      >>> t2.evaluate(test_sents)
      0.84491179108940495
  • 標註生詞:咱們標註生詞的方法仍然是回退到一個正則表達式標註器或一個默認標註器,這些都沒法利用上下文。
    • 所以,若是咱們的標註器遇到詞blog,訓練過程當中沒有看到過,它會分配相同的標記,不論這個詞出現的上下文是the blog 仍是to blog。
    • 一個有用的基於上下文標註生詞的方法是限制一個標註器的詞彙表爲最頻繁的n 個詞,使用5.3 節中的方法替代每一個其餘的詞爲一個特殊的詞UNK。訓練時,一個unigram 標註器可能會學到UNK 一般是一個名詞。然而,n-gram 標註器會檢測它的一些其餘標記中的上下文。例如:若是前面的詞是to(標註爲TO),那麼UNK 可能會被標註爲一個動詞。
  • 存儲標註器
    • 在大語料庫上訓練一個標註器可能須要大量的時間,一個訓練好的標註器保存到一個文件之後重複使用。
  • 跨句子邊界標註
    • 一個n-gram 標註器使用最近的標記做爲爲當前的詞選擇標記的指導。當標記一個句子的第一個詞時,trigram 標註器將使用前面兩個標識符的詞性標記,這一般會是前面句子的最後一個詞和句子結尾的標點符號。然而,在前一句結尾的詞的類別與下一句的開頭的一般沒有關係。爲了應對這種狀況,咱們可使用已標註句子的鏈表來訓練、運行和評估標註器,如例 所示。
    • 例. 句子層面的N-gram 標註
      brown_tagged_sents = brown.tagged_sents(categories='news')
      brown_sents = brown.sents(categories='news')
      size = int(len(brown_tagged_sents) * 0.9)
      train_sents = brown_tagged_sents[:size]
      test_sents = brown_tagged_sents[size:]
      t0 = nltk.DefaultTagger('NN')
      t1 = nltk.UnigramTagger(train_sents, backoff=t0)
      t2 = nltk.BigramTagger(train_sents, backoff=t1)
      >>> t2.evaluate(test_sents)
      0.84491179108940495
4.5 基於轉換的標註
Brill 標註是一種基於轉換的學習,通常的想法很簡單:猜每一個詞的標記,而後返回和修復錯誤的。在這種方式中,Brill 標註器陸續將一個不良標註的文本轉換成一個更好的。與n-gram 標註同樣,這是有監督的學習方法,由於咱們須要已標註的訓練數據來評估標註器的猜想是不是一個錯誤。然而,不像n-gram 標註,它不計數觀察結果,只編制一個轉換修正規則鏈表。
 
讓咱們看看下面的例子:
(1) The President said he will ask Congress to increase grants to states for vocational rehabilitation.
咱們將研究兩個規則的運做:
(a)當前面的詞是TO 時,替換NN 爲VB;
(b)當下一個標記是NNS 時,替換TO 爲IN 。
下表說明了這一過程,首先使用unigram 標註器標註,而後運用規則修正錯誤。
Brill 標註器的另外一個有趣的特性:規則是語言學可解釋的。與採用潛在的巨大的n-gram 表的n-gram 標註器相比,咱們並不能從直接觀察這樣的一個表中學到多少東西,而Brill標註器學到的規則能夠。
 
4.6 如何肯定一個詞的分類
在通常狀況下,語言學家使用形態學、句法和語義線索肯定一個詞的類別。
  • 形態學線索
    • 一個詞的內部結構可能爲這個詞分類提供有用的線索。舉例來講:-ness 是一個後綴,與形容詞結合產生一個名詞,如happy→happiness,ill→illness。所以,若是咱們遇到的一個以-ness 結尾的詞,極可能是一個名詞。一樣的,-ment 是與一些動詞結合產生一個名詞的後綴,如govern→government 和establish→establishment。
    • 英語動詞也能夠是形態複雜的。例如:一個動詞的如今分詞以-ing 結尾,表示正在進行的尚未結束的行動(如:falling,eating)的意思。-ing 後綴也出如今從動詞派生的名詞中,如:the falling of the leaves(這被稱爲動名詞)。
  • 句法線索
    另外一個信息來源是一個詞可能出現的典型的上下文語境。
    • 例如:假設咱們已經肯定了名詞類。那麼咱們能夠說,英語形容詞的句法標準是它能夠當即出如今一個名詞前,或緊跟在詞be 或very 後。根據這些測試,near 應該被歸類爲形容詞:
    • a. the near window
      b. The end is (very) near.
  • 語義線索
    最後,一個詞的意思對其詞彙範疇是一個有用的線索。
    • 例如:名詞的衆所周知的一個定義是根據語義的:「一我的、地方或事物的名稱。」在現代語言學,詞類的語義標準受到懷疑,主要是由於它們很難規範化。然而,語義標準鞏固了咱們對許多詞類的直覺,使咱們可以在不熟悉的語言中很好的猜想詞的分類。例如:若是咱們都知道荷蘭語詞verjaardag 的意思與英語詞birthday 相同,那麼咱們能夠猜想verjaardag 在荷蘭語中是一個名詞。然而,一些修補是必要的:雖然咱們可能翻譯zij is vandaag jarig as it ’s her birthday today,詞jarig在荷蘭語中其實是形容詞,與英語並不徹底相同。
  • 新詞
    全部的語言都學習新的詞彙。最近添加到牛津英語詞典中的一個單詞列表包括cyberslacker、fatoush、blamestorm、SARS、cantopop、bupkis、noughties、muggle 和robata。請注意,全部這些新詞都是名詞,這反映在名詞被稱爲開放類。相反,介詞被認爲是一個封閉類。也就是說,只有有限的詞屬於這個類別(例如:above、along、at、below、beside、between、during、for、from、in 、near、on、outside、over、past、through、towards、under、up、with),詞類成員隨着很長時間的推移才逐漸改變。
  • 詞性標記集中的形態學
    普通標記集常常捕捉一些構詞信息,即詞藉助它們的句法角色得到的一種形態標記的信息。
    • 例如:下面句子中詞go 的不一樣語法形式的選集:
      a. Go away!
      b. He sometimes goes to the cafe.
      c. All the cakes have gone.
      d. We went on the excursion.
      這些形態中的每個——go、goes、gone 和went——是形態學上的區別。思考形式goes。它出如今受限制的語法環境中,須要一個第三人稱單數的主語。所以,下面的句子是不合語法的。
    • 更細粒度的標記集提供有關這些形式的有用信息,能夠幫助嘗試檢測標記序列模式的其它處理者。布朗標記集捕捉這些區別,如表中的總結:
    • 除了這組動詞標記,動詞to be 的各類形式也有特殊的標記:be/BE,being/BEG,am/BEM,are/BER,is/BEZ,been/BEN,were/BED 和was/BEDZ(加上額外的動詞否認形式的標記)。總的來講,這種動詞細粒度標記意味着使用此標記集的自動標註器能有效開展有限數量的形態分析。
    • 大多數詞性標註集使用相同的基本類別,然而,標記集的相互區別不只在於它們如何細緻的將詞分類,也在於它們如何界定其類別。例如:is 在一個標記集可能會被簡單的標註爲動詞,而在另外一個標記集中被標註爲lexeme be 的不一樣形式(如在布朗語料庫中)。這種標記集的變化是不可避免的,由於詞性標記被以不一樣的方式用於不一樣的任務。換句話說,沒有一個「正確的方式」來分配標記,只有根據目標不一樣或多或少有用的方法。
4.7 小結
􀁺 詞能夠組成類,如名詞、動詞、形容詞以及副詞。這些類被稱爲詞彙範疇或者詞性。詞性被分配短標籤或者標記,如NN 和VB。
􀁺 給文本中的詞自動分配詞性的過程稱爲詞性標註、POS 標註或只是標註。
􀁺 自動標註是NLP 流程中重要的一步,在各類狀況下都十分有用,包括預測先前未見過的詞的行爲、分析語料庫中詞的使用以及文本到語音轉換系統。
􀁺 一些語言學語料庫,如布朗語料庫,已經作了詞性標註。
􀁺 有多種標註方法,如默認標註器、正則表達式標註器、unigram 標註器、n-gram 標註器。這些均可以結合一種叫作回退的技術一塊兒使用。
􀁺 標註器可使用已標註語料庫進行訓練和評估。
􀁺 回退是一個組合模型的方法:當一個較專業的模型(如bigram 標註器)不能爲給定內容分配標記時,咱們回退到一個較通常的模型(如unigram 標註器)
􀁺 詞性標註是NLP 中一個重要的早期的序列分類任務:利用局部上下文語境中的詞和標記對序列中任意一點的分類決策。
􀁺 字典用來映射任意類型之間的信息,如字符串和數字:freq['cat']=12。咱們使用大括號來建立字典:pos = {},pos = {'furiously': 'adv', 'ideas': 'n', 'colorless':'adj'}。
􀁺 N-gram 標註器能夠定義較大數值的n,可是當n 大於3 時,咱們經常會面臨數據稀疏問題;即便使用大量的訓練數據,咱們看到的也只是可能的上下文的一小部分。
􀁺 基於轉換的標註學習一系列「改變標記s 爲標記t 在上下文c 中」形式的修復規則,每一個規則會修復錯誤,也可能引入(較小的)錯誤。
 
 
-------

一.分詞軟件簡介

分詞算法在20世紀80年代就有研究,不過基於當時的技術條件所限,大多數就是原始的機械分詞算法。好比,最大匹配算法,mmseg等。關於原始的機械分詞算法 http://www.cnblogs.com/alic/articles/1215001.html 這篇blog有很詳細的介紹。html

以後隨着統計算法在天然語言處理領域地位的奠基以及機器學習的興起,基於統計和機器學習的分詞算法逐漸成爲主流。根據機器學習方法的分類,分詞算法也能夠分紅無監督分詞,半監督分詞以及有監督的分詞。目前有監督的分詞以及半監督的分詞已經研究的比較成熟。對於這種分詞算法,大體能夠分爲四類:前端

  • 第一類是生成式的基於詞的分詞方法,這類具備表明的是中科院的ICTCLAS等等比較經典的分詞軟件。
  • 第二類是判別式的基於詞的分詞方法,這類中的算法比較少,其中一個是基於平衡感知機的分詞。
  • 第三類是生成式基於字的生成式分詞方法,好比Wang(2009)所提出的n元模型分詞算法。
  • 第四類也是目前主流的是基於字的判別式分詞方法,主要是最大熵模型和條件隨機場模型。幾乎所有2003年以後提出的分詞算法都與這一類別有關,好比哈工大的LTP和Stanford Word Segmenter就是採用CRF模型。

此外,分詞算法還能夠根據在天然預言處理中的步驟來分,好比純分詞,就是除了分詞以外什麼都不作,大多數基於字的分詞算法都屬於這一類。此外將分詞和詞性標註結合在一塊兒完成,好比ICTCLAS。還有基於語義網絡分詞的算法。總的來講,結合額外信息越多,對於分詞結果就越好。好比ICTCLAS將分詞與詞性標註結果結合起來,效果就比光光使用一元機率模型(ICTCLAS)效果要好。java

分詞模型

分詞模型大體能夠分爲判別式和生成式,以及基於詞和基於字的方法。主要使用到的模型爲: n-Gram,Percepton,HMM,SVM,ME,CRF。判別式和生成式的區別就是判別式是計算P(Y|X)的條件機率,可是生成式則是計算P(X1, X2)的聯合機率,一般來講判別式的效果要比生成式的要好,這一分類比較複雜,很差解釋,涉及到不少數學模型,詳情能夠去看看相關資料。git

基於詞和基於字的分詞的區別就是基於詞的算法將詞當作算法中最小單元,好比這句話github

結合/成/分子/時web

在基於詞的分詞算法中,主要用到一個詞典,「結合」、「成」、「分子」在詞典中,它們是分詞中的最小單元,不可拆分,一旦拆分就會出現分詞錯誤。可是基於字的分詞算法則不一樣,它將每一個字當作是一個單元,一般和序列標註相結合,對每一個字進行標註,而後得出分詞結果。好比正則表達式

結合成分子時算法

使用CRF等序列標註模型得出的序列標註結果是編程

B E S B E S

其中B表示一個詞的開頭,E表示一個詞的結尾,S表示單個字做爲詞。而後分詞的結果通過一些小處理就能夠得出了。

一般來講基於詞的分詞算法在詞典比較全,文章比較正式的時候效果比較好。可是老是會碰見一些比較變態的詞典中沒有的詞,其中最有表明的就是人名地名還有商標名等等。因此通常這些基於詞分詞軟件還必需要加上識別人名地名的功能。

基於字的分詞算法主要是依賴於某些字在構詞方面的特徵,好比「的」字一般就是單個字出現,有很大的概率是標註S,「化」字比較喜歡出如今詞的末尾,好比現代化,工業化等等。根據這些信息進行標註分詞,它對於詞典中不存在的詞效果識別概率比較大,可是對於詞典中的詞可能會識別錯誤,另外還會出現千奇百怪的分詞錯誤,好比「沙把」等等。 所以,如今多數的分詞軟件在基於字的基於上,或多或少的結合了一點基於詞的特徵。

 

二.實現中文分詞的18種分詞工具

因爲中文文本詞與詞之間沒有像英文那樣有空格分隔,所以不少時候中文文本操做都涉及切詞,這裏整理了一些。通常來講用CRF實現的分詞工具的處理速度是比較慢的(訓練CRF模型是很是耗時的),可是精度高,涉及CRF的分詞工具備CRF++,Stanford分詞工具。

Bakeoff是一個國際中文處理比賽,有多個語料,因此每一個語料都有排名。只有部分優秀的Bakeoff工具開源,如下介紹如下18種分詞工具(大部分是基於java語言):

 

Stanford 漢語分詞工具      

官網:http://nlp.stanford.edu/software/segmenter.shtmlStanford 漢語分詞工具的成績:2005年Bakeoff2兩個語料的測試第一。Stanford 漢語分詞工具

一篇使用介紹:http://hi.baidu.com/liheming333/item/585fba1f898838623e87ce18

斯坦福天然語言小組直接使用CRF 的方法,特徵窗口爲5。

 

哈工大語言云(LTP -cloud)

項目網址:http://www.ltp-cloud.com/download/#ltp_cloud_sdk

HIT的ITNLP Lab, HIT Wei JIANG在Bakeoff 2005的open語料MSR上得到測評第一名。語言云曾獲CoNLL2009七國語言句法語義分析評測總成績第一名,使用方式爲web service。

語言云(語言技術平臺雲 LTP-Cloud)是由哈工大社會計算與信息檢索研究中心研發的雲端天然語言處理服務平臺。 後端依託於語言技術平臺,語言云爲用戶提供了包括分詞、詞性標註、依存句法分析、命名實體識別、語義角色標註在內的豐富高效的天然語言處理服務。

做爲基於雲端的服務,語言云具備以下一些優點:

  • 免安裝:用戶只須要下載語言云客戶端源代碼,編譯執行後便可得到分析結果,無需調用靜態庫或下載模型文件。
  • 省硬件:語言云客戶端幾乎能夠運行於任何硬件配置的計算機上,用戶不須要購買高性能的機器,便可快捷的得到分析結果。
  • 跨平臺:語言云客戶端幾乎能夠運行於任何操做系統之上,不管是Windows、Linux各個發行版或者Mac OS。
  • 跨編程語言:時至今日,語言云已經提供了包括C++,Java,C#,Python,Ruby在內的客戶端,其餘編程語言的客戶端也在開發之中。
在運算資源有限,編程語言受限的狀況下,語言云無疑是用戶進行語言分析更好的選擇。
從2006年9月5日開始該平臺對外免費共享目標代碼,截止目前,已經有國內外400多家研究單位共享了LTP,也有國內外多家商 業公司購買了LTP,用於實際的商業項目中。2011年6月1日,爲了與業界同行共同研究和開發中文信息處理核心技術,正式將LTP的源代碼對外共享,LTP由C++語言開發,可運行於Windows和Linux操做系統。

 

ICTCLAS: 漢語詞法分析系統

官網:http://ictclas.nlpir.org/ Author:中國科學院計算技術研究所

ICTCLAS(Institute of Computing Technology, Chinese Lexical Analysis System)獲取Bakeoff 1兩項第一。這是最先的中文開源分詞項目之一,ICTCLAS在國內973專家組組織的評測中活動得到了第一名,在第一屆(2003)國際中文處理研究機構SigHan組織的評測中都得到了多項第一名。

性能:分詞速度單機996KB/s, API 不超過 200KB ,各類詞典數據壓縮後不到 3M.

準確率:分詞精度98.45%

語言和平臺:ICTCLAS所有采用 C/C++ 編寫,支持 Linux 、 FreeBSD 及 Windows 系列操做系統,支持 C/C++ 、 C# 、 Delphi、 Java 等主流的開發語言。

主要功能:中文分詞;詞性標註;命名實體識別;新詞識別;同時支持用戶詞典;支持繁體中文;支持GBK 、 UTF-8 、 UTF-7 、 UNICODE 等多種編碼格式。

算法:完美PDAT 大規模知識庫管理技術( 200510130690.3 ),在高速度與高精度之間取得了重大突破,該技術能夠管理百萬級別的詞典知識庫,單機每秒能夠查詢 100 萬詞條,而內存消耗不到知識庫大小的 1.5 倍。層疊隱馬爾可夫模型( Hierarchical Hidden Markov Model ) ,該分詞系統的主要是思想是先經過 CHMM( 層疊形馬爾可夫模型 ) 進行分詞 , 經過分層 , 既增長了分詞的準確性 , 又保證了分詞的效率 . 共分五層, 以下圖所示。基本思路是進行原子切分 , 而後在此基礎上進行N- 最短路徑粗切分 , 找出前 N 個最符合的切分結果 , 生成二元分詞表 , 而後生成分詞結果 , 接着進行詞性標註並完成主要分詞步驟 .

 

Ansj(ICTCLAS的java實現)

項目網址:https://github.com/ansjsun/ansj_seg

做者網址:http://www.ansj.org/

ansj分詞.ict的真正java實現.分詞效果速度都超過開源版的ict.中文分詞,人名識別,詞性標註,用戶自定義詞典增長了對lucene的支持.若是不想編譯文件能夠直接到 https://github.com/ansjsun/mvn-repo/tree/gh-pages/org/ansj這裏下載jar包!

這是一個ictclas的java實現.基本上重寫了全部的數據結構和算法.詞典是用的開源版的ictclas所提供的.而且進行了部分的人工優化。

性能:內存中中文分詞每秒鐘大約100萬字(速度上已經超越ictclas),文件讀取分詞每秒鐘大約30萬字

正確率:準確率能達到96%以上

功能:目前實現了.中文分詞. 中文姓名識別 . 用戶自定義詞典能夠應用到天然語言處理等方面,適用於對分詞效果要求搞的各類項目.

 

庖丁解牛分詞

官網:http://code.google.com/p/paoding/

語言和平臺:Java,提供 lucence  3.0  接口,僅支持 Java 語言。

性能:在PIII 1G 內存我的機器上, 1 秒 可準確分詞  100 萬 漢字。

算法:採用基於 不限制個數 的詞典文件對文章進行有效切分

主要功能:使可以將對詞彙分類定義。可以對未知的詞彙進行合理解析

 

盤古分詞

官網:http://pangusegment.codeplex.com

博客:http://www.cnblogs.com/eaglet/

是一箇中英文分詞組件。Pan Gu Segment is alibrary that can segment Chinese and English words from sentence.盤古分詞是一箇中英文分詞組件。做者eaglet 曾經開發過KTDictSeg 中文分詞組件,擁有大量用戶。做者基於以前分詞組件的開發經驗,結合最新的開發技術從新編寫了盤古分詞組件。

主要功能:中文分詞功能,中文未登陸詞識別,詞頻優先, 盤古分詞能夠根據詞頻來解決分詞的歧義問題, 多元分詞, 盤古分詞提供多重輸出解決分詞粒度和分詞精度權衡的問題, 中文人名識別, 強制一元分詞, 繁體中文分詞, 同時輸出簡體和繁體 中文詞性輸出 盤古分詞能夠將以登陸詞的中文詞性輸出給用戶,以方便用戶作進一步處理,  全角字符支持,  盤古分詞能夠識別全角的字母和數字,  英文分詞,  英文專用詞識別(一些英文簡寫是字母符號混合,或者是字母數字混合,這個分詞起來就不能按照空格符號這樣分割了,對於字母符號混合的如 U.S.A  ,只要將這個詞錄入到字典中,盤古分詞就能夠分出整詞。對於字母和數字混合的,盤古分詞會自動做爲整詞輸出),英文原詞輸出,英文大小寫同時輸出。

其餘功能:

停用詞過濾:對於一些標點符號,連詞,助詞等有時候須要在分詞時過濾掉,盤古分詞提供一個 StopWord.txt  文件,用戶只要將須要過濾的詞加入到這個文件中,並將停用詞過濾開發打開,就能夠過濾掉這些詞。

設置分詞權值:盤古分詞可讓用戶對以下特性設置自定義權值,1 未登陸詞權值 2 最匹配詞權值 3 次匹配詞權值 4 再次匹配詞權值 5 強行輸出的單字的權值 6 數字的權值 7 英文詞彙權值 8 符號的權值 9 強制同時輸出簡繁漢字時,非原來文本的漢字輸出權值。

用戶自定義規則:

字典管理,盤古分詞提供一個字典管理工具 DictManage  經過這個工具,你能夠增長,修改,和刪除字典中的單詞

動態加載字典,經過字典工具增長,修改,和刪除字典中的單詞後,保持字典,盤古分詞會自動將新的字典文件加載進去,而不須要從新啓動。

關鍵詞高亮組件,Lucene 提供了一個關鍵詞高亮組件,但這個組件對中文的支持不是特別好,特別是若是還有多元分詞的狀況,處理的就更很差。盤古分詞提供了一個針對中文和英文的關鍵詞高亮組件  PanGu.HighLight  ,其對中文的支持要好於Lucene  那個高亮組件。

同義詞輸出( 後續版本提供 ),Lucene.net 接口及示例等在PanGu4Lucene 這個包裏面有我作的一個盤古 +Lucene  的簡單新聞搜索 Web 示例程序, Release  包裏面有使用說明。

性能:Core Duo 1.8 GHz 下單線程 分詞速度爲 390K  字符每秒, 2 線程分詞速度爲 690K  字符每秒。

算法:盤古分詞提供的字典包括17萬個中文經常使用單詞,但這個字典依然不夠完整,若是要分詞更準確,須要適當維護一下這個字典。中文人名的識別能力取決於  ChsSingleName.txt , ChsDoubleName1.txt ,  ChsDoubleName2.txt  這三個文件,它們分別表示單子人名,雙字人名的首字和雙字人名的尾字。

 

IKAnalyzer

官網:http://code.google.com/p/ik-analyzer/

做者博客:http://linliangyi2007.iteye.com/

從2006年12月推出1.0版開始。開源輕量級的包語言和平臺:基於java 語言開發 , 最初,它是以開源項目Luence爲應用主體的,結合詞典分詞和文法分析算法的中文分詞組件。新版本的 IKAnalyzer3.0 則發展爲面向 Java 的公用分詞組件,獨立於 Lucene 項目,同時提供了對 Lucene 的默認優化實現。

算法:採用了特有的「 正向迭代最細粒度切分算法 「 。採用了多子處理器分析模式,支持:英文字母( IP 地址、 Email 、 URL )、數字(日期,經常使用中文數量詞,羅馬數字,科學計數法),中文詞彙(姓名、地名處理)等分詞處理。優化的詞典存儲,更小的內存佔用。支持用戶詞典擴展定義。針對 Lucene 全文檢索優化的查詢分析器 IKQueryParser ;採用歧義分析算法優化查詢關鍵字的搜索排列組合,能極大的提升 Lucene 檢索的命中率。

性能:在系統環境:Core2i7 3.4G雙核,4G內存,window 7 64位, Sun JDK 1.6_29 64位 普通pc環境測試,IK2012具備160萬字/秒(3000KB/S)的高速處理能力

 

imdict-chinese-analyzer

官網:http://code.google.com/p/imdict-chinese-analyzer/是imdict 智能詞典的智能中文分詞模塊,ictclas4j中文分詞系統是 sinboy 在中科院張華平和劉羣老師的研製的 FreeICTCLAS 的基礎上完成的一個 java 開源分詞項目,簡化了原分詞程序的複雜度,旨在爲廣大的中文分詞愛好者一個更好的學習機會。

算法 :基於隱馬爾科夫模型(Hidden Markov Model, HMM) ,是中國科學院計算技術研究所的 ictclas 中文分詞程序的從新實現(基於 Java ),能夠直接爲lucene搜索引擎提供簡體中文分詞支持 。

主要功能:

1, 徹底 Unicode 支持,分詞核心模塊徹底採用Unicode 編碼,無須各類漢字編碼的轉換,極大的提高了分詞的效率。2. 提高搜索效率,根據imdict 智能詞典的實踐,在有智能中文分詞的狀況下,索引文件比沒有中文分詞的索引文件小 1/3

3. 提升搜索準確度,imdict-chinese-analyzer採用了 HHMM 分詞模型,極大的提升了分詞的準確率,在此基礎上的搜索,比對漢字逐個切分要準確得多!

4. 更高效的數據結構,爲了提升效率,針對經常使用中文檢索的應用場景,imdict-chinese-analyzer 對一些沒必要要的功能進行了刪減,例如詞性標註、人名識別、時間識別等等。另外還修改了算法的數據結構,在內存佔用量縮減到 1/3 的狀況下把效率提高了數倍。imdict-chinese-analyzer的分詞效率與 C ++實現的 ICTCLAS 3.0的分詞效率在同一個數量級,是  ictclas4j  的  36  倍!

 

mmseg4j

項目網址:(舊)http://code.google.com/p/mmseg4j/

(新)https://github.com/chenlb/mmseg4j-solr

做者博客:http://blog.chenlb.com/   http://chenlb.iteye.com/

 算法:

一、mmseg4j 用 Chih-Hao Tsai 的 MMSeg 算法(http://technology.chtsai.org/mmseg/)實現的中文分詞器,並實現 lucene 的 analyzer和 solr 的TokenizerFactory 以方便在Lucene和Solr中使用。

二、MMSeg 算法有兩種分詞方法:Simple和Complex,都是基於正向最大匹配。Complex 加了四個規則過慮。官方(指mmseg論文的做者)說:詞語的正確識別率達到了 98.41%。

mmseg4j 已經實現了這兩種分詞算法。

1.5版的分詞速度simple算法是 1100kb/s左右、complex算法是 700kb/s左右,(測試機:AMD athlon 64 2800+ 1G內存 xp)。
1.6版在complex基礎上實現了最多分詞(max-word)。「很好聽」 -> 「很好|好聽」; 「中華人民共和國」 -> 「中華|華人|共和|國」; 「中國人民銀行」 -> 「中國|人民|銀行」。
1.7-beta 版, 目前 complex 1200kb/s左右, simple 1900kb/s左右, 但內存開銷了50M左右. 上幾個版都是在10M左右.
1.8 後,增長 CutLetterDigitFilter過慮器,切分「字母和數」混在一塊兒的過慮器。好比:mb991ch 切爲 「mb 991 ch」。
 
mmseg4j實現的功能詳情請看: http://mmseg4j.googlecode.com/svn/trunk/CHANGES.txt 
 
FudanNLP(復旦大學)
2013.8.14 發佈FudanNLP1.6.1版。時常更新。復旦大學開發的軟件。FudanNLP主要是爲中文天然語言處理而開發的工具包,也包含爲實現這些任務的機器學習算法和數據集。本工具包及其包含數據集使用LGPL3.0許可證。開發語言爲Java。功能包括中文分詞等,不須要字典支持。
功能:
信息檢索: 文本分類 新聞聚類
中文處理: 中文分詞 詞性標註 實體名識別 關鍵詞抽取 依存句法分析 時間短語識別
結構化學習: 在線學習 層次分類 聚類 精確推理

 

Jcseg

官網:http://code.google.com/p/jcseg/

jcseg是使用Java開發的一箇中文分詞器,使用mmseg算法實現。目前最高版本:jcseg1.9.0。兼容最高版本lucene-4.x和最高版本solr-4.x

主要特性:

mmseg四種過濾算法,分詞準確率達到了98.41%。

支持自定義詞庫。在lexicon文件夾下,能夠隨便添加/刪除/更改詞庫和詞庫內容,而且對詞庫進行了分類。如何給jcseg添加詞庫/新詞

中英文同義詞追加/同義詞匹配 + 中文詞條拼音追加.詞庫整合了《現代漢語詞典》和cc-cedict辭典中的詞條,而且依據cc-cedict詞典爲詞條標上了拼音,依據《中華同義詞詞 典》爲詞條標上了同義詞(還沒有完成)。更改jcseg.properties配置文檔能夠在分詞的時候加入拼音和同義詞到分詞結果中。

中文數字和中文分數識別,例如:」一百五十我的都來了,四十分之一的人。」中的」一百五十」和」四十分之一」。而且jcseg會自動將其轉換爲阿拉伯數字加入到分詞結果中。如:150, 1/40。

支持中英混合詞和英中混合詞的識別(維護詞庫能夠識別任何一種組合)。例如:B超, x射線, 卡拉ok, 奇都ktv, 哆啦a夢。

更好的英文支持,電子郵件,網址,小數,分數,百分數,字母和標點組合詞(例如C++, c#)的識別。(這個對購物網址來講很重要)。

支持阿拉伯數字/小數/中文數字基本單字單位的識別,例如2012年,1.75米,38.6℃,五折,而且jcseg會將其轉換爲「5折」加入分詞結果中。

智能圓角半角, 英文大小寫轉換;特殊字母識別:例如:Ⅰ,Ⅱ;特殊數字識別:例如:①,⑩

配對標點內容提取:例如:最好的Java書《java編程思想》,‘暢想杯黑客技術大賽’,被《,‘,「,『標點標記的內容。(1.6.8版開始支持)。

智能中文人名識別。中文人名識別正確率達94%以上。(能夠維護lex-lname.lex,lex-dname-1.lex,lex-dname-2.lex來提升準確率),(引入規則和詞性後會達到98%以上的識別正確率)。

自動中英文中止詞過濾功能(須要在jcseg.properties中開啓該選項,lex-stopwords.lex爲中止詞詞庫)。

詞庫更新自動加載功能, 開啓一個守護線程隨時檢測詞庫的更新而且加載。

自動詞性標註。

分詞速度:

測試環境:2.8GHZ/2G/Ubuntu

Simple 模式: 1366058字/秒 3774.5KB/秒

Complex 模式: 479338字/秒 1324.4KB/秒

分詞正確率98%以上,請參考本算法的原做:http://technology.chtsai.org/mmseg/

測試文章,「世界與和平」 簡易模式830msec,複雜模式2461msec。

 

SCWS

算法:基於詞頻詞典的機械中文分詞引擎,採用的是採集的詞頻詞典,並輔以必定的專有名稱,人名,地名,數字年代等規則識別來達到基本分詞

準確率:經小範圍測試大概準確率在 90% ~ 95%  之間,已能基本知足一些小型搜索引擎、關鍵字提取等場合運用。

性能:45Kb左右的文本切詞時間是 0.026 秒,大概是 1.5MB 文本 / 秒,

語言和平臺:SCWS 採用純  C  代碼開發,以  Unix-Like OS  爲主要平臺環境,提供共享函數庫,方便植入各類現有軟件系統。此外它支持  GBK , UTF-8 ,BIG5  等漢字編碼。支持 PHP4 和PHP 5 。

版本列表


Friso

官網http://code.google.com/p/friso/

friso是使用c語言開發的一箇中文分詞器,使用流行的mmseg算法實現。徹底基於模塊化設計和實現,能夠很方便的植入到其餘程序中,例如:MySQL,PHP等。而且提供了一個php中文分詞擴展robbe。

特性:

只支持UTF-8編碼。【源碼無需修改就能在各類平臺下編譯使用,加載完20萬的詞條,內存佔用穩定爲14M。】。

mmseg四種過濾算法,分詞準確率達到了98.41%。

支持自定義詞庫。在dict文件夾下,能夠隨便添加/刪除/更改詞庫和詞庫詞條,而且對詞庫進行了分類。

詞庫使用了friso的Java版本jcseg的簡化詞庫。

支持中英混合詞的識別。例如:c語言,IC卡。

很好的英文支持,電子郵件,網址,小數,分數,百分數。

支持阿拉伯數字基本單字單位的識別,例如2012年,5噸,120斤。

自動英文圓角/半角,大寫/小寫轉換。而且具備很高的分詞速度:簡單模式:3.7M/秒,複雜模式:1.8M/秒。 

 

HTTPCWS:

PHPCWS 是一款開源的 PHP 中文分詞擴展,目前僅支持 Linux/Unix 系統。

算法:PHPCWS 先使用「ICTCLAS 3.0  共享版中文分詞算法 」 的 API 進行初次分詞處理,再使用自行編寫的 「 逆向最大匹配算法 」 對分詞和進行詞語合併處理,並增長標點符號過濾功能,得出分詞結果。 ICTCLAS 3.0  商業版是收費的,而免費提供的 ICTCLAS 3.0  共享版不開源,詞庫是根據人民日報一個月的語料得出的,不少詞語不存在。因此本人對 ICTCLAS 分詞後的結果,再採用逆向最大匹配算法,根據本身補充的一個 9 萬條詞語的自定義詞庫(與 ICTCLAS 詞庫中的詞語不重複),對 ICTCLAS 分詞結果進行合併處理,輸出最終分詞結果。因爲 ICTCLAS 3.0  共享版只支持 GBK 編碼,所以,若是是 UTF-8 編碼的字符串,能夠先用 PHP 的 iconv 函數轉換成 GBK 編碼,再用 phpcws_split 函數進行分詞處理,最後轉換回 UTF-8 編碼。

性能:5 8字節的一句話 ——「2009 年 2 月 13 日,我編寫了一款PHP 中文分詞擴展: PHPCWS 1.0.0。 」 ,分詞速度只需 0.0003 秒。對於那些採用二元交叉切分的搜索引擎, PHPCWS 用在前端搜索層對用戶輸入的搜索關鍵字、短語進行分詞處理,一樣適合。 PHPCWS 開發的目的正在於此,對於短句、小文本中文分詞切分,速度很是之快。

 

libmmseg

語言和平臺: 用C++ 編寫的開源的中文分詞軟件, libmmseg 主要被做者用來實現 Sphinx 全文檢索軟件的中文分詞功能,所以做者給 Sphinx 提供了一個補丁文件,可讓 Sphinx 集成 libmmseg ,從而支持對於中文文章的全文檢索功能。 libmmseg 從 0.7.2版本開始,做者提供了 ruby 調用的接口,因此咱們能夠直接在ruby 程序裏面調用 libmmseg 進行分詞了。特別是咱們能夠用 ferret 去調用 libmmseg 分詞功能,從而讓 ruby 原生支持中文的全文檢索。

算法 :「基於詞庫的最大匹配算法 」

性能:分詞速度爲每秒300KB左右。

 

OpenCLAS

是一個開源的中文詞法分析庫。

主要功能:其中包括了中文分詞、詞性標註等功能。系統使用基於機率的多層HMM 。能夠對已登陸詞和未登陸詞進行識別分析。OpenCLAS是對原有的 ICTCLAS ( 中科院中文詞法分析系統 ) 進行的重寫。 OpenCLAS 將不包含任何 ICTCLAS 中的源代碼,而且以 BSD 協議發佈。所以其代碼能夠在知足 BSD 協議的前提下,用於包括商用在內的各類場合。OpenCLAS將包含三個語言分支,C++, Java 和 C# 。 ( 目前只實現了 C++ 的版本 ) 。

 

CRF++(上海交大)

項目網址:http://code.google.com/p/crfpp/

詳細介紹:http://crfpp.googlecode.com/svn/trunk/doc/index.html

我的主頁:http://bcmi.sjtu.edu.cn/~zhaohai/index.ch.html

 

參考原文地址:

http://ling0322.info/2013/02/13/cws-intro.html

http://www.onexin.net/to-achieve-the-18-chinese-word-segmentation-tool/

相關文章
相關標籤/搜索