nltk StanfordNERTagger:NoClassDefFoundError:org / slf4j / LoggerFactory(在Windows中)

时间:2015-12-18 18:20:23

标签: python windows nlp nltk stanford-nlp

注意:我使用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环境变量中。例如,我解压缩stanford jar的文件夹,我解压缩slf4j的地方,甚至是stanford文件夹中的lib文件夹。我不知道为什么会这样:(

可能是Windows吗?在

之前我遇到过windows路径问题

更新

  1. 我的Stanford NER版本是3.6.0。该zip文件显示stanford-ner-2015-12-09.zip

  2. 我也尝试使用stanford-ner-3.6.0.jar代替stanford-ner.jar,但仍然遇到同样的错误

  3. 当我右键点击stanford-ner-3.6.0.jar时,我注意到

  4. jar properties

    我看到我提取的所有文件,甚至是slf4j文件。这会导致问题吗?

    1. 最后,为什么错误消息会说
    2. java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

      我看不到任何名为org的文件夹

      更新:Env变量

      以下是我的env变量

      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
      

      这里有什么问题吗?

9 个答案:

答案 0 :(得分:11)

EDITED

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

  • NLTK 3.1版
  • 自2015-04-20以来编制的斯坦福工具

由于这两种工具变化相当快,并且API可能在3-6个月后看起来非常不同。请将以下答案视为时间而非永恒的解决方法。

总是参考https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software获取有关如何使用NLTK连接Stanford 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说明,请参阅https://stackoverflow.com/a/17176423/610569

(有关在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

的更多详细说明

答案 1 :(得分:4)

我遇到了与你昨天描述的完全相同的问题。

您需要做三件事。

1)更新您的NLTK。

pip install -U nltk

您的版本应为&gt; 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的地方(可以在这里下载:{{3} })

3)不要忘记指定你下载的地方&#39; english.all.3class.distsim.crf.ser.gz&#39; &安培; &#39;斯坦福-ner.jar&#39;

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())

答案 2 :(得分:3)

注意:

以下是与之合作的时间黑客:

  • NLTK 3.1版
  • Stanford NER编译于2015-12-09

此解决方案 NOT 意味着永恒的解决方案。

总是参考https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software获取有关如何使用NLTK连接Stanford NLP工具的最新说明!!

如果您不想使用此问题,请跟踪此问题的更新&#34; hack&#34;:https://github.com/nltk/nltk/issues/1237或请在2015-04-20使用NER工具compield。

简而言之

确保您拥有:

  • NLTK 3.1版
  • Stanford NER编译于2015-12-09
  • 设置CLASSPATHSTANFORD_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')]

答案 3 :(得分:2)

我修好了!

你应该在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行: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)

答案 4 :(得分:2)

目前的斯坦福NER标记版与nltk不兼容,因为它需要nltk无法添加到CLASSPATH的其他广告。

相反,更喜欢旧版本的Stanford NER Tagger,它的效果非常好,如下所示:http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip

答案 5 :(得分:2)

对于那些想要使用Stanford NER&gt; = 3.6.0而不是2015-01-30(3.5.1)或其他旧版本的人,请改为:

  1. 将stanford-ner.jar和slf4j-api.jar放入相同文件夹

    例如,我将以下文件放入 / path-to-libs /

    • 斯坦福-NER-3.6.0.jar
    • SLF4J-API-1.7.18.jar
  2. 然后:

    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"])
    

答案 6 :(得分:1)

我认为问题在于如何使用slf4j

我在nltk 3.1并使用stanford-parser-full-2015-12-09。我只能这样做才能修改/Library/Python/2.7/site-packages/nltk/parse/stanford.py并在slf4j方法中将self._classpath jar添加到init

解决了它。原油 - 但是 - 有效。

注意 - 我没有完全尝试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>')

答案 7 :(得分:0)

据我所知,代码中没有为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())   

检查这是否解决了您的问题。

答案 8 :(得分:0)

最好的办法就是下载最新版本的Stanford NER标记器,其中依赖性问题现已修复(2018年3月)。

wget https://nlp.stanford.edu/software/stanford-ner-2018-02-27.zip