jieba 同义词_jieba分词详解
引言
“結巴”分詞是一個Python 中文分詞組件,參見https://github.com/fxsjy/jieba
可以對中文文本進行分詞、詞性標注、關鍵詞抽取等功能,并且支持自定義詞典。
本文包括以下內容:
1、jieba分詞包的安裝
2、jieba分詞的使用教程
3、jieba分詞的工作原理與工作流程
4、jieba分詞所涉及到的HMM、TextRank、TF-IDF等算法介紹
安裝
可以直接使用pip來進行安裝:
sudo pip install jieba
或者
sudo pip3 install jieba
簡單使用
分詞
對一句話進行分詞
import jieba
text = "征戰四海只為今日一勝,我不會再敗了。"
# jieba.cut直接得到generator形式的分詞結果
seg = jieba.cut(text)
print(' '.join(seg))
# 也可以使用jieba.lcut得到list的分詞結果
seg = jieba.lcut(text)
print(seg)
征戰 四海 只 為 今日 一勝 , 我 不會 再敗 了 。
['征戰', '四海', '只', '為', '今日', '一勝', ',', '我', '不會', '再敗', '了', '。']
命令行進行分詞
python -m jieba input.txt > output.txt
詞性分析
import jieba.posseg as posseg
text = "征戰四海只為今日一勝,我不會再敗了。"
# generator形式形如pair(‘word’, ‘pos’)的結果
seg = posseg.cut(text)
print([se for se in seg])
# 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')]
關鍵詞抽取
關鍵詞抽取有兩種算法,基于TF-IDF和基于TextRank:
import jieba.analyse as analyse
text = "征戰四海只為今日一勝,我不會再敗了。"
# TF-IDF
tf_result = analyse.extract_tags(text, topK=5) # topK指定數量,默認20
print(tf_result)
# TextRank
tr_result = analyse.textrank(text, topK=5) # topK指定數量,默認20
print(tr_result)
['一勝', '再敗', '征戰', '四海', '今日']
['一勝', '再敗', '征戰', '四海', '今日']
完整用法
分詞
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結果的函數:
jieba.lcut(sentence,cut_all=False,HMM=True) # 精確模式
jieba.lcut(sentence,cut_all=True,HMM=True) # 全模式
jieba.lcut_for_search (sentence, HMM=True) # 搜索引擎模式
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) # 調節單個詞語的詞頻,使其能/不能被分詞開
關鍵詞抽取
關鍵詞抽取的兩個函數的完整參數為:
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有默認值,即會默認過濾某些詞性。
并行分詞
可以通過
jieba.enable_parallel(4) # 開啟并行分詞模式,參數為并行進程數,默認全部
jieba.disable_parallel() # 關閉并行分詞模式
來打開或關閉并行分詞功能。
個人感覺一般用不到,大文件分詞需要手動實現多進程并行,句子分詞也不至于用這個。
代碼研讀與工作流程分析
整體工作流程
jieba分詞主要通過詞典來進行分詞及詞性標注,兩者使用了一個相同的詞典。正因如此,分詞的結果優劣將很大程度上取決于詞典,雖然使用了HMM來進行新詞發現。
jieba分詞包整體的工作流程如下圖所示:
整體工作流程
下面將根據源碼詳細地分析各個模塊的工作流程。
在之后幾節中,我們在藍色的方框中示范了關鍵步驟的輸出樣例或詞典文件的格式樣例。在本節中都采用類似的表示方式。
分詞
jieba分詞中,首先通過對照典生成句子的有向無環圖,再根據選擇的模式不同,根據詞典尋找最短路徑后對句子進行截取或直接對句子進行截取。對于未登陸詞(不在詞典中的詞)使用HMM進行新詞發現。
a.精確模式與全模式
b.搜索引擎模式
a圖中演示了分詞的主要過程,但是其中只演示了被切分出來的一個子字符串的分詞操作過程,在實際操作流程中,將對每一個子字符串都分別進行圖中的處理,最后將切分的分詞結果與非漢字部分依次連接起來,作為最終的分詞結果。
如果開啟了HMM,那么將會連起來不在詞典中出現的連續單字進行新詞發現。比如例子中的“真好啊”,詞典中沒有這個詞,所以會拿去HMM模型中進行新詞發現;但是如果原句是“今天天氣真好”,基于詞典切分為“今天天”“真”“好”,詞典中有“真好”一詞,但是因為頻率小所以未被選擇為最佳路徑,所以“真”“好”兩個字不會被拿去做新詞發現(即便其通過HMM的結果將會是“真好”),最終分詞結果將是“今天天氣”“真”“好”。
詞典的格式應為
word1 freq1 word_type1
word2 freq2 word_type2
…
其中自定義用戶詞典中詞性word_type可以省略。
詞典在其他模塊的流程中可能也會用到,為方便敘述,后續的流程圖中將會省略詞典的初始化部分。
圖b演示了搜索引擎模式的工作流程,它會在精確模式分詞的基礎上,將長詞再次進行切分。
HMM與新詞發現
在這里我們假定讀者已經了解HMM相關知識,如果沒有可先行閱讀下一章內容中的HMM相關部分或者跳過本節。
在jieba分詞中,將字在詞中的位置B、M、E、S作為隱藏狀態,字是觀測狀態,使用了詞典文件分別存儲字之間的表現概率矩陣(finalseg/prob_emit.py)、初始概率向量(finalseg/prob_start.py)和轉移概率矩陣(finalseg/prob_trans.py)。這就是一個標準的解碼問題,根據概率再利用viterbi算法對最大可能的隱藏狀態進行求解。
HMM工作流程
上圖簡單示范了jieba分詞中新詞發現模塊的工作流程,其具體計算過程可參考附錄內容,為求頁面整齊,這里不再累述。
在最后時刻,即“啊”對應的時刻里,最大概率的為S,而
,那么隱藏狀態序列即為(BES),對應于漢字“真好啊”——即“真好”是一個詞,“啊”字單字成詞。
詞性分析
詞性分析部分與分詞模塊用了同一個基礎的分詞器,對于詞典詞的詞性,將直接從詞典中提取,但是對于新詞,詞性分析部分有一個專屬的新詞及其詞性的發現模塊。
用于詞性標注的HMM模型與用于分詞的HMM模型相似,同樣將文字序列視為可見狀態,但是隱藏狀態不再是單單的詞的位置(B/E/M/S),而變成了詞的位置與詞性的組合,如(B,v)(B,n)(S,n)等等。因此其初始概率向量、轉移概率矩陣和表現概率矩陣和上一節中所用的相比都要龐大的多,但是其本質以及運算步驟都沒有變化。
具體的工作流程如下圖所示。
a.詞性標注工作流程
b.用于HMM的概率詞典示意圖
關鍵詞提取
jieba分詞中有兩種不同的用于關鍵詞抽取的算法,分別為TextRank和TF-IDF。實現流程比較簡單,其核心在于算法本身。下面簡單地畫出實現流程,具體的算法可以參閱下一章內容。
關鍵詞提取實現流程示意圖
TextRank方法默認篩選詞性,而TF-IDF方法模型不進行詞性篩選。
【附錄】
在本章中,將會簡單介紹相關的算法知識,主要包括用于新詞發現的隱馬爾科夫模型和維特比算法、用于關鍵詞提取的TextRank和TF-IDF算法。
HMM
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分詞中所用的是解碼問題,所以此處對預測問題和學習問題不做深入探討,在下一小節中我們將繼續以本節中的例子為例,對解碼問題進行求解。
Viterbi算法
在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處聯合概率最大的路徑,加粗的紅色線條表示能使最終時刻聯合概率最大(即
)的路徑。
TF-IDF
TF-IDF(詞頻-逆文本頻率)是一種用以評估字詞在文檔中重要程度的統計方法。它的核心思想是,如果某個詞在一篇文章中出現的頻率即TF高,并且在其他文檔中出現的很少,則認為這個詞有很好的類別區分能力。
其中:
式中,分子為i詞在j文檔中出現的次數,分母為j文檔中所有字詞出現的次數之和。
式中分子為語料庫中的文件總數,分母為包含該詞的文件數目。
jieba分詞中逆文檔頻率直接由詞典讀入。
TextRank
TextRank是一種用以關鍵詞提取的算法,因為是基于PageRank的,所以先介紹PageRank。
PageRank通過互聯網中的超鏈接關系確定一個網頁的排名,其公式是通過一種投票的思想來設計的:如果我們計算網頁A的PageRank值,那么我們需要知道哪些網頁鏈接到A,即首先得到A的入鏈,然后通過入鏈給網頁A進行投票來計算A的PR值。其公式為:
其中:
要計算PR值的網頁
鏈接到Vi的網頁,即它的入鏈
Vj的PR值
所有入鏈的集合
網頁j中鏈接存在的鏈接指向的網頁的集合
其個數
d為阻尼系數,取值范圍為0-1,代表從一定點指向其他任意點的概率,一般取值0.85。
將上式多次迭代即可直到收斂即可得到結果。
TextRank算法基于PageRank的思想,利用投票機制對文本中重要成分進行排序。如果兩個詞在一個固定大小的窗口內共同出現過,則認為兩個詞之間存在連線。
TextRank算法的得分定義為:
公式1
公式與PageRank的基本相同。多次迭代直至收斂,即可得到結果。
在jieba分詞中,TextRank設定的詞窗口大小為5,將公式1迭代10次的結果作為最終權重的結果,而不一定迭代至收斂。
總結
以上是生活随笔為你收集整理的jieba 同义词_jieba分词详解的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 好东西,资料!!
 - 下一篇: LeetCode—210. 课程表 II