自定義中文分詞

2021-10-03 15:32:22 字數 3861 閱讀 6780

基於統計的分詞

序列模型分詞

常用的分詞方法有:

基於規則的分詞是通過維護字典的方法,在切分語句時將語句中的字元與詞典進行逐一匹配去劃分詞語,是一種比較機械的分詞方式

my_dict = ["江大橋", "研究", "生命科學", "南京市", "研究生", "大橋", "科學", "課題", "南京市長", "生命", "長江大橋", "南京", "市長"]

max_length = max([len(word) for word in my_dict])

def word_cut_mm(sentence):

"""正向匹配"""

sentence = sentence.strip()

word_length = len(sentence)

cut_word_list =

while word_length > 0:

max_cut_length = min(max_length, word_length)

sub_sentence = sentence[:max_cut_length]

while max_cut_length > 0:

if sub_sentence in my_dict or max_cut_length == 1:

break

else:

max_cut_length = max_cut_length - 1

sub_sentence = sentence[:max_cut_length]

word_length = word_length - max_cut_length

sentence = sentence[max_cut_length:]

return cut_word_list

word = word_cut_mm("南京市長江大橋研究生課題是研究生命科學")

print(word)

# 輸出:['南京市長', '江大橋', '研究生', '課題', '是', '研究生', '命', '科學']

def word_cut_rmm(sentence):

"""逆向最大匹配"""

cut_word_list =

sen_length = len(sentence)

while sen_length > 0:

for max_cut_length in range(max_length, 0, -1):

if sen_length - max_cut_length < 0: continue

sub_sentence = sentence[(sen_length - max_cut_length):sen_length]

if sub_sentence in my_dict:

sen_length -= max_cut_length

break

if max_cut_length == 1:

sen_length -= 1

return cut_word_list[::-1]

word = word_cut_rmm("南京市長江大橋研究生課題是研究生命科學")

print(word)

# 輸出:['南京市', '長江大橋', '研究生', '課題', '是', '研究', '生命科學']

雙向匹配是綜合正了向匹配和逆向匹配

統計分詞是以字為最小單位,相連的字在不同文字**現的詞次越多,說明成詞的可能性越大。統計語料中相鄰的各個字組合出現的頻率,來確定此組字構成詞的可靠度。

一段文字通常有多種分隔方式 如:

c:結婚的和尚未結婚

s1:結婚/的/和尚/未/結婚

s2:結婚/的/和/尚未/結婚

求輸入c的最大概率切分路徑argmax p(s|c)(即要求的s1,s2…sk的最大值。求最大概率也是求最佳路徑的問題,一般採用的是動態規劃求最佳路徑)

p(s1|c)=p(c|s1)*p(s1)/p(c)

p(s2|c)=p(c|s2)*p(s2)/p(c)

因此比較p(s1|c)和p(s2|c)的大小就是比較p(s1)和p(s2)的大小

p(s1|c) = p(s1) =p(w1,w2...wm1)

p(s2|c) = p(s2) =p(w1,w2...wm2)

對於一元語言模型:
p(w1,w2...wm1)≈p(w1).p(w2)...p(wm1)

在w1,w2...wm1中,如果某個詞不存在,則其概率為零就導致相乘後所有的乘積都為零,一次一般會做 add-one smoothing操作

w1,w2...wm1都是大於0小於1的數,當序列比較長時,相乘後可能向下溢位變為0,因此一般會取單調遞增 log函式

於是可得:

p(s1) = p(w1,w2...wm1) = p(w1).p(w2)...p(wm1)

p(wi)=wi在語料庫出現的詞數/詞庫中的總數

logp(wi) = log(wi在語料庫出現的次數/詞庫中的總詞數) = log(wi在語料庫出現的次數)-log(詞庫中的總詞數)=log(freq wi) - logn

p(s1) = p(w1).p(w2)...p(wm1)∝logp(w1)+logp(w2)+...+logp(wm)

= (log(freq w1) - logn).(log(freq w2) - logn)...(log(freq wm1) - logn)

同理可以求出s2,比較s1和s2的大小,最終獲得分詞效果

對於二元語言模型

p(w1,w2…wm1)≈p(w1).p(w2|w1).p(w3|w2)…p(wm1|wm-1)∝logp(w1)+logp(w2|w1)+logp(w3|w2)+…+logp(wm|wm-1)

根據條件概率公式:

p(wm1|wm-1) = p(wm1,wm-1)/p(wm-1)

根據大數定律:

p(wm1,wm-1) = count(wm1,wm-1)/count(*)

p(wm-1) = count(wm-1)/count(*)

於是可得:

p(wm1|wm-1) = p(wm1,wm-1)/p(wm-1) = count(wm1,wm-1)/count(wm-1)

logp(wm1|wm-1) = logp(wm1|wm-1)= log(count(wm1,wm-1)/count(wm-1)) = log(count(wm1,wm-1)) - log(count(wm-1))

把logp(wm1|wm-1)代入logp(w1)+logp(w2|w1)+logp(w3|w2)+…+logp(wm|wm-1)即可求出s1的概率值

把分詞轉換為對句子序列中每個字的標註,根據標註對文字進行分詞,最常用的就是hmm和crf

b:標註要麼是乙個詞的開始

m:乙個詞的中間位置

e:乙個詞的結束位置

s:單個字的詞

π是初始狀態概率向量

a隱含狀態轉移概率矩陣

b發射概率矩陣

所有的狀態序列集合:s =

所有的觀測序列集合:o =

長度為t的狀態序列i:i =

i對應的觀測序列q:q =

在模型訓練階段,已知觀測序列o=,使用baum-welch演算法估計模型λ=πab的引數(或通過統計的方法獲得引數π、a、b),使得p(o|λ)的概率最大

在**階段,已知觀測序列並利用訓練階段求的的引數λ=πab,使用viterbi求給定觀測序列條件概率p(i|λo)最大狀態序列i

自定義遠端分詞

首先安裝乙個web伺服器 然後在nginx中新建乙個目錄和檔案用於儲存自定義分詞 然後啟動web伺服器即可 進入elasticsearch 7.16.3 plugins ik config目錄 編輯 ikanalyzer.cfg.xml 根據注釋內容填寫即可 http localhost es an...

IK中文分詞擴充套件自定義詞典!!!

1.基於分布式系統的自定義分詞要求與流程設計 見圖 e plan readingnote 分詞與索引 分詞 2012 4 20 2.分詞實現原理 詞典的載入過程 2.1.分詞詞典的載入過程涉及到3個類,分別是configuration類,directory類,以及dictsegment類。其中前兩個...

ES建立自定義模板,實現中文分詞

一.通過es的rest api,建立模板,設定好索引匹配,就可以了,不需要在logstash中作任何配置 推薦 get template logstash default properties version geoip location latitude longitude aliases put...