Skip to content

分词评价的不一致性

memeda edited this page Aug 30, 2016 · 1 revision

问题概述

在分词程序中需要实现评价逻辑,即计算P、R、F1值。

使用LTP的预测结果来评价,发现LTP自身给出的评价结果,与自己实现的代码得到的评价结果不同;同时,使用师兄代码中使用的评价脚本,结果又与上述都不一致。

详情

weibo-test的gold数据

  1. 使用otcws 得到如下结果:
P: 0.943104 ( 92709 / 98302 )
R: 0.942337 ( 92709 / 98382 )
F: 0.942720
  1. 自身实现
P = 0.941195 (92319 / 98087)
R = 0.938354 (92319 / 98384)
F = 0.939772 
  1. 评测脚本
=== TOTAL TRUE WORD COUNT:      98383
=== TOTAL TEST WORD COUNT:      98087
=== TOTAL TRUE WORDS RECALL:    0.9383
=== TOTAL TEST WORDS PRECISION: 0.9414
=== F MEASURE:  0.9398

可以看到他们在最基础的词个数统计上都不一致。

使用wc统计该文件的char数目:

98382

使用自己写的Python脚本做统计:

98384

二者依然不一致。

因为差距细微,并不能很好的确定究竟哪里出现了问题!

原因

因为最终的结果相较LTP差距较小,所以有必要弄清楚为何评价结果不一致。

首先需要明确是怎么去评价的:用GOLD的结果和LTP预测的结果作为评测程序的输入,比较二者的分词结果做评价。

通过再写一个Python评测脚本,发现此Python评测脚本的结果与C++写的评测结果在PKU上是一致的,但是在WEIBO上的GOLD上统计的Token数不一致。将GOLD中所有的Token打印出,发现GOLD中的全角空格在预测结果中被删除了。在LTP的Commit中发现了一个关于修复全角空格BUG的提交,点开发现大致就是将全角空格设为分隔符。这下就明白了原因!因为LTP将全角空格作为输入的分割信息了(相当于输入中的部分分词信息),所以就不会当作字符输出了。这就导致了在外部直接比较GOLD和预测结果得到的评价与LTP内部的评价不一致。再说外部,因为Python中做了decode后再split()的操作,该操作会将所有的空白符都分割开,包括全角空格。而C++的版本使用的是 stringstream 的>>,所以只能识别ASCII下的分割符,全角空格被当作普通字符了。

总结下来,全角空格是否被用作词语间的分割符,就是评价结果不一致的原因(之一?)。

这样说来,外部评测的结果就肯定是不对的。所以LTP自身的评测结果就应该被作为是可信的。而自身程序对全角空格是没有处理的,这样,我们就只能各自用自己的评价程序去比较,最后再拿各自的分数做对比。这样看来是相对可接受的。