jieba分詞詳解_鴻煊的學習筆記
文章推薦指數: 80 %
“結巴”分詞是一個Python中文分片語件,參見https://github.com/fxsjy/jieba. 可以對中文文字進行分詞、詞性標註、關鍵詞抽取等功能,並且支援自定義 ...
MdEditor
jieba分詞詳解
語言:CN/TW/HK
時間 2021-03-2423:51:52
鴻煊的學習筆記
主題:
結巴
作者:塵囂看客
連結:https://www.jianshu.com/p/2cccb07d9a4e
來源:簡書
1引言
“結巴”分詞是一個Python中文分片語件,參見https://github.com/fxsjy/jieba
可以對中文文字進行分詞、詞性標註、關鍵詞抽取等功能,並且支援自定義詞典。
本文包括以下內容:
1、jieba分詞包的安裝
2、jieba分詞的使用教程
3、jieba分詞的工作原理與工作流程
4、jieba分詞所涉及到的HMM、TextRank、TF-IDF等演算法介紹
2安裝
可以直接使用pip來進行安裝:
pipinstalljieba
3簡單使用
3.1分詞
對一句話進行分詞
importjiebatext="征戰四海只為今日一勝,我不會再敗了。
"#jieba.cut直接得到generator形式的分詞結果seg=jieba.cut(text)print(''.join(seg))#也可以使用jieba.lcut得到list的分詞結果seg=jieba.lcut(text)print(seg)
輸出
征戰四海只為今日一勝,我不會再敗了。
['征戰','四海','只','為','今日','一勝',',','我','不會','再敗','了','。
']
命令列分詞
python-mjiebainput.txt>output.txt
3.2詞性分析
importjieba.possegaspossegtext="征戰四海只為今日一勝,我不會再敗了。
"#generator形式形如pair(‘word’,‘pos’)的結果seg=posseg.cut(text)print([seforseinseg])#list形式的結果seg=posseg.lcut(text)print(seg)
輸出
[pair('征戰','v'),pair('四海','ns'),pair('只','d'),pair('為','p'),pair('今日','t'),pair('一','m'),pair('勝','v'),pair(',','x'),pair('我','r'),pair('不會','v'),pair('再敗','v'),pair('了','ul'),pair('。
','x')][pair('征戰','v'),pair('四海','ns'),pair('只','d'),pair('為','p'),pair('今日','t'),pair('一','m'),pair('勝','v'),pair(',','x'),pair('我','r'),pair('不會','v'),pair('再敗','v'),pair('了','ul'),pair('。
','x')]
3.3關鍵詞抽取
關鍵詞抽取有兩種演算法,基於TF-IDF和基於TextRank:
importjieba.analyseasanalysetext="征戰四海只為今日一勝,我不會再敗了。
"#TF-IDFtf_result=analyse.extract_tags(text,topK=5)#topK指定數量,預設20print(tf_result)#TextRanktr_result=analyse.textrank(text,topK=5)#topK指定數量,預設20print(tr_result)
['一勝','再敗','征戰','四海','今日']['一勝','再敗','征戰','四海','今日']
4完整用法
4.1分詞
jieba分詞有三種不同的分詞模式:精確模式、全模式和搜尋引擎模式:
jieba.cut(sentence,cut_all=False,HMM=True)#精確模式jieba.cut(sentence,cut_all=True,HMM=True)#全模式jieba.cut_for_search(sentence,HMM=True)#搜尋引擎模式
對應的,函式前加l即是對應得到list結果的函式:
sentence="征戰四海只為今日一勝,我不會再敗了。
"#---------------result----------------'今天天氣真好'#精確模式'今天今天天氣天天天氣真好'#全模式'今天天天天氣今天天氣真好'#搜尋引擎模式
精確模式是最常用的分詞方法,全模式會將句子中所有可能的詞都列舉出來,搜尋引擎模式則適用於搜尋引擎使用。
具體的差別可在下一節工作流程的分析中詳述。
在上述每個函式中,都有名為HMM的引數。
這一項表示是否在分詞過程中利用HMM進行新詞發現。
關於HMM,本文附錄中將簡述相關知識。
另外分詞支援自定義字典,詞典格式和dict.txt一樣,一個詞佔一行;每一行分三部分:詞語、詞頻(可省略)、詞性(可省略),用空格隔開,順序不可顛倒。
具體使用方法為:
jieba.load_userdict(file_name)#載入自定義詞典jieba.add_word(word,freq=None,tag=None)#在程式中動態修改詞典jieba.del_word(word)jieba.suggest_freq(segment,tune=True)#調節單個詞語的詞頻,使其能/不能被分詞開
4.2關鍵詞抽取
關鍵詞抽取的兩個函式的完整引數為:
jieba.analyse.extract_tags(sentence,topK=20,withWeight=False,allowPOS=(),withFlag=False)#topK表示返回最大權重關鍵詞的個數,None表示全部#withWeight表示是否返回權重,是的話返回(word,weight)的list#allowPOS僅包括指定詞性的詞,預設為空即不篩選。
jieba.analyse.textrank(self,sentence,topK=20,withWeight=False,allowPOS=('ns','n','vn','v'),withFlag=False)#與TF-IDF方法相似,但是注意allowPOS有預設值,即會預設過濾某些詞性。
4.3並行分詞
可以通過
jieba.enable_parallel(4)#開啟並行分詞模式,引數為並行程序數,預設全部jieba.disable_parallel()#關閉並行分詞模式
來開啟或關閉並行分詞功能。
個人感覺一般用不到,大檔案分詞需要手動實現多程序並行,句子分詞也不至於用這個。
5程式碼研讀與工作流程分析
5.1整體工作流程
jieba分詞主要通過詞典來進行分詞及詞性標註,兩者使用了一個相同的詞典。
正因如此,分詞的結果優劣將很大程度上取決於詞典,雖然使用了HMM來進行新詞發現。
jieba分詞包整體的工作流程如下圖所示:
下面將根據原始碼詳細地分析各個模組的工作流程。
在之後幾節中,我們在藍色的方框中示範了關鍵步驟的輸出樣例或詞典檔案的格式樣例。
在本節中都採用類似的表示方式。
5.2分詞
jieba分詞中,首先通過對照典生成句子的有向無環圖,再根據選擇的模式不同,根據詞典尋找最短路徑後對句子進行擷取或直接對句子進行擷取。
對於未登陸詞(不在詞典中的詞)使用HMM進行新詞發現。
a圖中演示了分詞的主要過程,但是其中只演示了被切分出來的一個子字串的分詞操作過程,在實際操作流程中,將對每一個子字串都分別進行圖中的處理,最後將切分的分詞結果與非漢字部分依次連線起來,作為最終的分詞結果。
如果開啟了HMM,那麼將會連起來不在詞典中出現的連續單字進行新詞發現。
比如例子中的“真好啊”,詞典中沒有這個詞,所以會拿去HMM模型中進行新詞發現;但是如果原句是“今天天氣真好”,基於詞典切分為“今天天”“真”“好”,詞典中有“真好”一詞,但是因為頻率小所以未被選擇為最佳路徑,所以“真”“好”兩個字不會被拿去做新詞發現(即便其通過HMM的結果將會是“真好”),最終分詞結果將是“今天天氣”“真”“好”。
詞典的格式應為
word1freq1word_type1word2freq2word_type2…
其中自定義使用者詞典中詞性word_type可以省略。
詞典在其他模組的流程中可能也會用到,為方便敘述,後續的流程圖中將會省略詞典的初始化部分。
圖b演示了搜尋引擎模式的工作流程,它會在精確模式分詞的基礎上,將長詞再次進行切分。
5.3HMM與新詞發現
在這裡我們假定讀者已經瞭解HMM相關知識,如果沒有可先行閱讀下一章內容中的HMM相關部分或者跳過本節。
在jieba分詞中,將字在詞中的位置B、M、E、S作為隱藏狀態,字是觀測狀態,使用了詞典檔案分別儲存字之間的表現概率矩陣(finalseg/prob_emit.py)、初始概率向量(finalseg/prob_start.py)和轉移概率矩陣(finalseg/prob_trans.py)。
這就是一個標準的解碼問題,根據概率再利用viterbi演算法對最大可能的隱藏狀態進行求解。
上圖簡單示範了jieba分詞中新詞發現模組的工作流程,其具體計算過程可參考附錄內容,為求頁面整齊,這裡不再累述。
在最後時刻,即“啊”對應的時刻裡,最大概率的為S,而
,那麼隱藏狀態序列即為(BES),對應於漢字“真好啊”——即“真好”是一個詞,“啊”字單字成詞。
5.4詞性分析
詞性分析部分與分詞模組用了同一個基礎的分詞器,對於詞典詞的詞性,將直接從詞典中提取,但是對於新詞,詞性分析部分有一個專屬的新詞及其詞性的發現模組。
用於詞性標註的HMM模型與用於分詞的HMM模型相似,同樣將文字序列視為可見狀態,但是隱藏狀態不再是單單的詞的位置(B/E/M/S),而變成了詞的位置與詞性的組合,如(B,v)(B,n)(S,n)等等。
因此其初始概率向量、轉移概率矩陣和表現概率矩陣和上一節中所用的相比都要龐大的多,但是其本質以及運算步驟都沒有變化。
具體的工作流程如下圖所示。
5.5關鍵詞提取
jieba分詞中有兩種不同的用於關鍵詞抽取的演算法,分別為TextRank和TF-IDF。
實現流程比較簡單,其核心在於演算法本身。
下面簡單地畫出實現流程,具體的演算法可以參閱下一章內容。
TextRank方法預設篩選詞性,而TF-IDF方法模型不進行詞性篩選。
6附錄
在本章中,將會簡單介紹相關的演算法知識,主要包括用於新詞發現的隱馬爾科夫模型和維特比演算法、用於關鍵詞提取的TextRank和TF-IDF演算法。
6.1HMM
HMM即隱馬爾科夫模型,是一種基於馬爾科夫假設的統計模型。
之所以為“隱”,是因為相較於馬爾科夫過程HMM有著未知的引數。
在世界上,能看到的往往都是表象,而事物的真正狀態往往都隱含在表象之下,並且與表象有一定的關聯關係。
此處我們假設讀者已經對機器學習或統計模型等相關內容有了一個大致的瞭解,我們利用各種模型的目的在於對於給定的輸入X,能夠預測出類別Y。
生成模型通過學習聯合概率分佈P(X,Y),然後通過貝葉斯定理求解條件概率
HMM屬於生成模型的有向圖PGM,通過聯合概率建模:
其中,S、O分別表示狀態序列與觀測序列。
HMM的解碼問題為
定義在時刻t狀態為s的所有單個路徑st1中的概率最大值為
則有:
此式即為用於HMM解碼問題的Viterbi演算法的遞推式。
如果讀者還對這部分內容心存疑問,不妨先往下閱讀,下面我們將以一個比較簡單的例子對HMM及解碼演算法進行實際說明與演示,在讀完下一小節之後再回來看這些式子,或許能夠恍然大悟。
下面以一個簡單的例子來進行闡述:
假設小明有一個網友小紅,小紅每天都會在朋友圈說明自己今天做了什麼,並且假設其僅受當天天氣的影響,而當天的天氣也只受前一天天氣的影響。
於小明而言,小紅每天做了什麼是可見狀態,而小紅那裡的天氣如何就是隱藏狀態,這就構成了一個HMM模型。
一個HMM模型需要有五個要素:隱藏狀態集、觀測集、轉移概率、觀測概率和初始狀態概率。
我們定義隱藏狀態集為N,N中包括了所有有可能出現的隱藏狀態,在本例中我們認為:
定義觀測集為M,M中包括了所有可能出現在觀測中的表現狀態,在本例中我們假設:
接下來定義觀測概率矩陣:
其中,
即在第j個隱藏狀態時,表現為i表現狀態的概率。
式中的n和m表示隱藏狀態集和觀測集中的數量。
本例中在不同的天氣下,小紅要做不同事情的概率也不同,觀測概率以表格的形式呈現如下:
HMM中還定義了轉移概率矩陣:
其中
表示第i個隱藏狀態轉移為第j個隱藏狀態的概率。
本例中我們認定,其轉移概率如下圖所示:
除此之外,還需要一個初始狀態概率向量π,它表示了觀測開始時,即t=0時,隱藏狀態的概率值。
本例中我們指定π={0,0,1}。
至此,一個完整的隱馬爾科夫模型已經定義完畢了。
HMM一般由三類問題:
概率計算問題,即給定A,B,π和隱藏狀態序列,計算觀測序列的概率;
預測問題,也成解碼問題,已知A,B,π和觀測序列,求最優可能對應的狀態序列;
學習問題,已知觀測序列,估計模型的A,B,π引數,使得在該模型下觀測序列的概率最大,即用極大似然估計的方法估計引數。
在jieba分詞中所用的是解碼問題,所以此處對預測問題和學習問題不做深入探討,在下一小節中我們將繼續以本節中的例子為例,對解碼問題進行求解。
6.2Viterbi演算法
在jieba分詞中,採用了HMM進行新詞發現,它將每一個字表示為B/M/E/S分別代表出現在詞頭、詞中、詞尾以及單字成詞。
將B/M/E/S作為HMM的隱藏狀態,而連續的各個單字作為觀測狀態,其任務即為利用觀測狀態預測隱藏狀態,並且其模型的A,B,π概率已經給出在檔案中,所以這是一個標準的解碼問題。
在jieba分詞中採用了Viterbi演算法來進行求解。
Viterbi演算法的基本思想是:如果最佳路徑經過一個點,那麼起始點到這個點的路徑一定是最短路徑,否則用起始點到這點更短的一條路徑代替這段,就會得到更短的路徑,這顯然是矛盾的;從起始點到結束點的路徑,必然要經過第n個時刻,假如第n個時刻有k個狀態,那麼最終路徑一定經過起始點到時刻n中k個狀態裡最短路徑的點。
將時刻t隱藏狀態為i所有可能的狀態轉移路徑i1到i2的狀態最大值記為:
我們可以據此由初始時刻依次向後推出每一個時刻的最大概率隱藏狀態。
下面我們繼續以上一節中的例子來對viterbi演算法進行闡述:
小明不知道小紅是哪裡人,他只能通過小紅每天的活動來推斷那裡的天氣。
假設連續三天,小紅的活動依次為:“睡覺-打遊戲-逛街”,我們將據此計算最有可能的天氣情況。
我們需要得到三種天氣在第一天對應的可能出現“睡覺”的可能性,考慮到初始概率向量:
現在開始遞推三個隱藏狀態(天氣)在第二天時對應的各自可見狀態(打遊戲):
在上式中,
表示能使得
最大的前一時刻的隱藏狀態,比如
表示第一天為雨天能夠使得第二天為晴天的概率最大(也就是說如果第二天是晴天在最短路徑上的話,第一天是雨天也一定在最短路徑上,參見上文中Viterbi演算法的基本思想)
下面繼續遞推第三天(逛街)的隱藏狀態:
此時已經到了最後的時刻,我們開始回溯。
此時的最大概率為
由於
從而得到最終最有可能的隱藏狀態序列為:(雨天,雨天,晴天)。
其計算過程示意圖如下圖所示。
在圖中,線條上方的數字表示轉移概率(或初始概率),隱藏狀態點框內的數字表示表現概率,隱藏狀態點框上方的數字表示此隱藏狀態點的最大聯合概率,即
,指向隱藏節點i的紅色的線條表示使得節點i處聯合概率最大的路徑,加粗的紅色線條表示能使最終時刻聯合概率最大(即
6.3TF-IDF
TF-IDF(詞頻-逆文字頻率)是一種用以評估字詞在文件中重要程度的統計方法。
它的核心思想是,如果某個詞在一篇文章中出現的頻率即TF高,並且在其他文件中出現的很少,則認為這個詞有很好的類別區分能力。
其中
式中,分子為i詞在j文件中出現的次數,分母為j文件中所有字詞出現的次數之和。
式中分子為語料庫中的檔案總數,分母為包含該詞的檔案數目。
jieba分詞中逆文件頻率直接由詞典讀入。
要仔細瞭解TF-IDF的相關知識,可以查閱:TF-IDF原理與實踐
6.4TextRank
TextRank是一種用以關鍵詞提取的演算法,因為是基於PageRank的,所以先介紹PageRank。
PageRank通過網際網路中的超連結關係確定一個網頁的排名,其公式是通過一種投票的思想來設計的:如果我們計算網頁A的PageRank值,那麼我們需要知道哪些網頁連結到A,即首先得到A的入鏈,然後通過入鏈給網頁A進行投票來計算A的PR值。
其公式為:
其中:
d為阻尼係數,取值範圍為0-1,代表從一定點指向其他任意點的概率,一般取值0.85。
將上式多次迭代即可直到收斂即可得到結果。
TextRank演算法基於PageRank的思想,利用投票機制對文字中重要成分進行排序。
如果兩個詞在一個固定大小的視窗內共同出現過,則認為兩個詞之間存在連線。
TextRank演算法的得分定義為:
公式與PageRank的基本相同。
多次迭代直至收斂,即可得到結果。
在jieba分詞中,TextRank設定的詞視窗大小為5,將公式1迭代10次的結果作為最終權重的結果,而不一定迭代至收斂。
「其他文章」
搜尋推薦排序相關的評估指標
GraphSAGE理論與實踐
常用的損失函式總結
jieba分詞詳解
BM25演算法原理與實現
常見的啟用函式總結
詞向量評估總結與實踐
KMeans評估(如何選擇最佳的k)
xDeepFM理論與實踐
「結巴」
利用python,jieba,bm25,django,nginx半小時打造一個基本可用的中文全文檢索的搜尋引擎
C#中使用jieba.NET、WordCloudSharp製作詞雲圖
jieba分詞詳解
從零開始學自然語言處理(一)——jieba分詞
淺談結巴分詞演算法原理
文字相似性熱度統計演算法實現(一)-整句熱度統計
jieba,宇宙最強Python分詞工具使用指南
結巴分詞快速入門指南
Jieba庫實現詞性標註及小說人物角色抽取
北大開源了Python中文分詞工具包,準確度遠超Jieba
延伸文章資訊
- 1Python自然語言處理(二):使用jieba進行中文斷詞
原本打算用英文寫的,可是jieba是在斷中文,還用英文寫就有點怪XD. Jieba提供了三種分詞模式:. 精確模式:試圖將句子最精確地切開,適合文本分析。
- 2Python jieba 中文斷詞套件 - 大學生's Blog
句子可以成詞的詞語切出,速度快。 搜索引擎模式. 精確模式的基礎上,將長的詞語再切分 import jieba documents = ...
- 3jieba - PyPI
jieba. “结巴”中文分词:做最好的Python 中文分词组件. “Jieba” (Chinese for “to stutter”) Chinese text segmentation: ...
- 4Python 结巴分词(jieba)使用方法文档及示例代码 - cjavapy.com
1、结巴分词(jieba)的介绍. 1) 支持四种分词模式. 精确模式:试图将句子最精确地切开,适合文本分析;. 全模式:把句子中所有的可以成词的词语都扫描 ...
- 5fxsjy/jieba: 结巴中文分词
"Jieba" (Chinese for "to stutter") Chinese text segmentation: built to be the best Python Chinese...