После обучения моего собственного классификатора с помощью nltk, как мне загрузить его в textblob?

Встроенный классификатор в textblob довольно тупой. Он обучен на обзорах фильмов, поэтому я создал огромный набор примеров в моем контексте (57 000 историй, классифицированных как положительные или отрицательные), а затем обучил его с помощью nltk.. Я пытался обучить его с помощью textblob, но это всегда терпело неудачу:

with open('train.json', 'r') as fp:
    cl = NaiveBayesClassifier(fp, format="json")

Это будет работать часами и закончится ошибкой памяти.

Я посмотрел на источник и обнаружил, что он просто использует nltk и обертывает его, поэтому я использовал его вместо этого, и это сработало.

Структура обучающего набора nltk должна была представлять собой список кортежей, причем первая часть представляла собой счетчик слов в тексте и частоту появления. Вторая часть кортежа была «pos» или «neg» для тональности.

>>> train_set = [(Counter(i["text"].split()),i["label"]) for i in data[200:]]
>>> test_set = [(Counter(i["text"].split()),i["label"]) for i in data[:200]] # withholding 200 examples for testing later

>>> cl = nltk.NaiveBayesClassifier.train(train_set) # <-- this is the same thing textblob was using

>>> print("Classifier accuracy percent:",(nltk.classify.accuracy(cl, test_set))*100)
('Classifier accuracy percent:', 66.5)
>>>>cl.show_most_informative_features(75)

Потом я замариновала.

with open('storybayes.pickle','wb') as f:
    pickle.dump(cl,f)

Теперь... Я взял этот маринованный файл и снова открыл его, чтобы получить nltk.classifier 'nltk.classify.naivebayes.NaiveBayesClassifier'›, и попытался передать его в textblob. Вместо

from textblob.classifiers import NaiveBayesClassifier
blob = TextBlob("I love this library", analyzer=NaiveBayesAnalyzer())

Я старался:

blob = TextBlob("I love this library", analyzer=myclassifier)
Traceback (most recent call last):
  File "<pyshell#116>", line 1, in <module>
    blob = TextBlob("I love this library", analyzer=cl4)
  File "C:\python\lib\site-packages\textblob\blob.py", line 369, in __init__
    parser, classifier)
  File "C:\python\lib\site-packages\textblob\blob.py", line 323, in 
_initialize_models
    BaseSentimentAnalyzer, BaseBlob.analyzer)
  File "C:\python\lib\site-packages\textblob\blob.py", line 305, in 
_validated_param
    .format(name=name, cls=base_class_name))
ValueError: analyzer must be an instance of BaseSentimentAnalyzer

что теперь? Я посмотрел на источник, и оба являются классами, но не совсем одинаковыми.


person Marc Maxmeister    schedule 13.06.2018    source источник
comment
классификатор textblob создает класс: classifier = NaiveBayesClassifier(train) >> <class 'textblob.classifiers.NaiveBayesClassifier'>, а классификатор nltk создает класс: <class 'nltk.classify.naivebayes.NaiveBayesClassifier'> — поэтому застрял на том, как заставить nltk работать в textblob.   -  person Marc Maxmeister    schedule 19.06.2018


Ответы (3)


Я не мог быть уверен, что корпус nltk не может работать с textblob, и это меня удивило бы, поскольку textblob импортирует все функции nltk в свой исходный код и по сути является оболочкой.

Но после многих часов тестирования я пришел к выводу, что nltk предлагает лучший встроенный корпус настроений под названием "vader", который превзошел все мои обученные модели.

import nltk
nltk.download('vader_lexicon') # do this once: grab the trained model from the web
from nltk.sentiment.vader import SentimentIntensityAnalyzer
Analyzer = SentimentIntensityAnalyzer()
Analyzer.polarity_scores("I find your lack of faith disturbing.")
{'neg': 0.491, 'neu': 0.263, 'pos': 0.246, 'compound': -0.4215}
CONCLUSION: NEGATIVE

vader_lexicon и код nltk намного больше разбирают язык отрицания в предложениях, чтобы отрицать положительные слова. Например, когда Дарт Вейдер говорит «недостаток веры», это меняет чувство на противоположное.

Я объяснил это здесь с примерами лучших результатов: https://chewychunks.wordpress.com/2018/06/19/sentiment-analysis-discovering-the-best-way-to-sort-positive.-and-negative-feedback/

Это заменяет эту реализацию textblob:

from textblob import TextBlob
from textblob.sentiments import NaiveBayesAnalyzer
TextBlob("I find your lack of faith disturbing.", analyzer=NaiveBayesAnalyzer())
{'neg': 0.182, 'pos': 0.817, 'combined': 0.635}
CONCLUSION: POSITIVE

Классификатор vader nltk также содержит дополнительную документацию по его использованию для анализа настроений: http://www.nltk.org/howto/sentiment.html

textBlob всегда приводил к краху моего компьютера всего с 5000 примерами.

person Marc Maxmeister    schedule 21.06.2018
comment
Спасибо за указание на nltk и vader. В вашей ссылке на nltk я не вижу никакой информации о том, как настроить словарь. - person dfrankow; 12.10.2019
comment
Я не думаю, что пытался настроить лексикон Вейдера. Я просто использовал его вместо своих пользовательских моделей настроений, потому что он работал лучше. - person Marc Maxmeister; 12.10.2019
comment
Попался. Вы сказали, что классификатор nltk также имеет лучшую документацию о том, как использовать собственный корпус для анализа настроений. Однако я не вижу этой информации на странице, на которую вы ссылаетесь. Я мог бы отредактировать это предложение следующим образом: «Вот документы по анализу настроений nltk». - person dfrankow; 12.10.2019

Судя по сообщению об ошибке, анализатор должен быть унаследован от абстрактного класса BaseSentimentAnalyzer. Как указано в документации здесь, класс должен реализовать функцию analyze(text). Однако при проверке документов по реализации NLTK я не смог найти этот метод в его основной документации здесь или его родительский класс ClassifierI здесь. Следовательно, я считаю, что обе эти реализации не могут быть объединены, если вы не можете реализовать новую функцию analyze в реализации NLTK, чтобы сделать ее совместимой с TextBlob.

person unholy_me    schedule 20.06.2018
comment
Спасибо. Я также просмотрел весь код, в nltk и textblob, чтобы увидеть, как классы используются исходным кодом, но недостаточно понимал подклассы, чтобы быть уверенным. - person Marc Maxmeister; 21.06.2018
comment
Я не уверен, можно ли совместить оба с временным взломом, если вы можете что-то сделать или у вас есть какие-либо обновления, пожалуйста, напишите здесь :) - person unholy_me; 22.06.2018

Еще одно перспективное решение — использовать для построения модели spaCy вместо textblob или nltk. Это новое для меня, но кажется намного проще в использовании и более мощным: https://spacy.io/usage/spacy-101#section-lightning-tour

«spaCy — это Ruby of Rails для обработки естественного языка».

import spacy
import random

nlp = spacy.load('en') # loads the trained starter model here
train_data = [("Uber blew through $1 million", {'entities': [(0, 4, 'ORG')]})] # better model stuff

with nlp.disable_pipes(*[pipe for pipe in nlp.pipe_names if pipe != 'ner']):
    optimizer = nlp.begin_training()
    for i in range(10):
        random.shuffle(train_data)
        for text, annotations in train_data:
            nlp.update([text], [annotations], sgd=optimizer)
nlp.to_disk('/model')
person Marc Maxmeister    schedule 13.07.2018
comment
Обновление: год спустя я полагаюсь на Spacy для решения таких проблем, а не на nltk в целом. - person Marc Maxmeister; 14.10.2019