【问题标题】:Cross validation error交叉验证错误
【发布时间】:2016-03-15 00:43:23
【问题描述】:

我正在尝试估计 nltk 电影评论语料库的朴素贝叶斯分类的准确性。

from nltk.corpus import movie_reviews
import random
import nltk
from sklearn import cross_validation
from nltk.corpus import stopwords
import string
from nltk.classify import apply_features

def document_features(document):
    document_words = set(document)
    features = {}
    for word in unigrams:
        features['contains({})'.format(word)] = (word in document_words)
    return features

documents = [(list(movie_reviews.words(fileid)), category)
             for category in movie_reviews.categories()
             for fileid in movie_reviews.fileids(category)]
random.shuffle(documents)
stop = stopwords.words('english')
all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words() if w.lower() not in stop and w.lower() not in string.punctuation)
unigrams = list(all_words)[:200]
featuresets = [(document_features(d), c) for (d,c) in documents]

我正在尝试执行 10 折交叉验证,我从 sklearn 中获取了一个示例。

training_set = nltk.classify.apply_features(featuresets, documents)
cv = cross_validation.KFold(len(training_set), n_folds=10, shuffle=True, random_state=None)

for traincv, testcv in cv:
    classifier = nltk.NaiveBayesClassifier.train(training_set[traincv[0]:traincv[len(traincv)-1]])
    result = nltk.classify.util.accuracy(classifier, training_set[testcv[0]:testcv[len(testcv)-1]])
    print 'Accuracy:', result

但我在行中遇到错误

classifier = nltk.NaiveBayesClassifier.train(training_set[traincv[0]:traincv[len(traincv)-1]])

'list' 对象不可调用

任何想法我做错了什么?

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    实际的错误在于这一行:

    training_set = nltk.classify.apply_features(featuresets, documents)
    

    featuresets 是 Python 抱怨的列表。

    来自nltk.classify.apply_features的文档:

    apply_features(feature_func, toks, label=None)

    使用LazyMap 类构造一个类似惰性列表 类似于map(feature_func, toks) 的对象。在 特别是,如果labeled=False,则返回类似列表 对象的值等于:

    [feature_func(tok) for tok in toks]
    

    如果labeled=True,则返回的类列表对象的值 等于:

    [(feature_func(tok), label) for (tok, label) in toks]
    

    map 的行为方式类似,该函数需要一个函数(特征提取器)作为第一个参数,该参数将应用于列表的每个元素(文档)作为第二个传递争论。它返回一个LazyMap,它会按需应用该函数来节省内存。

    但是您已将特征集列表传递给apply_features,而不是特征提取器函数。因此,有两种可能的解决方案可以让事情按您希望的方式运行:

    1. 放弃training_set 并改用featuresets
    2. 丢弃featuresets并使用training_set = nltk.classify.apply_features(document_features, documents, True)(注意第三个参数)。

    我推荐第二个选项,因为它不会构建内存中所有文档的特征列表。

    【讨论】:

    • 非常感谢您的回答!如果我删除training_set = nltk.classify.apply_features(featuresets, documents) 并说training_set = featuresets,它就会起作用。我会喜欢这个使用所有文档功能而不仅仅是 200 个 unigram 吗?使用training_set = nltk.classify.apply_features(featuresets, documents, True) 我得到同样的错误。
    • 对不起:第二种方式必须是:training_set = nltk.classify.apply_features(document_features, documents, True)(使用特征提取器函数而不是实际结果)。但是,您将始终使用前 200 个 unigram,因为您已将它们定义为布尔特征。如果你要使用任何文档中出现的所有单词,那么特征空间会非常大。
    猜你喜欢
    • 2017-05-07
    • 2023-03-15
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 2015-07-07
    • 2020-08-29
    • 2018-08-02
    • 2016-10-31
    相关资源
    最近更新 更多