我有一个 Python 脚本,它成功地创建、训练并将一个用于字符串情感分析的朴素贝叶斯分类器 pickle 化。我改编了在这里和这里找到的代码片段,这些对像我这样的初学者来说非常有帮助。然而,这两个资源都没有展示如何使用一个 pickled 的分类器。之前在 StackOverflow 的回答(这里和这里)暗示了分类器对象本身和特征向量都应该保存到磁盘,然后一起加载以便后续使用,但没有提供实现这一过程的语法示例。
更新:这段代码可以工作,用于训练和存储分类器:
...def get_words_in_descs(descs): all_words = [] for (words, sentiment) in descs: all_words.extend(words) return all_wordsdef get_word_features(wordlist): wordlist = nltk.FreqDist(wordlist) word_features = wordlist.keys() return word_featuresdef extract_features(document): document_words = set(document) features = {} for word in word_features: features['contains(%s)' % word] = (word in document_words) return featurestraining = [ (['Multipurpose 4140 alloy steel'], 'metal'), (['Easy-to-machine polyethylene tube'], 'plastic'), ... ] word_features = get_word_features(get_words_in_descs(training))training_set = nltk.classify.apply_features(extract_features, training)classifier = nltk.NaiveBayesClassifier.train(training_set)outputFile = open('maxModel.pkl','wb')pickle.dump(classifier, outputFile)outputFile.close()
更新:同样,上面的代码运行良好。我的问题是在另一个独立的 .py 文件中,我试图解封这个分类器,然后用它来对一个新的、之前未见过的字符串进行分类。我最初以为这是因为我把分类器从 word_features
中移走了,但可能还有其他问题?
这是无法工作的代码。现在我得到了这个错误…它是在某个地方期待一个列表吗? 'dict_keys' object has no attribute 'copy'
...def get_word_features(wordlist): wordlist = nltk.FreqDist(wordlist) word_features = wordlist.keys() return word_featureswith open('maxModelClassifier.pkl', 'rb') as fid: loaded_classifier = pickle.load(fid) #print(str(loaded_classifier.show_most_informative_features(100)))#尝试使用加载的分类器:print(loaded_classifier.classify(get_word_features(['super-cushioning', 'foam', 'sheet', 'adhesive-back', 'polyurethane'])))
感谢任何见解。
回答:
你的代码为每个推文计算特征并将它们保存到文件中。你是不是忘记了什么?你从未训练过你在问题中提到的朴素贝叶斯分类器。(或者如果你训练了,你没有用你代码中显示的 training
数据来做。)
-
通过调用其
train()
方法来训练分类器,并传递你计算的标记特征向量列表。classifier = nltk.classify.NaiveBayesClassifier(training)
请注意,训练集应该是一个标记字典的列表,而不是你正在创建的标记词列表。请参阅 NLTK 书籍的第6章,了解如何以正确格式创建标记特征向量的示例。
-
使用新训练的或解封的分类器,通过调用
classify()
、prob_classify()
、classify_many()
或prob_classify_many()
中的一个方法。你需要从你想要分类的输入中计算特征,并将这些特征传递给分类方法(显然不需要标签,因为这就是你想要找出的)。print(classifier.classify(get_word_features(["What", "is", "this"])))
-
对训练后的分类器进行 pickle 化,而不是特征。”语法”只是
pickle.dump(classifier, outputfile)
。