一階HMM詞性標註

2021-06-16 10:08:26 字數 3690 閱讀 7666

手頭的語料庫依然是msr_training.utf8和msr_test.utf8,它來自於自于sighan bakeoff 2005的 icwb2-data.rar

1.rmspace.cpp研究院的訓練文件是已經分好詞,但我們並不需要這個結果,我們要使用計算所有分詞系統重新進行分詞並進行詞性標註,所以第一步要把訓練文件中行內的空格去掉。

#include#include#include#includeusing namespace std;

int main(int argc,char *argv)

string filename = argv[1];

string outfile = filename + ".ws";

string initpath = "/home/orisun/master/ictclas50_linux_rhas_32_c/api";

if (!ictclas_init(initpath.c_str()))

ictclas_fileprocess(filename.c_str(), outfile.c_str(), code_type_utf8,1);

ictclas_exit();

return 0;

}

4.由於我們要做的是詞性標註,所以先要對測試文件進行分詞。仍然使用wordseg.cpp。

5.rmpos.cpp計算所的分詞系統在分詞的同時也做了詞性標註(修改配置檔案configure.xml是不起作用的),所以現在還得把測試文字中標註好的詞性去掉。

#include#include#include#includeusing namespace std;

int main(int argc,char *argv)

ofs<6.對訓練文字(即第3步的輸出)也實行rmpos.cpp。

7.createdict.cpp第5步和第6步生成了訓練集和測試集中出現的所有詞語和標點符號,現在要把它們都存入gdbm資料庫。

#include#include#include#include#include#includeusing namespace std;

int main(int argc,char *argv);

for(key=gdbm_firstkey(dbm_ptr);key.dptr;key=gdbm_nextkey(dbm_ptr,key))

gdbm_close(dbm_ptr);

return 0;

}

9.query.c和lookup.c(可選輔助)前者列印輸出資料庫中的所有資料,後者根據使用者輸出的key去gdbm中查詢對應的value。

#include#include#include#include#include#include#define db_file_block "dict_db"

int main(int argc,char* argv)

printf("\n");

gdbm_close(dbm_ptr);

return 0;

}

#include#include#include#include#includeint main(int argc,char *argv)

else

} gdbm_close(dbm_ptr);

return 0;

}

10.amatrix.cpp統計訓練文字(當然是第3步的輸出)生成狀態轉移矩陣和初始狀態概率矩陣,分別寫入a.mat和pi.mat。

header.h標頭檔案中主要包含ictclas的詞性標註集和good-turing平滑演算法。

#ifndef _header_h

#define _header_h

#include#include#includeusing namespace std;

const int pos_num=97; //計算所漢語詞性標記集去掉標點符號共有pos_num個元素

/*pos_num種詞性,即pos_num種狀態*/

string posarr[pos_num]=;

void goodturing(const int count,double prob,int len)

else

} map>::const_iterator iter=count_map.begin();

while(iter!=count_map.end())

else

} else

listl=(--iter)->second;

list::const_iterator itr1=l.begin();

while(itr1!=l.end())

++iter; }

//概率歸一化

double sum=0;

for(int i=0;i

#include#include#include#include#include#include#include#include#include#include"header.h"

int a[pos_num][pos_num]; //記錄狀態間轉移的次數

int pi[pos_num]; //記錄各種狀態出現的次數

inline int indexof(string search); //混淆矩陣(或稱發射矩陣)

inline int indexof(string search)

}else }

//讀取b

for(int i=0;i>word;

b[i][j]=atof(word.c_str());

} }ifs1.close();

ifs2.close();

ifs3.close();

}/*viterbi演算法進行詞性標註*/

void viterbi(vectorterms,string &result)

}q[i][j]=max*b[j][colindex];

path[i][j]=maxindex;

} }//找q矩陣最後一行的最大值

double max=-1.0;

int maxindex=-1;

for(int i=0;imax)

} //從maxindex出發,根據path矩陣找出最可能的狀態序列

stackst;

st.push(maxindex);

for(int i=row-1;i>0;--i)

//釋放二維陣列

for(int i=0;iterm_vec;

string result;

while(strstm>>term)

viterbi(term_vec,result);

ofs看一下效果吧,左邊是ictclas的pos-tagging結果,作為標準答案,右邊是我用一階hmm詞性標註的結果。

使用簡單的加1平滑:

可以看到詞性標註準確度還很低,並且"mq"貢獻了大部分的錯誤率。

使用good-turing平滑後的效果,大體上已經看不出有什麼錯誤:

詞性標註 HMM

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

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

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

一階邏輯 備忘

所有的無限迴圈小數都是有理數。即 對於論域中的所有個體,要麼它不是無限迴圈小數 要麼它是無限迴圈小數,同時是有理數。f x x是無限迴圈小數 g x x是有理數 x g 有的素數是偶數。即 存在乙個數,它是素數,同時它也是偶數。f x x是素數 g x x是偶數 x 並非所有的f都g x f x g...