2013-07-02 4 views
2

Я использую scikit для текстовой классификации коротких фраз в их значении. Вот некоторые примеры:Лучший классификатор scikit для задачи классификации текста

"Yes" - label.yes 
"Yeah" - label.yes 
... 
"I don't know" - label.i_don't_know 
"I am not sure" - label.i_don't_know 
"I have no idea" - label.i_don't_know 

Все работало довольно хорошо, используя TfidfVectorizer и классификатор MultinomialNB.

Проблема возникла, когда я добавил новый текст/метки пары:

"I" - label.i 

Предсказание класс для «Я» по-прежнему возвращает label.i_don't_know, даже если текст именно в обучающих данных, как это , что, вероятно, связано с тем, что униграмма «I» чаще встречается в label.i_don't_know, чем в label.i.

Существует ли классификатор, который даст сопоставимую или лучшую производительность для этой задачи и гарантирует правильное отображение прогнозов элементов данных обучения?

Этот код иллюстрирует проблему далее:

from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.naive_bayes import MultinomialNB 

#instantiate classifier and vectorizer 
clf=MultinomialNB(alpha=.01) 
vectorizer =TfidfVectorizer(min_df=1,ngram_range=(1,2)) 

#Apply vectorizer to training data 
traindata=['yes','yeah','i do not know','i am not sure','i have no idea','i']; 
X_train=vectorizer.fit_transform(traindata) 

#Label Ids 
y_train=[0,0,1,1,1,2]; 

#Train classifier 
clf.fit(X_train, y_train) 

print clf.predict(vectorizer.transform(['i'])) 

кода выводит метку 1, но правильная классификация будет метка 2.

+0

Без воспроизводимого примера вашего кода будет очень сложно сказать, будет ли решение использовать другой классификатор или изменить способ использования существующих классификаторов. – Marius

+0

Спасибо, я добавил пример кода. – Matt

ответ

6

Проблема не с классификатором, то с векторизатора , TfidfVectorizer имеет параметр token_pattern : string, который является «Регулярным выражением, обозначающим то, что представляет собой« токен », используется только в том случае, если tokenize == 'word'. По умолчанию regexp выбирает токены 2 или более символов символов (пунктуация полностью игнорируется и всегда обрабатывается как маркерный разделитель). " (выделено курсивом). Знаменатель выдает слово i, в результате чего появляется пустой документ. Наивный Байес затем классифицирует это как класс 1, потому что это самый частый класс в данных обучения.

В зависимости от данных, вы, возможно, захотите рассмотреть вопрос об использовании формы для наивных байесов.


Дальнейшие подсказки относительно того, почему вещи не могут работать:

Там могут быть некоторые другие странность в том, как ваш трубопровод настроен. Я считаю полезным проверять входы и выходы каждого этапа (токенизатор, векторизатор, классификатор и т. Д.). Инвестирование в течение некоторого времени в письменном виде модульного теста сэкономит вам много времени в долгосрочной перспективе.

Как только вы удовлетворены, все работает нормально, попробуйте оценить свой классификатор на тестовых данных. Мое подозрение в том, что между вашими классами существует значительное совпадение, в частности label.i_don't_know и label.i. Если это так, классификатор будет работать плохо.

+0

Спасибо, это помогло в приведенном выше наборе данных. Как ни странно, реальный набор данных с тысячами учебных документов не помогает. Что-нибудь еще, что может вызвать такое поведение? – Matt

+0

Когда вы говорите «что помогло», вы имеете в виду параметр «token_pattern» или «class_prior»? – mbatchkarov

+0

Я использовал 'token_pattern =" \ w {1,} "'. Я еще не изменил 'class_prior'. – Matt

Смежные вопросы