2013-06-04 17 views
6

Pracuję w dziale obsługi klienta i używam naukowego scikita do przewidywania tagów dla naszych biletów, biorąc pod uwagę zestaw szkoleń z biletów (około 40 000 biletów na szkolenie zestaw).Python: używanie scikita - ucz się przewidywać, daje puste prognozy

Używam modelu klasyfikacji opartego na this one. Przewiduje tylko "()" jako znaczniki dla wielu moich zestawów testowych biletów, mimo że żaden z biletów w zbiorze treningowym nie ma tagów.

Moje dane szkolenie dla znaczników znajduje się lista list, takich jak:

tags_train = [['international_solved'], ['from_build_guidelines my_new_idea eligibility'], ['dropbox other submitted_faq submitted_help'], ['my_new_idea_solved'], ['decline macro_backer_paypal macro_prob_errored_pledge_check_credit_card_us loading_problems'], ['dropbox macro__turnaround_time other plq__turnaround_time submitted_help'], ['dropbox macro_creator__logo_style_guide outreach press submitted_help']] 

Podczas moich danych szkoleniowe dla opisów bilet jest tylko lista ciągów, np:

descs_train = ['description of ticket one', 'description of ticket two', etc] 

Oto odnośny część mojego kodu do zbudowania modelu:

import numpy as np 
import scipy 
from sklearn.pipeline import Pipeline 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.feature_extraction.text import TfidfTransformer 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn.svm import LinearSVC 

# We have lists called tags_train, descs_train, tags_test, descs_test with the test and train data 

X_train = np.array(descs_train) 
y_train = tags_train 
X_test = np.array(descs_test) 

classifier = Pipeline([ 
    ('vectorizer', CountVectorizer()), 
    ('tfidf', TfidfTransformer()), 
    ('clf', OneVsRestClassifier(LinearSVC(class_weight='auto')))]) 

classifier.fit(X_train, y_train) 
predicted = classifier.predict(X_test) 

Jednak "przewidywane" daje listę, która wygląda jak:

predicted = [(), ('account_solved',),(), ('images_videos_solved',), ('my_new_idea_solved',),(),(),(),(),(), ('images_videos_solved', 'account_solved', 'macro_launched__edit_update other tips'), ('from_guidelines my_new_idea', 'from_guidelines my_new_idea macro__eligibility'),()] 

Nie rozumiem, dlaczego przewidywania są puste(), gdy nie ma ich w zbiorze treningowym. Czy nie powinien przewidzieć najbliższego tagu? Czy ktoś może polecić jakieś ulepszenia modelu, którego używam?

Z góry dziękuję bardzo za pomoc!

+0

[dokumentacji CountVectorizer] (http://scikit-learn.org/dev/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html) [ Dokumentacja TfidfTransformer] (http://scikit-learn.github.io/scikit-learn.org/0.8/modules/generated/scikits.learn.feature_extraction.text.TfidfTransformer.html) [Dokumentacja OneVsRestClassifier] (http://scikit-learn.org/dev/modules/generated/sklearn.multiclass.OneVsRestClassifier.html) – jegeragh

+0

Czy chcesz klasyfikować według wielu klas lub wielu etykiet? Czy bilet można oznakować więcej niż jednym tagiem? – mbatchkarov

+0

Tak, wiele etykiet! – jegeragh

Odpowiedz

5

Problem dotyczy zmiennej tags_train. Zgodnie z dokumentacją OneVsRestClassifier cele muszą być "sekwencją ciągów etykiet", a obiektami docelowymi są elementy o wartości jeden element.

Poniżej znajduje się edytowana, samodzielna i działająca wersja Twojego kodu. Zwróć uwagę na zmianę w tags_train, w szczególności fakt, że tags_train jest krotką jednopunktową.

import numpy as np 
import scipy 
from sklearn.pipeline import Pipeline 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.feature_extraction.text import TfidfTransformer 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn.svm import LinearSVC 


# We have lists called tags_train, descs_train, tags_test, descs_test with the test and train data 
tags_train = [('label',), ('international' ,'solved'), ('international','open')] 
descs_train = ['description of ticket one', 'some other ticket two', 'label'] 

X_train = np.array(descs_train) 
y_train = tags_train 
X_test = np.array(descs_train) 

classifier = Pipeline([ 
    ('vectorizer', CountVectorizer()), 
    ('tfidf', TfidfTransformer()), 
    ('clf', OneVsRestClassifier(LinearSVC(class_weight='auto')))]) 

classifier = classifier.fit(X_train, y_train) 
predicted = classifier.predict(X_test) 

print predicted 

Wyjście jest

[('international',), ('international',), ('international', 'open')] 
Powiązane problemy