hmm(隱馬爾可夫模型)是用來描述隱含未知引數的統計模型,舉乙個經典的例子:乙個東京的朋友每天根據天氣決定當天的活動中的一種,我每天只能在twitter上看到她發的推「啊,我前天公園散步、昨天購物、今天清理房間了!」,那麼我可以根據她發的推特推斷東京這三天的天氣。在這個例子裡,顯狀態是活動,隱狀態是天氣。
2023年11月23日更新:任何乙個hmm都可以通過下列五元組來描述: :param obs:觀測序列我已利用hmm角色標註實現了中國人名、翻譯人名、日本人名、地名、機構名等命名實體的識別,請參考此目錄命名實體識別。
: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,
for y in v[0].keys():
print "%.5s: " % y,
for t in range(len(v)):
print "%.7s" % ("%f" % v[t][y]),
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 2rainy: 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 是詞彙基本的語法範疇,通常也稱為詞類,主要用來描述乙個詞在上下文的作用。例如,描述乙個概念的詞就是名詞,在下文引用這個名詞的詞就是代詞。有的詞性經常會出現一些新的詞,例如名詞,這樣的詞性叫做開放式詞性。另外一些詞性中的詞比較固定,例如代詞,這樣的詞性叫做...