2017-05-26 2 views
0

Ich versuche, einen Sentiment-Analysator mit Scikit-lernen/Pandas zu bauen. Das Erstellen und Auswerten des Modells funktioniert, der Versuch, neuen Beispieltext zu klassifizieren, funktioniert jedoch nicht.NotFittedError: TfidfVectorizer - Vokabeln wurde nicht angepasst

Mein Code:

import csv 
import pandas as pd 
import numpy as np 
from sklearn.model_selection import train_test_split 
from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.naive_bayes import BernoulliNB 
from sklearn.metrics import classification_report 
from sklearn.metrics import accuracy_score 

infile = 'Sentiment_Analysis_Dataset.csv' 
data = "SentimentText" 
labels = "Sentiment" 


class Classifier(): 
    def __init__(self): 
     self.train_set, self.test_set = self.load_data() 
     self.counts, self.test_counts = self.vectorize() 
     self.classifier = self.train_model() 

    def load_data(self): 

     df = pd.read_csv(infile, header=0, error_bad_lines=False) 
     train_set, test_set = train_test_split(df, test_size=.3) 
     return train_set, test_set 

    def train_model(self): 
     classifier = BernoulliNB() 
     targets = self.train_set[labels] 
     classifier.fit(self.counts, targets) 
     return classifier 


    def vectorize(self): 

     vectorizer = TfidfVectorizer(min_df=5, 
           max_df = 0.8, 
           sublinear_tf=True, 
           ngram_range = (1,2), 
           use_idf=True) 
     counts = vectorizer.fit_transform(self.train_set[data]) 
     test_counts = vectorizer.transform(self.test_set[data]) 

     return counts, test_counts 

    def evaluate(self): 
     test_counts,test_set = self.test_counts, self.test_set 
     predictions = self.classifier.predict(test_counts) 
     print (classification_report(test_set[labels], predictions)) 
     print ("The accuracy score is {:.2%}".format(accuracy_score(test_set[labels], predictions))) 


    def classify(self, input): 
     input_text = input 

     input_vectorizer = TfidfVectorizer(min_df=5, 
           max_df = 0.8, 
           sublinear_tf=True, 
           ngram_range = (1,2), 
           use_idf=True) 
     input_counts = input_vectorizer.transform(input_text) 
     predictions = self.classifier.predict(input_counts) 
     print(predictions) 

myModel = Classifier() 

text = ['I like this I feel good about it', 'give me 5 dollars'] 

myModel.classify(text) 
myModel.evaluate() 

Der Fehler:

Traceback (most recent call last): 
    File "sentiment.py", line 74, in <module> 
    myModel.classify(text) 
    File "sentiment.py", line 66, in classify 
    input_counts = input_vectorizer.transform(input_text) 
    File "/home/rachel/Sentiment/ENV/lib/python3.5/site-packages/sklearn/feature_extraction/text.py", line 1380, in transform 
    X = super(TfidfVectorizer, self).transform(raw_documents) 
    File "/home/rachel/Sentiment/ENV/lib/python3.5/site-packages/sklearn/feature_extraction/text.py", line 890, in transform 
    self._check_vocabulary() 
    File "/home/rachel/Sentiment/ENV/lib/python3.5/site-packages/sklearn/feature_extraction/text.py", line 278, in _check_vocabulary 
    check_is_fitted(self, 'vocabulary_', msg=msg), 
    File "/home/rachel/Sentiment/ENV/lib/python3.5/site-packages/sklearn/utils/validation.py", line 690, in check_is_fitted 
    raise _NotFittedError(msg % {'name': type(estimator).__name__}) 
sklearn.exceptions.NotFittedError: TfidfVectorizer - Vocabulary wasn't fitted. 

Ich bin nicht sicher, was das Problem sein könnte. In meiner Klassifizierungsmethode erstelle ich einen brandneuen Vektorisierer, um den Text zu klassifizieren, den ich klassifizieren möchte, getrennt von dem Vektorizer, der zum Erstellen von Trainings- und Testdaten aus dem Modell verwendet wird.

Dank

+2

Wie auch immer, in Ihrer 'classify' -Funktion erstellen Sie ein neues Vectorizer-Objekt und rufen dann' transform' auf, bevor es angepasst wurde. –

+0

Hinzufügen zu @AryaMcCarthy die Antwort, die gesamte Klassifizierungsfunktion in dieser Klasse ist irreführend. Der Konstruktor ermöglicht die Übergabe der Eingabedaten. Warum also noch einmal klassifizieren? –

Antwort

3

Sie einen vectorizer ausgestattet haben, aber Sie werfen es weg, weil es über die gesamte Lebensdauer Ihrer vectorize Funktion existiert nicht. Stattdessen speichern Sie Ihr Modell in vectorize, nachdem es umgewandelt worden ist:

self._vectorizer = vectorizer 

Dann in Ihrer classify Funktion, keine neue vectorizer erstellen. Verwenden Sie statt dessen den, den Sie für die Trainingsdaten verwendet haben:

input_counts = self._vectorizer.transform(input_text) 
Verwandte Themen