最大概率分词程序

最大概率分词程序
最大概率分词程序,在所有可能分词路径中选择概率最大的一条路径最为分词结果
public   class  MPM  extends  M
{
    
public static final HashMap<Character,TreeNode> dic = Dictionary.loadFreqDictionary("sogou.txt");
    
public static final HashMap<String,Long> map=Dictionary.loadFreq("sogou.txt");
    
    
/** *//**
     * 
@return 返回可能匹配词的长度, 没有找到返回 0.
     
*/

    
public ArrayList<Integer> maxMatch(TreeNode node,char[] sen, int offset) 
    
{
        ArrayList
<Integer> list=new ArrayList<Integer>();
        
for(int i=offset; i<sen.length; i++
        
{
            node 
= node.subNode(sen[i]);
            
if(node != null
            
{
                
if(node.isAlsoLeaf()) 
                    list.add(i
+1);
            }

            
else 
                
break;
        }

        
return list;
    }

    
    @Override
    
public ArrayList<Token> getToken(ArrayList<Sentence> list) 
    
{
        ArrayList
<Token> tokenlist=new ArrayList<Token>();
        
for(Sentence sen:list)
        
{
            AdjList g 
= new AdjList(sen.getText().length+1);//存储所有被切分的可能的词
            int i=0;
            
while(i<sen.getText().length)
            
{
                Token token 
= new Token(new String(sen.getText(),i,1),i,i+1);
                
if(map.containsKey(token.getWord()))
                    token.setWeight(Math.log(map.get(token.getWord())));
                g.addEdge(token);
                
                TreeNode n
=dic.get(sen.getText()[i]);
                
if(n!=null)
                
{
                    ArrayList
<Integer> ilist =maxMatch(n, sen.getText(),i);
                    
if(ilist.size()>0)
                        
for(int j=0;j<ilist.size();j++)
                        
{
                            token 
= new Token(new String(sen.getText(),i,ilist.get(j)-i),i,ilist.get(j));
                            
if(map.containsKey(token.getWord()))
                                token.setWeight(Math.log(map.get(token.getWord())));
                            g.addEdge(token);
                        }

                }

                i
++;
            }

            
//System.out.println(g);
            ArrayList<Integer> ret=maxProb(g);
            Collections.reverse(ret);
            
int first=0;
            
for(Integer last:ret)
            
{
                Token token 
= new Token(new String(sen.getText(),first,last-first),sen.getStartOffset()+first,sen.getStartOffset()+last);
                tokenlist.add(token);
                first
=last;
            }

        }

        
return tokenlist;
    }

    
    
int[] prevNode;
    
double[] prob;
    
    
//计算出最大概率的数组
    public ArrayList<Integer> maxProb(AdjList g)
    
{
        prevNode 
= new int[g.verticesNum]; //最佳前驱节点
        prob = new double[g.verticesNum]; //节点概率
        prob[0= 0;//节点0的初始概率是1,取log后是0
        
        
//按节点求最佳前驱
        for (int index = 1; index < g.verticesNum; index++)
            getBestPrev(g,index);
//求出最佳前驱
        
        ArrayList
<Integer> ret = new ArrayList<Integer>();
        
for(int i=(g.verticesNum-1);i>0;i=prevNode[i]) // 从右向左找最佳前驱节点
            ret.add(i);
        
return ret;
    }

    
    
//计算节点i的最佳前驱节点
    void getBestPrev(AdjList g,int i)
    
{
        Iterator
<Token> it = g.getPrev(i);//得到前驱词集合,从中挑选最佳前趋词
        double maxProb = 0;
        
int maxNode = -1;
        
        
while(it.hasNext())
        
{
            Token itr 
= it.next();
            
double nodeProb = prob[itr.getStart()]+itr.getWeight();//候选节点概率
              if (nodeProb > maxProb)//概率最大的算作最佳前趋
              {
                  maxNode 
= itr.getStart();
                  maxProb 
= nodeProb;
              }

         }

        prob[i] 
= maxProb;//节点概率
        prevNode[i] = maxNode;//最佳前驱节点
    }

}

你可能感兴趣的:(最大概率分词程序)