最近需要使用到基于短语结构的parser来对句子进行分析,从进入实验室到现在大部分时间都在做parser相关的东西,但是一直都是最基于依存的,现在是第一次基础到基于短语结构的,这次任务需要使用多个短语结构的parser,从网上现在了berkeley parser,学习使用的过程并不是一帆风顺,特在此记下使用方法,以后回顾在看,也希望可以对需要学习的同学有帮助。
1、代码处理
首先从网站上下载源码,在google code上面就可以下载到。
在eclipse中新建一个项目,将源码导入项目中,我们会发现编译无法通过,需要做一下修改:
- 将 edu.berkeley.nlp.PCFGLA.HierarchicalFullyConnectedAdaptiveLexiconWithFeatures.java 的第9行注释掉
- 将 ListUtils.java文件中的toArray 函数中的三个注释,只留下返回值类型为 String[]的那一个
这样就可以编译通过了,但是如果要从eclipse导出得到jar包的话,还是会有错误,当时纠结了很长时间,为什么在eclipse中编译没问题,导出jar有问题呢,一直上网查,但是就是没想到去看看源代码。后来看代码才发现有问题的那几个源文件中的代码都被注释了,这样编译的时候就不会得到相应的.class文件。解决的方法就是直接把那几个文件删除。
2、语料处理
Berkeley Parser 的输入要求是按照 msj格式输入的, ctb中的文件内容还包含一些特殊的符号,需要将他们去掉才,最后只保留bracket形式的语料。
ctb5语料中有一些问题,查找语料问题是一个最让人崩溃的事情,当时差点就疯了。
我当时的语料主要有两个问题:
- 将(NP-PN (NR Ken Madsen)))改为(NP-PN (NR Ken_Madsen)))
- 有一行?后面少了一个“)”,需要加上。
3、训练和测试
在berkeley parser中,对于特定的treebank,train、test和dev的划分是直接写在代码中的,而且文件后缀名是wsj,可以直接在代码中修改问fid(这样就只能parser中文了),或者修改文件后缀。如果不想按照代码中写的划分,那么一种方法是改变代码,一种方法就是替换文件。还有一种方法就是将所有训练语料合并到一个文件中,然后在训练的时候加上参数 SINGLEFILE。
我认为最方便的还是使用一个文件来进行训练和测试。
训练命令:
nohup java -cp BerkeleyParser.jar edu.berkeley.nlp.PCFGLA.GrammarTrainer -path ./train.fid -out chn.gr -treebank SINGLEFILE > train.log &
当然还有很多可选的参数,可以直接运行java -cp berkeley.jar edu.berkeley.nlp.PCFGLA.GrammarTrainer查看。
测试的时候可以使用wsj格式的树库,也可以使用文本。
如果使用树库,那么在测试结果中可以直接得到parser的性能输出。命令为:
nohup java -cp BerkeleyParser.jar edu.berkeley.nlp.PCFGLA.GrammarTester -path ./corpus/ctb5/test.pid -treebank SINGLEFILE -maxL 200 -accurate -in chn.gr > test.result &
注意上面的命令也是讲所有的测试树库合并到可test.pid文件中。
如果直接使用文本的话,那么直接使用命令:
nohup java -jar BerkeleyParser.jar -gr chn.gr -accurate -tokenized < test.txt >test.out 2> test.log &
还有一些其他的参数选项,比如是否分词之类的,是否使用conll格式的语料(使用pos)等等。
最后就可以得到BerkeleyParser的性能了。