HMM與分詞 詞性標註 命名實體識別

2021-08-28 08:44:50 字數 3651 閱讀 2518

hmm(隱馬爾可夫模型)是用來描述隱含未知引數的統計模型,舉乙個經典的例子:乙個東京的朋友每天根據天氣決定當天的活動中的一種,我每天只能在twitter上看到她發的推「啊,我前天公園散步、昨天購物、今天清理房間了!」,那麼我可以根據她發的推特推斷東京這三天的天氣。在這個例子裡,顯狀態是活動,隱狀態是天氣。

2023年11月23日更新:

我已利用hmm角色標註實現了中國人名、翻譯人名、日本人名、地名、機構名等命名實體的識別,請參考此目錄命名實體識別。

任何乙個hmm都可以通過下列五元組來描述:

:param obs:觀測序列

:param states:隱狀態

:param start_p:初始概率(隱狀態)

:param trans_p:轉移概率(隱狀態)

:param emit_p: 發射概率 (隱狀態表現為顯狀態的概率)

這個例子可以用如下的hmm來描述:

states = ('rainy', 'sunny')

observations = ('walk', 'shop', 'clean')

start_probability = 

transition_probability = ,

'sunny' : ,

}emission_probability = ,

'sunny' : ,

}求解最可能的隱狀態序列是hmm的三個典型問題之一,通常用維特比演算法解決。維特比演算法就是求解hmm上的最短路徑(-log(prob),也即是最大概率)的演算法。

稍微用中文講講思路,很明顯,第一天天晴還是下雨可以算出來:

定義v[時間][今天天氣] = 概率,注意今天天氣指的是,前幾天的天氣都確定下來了(概率最大)今天天氣是x的概率,這裡的概率就是乙個累乘的概率了。

因為第一天我的朋友去散步了,所以第一天下雨的概率v[第一天][下雨] = 初始概率[下雨] * 發射概率[下雨][散步] = 0.6 * 0.1 = 0.06,同理可得v[第一天][天晴] = 0.24 。從直覺上來看,因為第一天朋友出門了,她一般喜歡在天晴的時候散步,所以第一天天晴的概率比較大,數字與直覺統一了。

從第二天開始,對於每種天氣y,都有前一天天氣是x的概率 * x轉移到y的概率 * y天氣下朋友進行這天這種活動的概率。因為前一天天氣x有兩種可能,所以y的概率有兩個,選取其中較大乙個作為v[第二天][天氣y]的概率,同時將今天的天氣加入到結果序列中

比較v[最後一天][下雨]和[最後一天][天晴]的概率,找出較大的哪乙個對應的序列,就是最終結果。

# -*- coding:utf-8 -*-

# filename: viterbi.py

# author:hankcs

# date: 2014-05-13 下午8:51

states = ('rainy', 'sunny')

observations = ('walk', 'shop', 'clean')

start_probability = 

transition_probability = ,

'sunny' : ,

}emission_probability = ,

'sunny' : ,

}# 列印路徑概率表

def print_dptable(v):

print "    ",

for i in range(len(v)): print "%7d" % i,

print

for y in v[0].keys():

print "%.5s: " % y,

for t in range(len(v)):

print "%.7s" % ("%f" % v[t][y]),

print

def viterbi(obs, states, start_p, trans_p, emit_p):

""":param obs:觀測序列

:param states:隱狀態

:param start_p:初始概率(隱狀態)

:param trans_p:轉移概率(隱狀態)

:param emit_p: 發射概率 (隱狀態表現為顯狀態的概率)

:return:

"""# 路徑概率表 v[時間][隱狀態] = 概率

v = [{}]

# 乙個中間變數,代表當前狀態是哪個隱狀態

path = {}

# 初始化初始狀態 (t == 0)

for y in states:

v[0][y] = start_p[y] * emit_p[y][obs[0]]

path[y] = [y]

# 對 t > 0 跑一遍維特比演算法

for t in range(1, len(obs)):

newpath = {}

for y in states:

# 概率 隱狀態 =    前狀態是y0的概率 * y0轉移到y的概率 * y表現為當前狀態的概率

(prob, state) = max([(v[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]], y0) for y0 in states])

# 記錄最大概率

v[t][y] = prob

# 記錄路徑

newpath[y] = path[state] + [y]

# 不需要保留舊路徑

path = newpath

print_dptable(v)

(prob, state) = max([(v[len(obs) - 1][y], y) for y in states])

return (prob, path[state])

def example():

return viterbi(observations,

states,

start_probability,

transition_probability,

emission_probability)

print example()

0       1       2

rainy:  0.06000 0.03840 0.01344

sunny:  0.24000 0.04320 0.00259

(0.01344, ['sunny', 'rainy', 'rainy'])

具體到分詞系統,可以將天氣當成「標籤」,活動當成「字或詞」。那麼,幾個nlp的問題就可以轉化為:

hmm是乙個通用的方法,可以解決貼標籤的一系列問題。

從結果看,第二天似乎應該是天晴才對吧,天晴的概率是0.04320,下雨的概率是0.0340,難道是我理解錯了嗎? 

對,你理解錯了,0.04320是累積概率,第二天天晴是區域性最優,必須以最終(第三天)的全域性最優為準。

第一天為天晴的概率為0.24,根據這個條件,計算第二天為天晴和下雨的概率分別為0.0432,0.0384,這時候我覺得第二天應該為天晴,在這個條件下,再計算第三天為天晴和下雨的概率分別為0.00259,0.00864,所以我覺得最後的結果應該為sunny,sunny,rainy。想請教一下大神,這樣理解對不?

詞性標註 HMM

1.給定語料,統計語料中的詞性為n,片語為m。2.hmm關注3個引數 a.初始化概率 b.狀態轉移矩陣 n n c.觀測狀態概率矩陣 n m 3.狀態轉移矩陣 詞a的詞性為詞性a,詞b的詞性為詞性b,ab為相連詞,從給定的語料中統計從詞性a轉換到詞性b出現的次數 詞性a轉換到所有可能轉換的詞性的次數...

中文分詞與詞性標註

概況介紹 中文分詞與詞性標註是自然語言處理的第乙個階段,是上層處理的基礎。分詞的主要研究內容是歧義切分和未登入詞識別。歧義切分是指對同乙個文字片斷具有不同的切分方式,如 結合成分子 這句話就有好幾種切分方法,但是正確的只有一種,能正確的進行歧義切分是分詞的乙個難點。分詞的另乙個難點是未登入詞識別,未...

結巴分詞 詞性標註

1 簡介 詞性 part of speech 是詞彙基本的語法範疇,通常也稱為詞類,主要用來描述乙個詞在上下文的作用。例如,描述乙個概念的詞就是名詞,在下文引用這個名詞的詞就是代詞。有的詞性經常會出現一些新的詞,例如名詞,這樣的詞性叫做開放式詞性。另外一些詞性中的詞比較固定,例如代詞,這樣的詞性叫做...