23

I have the following code snippet

classifier = NaiveBayesClassifier.train(train_data)
#classifier.show_most_informative_features(n=20)
results = classifier.classify(test_data)

and the error shows in the following line

results = classifier.classify(test_data)

error:

Traceback (most recent call last):
  File "trial_trial.py", line 46, in <module>
    results = classifier.classify(test_data)
  File "c:\Users\Amr\Anaconda\lib\site-packages\nltk\classify\naivebayes.py", line 88, in classify
    return self.prob_classify(featureset).max()
  File "c:\Users\Amr\Anaconda\lib\site-packages\nltk\classify\naivebayes.py", line 94, in prob_classify
    featureset = featureset.copy()
AttributeError: 'list' object has no attribute 'copy'

I think of extending base class list in python and add copy function but I'm not expert in python and I don't know how to solve this problem.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Amr Ragab
  • 437
  • 1
  • 4
  • 7

4 Answers4

59

The list.copy method does not work both in python 2.x and python 3.x, I wonder why it is still in the documentation. To achieve the results of copying a list, user the list keyword:

fruits = ['banana', 'cucumber', 'apple', 'water mellon']
my_fruits = list(fruits)

Optionally, you can copy a list by slicing it:

my_fruits_copy = fruits[:]
Shemogumbe
  • 788
  • 6
  • 8
  • 4
    It's in the documentation for the Python versions where it actually exists, which is Python 3.3 and up. If you think you got this AttributeError on Python 3, you're almost certainly not actually on Python 3. – user2357112 May 24 '20 at 02:15
4

NLTK classifiers work with feature sets; these are always given as dictionaries with feature names mapping to a value. You are passing in a list instead, so you are not producing features as per the NLTK documentation. The code simply expects a Python dictionary, and Python dictionaries have a .copy() method.

See the NLTK tutorial chapter on Learning to Classify Text:

The returned dictionary, known as a feature set, maps from feature names to their values. Feature names are case-sensitive strings that typically provide a short human-readable description of the feature, as in the example 'last_letter'. Feature values are values with simple types, such as booleans, numbers, and strings.

Also see the Featuresets section of the NLTK Classify API documentation:

The features describing a token are encoded using a “featureset”, which is a dictionary that maps from “feature names” to “feature values”. Feature names are unique strings that indicate what aspect of the token is encoded by the feature.

You haven't shared what kind of objects the train_data list contains; if those are feature set dictionaries, you want to use classify_many() instead:

results = classifier.classify_many(test_data)

That method does take a list, but each element must still be a valid feature set.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • once i posted the question i tried after reading the documentation to classify one element as a dictionary and worked, i will try to classify_many() – Amr Ragab May 05 '16 at 20:53
0

Solutions: classifier.classify receive a python dictionary as param.

After this: test_set1 = sentiment_analyzer.apply_features(test_sentence1)

you got something like this: [({'contains()': False, 'contains(im)': False,...

classifier.classify wants this:

test_set1[0][0]
...
{'contains()': False, 'contains(im)': False, ...
ZF007
  • 3,708
  • 8
  • 29
  • 48
-7

Why do you want do that? if you want set a list equal to another you can do that:

a = ['a', 'b', 'c']
b = a 

else if you want insert a list inside a secondone you can use append():

a = ['a','b','c']
b = ['d','e','f']
for i in len(a):
    b.append(i-1)
Polipizio
  • 46
  • 1
  • 5
  • 2
    See [How to clone or copy a list in Python?](http://stackoverflow.com/q/2612802); you are only creating an additional *reference* in the first example, not a copy. In this specific case, the OP is simply passing in the wrong datatype into an API that only handles dictionaries. – Martijn Pieters May 05 '16 at 20:25