轉載 基於HMM模型的詞性標註

HMM,它用來描述一個含有隱含未知參數的馬爾可夫過程。其難點是從可觀察的參數中確定該過程的隱含參數(後面要討論到的Viterbi算法)。然後利用這些參數來作進一步的分析,例如模式識別。在中文信息處理方面,它主要用於詞性標註,計算機並不知道一句話中某個詞的具體詞性,需要通過相應的模型和算法來使計算機能夠識別出一句話中具體某個詞的詞性,那麼模型就是某個HMM,算法就是在此模型上的Viterbi算法。

我的工作是以北大1998年1月份的語料爲基礎,求出此HMM,然後在這個HMM的基礎之上設計Viterbi算法,實現將一句已經分好詞的句子進行詞性自動標註。下面就將我的學習成果和大家一起分享,有不對的地方請大家指正

HMM中包含的三個值分別是:初始分佈、轉移矩陣、發射矩陣。

初始分佈就是一個隱藏狀態的初始概率分佈。就詞性標註來說,初始分佈表示的是一句話中第一個詞是什麼詞性的概率分佈。

轉移矩陣:如果有N個隱藏了的狀態(詞性),那麼轉移矩陣就是一個N*N的矩陣,它的元素表示的是一種狀態轉化到另一種狀態的概率。

發射矩陣:有時也稱爲混淆矩陣,它的行表示的是狀態(詞性),它的列所表示的是(詞語),它的元素表示在給定一個詞性(n)的情況下,它是(中國)的概率。


維特比算法提供了一種有效的計算方法來分析隱馬爾科夫模型的觀察序列,並捕獲最可能的隱藏狀態序列。它利用遞歸減少計算量,並使用整個序列的上下文來做判斷,從而對包含“噪音”的序列也能進行良好的分析。
  在使用時,維特比算法對於網格中的每一個單元(cell)都計算一個局部概率,同時包括一個反向指針用來指示最可能的到達該單元的路徑。當完成整個計算過程後,首先在終止時刻找到最可能的狀態,然後通過反向指針回溯到t=1時刻,這樣回溯路徑上的狀態序列就是最可能的隱藏狀態序列了。

下面是我實現的Viterbi算法的核心代碼
typedef struct viterBiNode
{
double probity;
int backpointer;
}ViterBiNode;//算法需要用到的結構體

 

 

for(int j=0;j<num;j++)//列或者是詞
{
for(int i=0;i<N;i++)//行
{ if(j==0)//第一個詞
vbNode[i][j].probity = mynode[i].probity*MyEmitArray[i][wordLocation];

else//其他的詞
{
double mymax=0.0f;
int myloc=-1;
for(int t=0;t<N;t++)//找出前一時刻局部概率和轉移概率乘積最大的一個
{
double temp=0.0f;
temp=vbNode[t][j-1].probity*ChangeResultArray[t][i];//局部概率和轉移概率乘積
if(mymax<temp)
{
mymax=temp;//將乘下來的值最大的賦給mymax
myloc=t;//記錄反向指針
}
}
vbNode[i][j].backpointer=myloc;//求得反向指針
wordLocation=WordSearch(MyWordArray,tempstr,myWordnumber);
vbNode[i][j].probity=mymax*MyEmitArray[i][wordLocation];
//局部概率和轉移概率和觀察概率的乘積

if(j>=num-1)//最後一個詞語時可以算出結果
{
if(pMax<vbNode[i][j].probity)
{
pMax=vbNode[i][j].probity;
pPos=i;
}

}


}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章