Python - 知名Jieba 中文斷詞工具教學

文章推薦指數: 80 %
投票人數:10人

今天要介紹的這個算是很知名的中文斷詞工具,這個是大陸人發明的工具,並且將其開源在GitHub 上,而且有積極維護中,非常不錯。

0% 今天要介紹的這個算是很知名的中文斷詞工具,這個是大陸人發明的工具,並且將其開源在GitHub上,而且有積極維護中,非常不錯。

但是可想而知它的這個工具對簡體中文分詞會比較準確,繁體中文雖然用這工具也還可以,但是有一些像是台灣用語就比較難斷得很好。

Jieba安裝教學 conda安裝 1condainstall-cconda-forgejieba pip安裝 1pipinstalljieba 適合的Python版本3或2都支援,但是建議大家還是盡快使用Python3,畢竟Python2已經官方公佈不支援了。

Jieba原理介紹 Jieba斷詞主要是结合: 規則斷詞 主要是透過詞典,在對句子進行斷詞的時候,將句子的每個字與詞典中的詞進行匹配,找到則斷詞,否則無法斷詞。

統計斷詞 主要是看如果相連的字在不同的文本中出現的次數越多,就推斷這相連的字很可能就是一個詞。

因此就可以利用字與字相鄰出现的頻率來做統計。

當高於某一個臨界值時,便可認為此字組是一個詞語。

透過以上兩種策略,再根據Jieba文檔的技術原理說明: 使用前綴詞典進行詞圖掃描,生成所有成詞情況的有向無環圖(DAG,directedacyclicgraph) 例如:上=>上海=>上海市 再透過,使用動態規劃查找最大概率路徑 使用HMM模型(HiddenMarkovModels)找出『未登錄詞』 所謂HMM模型就是一種統計斷詞的方法,未登錄詞就是想成詞典中沒有這種詞,必須經過統計來得知新的詞語。

這邊就不在多講裡面技術的演算法是怎樣,有興趣的話可以根據關鍵字去查詢演算法。

Jieba斷詞模式 最著名的功能就是提供斷詞模式,主要分為 精確模式 將句子最精確的切開,適合文本分析 全模式 把句子中所有的可以成詞的詞語都斷出来,速度非常快。

搜索引擎模式 在精確模式的基礎上,對長的詞語再次切分,提高召回率,適合用於搜索引擎分詞。

操作方式: 透過jieba.cut()來進行斷詞,cut_all參數為True的話為全模式,預設為False,也就是精確模式 jibea.cut_for_search()是搜索引擎模式 cut()、cur_for_search()返回的結構都是一个可迭代的generator,因此使用for迴圈來取得每個斷詞。

簡體中文測試 123456789101112131415161718192021importjiebadocuments=['我来自北京清华大学','我喜欢写程式','每天发技术文章']#精確模式forsentenceindocuments:seg_list=jieba.cut(sentence)print('/'.join(seg_list))print('---------------')#全模式forsentenceindocuments:seg_list=jieba.cut(sentence,cut_all=True)print('/'.join(seg_list))print('---------------')#搜索引擎模式forsentenceindocuments:seg_list=jieba.cut_for_search(sentence)print('/'.join(seg_list)) 輸出如下: 1234567891011我/来自/北京/清华大学我/喜欢/写/程式每天/发/技术/文章---------------我/来自/北京/清华/清华大学/华大/大学我/喜欢/写/程式每天/发/技术/文章---------------我/来自/北京/清华/华大/大学/清华大学我/喜欢/写/程式每天/发/技术/文章 可以看出其實是滿準確的,尤其是精確模式,斷詞斷得很正確,而這輸出結果也可以看出精確模式、全模式、搜索引擎模式差別在哪。

繁體中文測試 123456789101112131415161718192021importjiebadocuments=['我來自北京清華大學','我喜歡寫程式','每天發技術文章']#精確模式forsentenceindocuments:seg_list=jieba.cut(sentence)print('/'.join(seg_list))print('---------------')#全模式forsentenceindocuments:seg_list=jieba.cut(sentence,cut_all=True)print('/'.join(seg_list))print('---------------')#搜索引擎模式forsentenceindocuments:seg_list=jieba.cut_for_search(sentence)print('/'.join(seg_list)) 輸出如下: 1234567891011我來/自/北京/清華大學我/喜歡/寫/程式每天/發技術/文章---------------我/來/自/北京/清/華/大/學我/喜/歡/寫/程式每天/發/技/術/文章---------------我來/自/北京/清華大學我/喜歡/寫/程式每天/發技術/文章 將簡體中文成繁體中文,可以看出精確模式下,第三句每天發技術文章斷不準確,但其他句斷的前面簡體中文一樣。

jieba.lcut()示範 也可以使用lcut(),意思跟cut()是一樣的,只是返回的型態變成list,方便使用。

123456789101112131415161718192021importjiebadocuments=['我来自北京清华大学','我喜欢写程式','每天发技术文章']#精確模式forsentenceindocuments:seg_list=jieba.lcut(sentence)print(seg_list)print('---------------')#全模式forsentenceindocuments:seg_list=jieba.lcut(sentence,cut_all=True)print(seg_list)print('---------------')#搜索引擎模式forsentenceindocuments:seg_list=jieba.lcut_for_search(sentence)print(seg_list) 輸出如下: 1234567891011['我','来自','北京','清华大学']['我','喜欢','写','程式']['每天','发','技术','文章']---------------['我','来自','北京','清华','清华大学','华大','大学']['我','喜欢','写','程式']['每天','发','技术','文章']---------------['我','来自','北京','清华','华大','大学','清华大学']['我','喜欢','写','程式']['每天','发','技术','文章'] 台灣新聞文檔測試 這是我去拿最近的新聞稿的文字: 1蘇貞昌表示,春節期間中國武漢肺炎疫情急遽升高,他在年假第一天就到中央流行疫情指揮中心聽取簡報,並宣布提升到二級開設。

年假期間,衛福部及相關機關幾乎都放棄休假,每天監控及因應各項疫情,並宣布防疫資源整備情形及最新防疫作為,隨時讓國人瞭解最新疫情發展。

因為資訊透明,應變迅速,讓國人感受到「有政府,可放心」,感謝陳其邁副院長費心督導,對於年假期間各防疫機關人員的堅守崗位,也表示肯定與感謝。

用Jieba測試台灣用語的繁體中文效果如何: 12345importjiebanews='蘇貞昌表示,春節期間中國武漢肺炎疫情急遽升高,他在年假第一天就到中央流行疫情指揮中心聽取簡報,並宣布提升到二級開設。

年假期間,衛福部及相關機關幾乎都放棄休假,每天監控及因應各項疫情,並宣布防疫資源整備情形及最新防疫作為,隨時讓國人瞭解最新疫情發展。

因為資訊透明,應變迅速,讓國人感受到「有政府,可放心」,感謝陳其邁副院長費心督導,對於年假期間各防疫機關人員的堅守崗位,也表示肯定與感謝。

'seg_list=jieba.lcut(news)print(seg_list) 輸出如下: 1['蘇貞昌','表示',',','春節','期間','中國','武漢','肺炎','疫情','急遽','升高',',','他','在','年','假','第一天','就','到','中央','流行','疫情','指揮','中心','聽取','簡報',',','並','宣布','提升','到','二級','開設','。

','年','假期','間',',','衛福部','及','相關','機關','幾乎','都','放棄','休假',',','每天','監控及','因應','各項','疫情',',','並','宣布','防疫','資源','整備','情形','及','最新','防疫','作為',',','隨時','讓','國人','瞭解','最新','疫情','發展','。

','因為','資訊','透明',',','應變','迅速',',','讓','國人','感受','到','「','有','政府',',','可','放心','」',',','感謝','陳','其邁','副','院長','費心督導',',','對','於','年','假期','間','各','防疫','機關','人員','的','堅守崗位',',','也','表示','肯定','與','感謝','。

'] 發現以下幾點事情: 武漢肺炎、年假、陳其邁,這些詞沒斷好,推斷可能大陸用語沒有這樣的用法,此外台灣的人名也一定會是新詞沒辦法被斷好。

標點符號會自動被斷出來 還好,Jieba提供自定義詞典的功能,用來避免以上的情況。

Jieba自定義詞典 如果Jieba內建詞庫沒有你要的詞,可以建立自定義的詞典 讓Jieba根據你自定義的詞典來斷出你想要的詞。

雖然可能會覺得這樣不就很HardCode嗎?沒錯就是這樣,因為大部分的情況下雖說是依賴Jieba斷詞的能力,但在特殊的名詞或者台灣用語可以採用該方法 用法:jieba.load_userdict(file_path) file_path為自定義詞典的檔案路徑 自定義詞典格式 一個词占一行,每一行分三部分:詞語、詞頻(可省略)、磁性(可省略),用空格隔開,顺序不可錯誤。

file必須為UTF-8編碼。

詞頻省略的話Jieba內建會自動計算,保證可以分出你自定義的詞頻。

簡單來說,你可以想成,你自定義的詞語一定是優先度最大,儘管跟其他有衝突,你定義的Jieba一定會優先斷出來,保證正確性。

根據以上的新聞稿,我們將武漢肺炎、年假、陳其邁,加入自定義詞典試試看有沒有辦法成功斷詞出來。

在專案路徑下新增一個檔案叫做:userdict.txt 內容如下: 123武漢肺炎年假陳其邁 程式碼如下: 1234567importjiebajieba.load_userdict('./userdict.txt')news='蘇貞昌表示,春節期間中國武漢肺炎疫情急遽升高,他在年假第一天就到中央流行疫情指揮中心聽取簡報,並宣布提升到二級開設。

年假期間,衛福部及相關機關幾乎都放棄休假,每天監控及因應各項疫情,並宣布防疫資源整備情形及最新防疫作為,隨時讓國人瞭解最新疫情發展。

因為資訊透明,應變迅速,讓國人感受到「有政府,可放心」,感謝陳其邁副院長費心督導,對於年假期間各防疫機關人員的堅守崗位,也表示肯定與感謝。

'seg_list=jieba.lcut(news)print(seg_list) 輸出結果: 1['蘇貞昌','表示',',','春節','期間','中國','武漢肺炎','疫情','急遽','升高',',','他','在','年假','第一天','就','到','中央','流行','疫情','指揮','中心','聽取','簡報',',','並','宣布','提升','到','二級','開設','。

','年','假期','間',',','衛福部','及','相關','機關','幾乎','都','放棄','休假',',','每天','監控及','因應','各項','疫情',',','並','宣布','防疫','資源','整備','情形','及','最新','防疫','作為',',','隨時','讓','國人','瞭解','最新','疫情','發展','。

','因為','資訊','透明',',','應變','迅速',',','讓','國人','感受','到','「','有','政府',',','可','放心','」',',','感謝','陳其邁','副','院長','費心督導',',','對','於','年','假期','間','各','防疫','機關','人員','的','堅守崗位',',','也','表示','肯定','與','感謝','。

'] 可以看出,年假、武漢肺炎、陳其邁被成功斷出來,但你可能會發現年假期間沒有被斷好,所以可以考慮在把年假期間加入自定義詞典裡面。

基本上,我自己覺得在還沒有自定義詞典的話,大部分的詞語也算斷得不錯,再加入自定義詞典差不多也夠了。

說實在如果只是要做特定領域的機器人,像是現在很夯的LineBot、MessengerBot,且沒有很精確的要求,其實很多機器人它可能只是用到句子斷詞的功能,藉此找到該句子的一些關鍵字,而根據關鍵字,機器人再回答相對應的句子。

所以,有時候你會發現你如果只打一個關鍵字,機器人還是回你同樣的話,通常就是這樣設計的。

而除了自定義詞典,也可以在程式碼中動態加入自定義的詞,來幫助斷詞正確性提高: jieba.add_word(‘武漢肺炎’) jieba.suggest_freq(‘武漢肺炎’,tune=True) tune的參數代表該詞語要不要被成功斷出來。

Jieba透過TF-IDF找出句子關鍵字 此外,Jieba也有提供根據TF-IDF算法來找出句子的關鍵字。

程式碼如下: 123456importjieba.analysenews='蘇貞昌表示,春節期間中國武漢肺炎疫情急遽升高,他在年假第一天就到中央流行疫情指揮中心聽取簡報,並宣布提升到二級開設。

年假期間,衛福部及相關機關幾乎都放棄休假,每天監控及因應各項疫情,並宣布防疫資源整備情形及最新防疫作為,隨時讓國人瞭解最新疫情發展。

因為資訊透明,應變迅速,讓國人感受到「有政府,可放心」,感謝陳其邁副院長費心督導,對於年假期間各防疫機關人員的堅守崗位,也表示肯定與感謝。

'tags=jieba.analyse.extract_tags(news,topK=5,withWeight=True)fortagintags:print('word:',tag[0],'tf-idf:',tag[1]) jieba.analyse.extract_tags主要有以下的參數: sentence為句子 topK代表返回TF-IDF權重最大的關鍵字,默認為20 withWeight代表是否返回關鍵字權重值,默認為False allowPOS代表指定詞性,默認為空,也就是不篩選 輸出如下: 12345word:疫情tf-idf:0.4687853402985507word:防疫tf-idf:0.4334283486630435word:機關tf-idf:0.34651500008405794word:國人tf-idf:0.34651500008405794word:感謝tf-idf:0.34651500008405794 可以看到疫情的最高,實際上句子確實也是疫情出現最多次~符合關鍵字。

此外,除了TF-IDF算法,還有提供基於TextRank算法的關鍵字抽取,這邊就不多介紹,有興趣的話可以看文檔。

Jieba詞性標註功能 透過jiba.posseg.cut()可以將句子中的每個斷詞進行詞性標註。

程式碼: 123words=jieba.posseg.cut('我喜欢写程式')forword,flaginwords:print(f'{word}{flag}') 輸出如下: 1234我r喜欢v写v程式n 至於旁邊英文字母代表甚麼詞性,需要參考官方提供的說明: 標籤 含意 標籤 含意 標籤 含意 標籤 含意 n 普通名词 f 方位名词 s 处所名词 t 时间 nr 人名 ns 地名 nt 机构名 nw 作品名 nz 其他专名 v 普通动词 vd 动副词 vn 名动词 a 形容词 ad 副形词 an 名形词 d 副词 m 数量词 q 量词 r 代词 p 介词 c 连词 u 助词 xc 其他虚词 w 标点符号 PER 人名 LOC 地名 ORG 机构名 TIME 时间 總結 總的來說,身為一個開源工具提供這麼多功能還是很棒的,儘管對於繁體中文或台灣用語不是那麼好,不過我認為解決方法就是: https://github.com/ldkrsi/jieba-zh_TW 這個是有人將Jieba內建的詞典改成台灣繁體版本,因此可以考慮用這個jieba工具,缺點就是沒辦法跟著Jieba工具持續更新 用自定義詞典來解決台灣繁體用語 使用台灣中研院開源的CkipTagger,這個我還沒用過,聽說繁體中文斷詞很不錯,改天試試看,在發文紀錄XD 此外,官方文檔也有提供多種程式語言的版本,非常的不錯。

Jieba斷詞的速度也滿快的,當然如果參考其他語言的實作可能會更快。

總得來說,如果是做簡單的機器人且沒有那麼在乎準確性,使用Jieba是還不錯的選擇,此外也可以用在文檔分析上,幫助斷詞以便之後進行更進一步的操作。

最後最後!請聽我一言! 如果你還沒有註冊LikeCoin,你可以在文章最下方看到Like的按鈕,點下去後即可申請帳號,透過申請帳號後可以幫我的文章按下Like,而Like最多可以點五次,而你不用付出任何一塊錢,就能給我寫這篇文章的最大的回饋! 相關文章 Python-jupyternotebook互動式平台介紹 Python-型態大哉問 資料分析系列-探討決策樹(1)



請為這篇文章評分?