Scikit-learn 0.15.2 — OneVsRestClassifier не работает из-за того, что недоступна Predict_proba

Я пытаюсь сделать классификацию onevsrest, как показано ниже:

classifier = Pipeline([('vectorizer', CountVectorizer()),('tfidf', TfidfTransformer()),('clf', OneVsRestClassifier(SVC(kernel='rbf')))])

classifier.fit(X_train, Y)

predicted = classifier.predict(X_test)

И я получаю сообщение об ошибке «predict_proba недоступен, когда вероятность = ложь». Я видел сообщение об ошибке, приведенной ниже: https://github.com/scikit-learn/scikit-learn/issues/1946

И он был закрыт как исправленный, поэтому я убил scikit-learn на своем ПК с Windows и полностью повторно загрузил scikit-learn, чтобы иметь версию 0.15.2. Но я все еще получаю эту ошибку. Какие-либо предложения? Или я неправильно понял это, и я все еще не могу использовать SVC с OneVSRestClassifier, если я не укажу вероятность = истина?

ОБНОВЛЕНИЕ: просто чтобы уточнить, я пытаюсь на самом деле добиться классификации с несколькими метками, вот источник данных:

df = pd.read_csv(fileIn, header = 0, encoding='utf-8-sig')
rows = random.sample(df.index, int(len(df) * 0.9))

work = df.ix[rows]

work_test = df.drop(rows)

X_train = []

y_train = []

X_test = []

y_test = []
for i in work[[i for i in list(work.columns.values) if i.startswith('Change')]].values:
    X_train.append(','.join(i.T.tolist()))

X_train = np.array(X_train)

for i in work[[i for i in list(work.columns.values) if i.startswith('Corax')]].values:
    y_train.append(list(i))


for i in work_test[[i for i in list(work_test.columns.values) if i.startswith('Change')]].values:
    X_test.append(','.join(i.T.tolist()))

X_test = np.array(X_test)

for i in work_test[[i for i in list(work_test.columns.values) if i.startswith('Corax')]].values:
    y_test.append(list(i))


lb = preprocessing.MultiLabelBinarizer()

Y = lb.fit_transform(y_train)

И после этого я отправляю его в конвейер, упомянутый ранее


person Maksim Khaitovich    schedule 08.12.2014    source источник
comment
На моем ящике работает нормально (scikit-learn current master). Вы уверены, что не импортируете старую версию? python -c 'import sklearn; print(sklearn.__version__).   -  person Fred Foo    schedule 09.12.2014
comment
Там написано: 0.15.2. Возможно ли, что проблема вызвана тем, что используйте бинарники отсюда (предложено на сайте sklearn, но они пока неофициальные): lfd.uci.edu/~gohlke/pythonlibs/#scikit-learn. Вероятно, они построены неправильно. Должен ли я просто вытащить все со страницы github sklearn и заменить все мои локальные файлы?   -  person Maksim Khaitovich    schedule 09.12.2014
comment
Обновление. Я пытался использовать pip для обновления scikit-learn, но он говорит: D:\Apps\Python\Scripts›pip install -U scikit-learn Требование уже обновлено: scikit-learn в d:\apps\ python\lib\site-packages Очистка...   -  person Maksim Khaitovich    schedule 09.12.2014
comment
Еще более забавно - я полностью убил python со своего ПК вместе со всеми файлами пакетов. Затем я установил python 3.4, повторно загрузил все необходимые компоненты и установил sklearn с помощью pip. Даже после этого я все еще получаю эту ошибку. Любые идеи?   -  person Maksim Khaitovich    schedule 09.12.2014
comment
Я пытался копаться в коде, так как я вижу, что он сначала пытается вызвать solution_function(self, X), и если это приводит к NotImplementerError, он пытается предсказать_пробу. Итак, я пошел искать base.py в SVM, чтобы искать функцию решения. Я вижу, что у него есть это: if self._sparse: поднять NotImplementedError (Decision_function не поддерживается для разреженного SVM.). Так может дело в этом? Я не уверен, но, возможно, рабочий процесс, который я использовал, приводит к разреженной матрице.   -  person Maksim Khaitovich    schedule 09.12.2014
comment
Хотя предыдущий комментарий можно игнорировать, поскольку в руководстве sklearn говорится, что SVC можно использовать с разреженной матрицей, если он был обучен на разреженных данных. И поскольку я использую конвейер, я определенно предсказываю, используя то же представление, что и для обучения.   -  person Maksim Khaitovich    schedule 09.12.2014


Ответы (1)


Хорошо, я провел небольшое исследование кода. OneVsRestClassifier сначала пытается вызвать функцию solution_function, а если не получается, то переходит к функции predict_proba базового классификатора (в нашем случае svm.svc).

Насколько я вижу, мой X_test - это numpy.array списков строк. После того, как он претерпит последовательность преобразований, указанных в конвейере CountVectorizer -> TfidfTransformer, он станет разреженной матрицей (по замыслу этих вещей). Как я вижу, в настоящее время функция решения недоступна для разреженных матриц, и на github даже есть открытое предложение: https://github.com/scikit-learn/scikit-learn/issues/73

Итак, подводя итог, похоже, что вы не можете сделать классификацию с несколькими метками, используя svm.svc, если вы не укажете вероятность = True. Если вы сделаете это, вы внесете некоторые накладные расходы в процесс classifier.fit, но он будет работать.

person Maksim Khaitovich    schedule 09.12.2014
comment
Я не могу проверить это прямо сейчас, но я проверю это завтра и опубликую обновление здесь :) - person Maksim Khaitovich; 10.12.2014
comment
Хорошо, это работает (хотя и приводит к значительным накладным расходам). Обновленный ответ. - person Maksim Khaitovich; 10.12.2014
comment
Хммм, я только что заметил, что он работает ужасно. Когда я отправляю разные примеры обученному классификатору, он делает ОДИНАКОВЫЕ ПРОГНОЗЫ для каждого примера. - person Maksim Khaitovich; 11.12.2014
comment
Кстати, я проверил это с разными ядрами (линейными, rbf и т. д.) - каждое из них с вероятностью = True начинает выводить одинаковые прогнозы для каждого из примеров, которые я подаю им во время операции прогнозирования. Похоже, он просто выводит метку с наивысшей вероятностью. - person Maksim Khaitovich; 11.12.2014
comment
Я не могу комментировать это, не видя ваших данных и настроек. Классификаторы SVM нуждаются в обширной настройке для правильной работы, поэтому это может быть недостатком как вашего кода, так и библиотеки. - person Fred Foo; 13.12.2014
comment
Весь код прямо выше, никаких дополнительных шагов. Я не уверен, как я мог разместить здесь исходные данные, но в целом это просто файл csv, который читается на первом этапе в кадре данных pandas. csv имеет 6 столбцов с именами, начинающимися с «corax» — это угрожаемые y_train и y_test. Остальные столбцы имеют имена, начинающиеся с «change», и им угрожают как x_train и x_test. - person Maksim Khaitovich; 15.12.2014
comment
На самом деле я пытался использовать SVC(kernel='linear', probablility=True) в качестве классификатора, он выводит совершенно разные результаты (по сравнению только с классификатором LinearSVC), и у него также есть та же проблема - он выводит абсолютно одинаковые прогнозы для каждого примера. Другое наблюдение заключается в том, что если LinearSVC выводит что-то вроде 4-10 меток для каждого примера, то простой SVC с линейным ядром и вероятностью=True выводит 50 меток для каждого примера. - person Maksim Khaitovich; 15.12.2014