如何使用jieba 結巴中文分詞程式(Example) - Coderwall
文章推薦指數: 80 %
近來玩了一下jieba 結巴這個Python Based 的開源中文斷詞程式,感覺大好,順手發了一些pull request,今天早上就成為contributor 了! 感覺真爽!
LastUpdated:February25,2016
·
20.01K
·
fukuball
如何使用jieba結巴中文分詞程式
#python
#jieba
前言
自然語言處理的其中一個重要環節就是中文斷詞的處理,比起英文斷詞,中文斷詞在先天上就比較難處理,比如電腦要怎麼知道「全台大停電」要斷詞成「全台/大/停電」呢?如果是英文「PoweroutagealloverTaiwan」,就可以直接用空白斷成「Power/outage/all/over/Taiwan」,可見中文斷詞真的是一個大問題啊~
這樣的問題其實已經有很多解法,比如中研院也有提供「中文斷詞系統」,但就是很難用,不僅APICall的次數有限制,還很難串,Server也常常掛掉,真不曉得為何中研院不將核心開源出來,讓大家可以一起來改善這種現象,總之我要棄中研院的斷詞系統而去了。
近來玩了一下jieba結巴這個PythonBased的開源中文斷詞程式,感覺大好,順手發了一些pullrequest,今天早上就成為contributor了!感覺真爽!每次發pullrequest總是有種莫名的爽感,既期待被merge又怕被reject,就跟告白的感覺類似啊~
這麼好用的開源中文斷詞系統,當然要介紹給大家用啊!
背後演算法
jieba中文斷詞所使用的演算法是基於TrieTree結構去生成句子中中文字所有可能成詞的情況,然後使用動態規劃(Dynamicprogramming)算法來找出最大機率的路徑,這個路徑就是基於詞頻的最大斷詞結果。
對於辨識新詞(字典詞庫中不存在的詞)則使用了HMM模型(HiddenMarkovModel)及Viterbi算法來辨識出來。
基本上這樣就可以完成具有斷詞功能的程式了,或許我之後可以找個時間寫幾篇部落格來介紹這幾個演算法。
如何安裝
推薦用pip安裝jieba套件,或者使用Virtualenv安裝(未來可能會介紹如何使用Virtualevn,這樣就可以同時在一台機器上跑不同的Python環境):
pipinstalljieba
基本斷詞用法,使用預設詞庫
SampleCode:
jieba-default-mode.py
#encoding=utf-8
importjieba
sentence="獨立音樂需要大家一起來推廣,歡迎加入我們的行列!"
print"Input:",sentence
words=jieba.cut(sentence,cut_all=False)
print"Output精確模式FullMode:"
forwordinwords:
printword
sentence="独立音乐需要大家一起来推广,欢迎加入我们的行列!"
print"Input:",sentence
words=jieba.cut(sentence,cut_all=False)
print"Output精確模式FullMode:"
forwordinwords:
printword
得到的斷詞結果會是:
獨立/音樂/需要/大家/一起/來/推廣/,/歡迎/加入/我們/的/行列
独立/音乐/需要/大家/一/起来/推广/,/欢迎/加入/我们/的/行列
據原作者的說法,使用預設詞庫的話,繁體中文的斷詞結果應該會比較差,畢竟原來的詞庫是簡體中文,但在這個例子中,我感覺是繁體中文的斷詞結果比較好,這應該只是特例,我們接下來試試看中文歌詞的斷詞結果如何。
中文歌詞斷詞,使用預設詞庫
現在我們使用回聲樂團-座右銘的歌詞作為中文斷詞測試範例,歌詞我們先做成一個純文字檔,內容如下:
lyric.txt
我沒有心
我沒有真實的自我
我只有消瘦的臉孔
所謂軟弱
所謂的順從一向是我
的座右銘
而我
沒有那海洋的寬闊
我只要熱情的撫摸
所謂空洞
所謂不安全感是我
的墓誌銘
而你
是否和我一般怯懦
是否和我一般矯作
和我一般囉唆
而你
是否和我一般退縮
是否和我一般肌迫
一般地困惑
我沒有力
我沒有滿腔的熱火
我只有滿肚的如果
所謂勇氣
所謂的認同感是我
隨便說說
而你
是否和我一般怯懦
是否和我一般矯作
是否對你來說
只是一場遊戲
雖然沒有把握
而你
是否和我一般退縮
是否和我一般肌迫
是否對你來說
只是逼不得已
雖然沒有藉口
SampleCode:
jiebacutlyric.py
#encoding=utf-8
importjieba
content=open('lyric.txt','rb').read()
print"Input:",content
words=jieba.cut(content,cut_all=False)
print"Output精確模式FullMode:"
forwordinwords:
printword
得到的斷詞結果會是:
我/沒/有心/我/沒/有/真實/的/自我/我/只有/消瘦/的/臉孔/所謂/軟弱/所謂/的/順/從/一向/是/我/的/座/右銘/而/我/沒有/那/海洋/的/寬闊/我/只要/熱情/的/撫/摸/所謂/空洞//所謂/不安全感/是/我/的/墓誌/銘/而/你/是否/和/我/一般/怯懦/是否/和/我/一般/矯作/和/我/一般/囉/唆/而/你/是否/和/我/一般/退縮/是否/和/我/一般/肌迫/一般/地/困惑/我/沒/有力/我/沒/有/滿腔/的/熱火/我/只有/滿肚/的/如果/所謂/勇氣/所謂/的/認/同感/是/我/隨便/說/說/而/你/是否/和/我/一般/怯懦/是否/和/我/一般/矯作/是否/對/你/來/說/只是/一場/遊戲/雖然/沒/有把握/而/你/是否/和/我/一般/退縮/是否/和/我/一般/肌迫/是否/對/你/來/說/只是/逼不得已/雖然/沒有/藉口
我們可以從結果看出斷詞已經開始出了一些問題,比如「座右銘」被斷成了「座/右銘」,「墓誌銘」被斷成了「墓誌/銘」,這應該就是因為預設詞庫是簡體中文所造成,因此繁體中文的斷詞結果會比較差,還好jieba也提供了可以切換詞庫的功能,並提供了一個繁體中文詞庫,所以我們可以使用切換詞庫的功能來改善斷詞結果。
中文歌詞斷詞,使用繁體詞庫
SampleCode:
jiebacutlyric_zh.py
#encoding=utf-8
importjieba
jieba.set_dictionary('dict.txt.big')
content=open('lyric.txt','rb').read()
print"Input:",content
words=jieba.cut(content,cut_all=False)
print"Output精確模式FullMode:"
forwordinwords:
printword
我們在程式中多加一行jieba.set_dictionary('dict.txt.big'),這樣就可以將斷詞詞庫切換到dic.txt.big這個檔案。
得到的斷詞結果會是:
我/沒有/心/我/沒有/真實/的/自我/我/只有/消瘦/的/臉孔/所謂/軟弱/所謂/的/順從/一向/是/我/的/座右銘/而/我/沒有/那/海洋/的/寬闊/我/只要/熱情/的/撫摸/所謂/空洞/所謂/不安全感/是/我/的/墓誌銘/而/你/是否/和/我/一般/怯懦/是否/和/我/一般/矯作/和/我/一般/囉唆/而/你/是否/和/我/一般/退縮/是否/和/我/一般/肌迫/一般/地/困惑/我/沒有/力/我/沒有/滿腔/的/熱火/我/只有/滿肚/的/如果/所謂/勇氣/所謂/的/認同感/是/我/隨便說說/而/你/是否/和/我/一般/怯懦/是否/和/我/一般/矯作/是否/對/你/來說/只是/一場/遊戲/雖然/沒有/把握/而/你/是否/和/我/一般/退縮/是否/和/我/一般/肌迫/是否/對/你/來說/只是/逼不得已/雖然/沒有/藉口
我們可以看到「座右銘」成功斷成「座右銘」了!「墓誌銘」也成功斷成「墓誌銘」了!果然切換成繁體中文詞庫還是有用的!
台語歌詞斷詞,使用繁體詞庫
既然中文歌詞斷詞能夠得到不錯的斷詞結果了,那我們來試試看台語歌詞斷詞會是如何?在這邊我們使用滅火器-島嶼天光的歌詞作為台語斷詞測試範例,歌詞我們先做成一個純文字檔,內容如下:
lyric_tw.txt
親愛的媽媽
請你毋通煩惱我
原諒我
行袂開跤
我欲去對抗袂當原諒的人
歹勢啦
愛人啊
袂當陪你去看電影
原諒我
行袂開跤
我欲去對抗欺負咱的人
天色漸漸光
遮有一陣人
為了守護咱的夢
成做更加勇敢的人
天色漸漸光
已經不再驚惶
現在就是彼一工
換阮做守護恁的人
已經袂記
是第幾工
請毋通煩惱我
因為阮知道
無行過寒冬
袂有花開的一工
天色漸漸光
天色漸漸光
已經是更加勇敢的人
天色漸漸光
咱就大聲來唱著歌
一直到希望的光線
照光島嶼每一個人
天色漸漸光
咱就大聲來唱著歌
日頭一爬上山
就會使轉去啦
現在是彼一工
勇敢的台灣人
SampleCode:
jiebacutlyriczhtw.py
#encoding=utf-8
importjieba
jieba.set_dictionary('dict.txt.big')
content=open('lyric_tw.txt','rb').read()
print"Input:",content
words=jieba.cut(content,cut_all=False)
print"Output精確模式FullMode:"
forwordinwords:
printword
得到的斷詞結果會是:
親愛/的/媽媽/請/你/毋通/煩惱/我/原諒/我/行袂/開跤/我/欲/去/對抗/袂/當/原諒/的/人/歹勢/啦/愛人/啊/袂/當/陪你去/看/電影/原諒/我/行袂/開跤/我/欲/去/對抗/欺負/咱/的/人/天色/漸漸/光/遮有/一陣/人/為/了/守護/咱/的/夢/成/做/更加/勇敢的人/天色/漸漸/光/已經/不再/驚惶/現在/就是/彼一工/換阮/做/守護/恁/的/人/已經/袂/記/是/第幾/工/請/毋通/煩惱/我/因為/阮/知道/無行過/寒冬/袂/有/花開/的/一工/天色/漸漸/光/天色/漸漸/光/已經/是/更加/勇敢的人/天色/漸漸/光/咱/就/大聲/來/唱/著歌/一直/到/希望/的/光線/照光/島嶼/每/一個/人/天色/漸漸/光/咱/就/大聲/來/唱/著歌/日頭/一爬/上山/就/會/使/轉去/啦/現在/是/彼/一工/勇敢/的/台灣/人
原本猜想結果應該會蠻差的,畢竟詞庫中沒有台語的用詞,但是因為HMM的關係猜出了一些新詞,讓我們還是得到不錯的結果,「袂當」斷成了「袂」「當」,「袂記」斷成了「袂」「記」,「袂有」斷成了「袂」「有」等等,我們要如何改善這些結果呢?
jieba提供了一個功能讓使用者可以增加自定義詞庫,這種無法用HMM判斷出來的新詞就可以得到改善,我們就來試試看吧!
台語歌詞斷詞,使用繁體詞庫加自定義詞庫
首先我們新增一個純文字檔建立自定義詞庫,格式如下:
userdict.txt
行袂開跤2v
袂當4d
袂記4v
袂有4d
唱著4v
每一個4m
會使70d
其中每一行代表一筆語料資料,首先填上自定義詞如:「袂當」、「袂記」,然後填上權重,權重值可以依照斷詞結果做自己想做的調整,最後填上詞性,但詞性非必要填寫,詞性列表可以參考词性对照说明.中科院版本。
SampleCode:
jiebacutlyriczhtw_custom.py
#encoding=utf-8
importjieba
jieba.set_dictionary('dict.txt.big')
jieba.load_userdict("userdict.txt")
content=open('lyric_tw.txt','rb').read()
print"Input:",content
words=jieba.cut(content,cut_all=False)
print"Output精確模式FullMode:"
forwordinwords:
printword
我們在程式中多加一行jieba.load_userdict("userdict.txt"),這樣就可以將自定義詞庫加進來了,超級簡單的。
得到的斷詞結果會是:
親愛/的/媽媽/請/你/毋通/煩惱/我/原諒/我/行袂開跤/我/欲/去/對抗/袂當/原諒/的/人/歹勢/啦/愛人/啊/袂當/陪你去/看/電影/原諒/我/行袂開跤/我/欲/去/對抗/欺負/咱/的/人/天色/漸漸/光/遮有/一陣/人/為/了/守護/咱/的/夢/成/做/更加/勇敢的人/天色/漸漸/光/已經/不再/驚惶/現在/就是/彼一工/換阮/做/守護/恁/的/人/已經/袂記/是/第幾/工/請/毋通/煩惱/我/因為/阮/知道/無行過/寒冬/袂有/花開/的/一工/天色/漸漸/光/天色/漸漸/光/已經/是/更加/勇敢的人/天色/漸漸/光/咱/就/大聲/來/唱著/歌/一直/到/希望/的/光線/照光/島嶼/每/一個/人/天色/漸漸/光/咱/就/大聲/來/唱著/歌/日頭/一爬/上山/就/會使/轉去/啦/現在/是/彼/一工/勇敢/的/台灣/人
完美!
取出斷詞詞性
大部份的斷詞系統都可以列出斷詞的詞性,jieba也有這個功能,但結果可能不是那麼好,這其實是跟所使用的語料庫有關係,不過既然是OpenSource,希望未來能有語言學家可以加入,讓jieba可以得到更好的效果。
SampleCode:
jiebacutlyriczhflag.py
#encoding=utf-8
importjieba
importjieba.possegaspseg
jieba.set_dictionary('dict.txt.big')
content=open('lyric.txt','rb').read()
print"Input:",content
words=pseg.cut(content)
print"Output精確模式FullMode:"
forwordinwords:
printword.word,word.flag
得到的結果會是:
我r
沒有x
心n
我r
沒有x
真實x
的uj
自我r
...
取出斷詞位置
有時我們會需要得到斷詞在文章中的位置:
SampleCode:
jiebacutlyriczhtokenize.py
#encoding=utf-8
importjieba
jieba.set_dictionary('dict.txt.big')
content=open('lyric.txt','rb').read()
print"Input:",content
words=jieba.tokenize(unicode(content,'utf-8'))
print"Output精確模式FullMode:"
fortkinwords:
print"word%s\t\tstart:%d\t\tend:%d"%(tk[0],tk[1],tk[2])
得到的結果會是:
word我start:0end:1
word沒有start:1end:3
word心start:3end:4
wordstart:4end:5
word我start:5end:6
word沒有start:6end:8
word真實start:8end:10
word的start:10end:11
word自我start:11end:13
...
取出文章中的關鍵詞
jieba使用了tf-idf方法來實作萃取出文章中關鍵詞的功能:
SampleCode:
jiebacutlyriczhkeyword.py
#encoding=utf-8
importjieba
importjieba.analyse
jieba.set_dictionary('dict.txt.big')
content=open('lyric.txt','rb').read()
print"Input:",content
tags=jieba.analyse.extract_tags(content,10)
print"Output:"
print",".join(tags)
程式中的jieba.analyse.extract_tags(content,10),就是告訴jieba我們要從這個文章中取出前10個tf-idf值最大的關鍵詞。
得到的結果會是:
沒有,所謂,是否,一般,雖然,退縮,肌迫,矯作,來說,怯懦
一開始使用這個功能的時候,會不知道jieba的idf值是從哪裡來的,看了一下soucecode才知道原來jieba有提供一個idf的語料庫,但在實務上每個人所使用的語料庫可能會不太一樣,有時我們會想要使用自己的idf語料庫,stopwords的語料庫也可能會想換成自己的,比如目前的結果中,最重要的「座右銘」並沒有出現在關鍵詞裡,我就會想要將「座右銘」加到idf語料庫,並讓idf值高一點,而「沒有」這個關鍵詞對我來說是沒有用的,我就會想把它加到stopwords語料庫,這樣「沒有」就不會出現在關鍵詞裡。
可惜目前pip安裝的jieba版本並不能切換idf及stopwords語料庫,所以我才會修改了一下jieba,讓它可以支援idf及stopwords語料庫的切換,目前在github上的版本已經可以支援idf及stopwords切換的功能了!
結語
使用了jieba之後,其實有蠻深的感嘆,其實中研院的斷詞核心必非不好,想要收費也不是問題,但是API做得這麼差,根本就沒人有信心敢花錢下去使用這樣不可靠的系統,目前又有jieba這樣的opensourceproject,中研院的斷詞系統前途堪慮啊!
#python
#jieba
Writtenby
fukuball
SayThanks
Respond
Relatedprotips
FlattenalistoflistsinonelineinPython
325.3K
8
RemoteAccesstoIPythonNotebooksviaSSH
288.6K
23
Emulatedo-whileloopinPython
252.1K
4
1Response
Addyourresponse
hopingup
good
over1yearago
·
Haveafreshtip?SharewithCoderwallcommunity!
Post
Postatip
Best
#Python
Authors
terrasea
325.1K
#python
#Dart
#Java
cheglastgnat
288.2K
#python
#shell
#c++
projectcleverweb
274.4K
#python
#javascript
#css
saji89
252.1K
#python
#mantis
#linux
lotia
198K
#python
#OpenSource
#Shell
RelatedTags
#python
#jieba
Sponsoredby
#native_company#
#native_desc#
#native_cta#
AwesomeJob
SeeAllJobs
Postajobforonly
$299
Sponsoredby#native_company#—LearnMore
#native_title#
#native_desc#
#native_cta#
延伸文章資訊
- 1Python自然語言處理(二):使用jieba進行中文斷詞
结巴中文分词. Contribute to fxsjy/jieba development by creating an account on GitHub. ... Jieba提供了三種分詞模...
- 2Python jieba 中文斷詞套件 - 大學生's Blog
jieba中文斷詞套件. 结巴中文分词. https://github.com/fxsjy/jieba. 交大資管開發的結巴(jieba)斷詞台灣繁體特化版本.
- 3Python 结巴分词(jieba)使用方法文档及示例代码 - cjavapy.com
本文主要介绍Python中,结巴分词(jieba)的使用相关介绍文档,使用结巴分词(jieba)进行分词的方法,以及相关的示例代码。
- 4python 結巴分詞(jieba)詳解 - 程式人生
“結巴”中文分詞:做最好的Python 中文分片語件 ... Chinese text segmentation: built to be the best Python Chinese wor...
- 5筆記for Python (Jieba + Wordcloud) | by Jacky Lu | Medium
結巴(Jieba)是目前其中一個python的中文分詞模組; 支援簡體中文和繁體中文; 可自定義詞庫; 可分析關鍵詞(利用TF-IDF); 可作詞性分析但目前成效尚待商榷 ...