在 Python 中使用 Stanford Parser 对中文文本不起作用

Using The Stanford Parser in Python on Chinese text not working

我试过这段代码,但没有成功:

# -*- coding:utf-8 -*-
from nltk.parse import stanford
s = '你好'.decode('utf-8')

print s
parser = stanford.StanfordParser(path_to_jar='stanford-parser.jar',path_to_models_jar='stanford-parser-3.5.1-models.jar')
print parser.raw_parse_sents(s)

结果将你和好打印为两个词:

你好
[Tree('ROOT', [Tree('NP', [Tree('NNP', ['\u4f60'])])]), Tree('ROOT', [Tree('NP', [Tree('NNP', ['\u597d'])])])]

但是在在线解析器上(http://nlp.stanford.edu:8080/parser/index.jsp),结果是

解析 (根 (知识产权 (VP (VV 你好))))

如何修复我的代码以产生与在线解析器相同的结果?

有两个(好吧,三个......请参阅下面的 "Update 3" 第三个)独立的事情:

1) 您的代码返回两棵树(两棵 ROOTs),但您只希望得到一棵。发生这种情况是因为 raw_parse_sents 需要一个句子列表,而不是一个句子,如果你给它一个字符串,它会解析字符串中的每个字符,就好像它是它自己的句子一样,并返回一个列表 -性格树。因此,要么传递 raw_parse_sents 一个列表,要么使用 raw_parse

2) 您没有指定model_path,默认为英文。中文有五个选项,不过貌似这个符合在线解析器:

parser = stanford.StanfordParser(model_path='edu/stanford/nlp/models/lexparser/xinhuaFactored.ser.gz', path_to_jar='stanford-parser.jar',path_to_models_jar='stanford-parser-3.5.1-models.jar')

结合这两个更改,我能够匹配在线解析器(我还必须将返回的列表迭代器转换为列表以匹配您的输出格式):

from nltk.parse import stanford
s = '你好'.decode('utf-8')

print s.encode('utf-8')
parser = stanford.StanfordParser(model_path='edu/stanford/nlp/models/lexparser/chineseFactored.ser.gz', path_to_jar='stanford-parser.jar',path_to_models_jar='stanford-parser-3.5.1-models.jar')
print list(parser.raw_parse(s))

> 你好
> [Tree('ROOT', [Tree('IP', [Tree('VP', [Tree('VV', ['\u4f60\u597d'])])])])]

更新 1:

我意识到您可能也在寻找一种更像网站上的输出格式,在这种情况下,这很有效:

for tree in parser.raw_parse(s):
    print tree # or print tree.pformat().encode('utf-8') to force an encoding

更新二:

显然,如果您的 NLTK 版本早于 3.0.2,Tree.pformat() 就是 Tree.pprint()。来自 https://github.com/nltk/nltk/wiki/Porting-your-code-to-NLTK-3.0:

Printing changes (from 3.0.2, see https://github.com/nltk/nltk/issues/804):

  • classify.decisiontree.DecisionTreeClassifier.pp → pretty_format
  • metrics.confusionmatrix.ConfusionMatrix.pp → pretty_format
  • sem.lfg.FStructure.pprint → pretty_format
  • sem.drt.DrtExpression.pretty → pretty_format
  • parse.chart.Chart.pp → pretty_format
  • Tree.pprint() → pformat
  • FreqDist.pprint → pformat
  • Tree.pretty_print → pprint
  • Tree.pprint_latex_qtree → pformat_latex_qtree

更新 3:

我现在正在尝试匹配您评论中句子的输出,'你好,我心情不错今天,你呢?'

我在撰写此回复时广泛参考了 Stanford Parser FAQ,建议您检查一下(尤其是 "Can you give me some help in getting started parsing Chinese?")。这是我学到的东西:

一般情况下,您需要"segment"将中文文本转换为以空格分隔的单词(由一个或多个字符组成),然后再进行解析。在线解析器就是这样做的,你可以在网页上看到分割步骤和解析步骤的输出。对于我们的测试语句,它显示的切分是'你好 , 我 心情 不错 今天 , 你 呢 ?'.

如果我在本地通过 xinhuaFactored 模型 运行 这个分割字符串,我的输出与在线解析器完全匹配。

因此我们需要 运行 我们的文本在通过解析器 运行 之前通过分词器。常见问题解答推荐 Stanford Word Segmenter,这可能是在线解析器正在使用的:http://nlp.stanford.edu/software/segmenter.shtml.

(如常见问题解答所述,解析器还包含一个模型 xinhuaFactoredSegmenting,它在解析调用中进行近似分割。但是,它调用此方法 "reasonable, but not excellent",并且输出不无论如何都匹配在线解析器,这是我们的标准。)