jieba分詞流程及算法學習

jieba

Python 中文分詞庫:
github: https://github.com/fxsjy/jieba

特點

  • 支持三種分詞模式:

– 精確模式,試圖將句子最精確地切開,適合文本分析;
– 全模式,把句子中所有的可以成詞的詞語都掃描出來, 速度非常快,但是不能解決歧義;
– 搜索引擎模式,在精確模式的基礎上,對長詞再次切分,提高召回率,適合用於搜索引擎分詞。

  • 支持繁體分詞
  • 支持並行分詞。基於 python 自帶的 multiprocessing 模塊,目前暫不支持 Windows;並行分詞僅支持默認分詞器。
  • 支持自定義詞典
  • MIT 授權協議

算法

  • 基於前綴詞典實現高效的詞圖掃描,生成句子中漢字所有可能成詞情況所構成的有向無環圖 (DAG)
  • 基於 TF-IDF 算法的關鍵詞抽取
  • 基於 TextRank 算法的關鍵詞抽取
  • 對於未登錄詞,採用了基於漢字成詞能力的 HMM 模型,使用了 Viterbi 算法
  • 採用了動態規劃查找最大概率路徑, 找出基於詞頻的最大切分組合

jieba分詞流程圖

在這裏插入圖片描述

Trie 樹

Trie 字典樹/前綴樹。它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。
典型應用是用於統計、排序和保存大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。

借圖理解Trie樹結構:
例如:詞典中有“am”, “bad”,“be”,“so”,加入Trie樹後節點情況如下(當然Trie樹也可用中文節點)
在這裏插入圖片描述

建立 DAG 詞圖

Null

分詞 DAG 代碼實現

參考jieba源碼

# -*- coding:utf-8 -*-
class Trie:
	"""
	Trie 字典樹/前綴樹
	它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符串比較,查詢效率比哈希樹高。
	典型應用是用於統計、排序和保存大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。
	"""
	def __init__(self):
		self.root = {}
		self.word_end = -1

	def insert(self,word):
		curNode = self.root
		for c in word:
			if not c in curNode:
				curNode[c] = {}
			curNode = curNode[c]
		curNode[self.word_end] = True

	def search(self, word):
		curNode = self.root
		for c in word:
			if not c in curNode:
				return False
			curNode = curNode[c]

		if self.word_end not in curNode:
			return False
		return True

	def startsWith(self, prefix):
		curNode = self.root
		for c in prefix:
			if not c in curNode:
				return False
			curNode = curNode[c]
		return  True

t = Trie()
t.insert("你好")
t.insert("世界")
t.insert("世界之窗")

t.insert("北京")
t.insert("北京大學")
t.insert("大學生")
t.insert("學生")
t.insert("活動")
t.insert("中心")

print (t.root)

def get_DAG(sentence):
	DAG = {}  #DAG空字典,用來構建DAG有向無環圖
	N = len(sentence)  #賦值N詞的長度
	for k in range(N):  #創建N詞長度的列表,進行遍歷
		tmplist = []       #從字開始能在TrieNode中的匹配到的詞末尾位置所在的list
		i = k
		frag = sentence[k]   #取傳入詞中的值,例如k=0,frag=我
		#print("Debug 0 frag= %s" % frag)
		while i < N and t.startsWith(frag): #當傳入的詞,在Trie中時,就給tmplist賦值,構建字開始可能去往的所有的路徑列表
			#print("Debug: 1 frag = %s" % frag)
			tmplist.append(i)  #每個詞,在Trie中查找,查到,則將下標傳入templist中
			i += 1    #例如查找“北”,後繼續查找“我北京”是否也在語料庫中,直到查不到推出循環
			frag = sentence[k: i + 1]  #截取傳入值得詞語,i=1,時截取 我,i=2時截取我們

		if not tmplist:  #當傳入值,在語料庫中查詢不到時
			tmplist.append(k)
		DAG[k] = tmplist  #賦值DAG 詞典
	return DAG

print (get_DAG("北京大學生活動中心"))
#print (get_DAG("你好,歡迎來到世界之窗"))
print (t.root)

print log:

> {0: [0, 1, 2, 3], 1: [1], 2: [2, 3, 4], 3: [3, 4], 4: [4], 5: [5, 6], 6: [6], 7: [7, 8], 8: [8]}
> {'北': {'京': {-1: True, '大': {'學': {-1: True}}}}, '大': {'學': {'生': {-1: True}}}, '學': {'生': {-1: True}}, '活': {'動': {-1: True}}, '中': {'心': {-1: True}}}

計算全局概率Route ,基於詞頻最大切分組合

Null

隱馬爾可夫HMM 算法

與HMM模型相關的算法主要分三類,分別解決三種問題:

  1. 已知:隱含狀態序列,轉換概率,可見狀態鏈
    求解:隱含狀態鏈
    解法:Viterbi算法
    應用:輸入法 / 語音識別
  1. 已知:隱含狀態序列,轉換概率,可見狀態鏈
    求解:輸出概率(發射概率)
    解法:前/後向算法
    應用:反欺詐
  1. 已知:可見狀態鏈(觀測狀態序列)
    求解:建立包括 轉換概率 隱含狀態序列 觀測狀態序列 輸出概率 的模型
    解法:Baum -Welch 算法 (ME無監督訓練學習)
    應用:~

jieba採用Viterbi算法動態規劃得到分詞和標註:
引用小白教程幫助理解Viterbi算法:

  1. 小白給小白詳解維特比算法(一)
  2. 小白給小白詳解維特比算法(二)
  3. 貝葉斯公式由淺入深大講解—AI基礎算法入門

引用

本文所有引用及參考如下,感謝原作者的分享?

  1. jieba分詞流程之DAG、Route
  2. python 實現 trie(字典) 樹
  3. 隱馬爾科夫模型(HMM)
  4. Python第三方庫jieba(中文分詞)入門與進階(官方文檔)
  5. 小白給小白詳解維特比算法(一)
  6. 小白給小白詳解維特比算法(二)
  7. 貝葉斯公式由淺入深大講解—AI基礎算法入門
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章