0

Ich habe eine Aufgabe zum Erstellen eines Multi-Class-Klassifikator für Produkttitel, um sie in 11 Kategorien zu klassifizieren. Ich benutze Scikits LinearSVC für die Klassifizierung. Ich habe zuerst die Produkttitel vorverarbeitet, indem ich Stoppwörter löste, POS-Tags zur Lemmatisierung verwendete und Bigramme mit TFIDF-Vektorisierer verwendete.Verwenden von Feature-Auswahl mit LinearSVC in Python

Ich möchte jetzt die chi2 Methode der Feature-Auswahl zur Beseitigung nicht wichtige Funktionen von diesen und dann das Training zu tun. Aber wie benutze ich chi2 mit meinem Modell. Unten ist der Code:

def identity(arg): 
    """ 
    Simple identity function works as a passthrough. 
    """ 
    return arg 

class NLTKPreprocessor(BaseEstimator, TransformerMixin): 
    def __init__(self, stopwords=None, punct=None, 
       lower=True, strip=True): 

     self.lower  = lower 
     self.strip  = strip 
     self.stopwords = stopwords or set(sw.words('english')) 
     self.punct  = punct or set(string.punctuation) 
     self.lemmatizer = WordNetLemmatizer() 

    def fit(self, X, y=None): 
     return self 

    def inverse_transform(self, X): 
     return [" ".join(doc) for doc in X] 

    def transform(self, X): 
     return [ 
      list(self.tokenize(doc)) for doc in X 
     ] 

    def tokenize(self, document): 

     # Break the document into sentences 
     for sent in sent_tokenize(document): 
      # Break the sentence into part of speech tagged tokens 
      for token, tag in pos_tag(wordpunct_tokenize(sent)): 
       # Apply preprocessing to the token 
       token = token.lower() if self.lower else token 
       token = token.strip() if self.strip else token 
       token = token.strip('_') if self.strip else token 
       token = token.strip('*') if self.strip else token 

       # If stopword, ignore token and continue 
       if token in self.stopwords or token.isdigit() == True: 
        continue 

       # If punctuation, ignore token and continue 
       if all(char in self.punct for char in token): 
        continue 


       # Lemmatize the token and yield 
       lemma = self.lemmatize(token, tag) 


       yield lemma 

    def lemmatize(self, token, tag): 
     tag = { 
      'N': wn.NOUN, 
      'V': wn.VERB, 
      'R': wn.ADV, 
      'J': wn.ADJ 
     }.get(tag[0], wn.NOUN) 

     return self.lemmatizer.lemmatize(token, tag) 

def build_and_evaluate(X, y, 
    classifier=LinearSVC, outpath=None, verbose=True): 

    def build(classifier, X, y=None): 

     if isinstance(classifier, type): 
      classifier = classifier() 

     model = Pipeline([ 
      ('preprocessor', NLTKPreprocessor()), 
      ('vectorizer', TfidfVectorizer(
       tokenizer=identity, preprocessor=None, ngram_range = (1,2), min_df = 4, lowercase=False 
      )), 
      ('classifier', classifier), 
     ]) 

     model.fit(X, y) 
     return model 

    labels = LabelEncoder() 
    y = labels.fit_transform(y) 

    X_train, X_test, y_train, y_test = tts(X, y, test_size=0.2) 
    model = build(classifier, X_train, y_train) 

    y_pred = model.predict(X_test) 
    print(clsr(y_test, y_pred, target_names=labels.classes_)) 

    return model 


if __name__ == '__main__': 
    df = pd.read_csv('file.txt', sep='\t', quoting=csv.QUOTE_NONE, usecols=[6, 12], skiprows=[0], 
          names=["category", "product_title"]) 


    freq = df['category'].value_counts()[:10].to_dict() 
    new_categories = [] 
    for i, category in enumerate(df['category']): 
     if category in freq.keys(): 
      new_categories.append(category) 
     else: 
      new_categories.append('Other') 

    df['new_categories'] = new_categories 

    X = df['product_title'].tolist() 
    X = [i.replace('"', '') for i in X] 
    newlist=[] 
    for i in X: 
     i = i.decode('utf8') 
     newlist.append(i) 

    y = df['new_categories'].tolist() 

    model = build_and_evaluate(newlist,y) 

Kann mir jemand helfen mit, wie chi2 mit dem obigen Code zu benutzen? Vielen Dank!

+0

Verwenden Sie SelectKBest, um die wichtigsten Funktionen auszuwählen. Weitere Informationen finden Sie in der [Benutzeranleitung] (http://scikit-learn.org/stable/modules/feature_selection.html#univariate-feature-selection). –

+0

@VivekKumar Okay, wie das in der Pipeline zu verwenden ist, was ich wissen will. – akrama81

Antwort

1

Deklarieren Sie es auf die gleiche Weise wie für NLTKPreprocessor, aber direkt über dem Klassifizierer in der Pipeline.

Erklären Sie Ihre Pipeline wie folgt:

model = Pipeline([ 
     ('preprocessor', NLTKPreprocessor()), 
     ('vectorizer', TfidfVectorizer(
      tokenizer=identity, preprocessor=None, ngram_range = (1,2), min_df = 4, lowercase=False 
     )), 
     ('selector', SelectKBest(chi2, k=10)), 
     ('classifier', classifier), 
    ]) 

Experiment mit dem param k unterschiedliche Anzahl von ausgewählten Funktionen einzustellen. Ich habe 10 hier verwendet, aber Sie müssen das optimieren. Vielleicht mit GridSearchCV.

+0

Alles klar, danke. Gibt es andere Feature-Auswahlmethoden, die ich für meinen Anwendungsfall ausprobieren könnte? – akrama81

+0

@ akrama81 Siehe [Benutzerleitfaden] (http://scikit-learn.org/stable/modules/feature_selection.html#feature-selection) –

Verwandte Themen