用 nltk 训练我自己的分类器后,如何将它加载到 textblob 中?

Posted

技术标签:

【中文标题】用 nltk 训练我自己的分类器后,如何将它加载到 textblob 中?【英文标题】:After training my own classifier with nltk, how do I load it in textblob? 【发布时间】:2018-11-22 12:09:04 【问题描述】:

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

现在呢?我查看了源代码,两者都是类,但并不完全相同。

【问题讨论】:

textblob 的分类器创建了一个类:classifier = NaiveBayesClassifier(train) &gt;&gt; &lt;class 'textblob.classifiers.NaiveBayesClassifier'&gt;,而 nltk 的分类器创建了一个类:&lt;class 'nltk.classify.naivebayes.NaiveBayesClassifier'&gt;——所以一直坚持如何让 nltk 在 textblob 中工作。 【参考方案1】:

查看错误消息,分析器似乎必须继承自抽象类BaseSentimentAnalyzer。如文档here 中所述,此类必须 实现analyze(text) 函数。但是,在检查 NLTK 实现的文档时,我在它的主文档 here 或其父类 ClassifierI here 中找不到此方法。因此,我认为这两种实现不能结合使用,除非您可以在 NLTK 的实现中实现新的 analyze 函数以使其与 TextBlob 的兼容。

【讨论】:

谢谢。我也查看了nltktextblob 中的所有代码,以了解源代码是如何使用类的,但我对子类化的理解不足以确定。 我不确定是否可以将两者与临时黑客结合起来,如果您可以做点什么或有任何更新,请在此处发布:)【参考方案2】:

我无法确定 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 个示例。

【讨论】:

感谢指向 nltk 和 vader 的指针。在您指向 nltk 的链接中,我没有看到有关如何自定义字典的任何信息。 我不认为我尝试自定义维达的词典。我只是用它代替了我的自定义情绪模型,因为它效果更好。 明白了。你说“nltk 分类器也有关于如何使用你自己定制的语料库进行情感分析的更好的文档”。但是,我在您链接到的页面上看不到该信息。我可能会将那句话编辑为“这里是关于 nltk 情绪分析的文档”【参考方案3】:

另一个更具前瞻性的解决方案是使用 spaCy 来构建模型,而不是 textblobnltk。这对我来说是新的,但似乎更容易使用和更强大: https://spacy.io/usage/spacy-101#section-lightning-tour

“spaCy 是 Rails 自然语言处理的 Ruby。”

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

【讨论】:

更新:一年后,我通常依靠 Spacy 来解决这些类型的问题,而不是 nltk。

以上是关于用 nltk 训练我自己的分类器后,如何将它加载到 textblob 中?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 NLTK 中朴素贝叶斯分类器的平滑方法?

如何以我只训练一次分类器的方式调整 NLTK Python 代码

构建手动 bagging 分类器后绘制 ROC 曲线

Python NLTK:如何在分类器预测中检索百分比置信度

NLTK SklearnClassifier 包装数据

使用 NLTK 从自己的文本数据中进行情感分类