关于HMM分词的理论基础就不说了,第一,自己能力尚浅,说不好。第二,已经有说得很好的了。参考:
我这里自己实现了用msr_training.utf8 用以训练HMM的转移矩阵。
代码贴出来吧:
package com.xh.training;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;import java.util.HashMap;/* * 根据语料的结果训练HMM模型的状态转移矩阵 * 一共有四个状态: * B:一个词的开始 * E:一个词的结束 * M:一个词的中间 * S:单字成词 * 统计公式: Aij = P(Cj|Ci) = P(Ci,Cj) / P(Ci) = Count(Ci,Cj) / Count(Ci) * */public class StateTransferMatrixTraining { //private String fileName; private final static HashMapmap=new HashMap (); static{ map.put('B', 0);map.put('M', 1); map.put('E', 2);map.put('S', 3); } private long freq[][]=new long[4][4]; private long count[]=new long[4]; private void insert(StringBuilder sb,int start,int end){ if(end-start>1){ sb.append('B'); for(int i=0;i start){ //得到一个词 // insertWithContent(content,sb,start,end); insert(sb,start,end); ++end;start=end; }else{++start;++end;} }else{++end;} } //insertWithContent(content,sb,start,end); insert(sb,start,end); return sb.toString(); } private double[][] cal(){ double[][] transferMatrix=new double[4][4]; int i,j; for(i=0;i<4;i++){ for(j=0;j<4;j++){ transferMatrix[i][j]=(double)freq[i][j]/count[i]; } } return transferMatrix; } public double[][] readFile(String fileName){ BufferedReader br=null; String line; try { br=new BufferedReader(new InputStreamReader(new FileInputStream(new File(fileName)),"utf-8")); while((line=br.readLine())!=null){ if("".equals(line.trim()))continue; line=encode(line); stmTraining(line); } } catch (Exception e) { e.printStackTrace(); }finally{ try {br.close(); }catch (IOException e) {e.printStackTrace();} } //根据freq和count矩阵来计算转移矩阵 return cal(); } private void stmTraining(String encodeStr){ int i,j,len; len=encodeStr.length(); for(i=0;i 1){ sb.append(content.charAt(start)); sb.append('B'); for(int i=0;i
测试的结果如下:
跟参考博客上面的稍微有点出入,不知道是不是程序哪里有漏掉的地方。