学习深度解析中文分词器算法(最大正向/逆向匹配)

Posted PPV课数据科学社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习深度解析中文分词器算法(最大正向/逆向匹配)相关的知识,希望对你有一定的参考价值。

中文分词算法概述:

1:非基于词典的分词(人工智能领域)

相当于人工智能领域计算。一般用于机器学习,特定领域等方法,这种在特定领域的分词可以让计算机在现有的规则模型中,推理如何分词。在某个领域(垂直领域)分词精度较高。但是实现比较复杂。

例:比较流行的语义网:基于本体的语义检索。

大致实现:用protege工具构建一个本体(在哲学中也叫概念,在80年代开始被人工智能),通过jena的推理机制和实现方法。

实现对Ontology的语义检索。

Ontology语义检索这块自己和一朋友也还在琢磨,目前也只处于初级阶段。这一块有兴趣的朋友可以留言一起共享资源。

2:基于词典的分词(最为常见)

这类分词算法比较常见,比如正向/逆向匹配。例如: mmseg分词器 就是一种基于词典的分词算法。以最大正向匹配为主,多种 消除歧义算法为辅。但是不管怎么分。该类分词方法,分词精度不高。由于中文比较复杂,不推荐采用正向最大匹配算法的中文分词器。。逆向最大匹配算法在处理中文往往会比正向要准确。

接下来分析第2种:基于词典的分词算法(最长的词优先匹配)。 先分析最大正向匹配算法

一: 具体流程图如下:

【学习】深度解析中文分词器算法(最大正向/逆向匹配)


一:以下代码片段为最大正向匹配算法:

[html] view plaincopy

  1. package hhc.forwardAlgorithm;

  2. import java.net.URL;

  3. import java.nio.charset.Charset;

  4. import java.nio.file.Files;

  5. import java.nio.file.Path;

  6. import java.nio.file.Paths;

  7. import java.util.ArrayList;

  8. import java.util.List;

  9. import java.util.Stack;

  10. /**

  11. * @Description:

  12. * @Date: 2015-2-7上午02:00:51

  13. * @Author 胡慧超

  14. * @Version 1.0

  15. */

  16. @SuppressWarnings("unchecked")

  17. public class TokenizerAlgorithm {

  18. private static final List<String> DIC=new ArrayList<String>();

  19. private static int MAX_LENGTH;

  20. /**

  21. * 把词库词典转化成dic对象,并解析词典信息

  22. */

  23. static {

  24. try {

  25. System.out.println("开始初始化字典...");

  26. int max=1;

  27. int count=0;

  28. //读取词典中的每一个词

  29. URL url=TokenizerAlgorithm.class.getClassLoader().getResource("hhc/dic.txt");

  30. Path path=Paths.get(url.toString().replaceAll("file:/", ""));

  31. List<String> list=Files.readAllLines(path, Charset.forName("UTF-8"));

  32. System.out.println("读取词典文件结束,词总数为:"+list.size());

  33. for(String line:list){

  34. DIC.add(line);

  35. count++;

  36. //获取词库中 ,最大长度的词的长度

  37. if(line.length()>max){

  38. max=line.length();

  39. }

  40. }

  41. MAX_LENGTH=max;

  42. System.out.println("初始化词典结束,最大分词长度为:"+max+" !!");

  43. System.out.println("------------------------------------------------------------------------");

  44. } catch (Exception e) {

  45. // TODO Auto-generated catch block

  46. e.printStackTrace();

  47. }

  48. }

  49. /**

  50. * 正向分词算法

  51. * @param text

  52. * @return

  53. */

  54. public static List forwardSeg(String text){

  55. List result=new ArrayList();

  56. while(text.length()>0){

  57. int len=MAX_LENGTH;

  58. if(text.length()<MAX_LENGTH){

  59. len=text.length();

  60. }

  61. //取指定的最大长度 文本去字典中匹配

  62. String tryWord=text.substring(0, len);

  63. while(!DIC.contains(tryWord)){//如果词典中不包含该段文本

  64. //如果长度为1 的话,且没有在字典中匹配,返回

  65. if(tryWord.length()==1){

  66. break;

  67. }

  68. //如果匹配不到,则长度减1,继续匹配

  69. /**

  70. * --这里就是最关键的地方,把最右边的词去掉一个,继续循环

  71. */

  72. tryWord=tryWord.substring(0, tryWord.length()-1);

  73. }

  74. result.add(tryWord);

  75. //移除该次tryWord,继续循环

  76. text=text.substring(tryWord.length());

  77. }

  78. return result;

  79. }

  80. public static void main(String[] args) {

  81. // TODO Auto-generated method stub

  82. List<String> lst=new ArrayList();

  83. lst.add("研究生命起源");

  84. lst.add("食物和服装");

  85. lst.add("乒乓球拍卖完了");

  86. for(String str:lst){

  87. List<String> list=forwardSeg(str);

  88. String word="";

  89. for(String s:list){

  90. s+="/";

  91. word+=s;

  92. }

  93. System.out.println(word);

  94. }

  95. }

执行正向分词结果:




二:最大逆向分词算法

考虑到逆向,为了 区分分词的数据的连贯性。我们采用Stack(栈对象,数据结果,后进先出,不同于Queue和ArrayList有顺序的先进先出) 这个对象来存储分词结果。。

[java] view plaincopy

  1. /**

  2. * 逆向分词算法

  3. * @param text

  4. * @return

  5. */

  6. public static List reverseSeg(String text){

  7. Stack<String> result=new Stack();

  8. while(text.length()>0){

  9. int len=MAX_LENGTH;

  10. if(text.length()<MAX_LENGTH){

  11. len=text.length();

  12. }

  13. //取指定的最大长度 文本去字典中匹配

  14. String tryWord=text.substring(text.length()-len);

  15. while(!DIC.contains(tryWord)){//如果词典中不包含该段文本

  16. //如果长度为1 的话,且没有在字典中匹配,返回

  17. if(tryWord.length()==1){

  18. break;

  19. }

  20. //如果匹配不到,则长度减1,继续匹配

  21. /**

  22. * --这里就是最关键的地方,把最左边的词去掉一个,继续循环

  23. */

  24. tryWord=tryWord.substring(1);

  25. }

  26. result.add(tryWord);

  27. //移除该次tryWord,继续循环

  28. text=text.substring(0,text.length()-tryWord.length());

  29. }

  30. int size=result.size();

  31. List list =new ArrayList(size);

  32. for(int i=0;i<size;i++){

  33. list.add(result.pop());

  34. }

  35. return list;

  36. }

执行逆向分词结果




以上代码实现了两种正向和逆向的算法,可以很明显的比较中文分词结果。

但是效率,,呵呵!确实不咋的。欢迎打脸。

比如:数据结构就先不提。text.substring(0, 0+len)会导致产生大量的新的字符串的产生,消耗CPU的同时还会促发垃圾回收频繁发生导致性能下降。随着最大长度的增加,性能会严重下降。

像之前介绍的采取正向最大匹配算法的mmseg分词器,内部设置了4个消除歧义的过滤算法,这四个歧义解析规则表明是相当有效率的。总体来讲。mmseg的分词精度还是值得推荐的。。。




PPV课其他精彩文章:


0、回复“活动”查看PPV课社区百日掘金活动-积分兑换Iphone 5s、MINI金条

1、回复“干货”查看干货 数据分析师完整知识结构

2、回复“答案”查看大数据Hadoop面试笔试题及答案

3、回复“设计”查看这是我见过最逆天的设计,令人惊叹叫绝

4、回复“可视化”查看数据可视化专题-数据可视化案例与工具

5、回复“禅师”查看当禅师遇到一位理科生,后来禅师疯了!!知识无极限

6、回复“啤酒”查看数据挖掘关联注明案例-啤酒喝尿布

7、回复“栋察”查看大数据栋察——大数据时代的历史机遇连载

8、回复“数据咖”查看数据咖——PPV课数据爱好者俱乐部省分会会长招募

9、回复每日一课查看【每日一课】手机在线视频集锦



PPV课大数据ID: ppvke123 (长按可复制)

大数据人才的摇篮!专注大数据行业人才的培养。每日一课,大数据(EXCEL、SAS、SPSS、Hadoop、CDA)视频课程。大数据资讯,每日分享!数据咖—PPV课数据爱好者俱乐部!



以上是关于学习深度解析中文分词器算法(最大正向/逆向匹配)的主要内容,如果未能解决你的问题,请参考以下文章

nlp正向最大匹配算法逆向最大匹配算法双向最大匹配算法代码实现

基于中文词典的分词算法

中文分词--最大正向匹配算法python实现

中文分词--逆向最大匹配

中文分词:正向最大匹配与逆向最大匹配

seo问题,啥叫正向匹配?啥叫逆向匹配?举例说明