nltk StanfordNERTagger : NoClassDefFoundError: org/slf4j/LoggerFactory (In Windows)
nltk StanfordNERTagger : NoClassDefFoundError: org/slf4j/LoggerFactory (In Windows)
注意:我使用 Python 2.7 作为 Anaconda 发行版的一部分。我希望这不是 nltk 3.1 的问题。
我正在尝试将 nltk 用于 NER 作为
import nltk
from nltk.tag.stanford import StanfordNERTagger
#st = StanfordNERTagger('stanford-ner/all.3class.distsim.crf.ser.gz', 'stanford-ner/stanford-ner.jar')
st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz')
print st.tag(str)
但我得到
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at edu.stanford.nlp.io.IOUtils.<clinit>(IOUtils.java:41)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.classifyAndWriteAnswers(AbstractSequenceClassifier.java:1117)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.classifyAndWriteAnswers(AbstractSequenceClassifier.java:1076)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.classifyAndWriteAnswers(AbstractSequenceClassifier.java:1057)
at edu.stanford.nlp.ie.crf.CRFClassifier.main(CRFClassifier.java:3088)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 5 more
Traceback (most recent call last):
File "X:\jnk.py", line 47, in <module>
print st.tag(str)
File "X:\Anaconda2\lib\site-packages\nltk\tag\stanford.py", line 66, in tag
return sum(self.tag_sents([tokens]), [])
File "X:\Anaconda2\lib\site-packages\nltk\tag\stanford.py", line 89, in tag_sents
stdout=PIPE, stderr=PIPE)
File "X:\Anaconda2\lib\site-packages\nltk\internals.py", line 134, in java
raise OSError('Java command failed : ' + str(cmd))
OSError: Java command failed : ['X:\PROGRA~1\Java\JDK18~1.0_6\bin\java.exe', '-mx1000m', '-cp', 'X:\stanford\stanford-ner.jar', 'edu.stanford.nlp.ie.crf.CRFClassifier', '-loadClassifier', 'X:\stanford\classifiers\english.all.3class.distsim.crf.ser.gz', '-textFile', 'x:\appdata\local\temp\tmpqjsoma', '-outputFormat', 'slashTags', '-tokenizerFactory', 'edu.stanford.nlp.process.WhitespaceTokenizer', '-tokenizerOptions', '"tokenizeNLs=false"', '-encoding', 'utf8']
但我可以看到 slf4j jar 在我的 lib 文件夹中。我需要更新环境变量吗?
编辑
感谢大家的帮助,但我仍然得到同样的错误。这是我最近尝试过的
import nltk
from nltk.tag import StanfordNERTagger
print(nltk.__version__)
stanford_ner_dir = 'X:\stanford\'
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)
print st._stanford_model
print st._stanford_jar
st.tag('Rami Eid is studying at Stony Brook University in NY'.split())
还有
import nltk
from nltk.tag import StanfordNERTagger
print(nltk.__version__)
st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz')
print st._stanford_model
print st._stanford_jar
st.tag('Rami Eid is studying at Stony Brook University in NY'.split())
我得到
3.1
X:\stanford\classifiers\english.all.3class.distsim.crf.ser.gz
X:\stanford\stanford-ner.jar
之后它继续打印与之前相同的堆栈跟踪。 java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
知道为什么会这样吗?我也更新了我的 CLASSPATH。我什至将所有相关文件夹添加到我的 PATH 环境 variable.for 例如,我解压 stanford jars 的文件夹,我解压 slf4j 的地方,甚至是 stanford 文件夹中的 lib 文件夹。我不知道为什么会这样:(
难道是windows?我在
之前遇到 windows 路径问题
更新
我的 Stanford NER 版本是 3.6.0。 zip 文件显示 stanford-ner-2015-12-09.zip
我也尝试使用 stanford-ner-3.6.0.jar
而不是 stanford-ner.jar
但仍然得到相同的错误
当我右键单击 stanford-ner-3.6.0.jar
时,我注意到
我在提取的所有文件中都看到了这个,甚至是 slf4j files.could 这会导致问题吗?
- 最后,为什么报错信息说
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
我在任何地方都没有看到任何名为 org
的文件夹
更新:环境变量
这是我的环境变量
CLASSPATH
.;
X:\jre1.8.0_60\lib\rt.jar;
X:\stanford\stanford-ner-3.6.0.jar;
X:\stanford\stanford-ner.jar;
X:\stanford\lib\slf4j-simple.jar;
X:\stanford\lib\slf4j-api.jar;
X:\slf4j\slf4j-1.7.13\slf4j-1.7.13\slf4j-log4j12-1.7.13.jar
STANFORD_MODELS
X:\stanford\classifiers
JAVA_HOME
X:\PROGRA~1\Java\JDK18~1.0_6
PATH
X:\PROGRA~1\Java\JDK18~1.0_6\bin;
X:\stanford;
X:\stanford\lib;
X:\slf4j\slf4j-1.7.13\slf4j-1.7.13
这里有什么问题吗?
已编辑
注意:以下答案仅适用于:
- NLTK 版本 3.1
- 自 2015 年 4 月 20 日起编译的 Stanford 工具
因为这两种工具都变化得相当快,而且 API 可能在 3-6 个月后看起来非常不同。请将以下答案视为暂时的而非永恒的解决方案。
始终参考 https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software 以获取有关如何使用 NLTK 连接斯坦福 NLP 工具的最新说明!!
步骤 1
首先使用
将您的 NLTK 更新到版本 3.1
pip install -U nltk
或(对于 Windows)使用 http://pypi.python.org/pypi/nltk
下载最新的 NLTK
然后使用以下方法检查您的版本是否为 3.1:
python3 -c "import nltk; print(nltk.__version__)"
第 2 步
然后从 http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip 下载 zip 文件并解压缩文件并保存到 C:\some\path\to\stanford-ner\
(在 windows)
步骤 3
然后将CLASSPATH
的环境变量设置为C:\some\path\to\stanford-ner\stanford-ner.jar
和STANFORD_MODELS
的环境变量
C:\some\path\to\stanford-ner\classifiers
或在命令行中(仅适用于Windows):
set CLASSPATH=%CLASSPATH%;C:\some\path\to\stanford-ner\stanford-ner.jar
set STANFORD_MODELS=%STANFORD_MODELS%;C:\some\path\to\stanford-ner\classifiers
(有关在 Windows 中设置环境变量的单击 GUI 说明,请参阅 )
(有关在Linux中设置环境变量的详细信息,请参阅Stanford Parser and NLTK)
第 4 步
然后在 python:
>>> 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.tag import StanfordNERTagger
stanford_ner_dir = 'C:\some\path\to\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())
在 Stanford Parser and NLTK
上查看更详细的说明
我遇到了和你昨天描述的完全一样的问题。
您需要做 3 件事。
1) 更新您的 NLTK。
pip install -U nltk
你的版本应该>3.1
我看到你正在使用
from nltk.tag.stanford import StanfordNERTagger
但是,您必须使用新模块:
from nltk.tag import StanfordNERTagger
2) 下载 slf4j 并更新您的 CLASSPATH。
这是更新 CLASSPATH 的方法。
javapath = "/Users/aerin/Downloads/stanford-ner-2014-06-16/stanford-ner.jar:/Users/aerin/java/slf4j-1.7.13/slf4j-log4j12-1.7.13.jar"
os.environ['CLASSPATH'] = javapath
如上所见,javapath包含2个路径,一个是stanford-ner.jar所在,另一个是你下载slf4j-log4j12-1.7.13.jar的地方(可以下载这里:http://www.slf4j.org/download.html)
3) 不要忘记指定下载位置 'english.all.3class.distsim.crf.ser.gz' & 'stanford-ner.jar'
st = StanfordNERTagger('/Users/aerin/Downloads/stanford-ner-2014-06-16/classifiers/english.all.3class.distsim.crf.ser.gz','/Users/aerin/Downloads/stanford-ner-2014-06-16/stanford-ner.jar')
st.tag("Doneyo lab did such an awesome job!".split())
注意:
下面是一个可以使用的时间黑客:
- NLTK 版本 3.1
- 斯坦福 NER 编译于 2015-12-09
这个解决方案不是意味着一个永恒的解决方案。
请始终参考 https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software 以获取有关如何使用 NLTK 连接 Stanford NLP 工具的最新说明!!
如果您不想使用此 "hack",请跟踪此问题的更新:https://github.com/nltk/nltk/issues/1237 或请在 2015 年 4 月 20 日使用 NER 工具编译。
简而言之
确保您拥有:
- NLTK 版本 3.1
- 斯坦福 NER 编译于 2015-12-09
- 为
CLASSPATH
和 STANFORD_MODELS
设置环境变量
在Windows中设置环境变量:
set CLASSPATH=%CLASSPATH%;C:\some\path\to\stanford-ner\stanford-ner.jar
set STANFORD_MODELS=%STANFORD_MODELS%;C:\some\path\to\stanford-ner\classifiers
在Linux中设置环境变量:
export STANFORDTOOLSDIR=/home/some/path/to/stanfordtools/
export CLASSPATH=$STANFORDTOOLSDIR/stanford-ner-2015-12-09/stanford-ner.jar
export STANFORD_MODELS=$STANFORDTOOLSDIR/stanford-ner-2015-12-09/classifiers
然后:
>>> from nltk.internals import find_jars_within_path
>>> from nltk.tag import StanfordNERTagger
>>> st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz')
# Note this is where your stanford_jar is saved.
# We are accessing the environment variables you've
# set through the NLTK API.
>>> print st._stanford_jar
/home/alvas/stanford-ner-2015-12-09/stanford-ner.jar
>>> stanford_dir = st._stanford_jar.rpartition("\")[0] # windows
# Note in linux you do this instead:
>>> stanford_dir = st._stanford_jar.rpartition('/')[0] # linux
# Use the `find_jars_within_path` function to get all the
# jar files out from stanford NER tool under the libs/ dir.
>>> stanford_jars = find_jars_within_path(stanford_dir)
# Put the jars back into the `stanford_jar` classpath.
>>> st._stanford_jar = ':'.join(stanford_jars) # linux
>>> st._stanford_jar = ';'.join(stanford_jars) # windows
>>> 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')]
据我所知,您的代码中没有为 python 设置 java environment
。
您可以使用以下代码来完成此操作:
from nltk.tag.stanford import NERTagger
import os
java_path = "/Java/jdk1.8.0_45/bin/java.exe"
os.environ['JAVAHOME'] = java_path
st = NERTagger('../ner-model.ser.gz','../stanford-ner.jar')
tagging = st.tag(text.split())
检查这是否解决了您的问题。
我认为问题在于 slf4j
的使用方式。
我正在使用 nltk 3.1 并使用 stanford-parser-full-2015-12-09
。我唯一能让它工作的方法是修改 /Library/Python/2.7/site-packages/nltk/parse/stanford.py
并将 slf4j
jar 添加到 init
方法中的 self._classpath
。
这就解决了。粗糙 - 但 - 有效。
注意 - 我并没有完全尝试 NER。我正在尝试类似下面的东西
import os
from nltk.parse import stanford
os.environ['STANFORD_PARSER'] = '/Users/run2/stanford-parser-full-2015-12-09'
os.environ['STANFORD_MODELS'] = '/Users/run2/stanford-parser-full-2015-12-09'
parser = stanford.StanfordParser(model_path='/Users/run2/stanford-parser-full-2015-12-09/englishPCFG.ser.gz')
sentences = parser.raw_parse_sents('<some sentence from my corpus>')
我修好了!
u 应该在CLASSPATH
中指明slf4j-api.jar的完整路径
而不是将 jar-path 添加到系统环境变量中,您可以在代码中这样做:
_CLASS_PATH = "."
if os.environ.get('CLASSPATH') is not None:
_CLASS_PATH = os.environ.get('CLASSPATH')
os.environ['CLASSPATH'] = _CLASS_PATH + ';F:\Python\Lib\slf4j\slf4j-api-1.7.13.jar'
重要,在nltk/*/stanford.py中会重置这样的类路径:
stdout, stderr = java(cmd, classpath=self._stanford_jar, stdout=PIPE, stderr=PIPE)
例如。 \Python34\Lib\site-packages\nltk\tokenize\stanford.py line:90
你可以这样解决:
_CLASS_PATH = "."
if os.environ.get('CLASSPATH') is not None:
_CLASS_PATH = os.environ.get('CLASSPATH')
stdout, stderr = java(cmd, classpath=(self._stanford_jar, _CLASS_PATH), stdout=PIPE, stderr=PIPE)
当前 Stanford NER 标记器版本与 nltk
不兼容,因为它需要 nltk
无法添加到 CLASSPATH
的额外 jar。
相反,更喜欢旧版本的 Stanford NER Tagger,它可以像这样完美地工作:http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip
对于那些想要使用 Stanford NER >= 3.6.0 而不是 2015-01-30 (3.5.1) 或其他旧版本的人,请改为:
将stanford-ner.jar和slf4j-api.jar放入同一个文件夹
比如我把下面的文件放到/path-to-libs/
- stanford-ner-3.6.0.jar
- slf4j-api-1.7.18.jar
然后:
classpath = "/path-to-libs/*"
st = nltk.tag.StanfordNERTagger(
"/path-to-model/ner-model.ser.gz",
"/path-to-libs/stanford-ner-3.6.0.jar"
)
st._stanford_jar = classpath
result = st.tag(["Hello"])
最好的办法就是下载最新版本的 Stanford NER 标注器,其中依赖性问题现已修复(2018 年 3 月)。
wget https://nlp.stanford.edu/software/stanford-ner-2018-02-27.zip
注意:我使用 Python 2.7 作为 Anaconda 发行版的一部分。我希望这不是 nltk 3.1 的问题。
我正在尝试将 nltk 用于 NER 作为
import nltk
from nltk.tag.stanford import StanfordNERTagger
#st = StanfordNERTagger('stanford-ner/all.3class.distsim.crf.ser.gz', 'stanford-ner/stanford-ner.jar')
st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz')
print st.tag(str)
但我得到
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at edu.stanford.nlp.io.IOUtils.<clinit>(IOUtils.java:41)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.classifyAndWriteAnswers(AbstractSequenceClassifier.java:1117)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.classifyAndWriteAnswers(AbstractSequenceClassifier.java:1076)
at edu.stanford.nlp.ie.AbstractSequenceClassifier.classifyAndWriteAnswers(AbstractSequenceClassifier.java:1057)
at edu.stanford.nlp.ie.crf.CRFClassifier.main(CRFClassifier.java:3088)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 5 more
Traceback (most recent call last):
File "X:\jnk.py", line 47, in <module>
print st.tag(str)
File "X:\Anaconda2\lib\site-packages\nltk\tag\stanford.py", line 66, in tag
return sum(self.tag_sents([tokens]), [])
File "X:\Anaconda2\lib\site-packages\nltk\tag\stanford.py", line 89, in tag_sents
stdout=PIPE, stderr=PIPE)
File "X:\Anaconda2\lib\site-packages\nltk\internals.py", line 134, in java
raise OSError('Java command failed : ' + str(cmd))
OSError: Java command failed : ['X:\PROGRA~1\Java\JDK18~1.0_6\bin\java.exe', '-mx1000m', '-cp', 'X:\stanford\stanford-ner.jar', 'edu.stanford.nlp.ie.crf.CRFClassifier', '-loadClassifier', 'X:\stanford\classifiers\english.all.3class.distsim.crf.ser.gz', '-textFile', 'x:\appdata\local\temp\tmpqjsoma', '-outputFormat', 'slashTags', '-tokenizerFactory', 'edu.stanford.nlp.process.WhitespaceTokenizer', '-tokenizerOptions', '"tokenizeNLs=false"', '-encoding', 'utf8']
但我可以看到 slf4j jar 在我的 lib 文件夹中。我需要更新环境变量吗?
编辑
感谢大家的帮助,但我仍然得到同样的错误。这是我最近尝试过的
import nltk
from nltk.tag import StanfordNERTagger
print(nltk.__version__)
stanford_ner_dir = 'X:\stanford\'
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)
print st._stanford_model
print st._stanford_jar
st.tag('Rami Eid is studying at Stony Brook University in NY'.split())
还有
import nltk
from nltk.tag import StanfordNERTagger
print(nltk.__version__)
st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz')
print st._stanford_model
print st._stanford_jar
st.tag('Rami Eid is studying at Stony Brook University in NY'.split())
我得到
3.1
X:\stanford\classifiers\english.all.3class.distsim.crf.ser.gz
X:\stanford\stanford-ner.jar
之后它继续打印与之前相同的堆栈跟踪。 java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
知道为什么会这样吗?我也更新了我的 CLASSPATH。我什至将所有相关文件夹添加到我的 PATH 环境 variable.for 例如,我解压 stanford jars 的文件夹,我解压 slf4j 的地方,甚至是 stanford 文件夹中的 lib 文件夹。我不知道为什么会这样:(
难道是windows?我在
之前遇到 windows 路径问题更新
我的 Stanford NER 版本是 3.6.0。 zip 文件显示
stanford-ner-2015-12-09.zip
我也尝试使用
stanford-ner-3.6.0.jar
而不是stanford-ner.jar
但仍然得到相同的错误当我右键单击
stanford-ner-3.6.0.jar
时,我注意到
我在提取的所有文件中都看到了这个,甚至是 slf4j files.could 这会导致问题吗?
- 最后,为什么报错信息说
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
我在任何地方都没有看到任何名为 org
的文件夹
更新:环境变量
这是我的环境变量
CLASSPATH
.;
X:\jre1.8.0_60\lib\rt.jar;
X:\stanford\stanford-ner-3.6.0.jar;
X:\stanford\stanford-ner.jar;
X:\stanford\lib\slf4j-simple.jar;
X:\stanford\lib\slf4j-api.jar;
X:\slf4j\slf4j-1.7.13\slf4j-1.7.13\slf4j-log4j12-1.7.13.jar
STANFORD_MODELS
X:\stanford\classifiers
JAVA_HOME
X:\PROGRA~1\Java\JDK18~1.0_6
PATH
X:\PROGRA~1\Java\JDK18~1.0_6\bin;
X:\stanford;
X:\stanford\lib;
X:\slf4j\slf4j-1.7.13\slf4j-1.7.13
这里有什么问题吗?
已编辑
注意:以下答案仅适用于:
- NLTK 版本 3.1
- 自 2015 年 4 月 20 日起编译的 Stanford 工具
因为这两种工具都变化得相当快,而且 API 可能在 3-6 个月后看起来非常不同。请将以下答案视为暂时的而非永恒的解决方案。
始终参考 https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software 以获取有关如何使用 NLTK 连接斯坦福 NLP 工具的最新说明!!
步骤 1
首先使用
将您的 NLTK 更新到版本 3.1pip install -U nltk
或(对于 Windows)使用 http://pypi.python.org/pypi/nltk
下载最新的 NLTK然后使用以下方法检查您的版本是否为 3.1:
python3 -c "import nltk; print(nltk.__version__)"
第 2 步
然后从 http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip 下载 zip 文件并解压缩文件并保存到 C:\some\path\to\stanford-ner\
(在 windows)
步骤 3
然后将CLASSPATH
的环境变量设置为C:\some\path\to\stanford-ner\stanford-ner.jar
和STANFORD_MODELS
的环境变量
C:\some\path\to\stanford-ner\classifiers
或在命令行中(仅适用于Windows):
set CLASSPATH=%CLASSPATH%;C:\some\path\to\stanford-ner\stanford-ner.jar
set STANFORD_MODELS=%STANFORD_MODELS%;C:\some\path\to\stanford-ner\classifiers
(有关在 Windows 中设置环境变量的单击 GUI 说明,请参阅 )
(有关在Linux中设置环境变量的详细信息,请参阅Stanford Parser and NLTK)
第 4 步
然后在 python:
>>> 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.tag import StanfordNERTagger
stanford_ner_dir = 'C:\some\path\to\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())
在 Stanford Parser and NLTK
上查看更详细的说明我遇到了和你昨天描述的完全一样的问题。
您需要做 3 件事。
1) 更新您的 NLTK。
pip install -U nltk
你的版本应该>3.1 我看到你正在使用
from nltk.tag.stanford import StanfordNERTagger
但是,您必须使用新模块:
from nltk.tag import StanfordNERTagger
2) 下载 slf4j 并更新您的 CLASSPATH。
这是更新 CLASSPATH 的方法。
javapath = "/Users/aerin/Downloads/stanford-ner-2014-06-16/stanford-ner.jar:/Users/aerin/java/slf4j-1.7.13/slf4j-log4j12-1.7.13.jar"
os.environ['CLASSPATH'] = javapath
如上所见,javapath包含2个路径,一个是stanford-ner.jar所在,另一个是你下载slf4j-log4j12-1.7.13.jar的地方(可以下载这里:http://www.slf4j.org/download.html)
3) 不要忘记指定下载位置 'english.all.3class.distsim.crf.ser.gz' & 'stanford-ner.jar'
st = StanfordNERTagger('/Users/aerin/Downloads/stanford-ner-2014-06-16/classifiers/english.all.3class.distsim.crf.ser.gz','/Users/aerin/Downloads/stanford-ner-2014-06-16/stanford-ner.jar')
st.tag("Doneyo lab did such an awesome job!".split())
注意:
下面是一个可以使用的时间黑客:
- NLTK 版本 3.1
- 斯坦福 NER 编译于 2015-12-09
这个解决方案不是意味着一个永恒的解决方案。
请始终参考 https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software 以获取有关如何使用 NLTK 连接 Stanford NLP 工具的最新说明!!
如果您不想使用此 "hack",请跟踪此问题的更新:https://github.com/nltk/nltk/issues/1237 或请在 2015 年 4 月 20 日使用 NER 工具编译。
简而言之
确保您拥有:
- NLTK 版本 3.1
- 斯坦福 NER 编译于 2015-12-09
- 为
CLASSPATH
和STANFORD_MODELS
设置环境变量
在Windows中设置环境变量:
set CLASSPATH=%CLASSPATH%;C:\some\path\to\stanford-ner\stanford-ner.jar
set STANFORD_MODELS=%STANFORD_MODELS%;C:\some\path\to\stanford-ner\classifiers
在Linux中设置环境变量:
export STANFORDTOOLSDIR=/home/some/path/to/stanfordtools/
export CLASSPATH=$STANFORDTOOLSDIR/stanford-ner-2015-12-09/stanford-ner.jar
export STANFORD_MODELS=$STANFORDTOOLSDIR/stanford-ner-2015-12-09/classifiers
然后:
>>> from nltk.internals import find_jars_within_path
>>> from nltk.tag import StanfordNERTagger
>>> st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz')
# Note this is where your stanford_jar is saved.
# We are accessing the environment variables you've
# set through the NLTK API.
>>> print st._stanford_jar
/home/alvas/stanford-ner-2015-12-09/stanford-ner.jar
>>> stanford_dir = st._stanford_jar.rpartition("\")[0] # windows
# Note in linux you do this instead:
>>> stanford_dir = st._stanford_jar.rpartition('/')[0] # linux
# Use the `find_jars_within_path` function to get all the
# jar files out from stanford NER tool under the libs/ dir.
>>> stanford_jars = find_jars_within_path(stanford_dir)
# Put the jars back into the `stanford_jar` classpath.
>>> st._stanford_jar = ':'.join(stanford_jars) # linux
>>> st._stanford_jar = ';'.join(stanford_jars) # windows
>>> 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')]
据我所知,您的代码中没有为 python 设置 java environment
。
您可以使用以下代码来完成此操作:
from nltk.tag.stanford import NERTagger
import os
java_path = "/Java/jdk1.8.0_45/bin/java.exe"
os.environ['JAVAHOME'] = java_path
st = NERTagger('../ner-model.ser.gz','../stanford-ner.jar')
tagging = st.tag(text.split())
检查这是否解决了您的问题。
我认为问题在于 slf4j
的使用方式。
我正在使用 nltk 3.1 并使用 stanford-parser-full-2015-12-09
。我唯一能让它工作的方法是修改 /Library/Python/2.7/site-packages/nltk/parse/stanford.py
并将 slf4j
jar 添加到 init
方法中的 self._classpath
。
这就解决了。粗糙 - 但 - 有效。
注意 - 我并没有完全尝试 NER。我正在尝试类似下面的东西
import os
from nltk.parse import stanford
os.environ['STANFORD_PARSER'] = '/Users/run2/stanford-parser-full-2015-12-09'
os.environ['STANFORD_MODELS'] = '/Users/run2/stanford-parser-full-2015-12-09'
parser = stanford.StanfordParser(model_path='/Users/run2/stanford-parser-full-2015-12-09/englishPCFG.ser.gz')
sentences = parser.raw_parse_sents('<some sentence from my corpus>')
我修好了!
u 应该在CLASSPATH
中指明slf4j-api.jar的完整路径而不是将 jar-path 添加到系统环境变量中,您可以在代码中这样做:
_CLASS_PATH = "."
if os.environ.get('CLASSPATH') is not None:
_CLASS_PATH = os.environ.get('CLASSPATH')
os.environ['CLASSPATH'] = _CLASS_PATH + ';F:\Python\Lib\slf4j\slf4j-api-1.7.13.jar'
重要,在nltk/*/stanford.py中会重置这样的类路径:
stdout, stderr = java(cmd, classpath=self._stanford_jar, stdout=PIPE, stderr=PIPE)
例如。 \Python34\Lib\site-packages\nltk\tokenize\stanford.py line:90
你可以这样解决:
_CLASS_PATH = "."
if os.environ.get('CLASSPATH') is not None:
_CLASS_PATH = os.environ.get('CLASSPATH')
stdout, stderr = java(cmd, classpath=(self._stanford_jar, _CLASS_PATH), stdout=PIPE, stderr=PIPE)
当前 Stanford NER 标记器版本与 nltk
不兼容,因为它需要 nltk
无法添加到 CLASSPATH
的额外 jar。
相反,更喜欢旧版本的 Stanford NER Tagger,它可以像这样完美地工作:http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip
对于那些想要使用 Stanford NER >= 3.6.0 而不是 2015-01-30 (3.5.1) 或其他旧版本的人,请改为:
将stanford-ner.jar和slf4j-api.jar放入同一个文件夹
比如我把下面的文件放到/path-to-libs/
- stanford-ner-3.6.0.jar
- slf4j-api-1.7.18.jar
然后:
classpath = "/path-to-libs/*" st = nltk.tag.StanfordNERTagger( "/path-to-model/ner-model.ser.gz", "/path-to-libs/stanford-ner-3.6.0.jar" ) st._stanford_jar = classpath result = st.tag(["Hello"])
最好的办法就是下载最新版本的 Stanford NER 标注器,其中依赖性问题现已修复(2018 年 3 月)。
wget https://nlp.stanford.edu/software/stanford-ner-2018-02-27.zip