设计朴素贝叶斯分类器时的AttributeError

时间:2018-01-27 19:45:43

标签: python text-classification naivebayes

我正在尝试创建一个简单的Naive Bayes Classifier,用于在两个类之间对数据进行分类,如下面的代码所示。但我坚持以下错误,任何人都可以告诉我我做错了什么。

Traceback (most recent call last):
  File "NBC.py", line 33, in <module>
    test(['Apple', 'Banana'])
  File "NBC.py", line 16, in test
    prob_dist = classifier.prob_classify(lst)
  File "/home/***/.local/lib/python3.6/site-packages/nltk/classify/naivebayes.py", line 95, in prob_classify
    for fname in list(featureset.keys()):
AttributeError: 'list' object has no attribute 'keys'

“NBC.py”

from nltk.classify import NaiveBayesClassifier

dataFruits = ['Apple', 'Banana', 'Cherry', 'Grape', 'Guava', 
              'Lemon', 'Mangos', 'Orange', 'Strawberry', 'Watermelon']

dataVeggies = ['Potato', 'Spinach', 'Carrot', 'Onion', 'Cabbage', 
               'Barccoli', 'Tomatoe', 'Pea', 'Cucumber', 'Eggplant']

def create_features(word):
    my_dict = dict([(word, True)])
    return my_dict

def test(words):
    lst = [create_features(wd) for wd in words]

    prob_dist = classifier.prob_classify(lst)
    print(prob_dist.prob('fruit'))

class1= [(create_features(item), 'fruit') for item in dataFruits]
#print(class1)

class2 = [(create_features(item), 'veggie') for item in dataVeggies]
#print(class2)

train_set = class1[:] + class2
print(train_set)

# Train
classifier = NaiveBayesClassifier.train(train_set)


# Predict
test(['Apple', 'Banana'])

1 个答案:

答案 0 :(得分:1)

您的代码尝试做的是构建一个基于名称功能的非常简单的分类器。根据其名称,项目将被归类为'fruit''veggie'。训练集包含几个名称及其各自的类别。

您获得的错误是由于训练集和测试集的格式错误造成的。训练集是 featuresets 的列表(每个训练示例的一个功能集),并且应该具有以下形式的结构:

training_set = [featureset1, featureset2, ...]

每个功能集都是 (features, class),其中features是字典

{'f1': value1, 'f2': value2, ...}

class是一些价值。例如,在您的分类器中,'Apple'的功能集是:

({'Apple': True,
  'Banana': False,
  'Broccoli': False,
  'Cabbage': False,
  'Carrot': False,
  'Cherry': False,
  'Cucumber': False,
  'Eggplant': False,
  'Grape': False,
  'Guava': False,
  'Lemon': False,
  'Mangos': False,
  'Onion': False,
  'Orange': False,
  'Pea': False,
  'Potato': False,
  'Spinach': False,
  'Strawberry': False,
  'Tomato': False,
  'Watermelon': False},
 'fruit')

以下是更正后的代码:

from nltk.classify import NaiveBayesClassifier, accuracy

dataFruits = ['Apple', 'Banana', 'Cherry', 'Grape', 'Guava', 
              'Lemon', 'Mangos', 'Orange', 'Strawberry', 'Watermelon']

dataVeggies = ['Potato', 'Spinach', 'Carrot', 'Onion', 'Cabbage', 
               'Broccoli', 'Tomato', 'Pea', 'Cucumber', 'Eggplant']

def create_features(word, featureNames):
    my_dict = dict([(w, False) for w in featureNames])    
    my_dict[word] = True
    return my_dict

def test(word):
    lst = create_features(word, allFeatures)
    prob_dist = classifier.prob_classify(lst)
    print('{}'.format(word))
    print('Fruit probability: {:.2f}\tVeggie probability: {:.2f}'.format( prob_dist.prob('fruit'), prob_dist.prob('veggie')))
    return prob_dist

allFeatures = dataFruits + dataVeggies
class1= [(create_features(item, allFeatures), 'fruit') for item in dataFruits]

class2 = [(create_features(item, allFeatures), 'veggie') for item in dataVeggies]

train_set = class1[:] + class2
test_set = [(create_features(item, allFeatures), 'fruit') for item in ['Apple','Banana']]

# Train
classifier = NaiveBayesClassifier.train(train_set)


# Predict
test('Strawberry')
test('Strawby')

# Accuracy on test set
print('Accuracy on test set: {:.2f}'.format(accuracy(classifier, test_set)))  

稍微好一点的分类器,也许这就是你想到的(沿着http://www.nltk.org/book/ch06.html(文件分类)中的例子。这里的分类器只是预测篮子是否包含更多的水果或蔬菜。这可以构建更复杂的分类器(具有更好的功能和更多的训练数据)。

from nltk.classify import NaiveBayesClassifier, accuracy

dataFruits = ['Apple', 'Banana', 'Cherry', 'Grape', 'Guava', 
              'Lemon', 'Mangos', 'Orange', 'Strawberry', 'Watermelon']

dataVeggies = ['Potato', 'Spinach', 'Carrot', 'Onion', 'Cabbage', 
               'Broccoli', 'Tomato', 'Pea', 'Cucumber', 'Eggplant']


def basket_features(basket): 
    basket_items = set(basket) 
    features = {}
    for item in allFeatures:
        features['contains({})'.format(item)] = (item in basket_items)
    return features

def test(basket):
    lst = basket_features(basket)
    prob_dist = classifier.prob_classify(lst)
    print('Basket: {}'.format(basket))
    print('Fruit probability: {:.2f}\tVeggie probability: {:.2f}'.format(prob_dist.prob('fruit'), prob_dist.prob('veggie')))
    return prob_dist

allFeatures = dataFruits + dataVeggies
class1= [(basket_features([item]), 'fruit') for item in dataFruits]

class2 = [(basket_features([item]), 'veggie') for item in dataVeggies]

train_set = class1[:] + class2

# Train
classifier = NaiveBayesClassifier.train(train_set)


# Predict
test(['Apple', 'Banana', 'Cherry', 'Carrot', 'Eggplant', 'Cabbage','Pea'])
test(['Apple', 'Banana',  'Mangos', 'Carrot', 'Eggplant', 'Cabbage','Pea', 'Cucumber'])
test(['Apple', 'Banana'])
test(['Apple', 'Banana', 'Grape'])

classifier.show_most_informative_features(5)