2014-05-23 9 views
9

Ich bin neu in Python und Stackoverflow (bitte sei sanft) und versuche zu lernen, wie man eine Sentiment-Analyse macht. Ich verwende eine Kombination aus Code, den ich in einem Tutorial gefunden und hier: Python - AttributeError: 'list' object has no attribute Aber ich bekomme immer wiederPython Textverarbeitung: AttributeError: 'list' Objekt hat kein Attribut 'lower'

Traceback (most recent call last): 
    File "C:/Python27/training", line 111, in <module> 
    processedTestTweet = processTweet(row) 
    File "C:/Python27/training", line 19, in processTweet 
    tweet = tweet.lower() 
AttributeError: 'list' object has no attribute 'lower'` 

Dies ist mein Code:

import csv 
#import regex 
import re 
import pprint 
import nltk.classify 


#start replaceTwoOrMore 
def replaceTwoOrMore(s): 
    #look for 2 or more repetitions of character 
    pattern = re.compile(r"(.)\1{1,}", re.DOTALL) 
    return pattern.sub(r"\1\1", s) 

# process the tweets 
def processTweet(tweet): 
    #Convert to lower case 
    tweet = tweet.lower() 
    #Convert www.* or https?://* to URL 
    tweet = re.sub('((www\.[\s]+)|(https?://[^\s]+))','URL',tweet) 
    #Convert @username to AT_USER 
    tweet = re.sub('@[^\s]+','AT_USER',tweet) 
    #Remove additional white spaces 
    tweet = re.sub('[\s]+', ' ', tweet) 
    #Replace #word with word 
    tweet = re.sub(r'#([^\s]+)', r'\1', tweet) 
    #trim 
    tweet = tweet.strip('\'"') 
    return tweet 

#start getStopWordList 
def getStopWordList(stopWordListFileName): 
    #read the stopwords file and build a list 
    stopWords = [] 
    stopWords.append('AT_USER') 
    stopWords.append('URL') 

    fp = open(stopWordListFileName, 'r') 
    line = fp.readline() 
    while line: 
     word = line.strip() 
     stopWords.append(word) 
     line = fp.readline() 
    fp.close() 
    return stopWords 

def getFeatureVector(tweet, stopWords): 
    featureVector = [] 
    words = tweet.split() 
    for w in words: 
     #replace two or more with two occurrences 
     w = replaceTwoOrMore(w) 
     #strip punctuation 
     w = w.strip('\'"?,.') 
     #check if it consists of only words 
     val = re.search(r"^[a-zA-Z][a-zA-Z0-9]*[a-zA-Z]+[a-zA-Z0-9]*$", w) 
     #ignore if it is a stopWord 
     if(w in stopWords or val is None): 
      continue 
     else: 
      featureVector.append(w.lower()) 
    return featureVector 

def extract_features(tweet): 
    tweet_words = set(tweet) 
    features = {} 
    for word in featureList: 
     features['contains(%s)' % word] = (word in tweet_words) 
    return features 


#Read the tweets one by one and process it 
inpTweets = csv.reader(open('C:/GsTraining.csv', 'rb'), 
         delimiter=',', 
         quotechar='|') 
stopWords = getStopWordList('C:/stop.txt') 
count = 0; 
featureList = [] 
tweets = [] 

for row in inpTweets: 
    sentiment = row[0] 
    tweet = row[1] 
    processedTweet = processTweet(tweet) 
    featureVector = getFeatureVector(processedTweet, stopWords) 
    featureList.extend(featureVector) 
    tweets.append((featureVector, sentiment)) 

# Remove featureList duplicates 
featureList = list(set(featureList)) 

# Generate the training set 
training_set = nltk.classify.util.apply_features(extract_features, tweets) 

# Train the Naive Bayes classifier 
NBClassifier = nltk.NaiveBayesClassifier.train(training_set) 

# Test the classifier 
with open('C:/CleanedNewGSMain.txt', 'r') as csvinput: 
    with open('GSnewmain.csv', 'w') as csvoutput: 
    writer = csv.writer(csvoutput, lineterminator='\n') 
    reader = csv.reader(csvinput) 

    all=[] 
    row = next(reader) 

    for row in reader: 
     processedTestTweet = processTweet(row) 
     sentiment = NBClassifier.classify(
      extract_features(getFeatureVector(processedTestTweet, stopWords))) 
     row.append(sentiment) 
     processTweet(row[1]) 

    writer.writerows(all) 

Jede Hilfe massiv geschätzt würde.

Antwort

8

Das Ergebnis aus dem CSV-Reader ist eine Liste, lower funktioniert nur auf Strings. Vermutlich ist es eine Liste von Strings, also gibt es zwei Möglichkeiten. Entweder Sie können lower für jedes Element aufrufen oder die Liste in eine Zeichenfolge umwandeln und dann lower darauf anrufen.

Aber vernünftiger (schwer zu sagen, ohne weitere Informationen) Sie wollen nur einen Artikel aus Ihrer Liste. Etwas entlang der Linien von:

for row in reader: 
    processedTestTweet = processTweet(row[0]) # Again, can't know if this is actually correct without seeing the file 

auch zu raten, dass Sie nicht den csv Leser verwenden ganz wie Sie denken, Sie sind, weil gerade jetzt jedes Mal ein Bayes-Klassifikator auf einem einzigen Beispiel trainieren und dann dass es das eine Beispiel vorhersagt, an dem es trainiert wurde. Kannst du vielleicht erklären, was du zu tun versuchst?

+0

Vielen Dank für die schnelle Antwort. Was ich versuche, ist: Ich habe ein kleines, beschriftetes .csv Trainingssatz mit 1000 positiven und 1000 negativen Aussagen. Training scheint zu funktionieren, als ich es nur durch harte Codierung in einer Test-Anweisung getestet habe, z. ' das ist großartig!'. Allerdings habe ich eine Datei mit etwa 10000 Tweets und Facebook-Postings, und ich möchte das in diesem Programm öffnen und die Stimmung mit Naive Bayes testen. Ich glaube nicht, dass ich den CSV-Reader auch richtig benutze, aber ich kann es noch nicht sagen. – user3670554

Verwandte Themen