中文分詞,即 Chinese Word Segmentation,即將一個漢字序列進行切分,獲得一個個單獨的詞。表面上看,分詞其實就是那麼回事,但分詞效果好很差對信息檢索、實驗結果仍是有很大影響的,同時分詞的背後實際上是涉及各類各樣的算法的。html
中文分詞與英文分詞有很大的不一樣,對英文而言,一個單詞就是一個詞,而漢語是以字爲基本的書寫單位,詞語之間沒有明顯的區分標記,須要人爲切分。根據其特色,能夠把分詞算法分爲四大類:git
下面咱們對這幾種方法分別進行總結。github
這種方法又叫做機械分詞方法、基於字典的分詞方法,它是按照必定的策略將待分析的漢字串與一個「充分大的」機器詞典中的詞條進行匹配。若在詞典中找到某個字符串,則匹配成功。該方法有三個要素,即分詞詞典、文本掃描順序和匹配原則。文本的掃描順序有正向掃描、逆向掃描和雙向掃描。匹配原則主要有最大匹配、最小匹配、逐詞匹配和最佳匹配。web
此種方法優勢是簡單,易於實現。但缺點有不少:匹配速度慢;存在交集型和組合型歧義切分問題;詞自己沒有一個標準的定義,沒有統一標準的詞集;不一樣詞典產生的歧義也不一樣;缺少自學習的智能性。算法
該方法的主要思想:詞是穩定的組合,所以在上下文中,相鄰的字同時出現的次數越多,就越有可能構成一個詞。所以字與字相鄰出現的機率或頻率能較好地反映成詞的可信度。能夠對訓練文本中相鄰出現的各個字的組合的頻度進行統計,計算它們之間的互現信息。互現信息體現了漢字之間結合關係的緊密程度。當緊密程 度高於某一個閾值時,即可以認爲此字組可能構成了一個詞。該方法又稱爲無字典分詞。bash
該方法所應用的主要的統計模型有:N 元文法模型(N-gram)、隱馬爾可夫模型(Hiden Markov Model,HMM)、最大熵模型(ME)、條件隨機場模型(Conditional Random Fields,CRF)等。微信
在實際應用中此類分詞算法通常是將其與基於詞典的分詞方法結合起來,既發揮匹配分詞切分速度快、效率高的特色,又利用了無詞典分詞結合上下文識別生詞、自動消除歧義的優勢。網絡
語義分詞法引入了語義分析,對天然語言自身的語言信息進行更多的處理,如擴充轉移網絡法、知識分詞語義分析法、鄰接約束法、綜合匹配法、後綴分詞法、特徵詞庫法、矩陣約束法、語法分析法等。dom
基於理解的分詞方法是經過讓計算機模擬人對句子的理解,達到識別詞的效果。其基本思想就是在分詞的同時進行句法、語義分析,利用句法信息和語義信息來處理歧義現象。它一般包括三個部分:分詞子系統、句法語義子系統、總控部分。在總控部分的協調下,分詞子系統能夠得到有關詞、句子等的句法和語義信息來對分詞歧義進行判斷,即它模擬了人對句子的理解過程。這種分詞方法須要使用大量的語言知識和信息。目前基於理解的分詞方法主要有專家系統分詞法和神經網絡分詞法等。ide
以上即是對分詞算法的基本介紹,接下來咱們再介紹幾個比較實用的分詞 Python 庫及它們的使用方法。
在這裏介紹幾個比較有表明性的支持分詞的 Python 庫,主要有:
專用於分詞的 Python 庫,GitHub:github.com/fxsjy/jieba,分詞效果較好。
支持三種分詞模式:
另外 jieba 支持繁體分詞,支持自定義詞典。
其使用的算法是基於統計的分詞方法,主要有以下幾種:
首先咱們來看下精確模式分詞,使用 lcut() 方法,相似 cut() 方法,其參數和 cut() 是一致的,只不過返回結果是列表而不是生成器,默認使用精確模式,代碼以下:
1234import jiebastring = '這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做'result = jieba.lcut(string)print(len(result), '/'.join(result))複製代碼
結果:
1
|
38 這個/把手/該換/了/,/我/不/喜歡/日本/和服/,/別/把手/放在/我/的/肩膀/上/,/工信處/女幹事/每個月/通過/下屬/科室/都/要/親口/交代/24/口/交換機/等/技術性/器件/的/安裝/工做
|
可見分詞效果仍是不錯的。
使用全模式分詞須要添加 cut_all 參數,將其設置爲 True,代碼以下:
12result = jieba.lcut(string, cut_all=True)print(len(result), '/'.join(result))複製代碼
結果以下:
1
|
51 這個/把手/該換/了///我/不/喜歡/日本/和服///別/把手/放在/我/的/肩膀/上///工信處/處女/女幹事/幹事/每個月/月經/通過/下屬/科室/都/要/親口/口交/交代/24/口交/交換/交換機/換機/等/技術/技術性/性器/器件/的/安裝/安裝工/裝工/工做
|
使用搜索引擎模式分詞須要調用 cut_for_search() 方法,代碼以下:
12result = jieba.lcut_for_search(string)print(len(result), '/'.join(result))複製代碼
結果以下:
1
|
42 這個/把手/該換/了/,/我/不/喜歡/日本/和服/,/別/把手/放在/我/的/肩膀/上/,/工信處/幹事/女幹事/每個月/通過/下屬/科室/都/要/親口/交代/24/口/交換/換機/交換機/等/技術/技術性/器件/的/安裝/工做
|
另外能夠加入自定義詞典,如咱們想把 日本和服 做爲一個總體,能夠把它添加到詞典中,代碼以下:
123jieba.add_word('日本和服')result = jieba.lcut(string)print(len(result), '/'.join(result))複製代碼
結果以下:
1
|
37 這個/把手/該換/了/,/我/不/喜歡/日本和服/,/別/把手/放在/我/的/肩膀/上/,/工信處/女幹事/每個月/通過/下屬/科室/都/要/親口/交代/24/口/交換機/等/技術性/器件/的/安裝/工做
|
能夠看到切分結果中,日本和服 四個字就做爲一個總體出如今結果中了,分詞數量比精確模式少了一個。
另外 jieba 還支持詞性標註,能夠輸出分詞後每一個詞的詞性,實例以下:
12words = pseg.lcut(string)print(list(map(lambda x: list(x), words)))複製代碼
運行結果:
1
|
[['這個', 'r'], ['把手', 'v'], ['該', 'r'], ['換', 'v'], ['了', 'ul'], [',', 'x'], ['我', 'r'], ['不', 'd'], ['喜歡', 'v'], ['日本和服', 'x'], [',', 'x'], ['別', 'r'], ['把手', 'v'], ['放在', 'v'], ['我', 'r'], ['的', 'uj'], ['肩膀', 'n'], ['上', 'f'], [',', 'x'], ['工信處', 'n'], ['女幹事', 'n'], ['每個月', 'r'], ['通過', 'p'], ['下屬', 'v'], ['科室', 'n'], ['都', 'd'], ['要', 'v'], ['親口', 'n'], ['交代', 'n'], ['24', 'm'], ['口', 'n'], ['交換機', 'n'], ['等', 'u'], ['技術性', 'n'], ['器件', 'n'], ['的', 'uj'], ['安裝', 'v'], ['工做', 'vn']]
|
關於詞性的說明能夠參考:gist.github.com/luw2007/601…。
SnowNLP: Simplified Chinese Text Processing,能夠方便的處理中文文本內容,是受到了 TextBlob 的啓發而寫的,因爲如今大部分的天然語言處理庫基本都是針對英文的,因而寫了一個方便處理中文的類庫,而且和 TextBlob 不一樣的是,這裏沒有用 NLTK,全部的算法都是本身實現的,而且自帶了一些訓練好的字典。GitHub地址:github.com/isnowfy/sno…。
這裏的分詞是基於 Character-Based Generative Model 來實現的,論文地址:aclweb.org/anthology//…,咱們仍是以上面的例子說明,相關使用說明以下:
123456from snownlp import SnowNLP string = '這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做's = SnowNLP(string)result = s.wordsprint(len(result), '/'.join(result))複製代碼
運行結果:
1
|
40 這個/把手/該/換/了/,/我/不/喜歡/日本/和/服/,/別把手/放在/我/的/肩膀/上/,/工/信處女/幹事/每個月/通過/下屬/科室/都/要/親口/交代/24/口/交換機/等/技術性/器件/的/安裝/工做
|
通過觀察,能夠發現分詞效果其實不怎麼理想,和服 被分開了,工信處 也被分開了,女幹事 也被分開了。
另外 SnowNLP 還支持不少功能,例如詞性標註(HMM)、情感分析、拼音轉換(Trie樹)、關鍵詞和摘要生成(TextRank)。
咱們簡單看一個實例:
123print('Tags:', list(s.tags))print('Sentiments:', s.sentiments)print('Pinyin:', s.pinyin)複製代碼
運行結果:
123Tags: [('這個', 'r'), ('把手', 'Ng'), ('該', 'r'), ('換', 'v'), ('了', 'y'), (',', 'w'), ('我', 'r'), ('不', 'd'), ('喜歡', 'v'), ('日本', 'ns'), ('和', 'c'), ('服', 'v'), (',', 'w'), ('別把手', 'ad'), ('放在', 'v'), ('我', 'r'), ('的', 'u'), ('肩膀', 'n'), ('上', 'f'), (',', 'w'), ('工', 'j'), ('信處女', 'j'), ('幹事', 'n'), ('每個月', 'r'), ('通過', 'p'), ('下屬', 'v'), ('科室', 'n'), ('都', 'd'), ('要', 'v'), ('親口', 'd'), ('交代', 'v'), ('24', 'm'), ('口', 'q'), ('交換機', 'n'), ('等', 'u'), ('技術性', 'n'), ('器件', 'n'), ('的', 'u'), ('安裝', 'vn'), ('工做', 'vn')]Sentiments: 0.015678817603646866Pinyin: ['zhe', 'ge', 'ba', 'shou', 'gai', 'huan', 'liao', ',', 'wo', 'bu', 'xi', 'huan', 'ri', 'ben', 'he', 'fu', ',', 'bie', 'ba', 'shou', 'fang', 'zai', 'wo', 'de', 'jian', 'bang', 'shang', ',', 'gong', 'xin', 'chu', 'nv', 'gan', 'shi', 'mei', 'yue', 'jing', 'guo', 'xia', 'shu', 'ke', 'shi', 'dou', 'yao', 'qin', 'kou', 'jiao', 'dai', '24', 'kou', 'jiao', 'huan', 'ji', 'deng', 'ji', 'shu', 'xing', 'qi', 'jian', 'de', 'an', 'zhuang', 'gong', 'zuo']複製代碼
THULAC(THU Lexical Analyzer for Chinese)由清華大學天然語言處理與社會人文計算實驗室研製推出的一套中文詞法分析工具包,GitHub 連接:github.com/thunlp/THUL…,具備中文分詞和詞性標註功能。THULAC具備以下幾個特色:
咱們用一個實例看一下分詞效果:
123456import thulac string = '這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做't = thulac.thulac()result = t.cut(string)print(result)複製代碼
運行結果:
1
|
[['這個', 'r'], ['把手', 'n'], ['該', 'v'], ['換', 'v'], ['了', 'u'], [',', 'w'], ['我', 'r'], ['不', 'd'], ['喜歡', 'v'], ['日本', 'ns'], ['和服', 'n'], [',', 'w'], ['別把手', 'n'], ['放', 'v'], ['在', 'p'], ['我', 'r'], ['的', 'u'], ['肩膀', 'n'], ['上', 'f'], [',', 'w'], ['工信處', 'n'], ['女', 'a'], ['幹事', 'n'], ['每個月', 'r'], ['通過', 'p'], ['下屬', 'v'], ['科室', 'n'], ['都', 'd'], ['要', 'v'], ['親口', 'd'], ['交代', 'v'], ['24', 'm'], ['口', 'q'], ['交換機', 'n'], ['等', 'u'], ['技術性', 'n'], ['器件', 'n'], ['的', 'u'], ['安裝', 'v'], ['工做', 'v']]
|
NLPIR 分詞系統,前身爲2000年發佈的 ICTCLAS 詞法分析系統,GitHub 連接:github.com/NLPIR-team/…,是由北京理工大學張華平博士研發的中文分詞系統,通過十餘年的不斷完善,擁有豐富的功能和強大的性能。NLPIR是一整套對原始文本集進行處理和加工的軟件,提供了中間件處理效果的可視化展現,也能夠做爲小規模數據的處理加工工具。主要功能包括:中文分詞,詞性標註,命名實體識別,用戶詞典、新詞發現與關鍵詞提取等功能。另外對於分詞功能,它有 Python 實現的版本,GitHub 連接:github.com/tsroten/pyn…。
使用方法以下:
123456import pynlpir pynlpir.open()string = '這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做'result = pynlpir.segment(string)print(result)
複製代碼
運行結果以下:
1[('這個', 'pronoun'), ('把', 'preposition'), ('手', 'noun'), ('該', 'pronoun'), ('換', 'verb'), ('了', 'modal particle'), (',', 'punctuation mark'), ('我', 'pronoun'), ('不', 'adverb'), ('喜歡', 'verb'), ('日本', 'noun'), ('和', 'conjunction'), ('服', 'verb'), (',', 'punctuation mark'), ('別', 'adverb'), ('把', 'preposition'), ('手', 'noun'), ('放', 'verb'), ('在', 'preposition'), ('我', 'pronoun'), ('的', 'particle'), ('肩膀', 'noun'), ('上', 'noun of locality'), (',', 'punctuation mark'), ('工', 'noun'), ('信', 'noun'), ('處女', 'noun'), ('幹事', 'noun'), ('每個月', 'pronoun'), ('通過', 'preposition'), ('下屬', 'verb'), ('科室', 'noun'), ('都', 'adverb'), ('要', 'verb'), ('親口', 'adverb'), ('交代', 'verb'), ('24', 'numeral'), ('口', 'classifier'), ('交換機', 'noun'), ('等', 'particle'), ('技術性', 'noun'), ('器件', 'noun'), ('的', 'particle'), ('安裝', 'verb'), ('工做', 'verb')]複製代碼
這裏 把手 和 和服 也被分開了。
NLTK,Natural Language Toolkit,是一個天然語言處理的包工具,各類多種 NLP 處理相關功能,GitHub 連接:github.com/nltk/nltk。
可是 NLTK 對於中文分詞是不支持的,示例以下:
12345from nltk import word_tokenize string = '這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做'result = word_tokenize(string)print(result)複製代碼
結果:
1['這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做']複製代碼
若是要用中文分詞的話,可使用 FoolNLTK,它使用 Bi-LSTM 訓練而成,包含分詞、詞性標註、實體識別等功能,同時支持自定義詞典,能夠訓練本身的模型,能夠進行批量處理。
使用方法以下:
12345import fool string = '這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做'result = fool.cut(string)print(result)複製代碼
運行結果:
1[['這個', '把手', '該', '換', '了', ',', '我', '不', '喜歡', '日本', '和服', ',', '別', '把', '手', '放', '在', '我', '的', '肩膀', '上', ',', '工信處', '女', '幹事', '每個月', '通過', '下屬', '科室', '都', '要', '親', '口', '交代', '24', '口', '交換機', '等', '技術性', '器件', '的', '安裝', '工做']]複製代碼
能夠看到這個分詞效果仍是不錯的。
另外還能夠進行詞性標註,實體識別:
1234result = fool.pos_cut(string)print(result)_, ners = fool.analysis(string)print(ners)複製代碼
運行結果:
12[[('這個', 'r'), ('把手', 'n'), ('該', 'r'), ('換', 'v'), ('了', 'y'), (',', 'wd'), ('我', 'r'), ('不', 'd'), ('喜歡', 'vi'), ('日本', 'ns'), ('和服', 'n'), (',', 'wd'), ('別', 'd'), ('把', 'pba'), ('手', 'n'), ('放', 'v'), ('在', 'p'), ('我', 'r'), ('的', 'ude'), ('肩膀', 'n'), ('上', 'f'), (',', 'wd'), ('工信處', 'ns'), ('女', 'b'), ('幹事', 'n'), ('每個月', 'r'), ('通過', 'p'), ('下屬', 'v'), ('科室', 'n'), ('都', 'd'), ('要', 'v'), ('親', 'a'), ('口', 'n'), ('交代', 'v'), ('24', 'm'), ('口', 'q'), ('交換機', 'n'), ('等', 'udeng'), ('技術性', 'n'), ('器件', 'n'), ('的', 'ude'), ('安裝', 'n'), ('工做', 'n')]][[(12, 15, 'location', '日本')]]複製代碼
語言技術平臺(Language Technology Platform,LTP)是哈工大社會計算與信息檢索研究中心歷時十年開發的一整套中文語言處理系統。LTP制定了基於XML的語言處理結果表示,並在此基礎上提供了一整套自底向上的豐富並且高效的中文語言處理模塊(包括詞法、句法、語義等6項中文處理核心技術),以及基於動態連接庫(Dynamic Link Library, DLL)的應用程序接口、可視化工具,而且可以以網絡服務(Web Service)的形式進行使用。
LTP 有 Python 版本,GitHub地址:github.com/HIT-SCIR/py…,另外運行的時候須要下載模型,模型還比較大,下載地址:ltp.ai/download.ht…。
示例代碼以下:
12345678from pyltp import Segmentor string = '這個把手該換了,我不喜歡日本和服,別把手放在個人肩膀上,工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做'segmentor = Segmentor()segmentor.load('./cws.model')result = list(segmentor.segment(string))segmentor.release()print(result)複製代碼
運行結果:
1
|
41 這個/把手/該/換/了/,/我/不/喜歡/日本/和服/,/別/把/手/放在/我/的/肩膀/上/,/工信/處女/幹事/每個月/通過/下屬/科室/都/要/親口/交代/24/口/交換機/等/技術性/器件/的/安裝/工做
|
能夠發現 工信處、女幹事 沒有正確分開。
以上即是一些分詞庫的基本使用,我的比較推薦的有 jieba、THULAC、FoolNLTK。
本資源首發於崔慶才的我的博客靜覓: Python3網絡爬蟲開發實戰教程 | 靜覓
如想了解更多爬蟲資訊,請關注個人我的微信公衆號:進擊的Coder
weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)