Я пытаюсь провести многозначную классификацию с помощью SVM. У меня почти 8k функций, а также вектор y длиной почти 400. У меня уже есть бинаризованные векторы Y, поэтому я не использовал MultiLabelBinarizer (), но когда я использую его с необработанной формой данных Y, он по-прежнему дает то же самое.

Я запускаю этот код:

X = np.genfromtxt('data_X', delimiter=";")
Y = np.genfromtxt('data_y', delimiter=";")
training_X = X[:2600,:]
training_y = Y[:2600,:]

test_sample = X[2600:2601,:]
test_result = Y[2600:2601,:]

classif = OneVsRestClassifier(SVC(kernel='rbf'))
classif.fit(training_X, training_y)
print(classif.predict(test_sample))
print(test_result)

После всего процесса подгонки, когда дело доходит до части прогнозирования, говорится: Метка, а не x присутствует во всех обучающих примерах (x - это несколько разных чисел в диапазоне моей длины вектора y, равной 400). После этого он дает предсказанный вектор y, который всегда является нулевым вектором длиной 400 (длина вектора y). Я новичок в scikit-learn, а также в машинном обучении. Я не мог понять, в чем проблема. В чем проблема и что мне делать, чтобы ее исправить? Спасибо.

Ответы (1)

Тут 2 проблемы:

1) Предупреждение об отсутствии этикетки
2) Вы получаете все 0 для прогнозов

Предупреждение означает, что некоторые из ваших классов отсутствуют в обучающих данных. Это распространенная проблема. Если у вас 400 классов, то некоторые из них должны встречаться очень редко, и при любом разбиении данных некоторые классы могут отсутствовать с одной стороны разбиения. Также могут быть классы, которые просто не встречаются в ваших данных. Вы можете попробовать Y.sum (axis = 0) .all (), и если это False, то некоторые классы не встречаются даже в Y. Все это звучит ужасно, но на самом деле вы не собираетесь чтобы иметь возможность правильно предсказывать классы, которые встречаются 0, 1 или любое очень небольшое количество раз в любом случае, поэтому предсказание 0 для них, вероятно, лучшее, что вы можете сделать.

Что касается прогнозов all-0, я отмечу, что с 400 классами, вероятно, все ваши классы встречаются гораздо реже, чем в половине случаев. Вы можете проверить Y.mean (axis = 0) .max (), чтобы получить самую высокую частоту меток. С 400 классами это может быть всего несколько процентов. Если это так, двоичный классификатор, который должен делать прогноз 0-1 для каждого класса, вероятно, выберет 0 для всех классов во всех экземплярах. На самом деле это не ошибка, это просто потому, что частоты всех классов низкие.

Если вы знаете, что у каждого экземпляра есть положительная метка (по крайней мере, одна), вы можете получить значения решения (clf.decision_function) и выбрать класс с наивысшим из них для каждого экземпляра. Однако для этого вам придется написать код.

Однажды я попал в топ-10 в конкурсе Kaggle, который был похож на этот. Это была проблема с несколькими метками с ~ 200 классами, ни один из которых не возникал даже с частотой 10%, и нам требовались прогнозы 0-1. В этом случае я получил значения решения и взял наивысшее, плюс все, что было выше порога. Я выбрал порог, который лучше всего работал на удерживающем наборе. Код для этой записи находится на Github: Kaggle Greek Media code. Вы можете взглянуть на это.

Если вы дошли до этого места, спасибо за чтение. Надеюсь, это поможет.

2022 WebDevInsider