📄 read me.txt
字号:
语言模型训练:
类HMM
Add_delta_train 第一个参数为训练函数名,第二个函数为lambda数
先对训练语料统计所有状态跳转、状态到输出的出现频率。再对它们进行Add_delta平滑。在计算概率前,需要先对概率矩阵初始化为一个最小值。
Hold_out_train 第一个参数为训练函数名,第二个为训练集占整个训练语料的比例
分别对训练集和留存集的数据统计状态跳转、状态到输出的出现频率。然后统计训练集中某个状态跳转(或状态到输出)的频率,用一个map<int,vector<node>>来储存。Int是出现频率,node是该点在训练集中的位置。然后对照map,在留存集中找到相应的点,并计算概率。
但是这里有一点值得注意:留存平滑求得的是共现概率,而不是HMM所假设的条件概率。尝试用p(w,pos)/p(pos)来取代。
AllSeg 全切分函数,参数为要切分的句子
typedef struct { typedef struct{
int Pre_NodeId; string str;
int Pre_TagId; int start; //该词在整个句子中的起始位置
double Score; int end; //该词在整个句子中的结束位置
}TagNode; TagNode * tagnode;
}WordNode;
用两个for循环嵌套找到所有在词典中存在的词的切分,把每个词都按照WordNode的格式储存。
ViterbiDecoder 韦特比解码
对于AllSeg分割产生的Words向量,通过找到每个点的后继点,同时计算它们之间的跳转概率以及状态到输出的概率。并将每个前驱到该点的某一个状态的概率最大值及路径予以保留。在到达终点<EOS>后,再从后往前走,按照最大的概率得到找到最优路径,保留在向量RWList里。
其中最优路径保留的每个点结构为:
typedef struct {
string str;
string curTag;
int start;
int end;
int preNode;
int preTag;
}ResultWord;
test 第一个参数是标准答案,第二个参数是要输出的文件流
测试时,先把标准答案进行处理,压入一个向量Answer里,和RWList结构一样。再对两个向量进行比较。比较时,对于某一个测试生成的词,利用最长公共子串匹配原则,判断是否分割正确。只有在分割正确的前提下,再判断POS是否标注正确。
Bigram训练:
Bigram训练和HMM训练过程相似,而且只有一个状态跳转概率需要计算。只是由于它的状态跳转是一个词到词的转换,如果直接建立一个大矩阵,要消耗相当大的内存。所以主要是考虑如何储存频率和模型的问题。
解码过程和HMM也很相近,而且还要简单。因为没有了词性标注这一块,对每个点只需要保留该点的前驱到它的最大的概率得分和路径即可。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -