nltk StanfordNERTagger: NoClassDefFoundError: org / slf4j / LoggerFactory (в 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:Anaconda2libsite-packagesnltktagstanford.py", line 66, in tag
    return sum(self.tag_sents([tokens]), []) 
  File "X:Anaconda2libsite-packagesnltktagstanford.py", line 89, in tag_sents
    stdout=PIPE, stderr=PIPE)
  File "X:Anaconda2libsite-packagesnltkinternals.py", line 134, in java
    raise OSError('Java command failed : ' + str(cmd))
OSError: Java command failed : ['X:PROGRA~1JavaJDK18~1.0_6binjava.exe', '-mx1000m', '-cp', 'X:stanfordstanford-ner.jar', 'edu.stanford.nlp.ie.crf.CRFClassifier', '-loadClassifier', 'X:stanfordclassifiersenglish.all.3class.distsim.crf.ser.gz', '-textFile', 'x:appdatalocaltemptmpqjsoma', '-outputFormat', 'slashTags', '-tokenizerFactory', 'edu.stanford.nlp.process.WhitespaceTokenizer', '-tokenizerOptions', '"tokenizeNLs=false"', '-encoding', 'utf8']

но я вижу, что Банка slf4j находится в моей папке lib. нужно ли обновлять переменную среды?

редактировать

спасибо всем за помощь, но я все еще получаю ту же ошибку. Вот что я пробовал недавно

import nltk
from nltk.tag import StanfordNERTagger 
print(nltk.__version__)
stanford_ner_dir = 'X:stanford'
eng_model_filename= stanford_ner_dir + 'classifiersenglish.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:stanfordclassifiersenglish.all.3class.distsim.crf.ser.gz
X:stanfordstanford-ner.jar

после этого он продолжает печатать тот же stacktrace, что и раньше. java.lang.ClassNotFoundException: org.slf4j.LoggerFactory

есть идеи, почему это может произойти? Я также обновил свой путь к классам. Я даже добавил все соответствующие папки в переменную среды PATH.например, папку, в которой я расстегнул банки Стэнфорда, место, где я расстегнул slf4j, и даже папку 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, я заметил

jar properties

я вижу это для всех файлов, которые я извлек, даже файлы slf4j.может ли это быть причиной проблемы?

  1. наконец, почему сообщение об ошибке сказать

java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

Я не вижу папку с именем org в любом месте

обновление: переменные Env

вот мой env переменные

CLASSPATH
.;
X:jre1.8.0_60librt.jar;
X:stanfordstanford-ner-3.6.0.jar;
X:stanfordstanford-ner.jar;
X:stanfordlibslf4j-simple.jar;
X:stanfordlibslf4j-api.jar;
X:slf4jslf4j-1.7.13slf4j-1.7.13slf4j-log4j12-1.7.13.jar

STANFORD_MODELS
X:stanfordclassifiers

JAVA_HOME
X:PROGRA~1JavaJDK18~1.0_6

PATH
X:PROGRA~1JavaJDK18~1.0_6bin;
X:stanford;
X:stanfordlib;
X:slf4jslf4j-1.7.13slf4j-1.7.13

что здесь не так?

9 ответов


редактировать

Примечание: следующий ответ будет работать только на:

  • nltk версии 3.1
  • инструменты Стэнфорда, составленные с 2015-04-20

поскольку оба инструмента меняются довольно быстро, и API может выглядеть очень по-разному 3-6 месяцев спустя. Пожалуйста, рассматривайте следующий ответ как временное, а не вечное исправление.

всегда относятся к https://github.com/nltk/nltk/wiki/Installing-Third-Party-Software для последней инструкции о том, как взаимодействовать инструменты НЛП Стэнфорда с помощью NLTK!!


Шаг 1

сначала обновите NLTK до версии 3.1 с помощью

pip install -U nltk

или (для Windows) загрузите последнюю версию NLTK с помощьюhttp://pypi.python.org/pypi/nltk

затем проверьте, что у вас есть версия 3.1 с помощью:

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

шаг 2

затем загрузите zip-файл из http://nlp.stanford.edu/software/stanford-ner-2015-04-20.zip и распаковать файл и сохранить в C:\some\path\to\stanford-ner\ (в windows)

Шаг 3

затем установите переменную окружения для CLASSPATH to 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

(см. https://stackoverflow.com/a/17176423/610569 для click-click GUI инструкции по настройке переменных среды в Windows)

(см. Стэнфордский парсер и NLTK подробнее о настройке переменных среды в Linux)

Шаг 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())

посмотреть более подробную инструкцию о Стэнфордский Парсер и НЛТК


я столкнулся с точно такой же проблемой, как вы описали вчера.

есть 3 вещи, которые нужно сделать.

1) обновите свой NLTK.

pip install -U nltk

ваша версия должна быть >3.1 и я вижу, что вы используете

from nltk.tag.stanford import StanfordNERTagger

однако, вы должны использовать новый модуль:

from nltk.tag import StanfordNERTagger

2) Загрузите slf4j и обновите свой путь к классам.

вот как вы обновите ПУТЬ КЛАССА.

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 пути, один из которых-Стэнфорд-Нер.jar, другой, где вы загрузили slf4j-log4j12-1.7.13.jar (его можно скачать здесь:http://www.slf4j.org/download.html)

3) Не забудьте указать где вы скачали английский.все.3class.distsim.ОФД.серийный.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!!

пожалуйста, отслеживайте обновления по этому вопросу, если вы не хотите использовать этот "хак":https://github.com/nltk/nltk/issues/1237 или, пожалуйста, используйте Ner tool compield на 2015-04-20.


Короче

убедитесь, что у вас есть:

  • 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')]

Я починил!

u должен указывать полный путь из slf4j-API-интерфейс.jar в CLASSPATH

вместо добавления jar-path в системную переменную среды, u может сделать это в коде:

_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 будет сброс переменной classpath такой:

stdout, stderr = java(cmd, classpath=self._stanford_jar, stdout=PIPE, stderr=PIPE)

например. \Python34\Lib\site-packages\nltk\tokenize\stanford.py линия: 90

u может исправить это следующим образом:

_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 tagger не совместима с nltk потому что это требует дополнительных коробит, что nltk не добавлять к CLASSPATH.

вместо этого предпочитайте более старую версию 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) или другой старой версии, сделайте это вместо:

  1. положите Стэнфорд-Нер.jar и slf4j-API-интерфейс.jar в папку

    например, я помещаю следующие файлы в /путь-к-библиотеки/

    • Стэнфорд-Нер-3.6.0.Джар
    • slf4j-API-интерфейс-1.7.18.Джар
  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"])
    

Я думаю, что проблема в том, как slf4j использовался.

Я на nltk 3.1 и использую stanford-parser-full-2015-12-09. Я только так мог заставить его работать, чтобы изменить /Library/Python/2.7/site-packages/nltk/parse/stanford.py и добавить slf4j jar to self._classpath внутри init метод.

это решено. Сырой, но работает.

примечание - Я не пытался точно. Я пытался что-то вроде ниже

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

по-моему java environment не установлен для python в вашем коде.

Вы можете сделать это, используя следующий код:

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

Проверьте, решает ли это вашу проблему.


лучше всего просто загрузить последнюю версию теггера Stanford NER, где проблема зависимости теперь исправлена (март 2018).

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