在 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) 您的代码返回两棵树(两棵 ROOT
s),但您只希望得到一棵。发生这种情况是因为 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",并且输出不无论如何都匹配在线解析器,这是我们的标准。)
我试过这段代码,但没有成功:
# -*- 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) 您的代码返回两棵树(两棵 ROOT
s),但您只希望得到一棵。发生这种情况是因为 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",并且输出不无论如何都匹配在线解析器,这是我们的标准。)