基于.NET的分词软件设计与实现V3.0--对比测试及改变

  系列索引:基于.NET的分词软件设计与实现--索引及说明

  在前面的两个版本中我们已经实现了所有的功能,即针对中文、英文、数字及特殊符号的分词功能,所以整体的功能已经基本实现,所有从这一篇开始起,系列的重点就放在了对比测试和性能优化上。
  首先来看对比测试,俗话说:有比较才有进步。所以偶下载了很多分词软件,通过分词算法、分词效果及分词耗时等多项指标的比对,对自己的分词软件做出了相应的功能修补:

  如果没有特别说明,从本文开始的所有文章均以下图所示的某新闻报道为测试文本

  

  1、文本预处理功能。

  在上篇中我提到了一个预处理功能,下面看一下我搜集的一些分词软件对于这样的一些特殊情况是怎么处理的。

  (1)中科天玑分词软件    下载

    

  标注不是本系列的关注点,所以暂且pass(下同)。可以看到本分词软件的结果分隔并不是很明显,用户体验较差。

  (2)中科院计算所汉语词法分析系统     下载

  

  这里可以看到软件对于分词的文本长度是有限制的,上面的输入文本框明显产生了字符的截断。而在输出格式上,这里提供了三种输出格式,上图所示的是使用了973标准的输出格式,也就是我的分词软件里面采用的格式,而采用北大标准的效果如下:

  

  即把所有的斜线分隔符换成了来两个空格的形式。基于xml格式的即把分出来的词使用<src></src>的标签包裹。

  (3)、盘古分词   下载

  看到下面的留言有人提到盘古分词,我也下载了测试一下,效果如下:

 

  

  可以看到其功能还是灰常强大滴,其对分词输出的结果采用了预处理,去除了标点符号及换行符等,并以“/”作为分割间隔,相对于其他的分词软件,这里提供了很多的附加功能,大家感兴趣的可以自行下载进行测试。

  (4)、搜价网中文分词     下载


  

  可以看出本软件并没有对特殊字符(如换行符)作特殊处理,且分词只有一种输出格式,并且文本溢出时没有显示下拉框,体验不是很好。

  (5)网络在线分词

  下面提供一些我找到的还算可以的网络在线分词系统:

    我爱火星文在线分词:http://tool.52hxw.com/015.php(这个貌似和上面用的是一套程序)

    高速在线中文分词:http://www.goocnjp.com/test/fenci/

  

  好的,讲的太多,让我们总结归纳一下:

  

  此外,个人还做了一些分词软件的测试,结果是大多数分词对于待分词文本均不进行附加处理,而是保留其格式输出,而且其中作为分词方面权威的中科院的两款分词软件也是如此,这更说明了我们应该保留文本的原意,所以综合以上测试,我否定了自己在V2.0中提出的文本预处理的做法。


  2、使用数组索引进行分词效率提升尝试。

  回顾上篇的程序流程图,可以看到,我构造了一个集合用来存储非中文字符,在分词时出来循环遍历词典,还要遍历非中文字符的集合,效率自然比较悲催。。。

  所以在V3.0中采取了数组索引的方式,所谓数组索引,代码如下:

1 /// <summary>
2 /// Updated:为所有数字英文添加分隔符
3 /// </summary>
4 /// <returns></returns>
5   string SplitNonChinese()
6 {
7 for (int j = 0; j < _nonChineseRegex.Matches(_inputStr).Count; j++)
8 {
9 _inputStr = _inputStr.Insert(_nonChineseRegex.Matches(_inputStr)[j].Index
+ _nonChineseRegex.Matches(_inputStr)[j].Value.Length, @"\");
10 }
11 return _inputStr;
12 }
13
14 /// <summary>
15 /// Updated:为所有中文标点添加分隔符
16 /// </summary>
17   string SplitChinesePunctuation()
18 {
19 _inputStr = SplitNonChinese();
20 for (int i = 0; i < _chinesePunctuationRegex.Matches(_inputStr).Count; i++)
21 {
22 _inputStr = _inputStr.Insert(_chinesePunctuationRegex.Matches(_inputStr)[i].
Index + _chinesePunctuationRegex.Matches(_inputStr)[i].Value.Length, @"\");
23 }
24 return _inputStr;
25 }
26
27 /// <summary>
28 /// Updated:为所有汉字添加分隔符
29 /// </summary>
30 string SplitChinese()
31 {
32 _inputStr = SplitChinesePunctuation();
33 StringBuilder sb = new StringBuilder(_inputStr);
34 int i = 0;
35 foreach (Match item in _chineseRegex.Matches(sb.ToString()))
36 {
37 sb = sb.Insert(item.Index + item.Value.Length + i, "\\");
38 i++;
39 }
40 return sb.ToString();
41 }

  由上可以看出,我们利用正则匹配,对匹配的位置分别加入斜杠分割,这样我们在正式的RMM(逆向最大匹配算法)开始分词之前就将文本进行了划分,划分出中文、非中文和标点符号。

  程序流程图:

  

  可以看到之前的遍历非中文集合操作已经被取消,更改为判断是否是中文字符,只要通过:_nonChineseRegex.IsMatch(strList[i])判断出有一个字符不是中文,介于之前已经对文本进行了拆分,所以我们可以很肯定的认为整个子句均为非中文,故直接加入到待输出集合中即可。

  结果:截取测试文本的1000个字进行测试,结果从V2.0的11秒左右提升到了8秒左右,效率提升27%


作者:Rocky翔
出处:http://www.cnblogs.com/RockyMyx/
本文版权归作者和博客园共有,欢迎转载,但请在文章明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2011-06-15 07:40  RockyXiang  阅读(2504)  评论(13编辑  收藏  举报