斯坦福解析器和NLTK

2024-04-20 04:42:33 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
3条回答

不赞成的回答

下面的答案不推荐使用,请使用https://stackoverflow.com/a/51981566/610569上的解决方案,用于NLTK v3.3及更高版本。


编辑

注意:以下答案仅适用于:

  • NLTK版本=3.2.4
  • 斯坦福工具自2015年4月20日起编制
  • Python2.7、3.4和3.5(Python3.6还没有正式支持)

由于这两种工具的变化都相当快,而且3-6个月后,API可能看起来非常不同。请把下面的答案看作是暂时的,而不是永恒的。

有关如何使用NLTK连接斯坦福NLP工具的最新说明,请始终参阅https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software!!


TL;博士

cd $HOME

# Update / Install NLTK
pip install -U nltk

# Download the Stanford NLP tools
wget http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip
wget http://nlp.stanford.edu/software/stanford-postagger-full-2015-04-20.zip
wget http://nlp.stanford.edu/software/stanford-parser-full-2015-04-20.zip
# Extract the zip file.
unzip stanford-ner-2015-04-20.zip 
unzip stanford-parser-full-2015-04-20.zip 
unzip stanford-postagger-full-2015-04-20.zip


export STANFORDTOOLSDIR=$HOME

export CLASSPATH=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/stanford-postagger.jar:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/stanford-ner.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar

export STANFORD_MODELS=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/models:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/classifiers

然后:

>>> from nltk.tag.stanford import StanfordPOSTagger
>>> st = StanfordPOSTagger('english-bidirectional-distsim.tagger')
>>> st.tag('What is the airspeed of an unladen swallow ?'.split())
[(u'What', u'WP'), (u'is', u'VBZ'), (u'the', u'DT'), (u'airspeed', u'NN'), (u'of', u'IN'), (u'an', u'DT'), (u'unladen', u'JJ'), (u'swallow', u'VB'), (u'?', u'.')]

>>> from nltk.tag import StanfordNERTagger
>>> st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz') 
>>> st.tag('Rami Eid is studying at Stony Brook University in NY'.split())
[(u'Rami', u'PERSON'), (u'Eid', u'PERSON'), (u'is', u'O'), (u'studying', u'O'), (u'at', u'O'), (u'Stony', u'ORGANIZATION'), (u'Brook', u'ORGANIZATION'), (u'University', u'ORGANIZATION'), (u'in', u'O'), (u'NY', u'O')]


>>> from nltk.parse.stanford import StanfordParser
>>> parser=StanfordParser(model_path="edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz")
>>> list(parser.raw_parse("the quick brown fox jumps over the lazy dog"))
[Tree('ROOT', [Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['quick']), Tree('JJ', ['brown']), Tree('NN', ['fox'])]), Tree('NP', [Tree('NP', [Tree('NNS', ['jumps'])]), Tree('PP', [Tree('IN', ['over']), Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['lazy']), Tree('NN', ['dog'])])])])])])]

>>> from nltk.parse.stanford import StanfordDependencyParser
>>> dep_parser=StanfordDependencyParser(model_path="edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz")
>>> print [parse.tree() for parse in dep_parser.raw_parse("The quick brown fox jumps over the lazy dog.")]
[Tree('jumps', [Tree('fox', ['The', 'quick', 'brown']), Tree('dog', ['over', 'the', 'lazy'])])]

长:


首先,必须注意斯坦福NLP工具是用Java编写的,而NLTK是用Python编写的。NLTK连接工具的方式是通过命令行接口调用Java工具。

其次,斯坦福NLP工具的API自3.1版以来已经发生了很大的变化。因此,建议将NLTK包更新到v3.1。

第三,Stanford NLP工具的NLTKAPI围绕着各个NLP工具,例如Stanford POS taggerStanford NER TaggerStanford Parser

对于POS和NER标记符,它不会环绕Stanford Core NLP package

对于Stanford解析器来说,这是一个特殊的情况,它包装了Stanford解析器和Stanford Core NLP(就我个人而言,我没有使用后者使用NLTK,我更愿意遵循@dimazest在http://www.eecs.qmul.ac.uk/~dm303/stanford-dependency-parser-nltk-and-anaconda.html上的演示)

请注意,从NLTK v3.1开始,STANFORD_JARSTANFORD_PARSER变量已弃用,不再使用


在更长时间内:


步骤1

假设您已在操作系统上正确安装了Java。

现在,安装/更新NLTK版本(请参见http://www.nltk.org/install.html):

  • 使用pipsudo pip install -U nltk
  • Debian发行版(使用apt get):sudo apt-get install python-nltk

对于Windows(使用32位二进制安装):

  1. 安装Python 3.4:http://www.python.org/downloads/(避免64位版本)
  2. 安装Numpy(可选):http://sourceforge.net/projects/numpy/files/NumPy/(指定pythnon3.4的版本)
  3. 安装NLTK:http://pypi.python.org/pypi/nltk
  4. 测试安装:启动>;Python34,然后键入import nltk

为什么不是64位?https://github.com/nltk/nltk/issues/1079


然后出于偏执,重新检查python中的nltk版本:

from __future__ import print_function
import nltk
print(nltk.__version__)

或者在命令行上:

python3 -c "import nltk; print(nltk.__version__)"

确保看到3.1作为输出。

更偏执的是,检查你最喜欢的斯坦福NLP工具API是否可用:

from nltk.parse.stanford import StanfordParser
from nltk.parse.stanford import StanfordDependencyParser
from nltk.parse.stanford import StanfordNeuralDependencyParser
from nltk.tag.stanford import StanfordPOSTagger, StanfordNERTagger
from nltk.tokenize.stanford import StanfordTokenizer

注意:上面的导入只会确保您使用的是包含这些api的正确NLTK版本。没有看到导入中的错误并不意味着您已经成功地将NLTK API配置为使用Stanford工具)


步骤2

现在您已经检查了NLTK的正确版本,该版本包含必要的Stanford NLP工具接口。你需要下载并提取所有必要的斯坦福NLP工具。

TL;DR,在Unix中:

cd $HOME

# Download the Stanford NLP tools
wget http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip
wget http://nlp.stanford.edu/software/stanford-postagger-full-2015-04-20.zip
wget http://nlp.stanford.edu/software/stanford-parser-full-2015-04-20.zip
# Extract the zip file.
unzip stanford-ner-2015-04-20.zip 
unzip stanford-parser-full-2015-04-20.zip 
unzip stanford-postagger-full-2015-04-20.zip

在Windows/Mac中:


步骤3

设置环境变量,以便NLTK可以自动找到相关的文件路径。必须设置以下变量:

  • 将适当的Stanford NLP.jar文件添加到CLASSPATH环境变量中。

    • e、 g.对于内质网来说stanford-ner-2015-04-20/stanford-ner.jar
    • e、 g.对于POS,它将是stanford-postagger-full-2015-04-20/stanford-postagger.jar
    • e、 g.对于解析器,它是stanford-parser-full-2015-04-20/stanford-parser.jar,解析器模型jar文件是stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar
  • 将适当的模型目录添加到STANFORD_MODELS变量中(即,可以在其中找到预训练模型的保存位置的目录)

    • e、 g.对于NER,它将位于stanford-ner-2015-04-20/classifiers/
    • e、 g.对于POS,它将位于stanford-postagger-full-2015-04-20/models/
    • e、 对于解析器,不会有一个模型目录。

在代码中,请确保在追加模型名称之前搜索^{}目录。也可以看到,API还自动尝试在OS环境中搜索`CLASSPATH

请注意,从NLTK v3.1开始,STANFORD_JAR变量已弃用,不再使用。在以下Stackoverflow问题中找到的代码段可能无法工作:

TL;Ubuntu步骤3的DR

export STANFORDTOOLSDIR=/home/path/to/stanford/tools/

export CLASSPATH=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/stanford-postagger.jar:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/stanford-ner.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar

export STANFORD_MODELS=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/models:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/classifiers

对于Windows:有关设置环境变量的说明,请参见https://stackoverflow.com/a/17176423/610569

在启动python之前,必须按上述方式设置变量,然后:

>>> from nltk.tag.stanford import StanfordPOSTagger
>>> st = StanfordPOSTagger('english-bidirectional-distsim.tagger')
>>> st.tag('What is the airspeed of an unladen swallow ?'.split())
[(u'What', u'WP'), (u'is', u'VBZ'), (u'the', u'DT'), (u'airspeed', u'NN'), (u'of', u'IN'), (u'an', u'DT'), (u'unladen', u'JJ'), (u'swallow', u'VB'), (u'?', u'.')]

>>> from nltk.tag import StanfordNERTagger
>>> st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz') 
>>> st.tag('Rami Eid is studying at Stony Brook University in NY'.split())
[(u'Rami', u'PERSON'), (u'Eid', u'PERSON'), (u'is', u'O'), (u'studying', u'O'), (u'at', u'O'), (u'Stony', u'ORGANIZATION'), (u'Brook', u'ORGANIZATION'), (u'University', u'ORGANIZATION'), (u'in', u'O'), (u'NY', u'O')]


>>> from nltk.parse.stanford import StanfordParser
>>> parser=StanfordParser(model_path="edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz")
>>> list(parser.raw_parse("the quick brown fox jumps over the lazy dog"))
[Tree('ROOT', [Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['quick']), Tree('JJ', ['brown']), Tree('NN', ['fox'])]), Tree('NP', [Tree('NP', [Tree('NNS', ['jumps'])]), Tree('PP', [Tree('IN', ['over']), Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['lazy']), Tree('NN', ['dog'])])])])])])]

或者,您可以尝试在python中添加环境变量,正如前面的答案所建议的,但是您也可以直接告诉解析器/标记器初始化到保存.jar文件和模型的直接路径。

如果使用以下方法,则无需设置环境变量,但当API更改其参数名时,则需要相应更改。这就是为什么设置环境变量比修改python代码以适应NLTK版本更可取的原因。

例如(不设置任何环境变量):

# POS tagging:

from nltk.tag import StanfordPOSTagger

stanford_pos_dir = '/home/alvas/stanford-postagger-full-2015-04-20/'
eng_model_filename= stanford_pos_dir + 'models/english-left3words-distsim.tagger'
my_path_to_jar= stanford_pos_dir + 'stanford-postagger.jar'

st = StanfordPOSTagger(model_filename=eng_model_filename, path_to_jar=my_path_to_jar) 
st.tag('What is the airspeed of an unladen swallow ?'.split())


# NER Tagging:
from nltk.tag import StanfordNERTagger

stanford_ner_dir = '/home/alvas/stanford-ner/'
eng_model_filename= stanford_ner_dir + 'classifiers/english.all.3class.distsim.crf.ser.gz'
my_path_to_jar= stanford_ner_dir + 'stanford-ner.jar'

st = StanfordNERTagger(model_filename=eng_model_filename, path_to_jar=my_path_to_jar) 
st.tag('Rami Eid is studying at Stony Brook University in NY'.split())

# Parsing:
from nltk.parse.stanford import StanfordParser

stanford_parser_dir = '/home/alvas/stanford-parser/'
eng_model_path = stanford_parser_dir  + "edu/stanford/nlp/models/lexparser/englishRNN.ser.gz"
my_path_to_models_jar = stanford_parser_dir  + "stanford-parser-3.5.2-models.jar"
my_path_to_jar = stanford_parser_dir  + "stanford-parser.jar"

parser=StanfordParser(model_path=eng_model_path, path_to_models_jar=my_path_to_models_jar, path_to_jar=my_path_to_jar)

注意,这个答案适用于NLTK v 3.0,而不是更新的版本。

当然,在Python中尝试以下操作:

import os
from nltk.parse import stanford
os.environ['STANFORD_PARSER'] = '/path/to/standford/jars'
os.environ['STANFORD_MODELS'] = '/path/to/standford/jars'

parser = stanford.StanfordParser(model_path="/location/of/the/englishPCFG.ser.gz")
sentences = parser.raw_parse_sents(("Hello, My name is Melroy.", "What is your name?"))
print sentences

# GUI
for line in sentences:
    for sentence in line:
        sentence.draw()

输出:

[Tree('ROOT', [Tree('S', [Tree('INTJ', [Tree('UH', ['Hello'])]), Tree(',', [',']), Tree('NP', [Tree('PRP$', ['My']), Tree('NN', ['name'])]), Tree('VP', [Tree('VBZ', ['is']), Tree('ADJP', [Tree('JJ', ['Melroy'])])]), Tree('.', ['.'])])]), Tree('ROOT', [Tree('SBARQ', [Tree('WHNP', [Tree('WP', ['What'])]), Tree('SQ', [Tree('VBZ', ['is']), Tree('NP', [Tree('PRP$', ['your']), Tree('NN', ['name'])])]), Tree('.', ['?'])])])]

注1: 在本例中,解析器和模型jar都在同一个文件夹中。

注2:

  • 斯坦福解析器文件名为:stanford-parser.jar
  • 斯坦福模型文件名为:stanford-parser-x.x.x-models.jar

注3: englishPCFG.ser.gz文件可以在models.jar文件(/edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz)中找到。请使用come archive manager“解压缩”models.jar文件。

注4: 确保您使用的是Java JRE(运行时环境)1.8也称为Oracle JDK 8。否则将得到:不支持的主版本52.0。

安装

  1. https://github.com/nltk/nltk下载NLTK v3。安装NLTK:

    sudo python setup.py安装

  2. 您可以使用NLTK下载程序获得Stanford解析器,使用Python:

    import nltk
    nltk.download()
    
  3. 试试我的例子!(不要忘记更改jar路径并将模型路径更改为ser.gz位置)

或:

  1. 下载并安装NLTK v3,同上。

  2. 从(当前版本文件名为stanford-parser-full-2015-01-29.zip)下载最新版本: http://nlp.stanford.edu/software/lex-parser.shtml#Download

  3. 提取standford-parser-full-20xx-xx-xx.zip。

  4. 创建一个新文件夹(在我的示例中为“jars”)。将提取的文件放入这个jar文件夹:stanford-parser-3.x.x-models.jar和stanford-parser.jar。

    如上图所示,您可以使用环境变量(斯坦福解析器和斯坦福模型)指向这个“jars”文件夹。我正在使用Linux,所以如果您使用Windows,请使用类似于:C://folder//jars的内容。

  5. 使用归档管理器(7zip)打开stanford-parser-3.x.x-models.jar。

  6. 浏览jar文件:edu/stanford/nlp/models/lexparser。再次提取名为“englishPCFG.ser.gz”的文件。记住提取这个ser.gz文件的位置。

  7. 创建StanfordParser实例时,可以将模型路径作为参数提供。这是模型的完整路径,在我们的案例中是/location/of/englishPCFG.ser.gz。

  8. 试试我的例子!(不要忘记更改jar路径并将模型路径更改为ser.gz位置)

不赞成的回答

下面的答案不推荐使用,请使用https://stackoverflow.com/a/51981566/610569上的解决方案,用于NLTK v3.3及更高版本。


编辑

从当前的斯坦福解析器(2015-04-20)开始,lexparser.sh的默认输出已经更改,因此下面的脚本将不起作用。

但是这个答案是为了遗产而保留的,它仍然可以与http://nlp.stanford.edu/software/stanford-parser-2012-11-12.zip一起使用。


原始答案

我建议你不要搞乱Jython,Jype。让python做python的事情,让java做java的事情,通过控制台得到Stanford解析器的输出。

Stanford Parser安装到主目录~/中后,只需使用此python配方即可获得平括号解析:

import os
sentence = "this is a foo bar i want to parse."

os.popen("echo '"+sentence+"' > ~/stanfordtemp.txt")
parser_out = os.popen("~/stanford-parser-2012-11-12/lexparser.sh ~/stanfordtemp.txt").readlines()

bracketed_parse = " ".join( [i.strip() for i in parser_out if i.strip()[0] == "("] )
print bracketed_parse

相关问题 更多 >