原创中文分词代码分享(2.2)——基于词典的分词接口

接着是正向最大匹配的实现类MaxMatchSegmentProcessor:
java 代码
 
  1. /* 
  2.  * @作者:Hades , 创建日期:2006-11-17 
  3.  * 
  4.  * 汕头大学03计算机本科 
  5.  *  
  6.  */  
  7. package edu.stu.cn.segment.matching.processor;  
  8.   
  9. import java.util.LinkedList;  
  10. import java.util.StringTokenizer;  
  11.   
  12. import edu.stu.cn.segment.matching.dictionary.DictionaryImpl;  
  13.   
  14. /** 
  15.  * @author Hades Guan 正向最大匹配分词法操作类 
  16.  */  
  17. public class MaxMatchSegmentProcessor extends MatchSegmentProcessor  
  18. {  
  19.     /** 
  20.      * 字符串分隔器 
  21.      */  
  22.     private StringTokenizer tokenizer = null;  
  23.   
  24.     /** 
  25.      * 默认构造函数 
  26.      */  
  27.     public MaxMatchSegmentProcessor()  
  28.     {  
  29.         this.initSeperator();  
  30.     }  
  31.   
  32.     /** 
  33.      * 以一个词典操作类实例为参数的构造函数 
  34.      *  
  35.      * @param dic 
  36.      *            词典操作类实例 
  37.      */  
  38.     public MaxMatchSegmentProcessor(DictionaryImpl dic)  
  39.     {  
  40.         this.dic = dic;  
  41.         this.initSeperator();  
  42.     }  
  43.   
  44.     /** 
  45.      * 对text文本进行分词,把结果保存为字符串链表 
  46.      *  
  47.      * @param text 
  48.      *            待分词的文本 
  49.      * @return 分词结果 
  50.      */  
  51.     public LinkedList<string> textProcess(String text)  </string>
  52.     {  
  53.         if (text == null)  
  54.             return null;  
  55.   
  56.         // 初始化结果链表  
  57.         LinkedList<string> result = new LinkedList<string>();  </string></string>
  58.         // 对待分词文本进行分隔  
  59.         this.tokenizer = new StringTokenizer(text, this.seperator);  
  60.         while (tokenizer.hasMoreTokens())  
  61.         {  
  62.             String token = tokenizer.nextToken();  
  63.   
  64.             // 判断分隔文本是否为null  
  65.             if (token == null)  
  66.                 continue;  
  67.   
  68.             // 初始化位置标签  
  69.             int pos = 0;  
  70.             // 当前分隔文本长度  
  71.             int len = token.length();  
  72.             // 结尾位置  
  73.             int end = len;  
  74.             // 循环匹配  
  75.             while (pos < len)  
  76.             {  
  77.                 while (end > pos)  
  78.                 {  
  79.                     // 判断end处字符是否为数字或英文字母  
  80.                     if (end > 0  
  81.                             && CHAR_AND_NUM.indexOf(token.charAt(end - 1)) >= 0)  
  82.                     {  
  83.                         // 记录英语字母开始位置、英语字母结束位置  
  84.                         int englishEnd = end, englishStart = end;  
  85.                         while (englishStart > 0  
  86.                                 && CHAR_AND_NUM.indexOf(token  
  87.                                         .charAt(englishStart - 1)) >= 0)  
  88.                             englishStart--;  
  89.                         // 判断当位置标签指向当前英文串首地址时将结果插入分词结果集  
  90.                         if (pos == englishStart)  
  91.                         {  
  92.                             result.add(token  
  93.                                     .substring(englishStart, englishEnd));  
  94.                             pos = end;  
  95.                             end = len;  
  96.                         }  
  97.                     }  
  98.                     // end of 判断end处字符是否为数字或英文字母  
  99.   
  100.                     // 判断分段是否已分析完毕  
  101.                     if (end > pos)  
  102.                     {  
  103.                         // 汉字处理  
  104.                         String word = token.substring(pos, end);  
  105.                         if (dic.match(word))  
  106.                         {  
  107.                             result.add(word);  
  108.                             pos = end;  
  109.                             end = len;  
  110.                         }  
  111.                         else  
  112.                         {  
  113.                             // 当判断到剩余单字时,将词加入到词库中  
  114.                             if (word.length() == 1)  
  115.                             {  
  116.                                 result.add(word);  
  117.                                 pos = end;  
  118.                                 end = len;  
  119.                             }  
  120.                             else  
  121.                                 end--;  
  122.                         }  
  123.                         // end of match  
  124.                     }  
  125.                     // end of if(end>pos)  
  126.                 }  
  127.                 // end of while (end > pos)  
  128.             }  
  129.             // end of while (pos < len)  
  130.         }  
  131.         // end of while (tokenizer.hasMoreTokens())  
  132.         return result;  
  133.     }  
  134. }  

最后是反向最大匹配的实现类ReverseMaxMatchSegmentProcessor:
java 代码
 
  1. /* 
  2.  * @作者:Hades , 创建日期:2006-11-17 
  3.  * 
  4.  * 汕头大学03计算机本科 
  5.  *  
  6.  */  
  7. package edu.stu.cn.segment.matching.processor;  
  8.   
  9. import java.util.LinkedList;  
  10. import java.util.StringTokenizer;  
  11.   
  12. import edu.stu.cn.segment.matching.dictionary.DictionaryImpl;  
  13.   
  14. /** 
  15.  * @author Hades Guan 反向最大匹配分词法操作类 
  16.  */  
  17. public class ReverseMaxMatchSegmentProcessor extends MatchSegmentProcessor  
  18. {  
  19.     /** 
  20.      * 字符串分隔器 
  21.      */  
  22.     private StringTokenizer tokenizer = null;  
  23.   
  24.     /** 
  25.      * 默认构造函数 
  26.      */  
  27.     public ReverseMaxMatchSegmentProcessor()  
  28.     {  
  29.         this.initSeperator();  
  30.     }  
  31.   
  32.     /** 
  33.      * 以一个词典操作类实例为参数的构造函数 
  34.      *  
  35.      * @param dic 
  36.      *            词典操作类实例 
  37.      */  
  38.     public ReverseMaxMatchSegmentProcessor(DictionaryImpl dic)  
  39.     {  
  40.         this.dic = dic;  
  41.         this.initSeperator();  
  42.     }  
  43.   
  44.     /** 
  45.      * 对text文本进行分词,把结果保存为字符串链表 
  46.      *  
  47.      * @param text 
  48.      *            待分词的文本 
  49.      * @return 分词结果 
  50.      */  
  51.     public LinkedList<string> textProcess(String text)  </string>
  52.     {  
  53.         if (text == null)  
  54.             return null;  
  55.   
  56.         // 初始化分词结果集  
  57.         LinkedList<string> result = new LinkedList<string>();  </string></string>
  58.         // 初始化分隔器  
  59.         this.tokenizer = new StringTokenizer(text, this.seperator);  
  60.         // 分隔文本  
  61.         while (tokenizer.hasMoreTokens())  
  62.         {  
  63.             // 获取分隔文本  
  64.             String token = tokenizer.nextToken();  
  65.   
  66.             // 如果分隔文本为空则开始下一个循环  
  67.             if (token == null)  
  68.                 continue;  
  69.   
  70.             // 初始化变量  
  71.             int len = token.length(), start = 0, pos = len;  
  72.             int wordCount = 0;  
  73.             // 循环匹配  
  74.             while (pos > 0)  
  75.             {  
  76.                 while (start < pos)  
  77.                 {  
  78.                     // 判断start处字符是否为数字或英文字母  
  79.                     if (start < len  
  80.                             && CHAR_AND_NUM.indexOf(token.charAt(start)) >= 0)  
  81.                     {  
  82.                         // 记录英语字母开始位置、英语字母结束位置  
  83.                         int englishEnd = start, englishStart = start;  
  84.                         while (englishEnd < len  
  85.                                 && CHAR_AND_NUM.indexOf(token  
  86.                                         .charAt(englishEnd)) >= 0)  
  87.                             englishEnd++;  
  88.                         // 判断当位置标签指向当前英文串首地址时将结果插入分词结果集  
  89.                         if (englishEnd == pos)  
  90.                         {  
  91.                             result.add(result.size() - wordCount, token  
  92.                                     .substring(englishStart, englishEnd));  
  93.                             wordCount++;  
  94.                             pos = start;  
  95.                             start = 0;  
  96.                         }  
  97.                     }  
  98.                     // end of if(CHAR_AND_NUM.indexOf(token.charAt(start))>=0)  
  99.   
  100.                     // 判断分段是否已分析完毕  
  101.                     if (start < pos)  
  102.                     {  
  103.                         String word = token.substring(start, pos);  
  104.                         if (dic.match(word))  
  105.                         {  
  106.                             result.add(result.size() - wordCount, word);  
  107.                             wordCount++;  
  108.                             pos = start;  
  109.                             start = 0;  
  110.                         }  
  111.                         else  
  112.                         {  
  113.                             // 当判断到剩余单字时,将词加入到词库中  
  114.                             if (word.length() == 1)  
  115.                             {  
  116.                                 result.add(result.size() - wordCount, word);  
  117.                                 wordCount++;  
  118.                                 pos = start;  
  119.                                 start = 0;  
  120.                             }  
  121.                             else  
  122.                                 start++;  
  123.                         }  
  124.                         // end of match  
  125.                     }  
  126.                     // end of if(start  
  127.                 }  
  128.                 // end of while (start < pos)  
  129.             }  
  130.             // end of while (pos > 0)  
  131.         }  
  132.         // end of while (tokenizer.hasMoreTokens())  
  133.         return result;  
  134.     }  
  135.   
  136. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HMM分词是汉语分词的一种基础方法,其核心算法是隐马尔可夫模型。Python作为一种高级编程语言,拥有丰富的自然语言处理库和工具。下面是基于HMM算法的Python分词代码实现。 首先,需要准备好语料库和词典库。语料库是用于训练模型和测试分词效果的文本集合,而词典库则是包含一些常见词语的列表或文件。 接着,需要定义HMM模型中的状态和观测值。在汉语分词中,状态通常为“B(开头)、M(中间)、E(结尾)和S(单个字)”,观测值则为每个汉字。通过预处理语料库和词典库,可以得到每个汉字出现在每个位置上的概率、每个位置上以某个字为结尾的概率和某个位置上以某个字为开头的概率。 然后,通过Viterbi算法来实现分词。Viterbi算法用于求解HMM模型中的最优路径,即最有可能的分词结果。需要对输入文本进行预处理,将输入文本中的汉字转换成相应的观测值,并计算每个位置上的概率值。接着,通过动态规划的方法求解每个位置上的最优状态,最后将最优状态转换成分词结果即可。 最后,需要对分词结果进行一些后处理,例如去除停用词、合并一些特殊的词语等等,以达到更好的分词效果。 综上所述,基于HMM算法的Python分词代码实现需要准备好语料库和词典库,定义HMM模型的状态和观测值,以及编写Viterbi算法来求解最优路径。最终通过后处理来优化分词结果。这样的代码实现可以很好地对汉语文本进行分词处理,是自然语言处理领域中不可或缺的一部分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值