機器學習 基於HMM的中文分詞

2021-10-03 03:10:08 字數 4737 閱讀 7973

#encoding=utf-8

'''b表示詞彙的開始

m表示詞彙的中間

e表示詞彙的尾部

s表示詞彙單獨成詞

'''class

hmm(

object):

def__init__

(self)

: self.states =

['b'

,'m'

,'e'

,'s'

] self.load_para =

false

self.a_dic =

self.b_dic =

self.pai_dic =

defgeneratepropbility

(self,path)

:'''

統計概率,生成π,a,b

'''count_dic =

#統計各個狀態的次數,用於後面的歸一化使用

definit_parameters()

:'''

初始化pai,a,b三個權重矩陣

'''for state in self.states:

self.a_dic[state]

= self.pai_dic[state]

=0.0

self.b_dic[state]

= count_dic[state]=0

defmarklaebl

(word)

:'''

為訓練資料中的每乙個字,根據其所處的位置,打標籤

text是傳入的乙個詞

'''out_text =

if(len(word)==1

):'s')

else

:#將輸入的文字轉換成標籤序列的表示

out_text +=

['b']+

['m']*

(len

(word)-2

)+['e'

]return out_text

init_parameters(

)

line_num =-1

words =

set(

)with

open

(path,

'r',encoding=

'utf-8'

)as f:

data_lines = f.readlines(

)#獲取訓練資料

#對於資料中的每一行進行處理

for line in data_lines:

line_num +=

1 line = line.strip()if

not line:

continue

word_list =

[i for i in line if i !=

" "]

words |

=set

(word_list)

#words中去除了重複的詞彙

linelist = line.split(

) line_state =

for w in linelist:

line_state.extend(marklaebl(w)

)#將每乙個詞彙轉換成標籤 此時的line_state是乙個list,表示乙個句子所有的標籤

assert

len(word_list)

==len

(line_state)

for k,v in

enumerate

(line_state)

: count_dic[v]+=1

#計算各個標籤出現的總數

if k ==0:

self.pai_dic[v]+=1

#計算各個標籤出現在第乙個位置概率

else

: self.a_dic[line_state[k-1]

][v]+=1

#a_dic詞典的第乙個索引是前乙個狀態,v表示當前狀態

#b_dic詞典的第乙個索引是當前的狀態,第二個所有是當前狀態對應的字

self.b_dic[line_state[k]

][word_list[k]

]= \

self.b_dic[line_state[k]

].get(word_list[k],0

)+1.0#轉換成概率

self.pai_dic =

self.a_dic =

for k,v in self.a_dic.items()}

#這裡使用到了加1平滑

self.b_dic =

for k,v in self.b_dic.items()}

defviterbi

(self,text,states,pai,a,b)

:'''

維特比演算法過程

'''v =

path =

for y in states:

#第一步

v[0]

[y]= pai[y]

* b[y]

.get(text[0]

,0)#第乙個引數是時間,第二個引數是對應的狀態

path[y]

=[y]

for t in

range(1

,len

(text)):

#從第二個字的標籤開始迭代

) newpath =

# 檢查b中是否有產生該字的概率

neverseen = text[t]

notin b[

's']

.keys(

)and \

text[t]

notin b[

'm']

.keys(

)and \

text[t]

notin b[

'b']

.keys(

)and \

text[t]

notin b[

'e']

.keys(

)#對於每乙個可能的狀態進行取最大值的操作

for y in states:

#這裡先計算每乙個狀態生成該字的概率pb

pb = b[y]

.get(text[t],0

)ifnot neverseen else

1.0# y0是前乙個時刻的每乙個狀態,取概率的最大值和對應的前乙個時刻的狀態

(prob,state)

=max([

(v[t-1]

[y0]

*a[y0]

.get(y,0)

*pb,y0)

for y0 in states if v[t-1]

[y0]

>0]

) v[t]

[y]= prob

#這裡更新路徑,state是前乙個時刻的狀態,y是當前時刻的狀態

newpath[y]

= path[state]

+[y]

#更新總的路徑

path = newpath

#判斷最後乙個字是單獨成詞還是屬於乙個詞的一部分

if b[

'm']

.get(text[-1

],0)

> b[

's']

.get(text[-1

],0)

:(prob,state)

=max([

(v[len

(text)-1

][y]

,y)for y in

('e'

,'m')]

)else

:(prob,state)

=max([

(v[len

(text)-1

][y]

,y)for y in states]

)return

(prob,path[state]

)def

cut(self,text)

:'''

切分過程

'''#獲取最大最大概率和狀態列表

基於規則的中文分詞

正向最大匹配 maximum match method,mm法 的基本思想為 假定分詞詞典中的最長詞有i個漢字字元,則用被處理文件的當前字串中的前i個字作為匹配字段,查詢字典。若字典中存在這樣的乙個i字詞,則匹配成功,匹配欄位被作為乙個詞切分出來。如果詞典中找不到這樣的乙個i字詞,則匹配失敗,將匹配...

機器學習 HMM 演算法

已知觀測序列o o1,ot 估計模型 a,b 的引數,使得在該模型下觀測序列概率 p o 極大似然估計的方法 樣本中時刻 t 處於狀態 i 時刻 t 1 轉移到狀態 j的頻數ai j,則轉移狀態概率矩陣ai j 的估計a ij a ij j 1na ij樣本中狀態為 j 並觀測為 k的頻數是bj k...

中文分詞 基於字標註法的分詞

中文分詞字標註通常有2 tag,4 tag和6 tag這幾種方法,其中4 tag方法最為常用。標註集是依據漢字 其中也有少量的非漢字字元 在漢語詞中的位置設計的。1.2 tag法 2 tag是一種最簡單的標註方法,標註集合為,其將詞首標記設計為b,而將詞的其他位置標記設計為i。例如詞語 重慶 的標註...