Flyaway's Blog

开源项目PYEVALB

起因

秋假在家略无聊,在翻阅过去代码的时候,发现曾经为了对句法树进行打分而写过一个小项目。 于是,决定利用这个假期把这个小项目给开源了,取名为PYEVALB.

PYEVALB是我个人真正意义上的第一个开源项目,将它发表之后还是感觉很高兴的。

PYEVALB

自然语言处理中,有一个称为句法分析的基本任务: 将一个句子表示成一棵句法树。 而PYEVALB就是用来衡量两棵树的相似程度的一个工具。

目前学术界大家要不就是自己写,要不就是用纽约大学开放的工具Evalb. 但是Evalb是用C语言写的,作为独立工具当然是很方便的,但是如果希望能将其集成到某个项目中去,那就比较麻烦了。

因此,为了更好的集成到开发过程中,我用Python重写了Evalb的功能,开发了PYEVALB项目。

安装

1
pip install PYEVALB

为句法树库打分

对两个句法树库进行打分比较:

1
2
3
4
5
from PYEVALB import scorer
gold_path = 'gold_corpus.txt'
test_path = 'test_corpus.txt'
result_path = 'result.txt'
scorer.evalb(gold_path, test_path, result_path)

result.txt中,我们会得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ID | length | state | recall | prec | matched_brackets | gold_brackets | test_brackets | cross_brackets | words | correct_tags | tag_accracy
---:|-------:|------:|-------:|-----:|-----------------:|--------------:|--------------:|---------------:|------:|-------------:|------------:
0| 44| 0| 0.57| 0.61| 31| 54| 51| 16| 44| 43| 0.98
1| 13| 0| 0.64| 0.60| 9| 14| 15| 3| 13| 12| 0.92
2| 29| 0| 0.97| 0.97| 29| 30| 30| 0| 29| 29| 1.00
3| 20| 0| 0.80| 0.80| 20| 25| 25| 4| 20| 20| 1.00
4| 19| 0| 0.91| 1.00| 21| 23| 21| 0| 19| 19| 1.00
5| 71| 0| 0.67| 0.68| 52| 78| 77| 15| 71| 65| 0.92
6| 16| 0| 0.61| 0.69| 11| 18| 16| 0| 16| 14| 0.88
7| 27| 0| 0.92| 0.96| 24| 26| 25| 0| 27| 26| 0.96
8| 19| 0| 1.00| 1.00| 20| 20| 20| 0| 19| 19| 1.00
9| 41| 0| 0.80| 0.78| 32| 40| 41| 5| 41| 39| 0.95
=================================================================================================================================================
Number of sentence: 10.00
Number of Error sentence: 0.00
Number of Skip sentence: 0.00
Number of Valid sentence: 10.00
Bracketing Recall: 75.91
Bracketing Precision: 77.57
Bracketing FMeasure: 76.73
Complete match: 10.00
Average crossing: 4.30
No crossing: 50.00
Tagging accuracy: 95.65

为两棵树打分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from PYEVALB import scorer
from PYEVALB import parser
gold = '(IP (NP (PN 这里)) (VP (ADVP (AD 便)) (VP (VV 产生) (IP (NP (QP (CD 一) (CLP (M 个))) (DNP (NP (JJ 结构性)) (DEG 的)) (NP (NN 盲点))) (PU :) (IP (VP (VV 臭味相投) (PU ,) (VV 物以类聚)))))) (PU 。))'
test = '(IP (IP (NP (PN 这里)) (VP (ADVP (AD 便)) (VP (VV 产生) (NP (QP (CD 一) (CLP (M 个))) (DNP (ADJP (JJ 结构性)) (DEG 的)) (NP (NN 盲点)))))) (PU :) (IP (NP (NN 臭味相投)) (PU ,) (VP (VV 物以类聚))) (PU 。))'
gold_tree = parser.create_from_bracket_string(gold)
test_tree = parser.create_from_bracket_string(test)
result = scorer.score_trees(gold_tree, test_tree)
print('Recall =' + str(result.recall))
print('Precision =' + str(result.prec))

运行上述代码之后,我们能得到如下的输出:

1
2
Recall = 64.29
Precision = 56.25

结论

PYEVALB这个工具还很简陋,只是完成了最初步的功能,还有很多地方需要完善。 后面我也会好好维护这个项目,尽管是比较小众的工具……

参考资料

更新日志

打赏杯咖啡吧~