Почему цепочка классификаторов требует как минимум 2 класса, когда у меня есть?

Вопрос или проблема

Я использую Classifier Chain с логистической регрессией, и когда пытаюсь использовать метод fit, получаю

Этот решатель требует наличие образцов как минимум 2 классов в данных, но данные содержат только один класс: 1

Но я довольно уверен, что в моих данных есть два класса, вот мой X_test

<5825x2000 разреженная матрица типа '<class 'numpy.float64'>'
    с 219990 сохраненными элементами в формате сжатой разреженной строки>

А вот мои данные для y_train:

array([[1, 0, 0, ..., 0, 1, 0],
       [1, 0, 0, ..., 1, 1, 0],
       [1, 0, 0, ..., 0, 1, 0],
       ...,
       [1, 0, 0, ..., 1, 1, 0],
       [1, 0, 0, ..., 0, 1, 0],
       [1, 0, 0, ..., 0, 1, 0]])

А это часть кода, которую я пытаюсь запустить

cc_clf = ClassifierChain(LogisticRegression(penalty='l1', C=1, dual=False, solver="liblinear"))
cc_clf.fit(X_train, y_train)
cc_y_pred = cc_clf.predict(X_test)

Я неправильно использую цепочку классификаторов? Когда я передаю те же данные в одну против остальных, это работает.

clf = OneVsRestClassifier(classifier1)
clf.fit(X_train, y_train)

Для использования ClassifierChain в каждом столбце y_train должны быть как 0, так и 1. Вот валидный и невалидный примеры:

import numpy as np
from sklearn.multioutput  import ClassifierChain
from sklearn.linear_model import LogisticRegression

X_train = np.array([[1], [2]])

# Работает
y_train = np.array([[0, 1], [1, 0]]) 
cc_clf = ClassifierChain(LogisticRegression(penalty='l1', C=1, dual=False, solver="liblinear"))
cc_clf.fit(X_train, y_train)

# ValueError
y_train = np.array([[0, 1], [0, 0]])   
cc_clf = ClassifierChain(LogisticRegression(penalty='l1', C=1, dual=False, solver="liblinear"))
cc_clf.fit(X_train, y_train)

Ответ или решение

Причина, по которой метод ClassifierChain требует наличия по крайней мере двух классов, заключается в особой структуре y_train, передаваемого в селектор. При использовании ClassifierChain каждый столбец в y_train должен содержать как классы 0, так и 1. Если хотя бы один столбец из y_train содержит только один уникальный класс, это приведет к ошибке, так как классификатор не может быть обучен на одноклассных данных.

Как видно из вашего примера, вы получаете ошибку:

This solver needs samples of at least 2 classes in the data, but the data contains only one class: 1

Это сообщение указывает на то, что в как минимум одном из столбцов y_train присутствует только 1. Чтобы разобраться с данной проблемой, вы можете выполнить следующие шаги:

  1. Проверьте данные y_train: Убедитесь, что каждая колонка вашего массива y_train содержит и 0, и 1. Вы можете использовать np.unique() для проверки уникальных значений в каждом столбце:

    import numpy as np
    
    unique_classes = [np.unique(y_train[:, i]) for i in range(y_train.shape[1])]
    print(unique_classes)

    Убедитесь, что для каждого столбца выводятся значения, содержащие оба класса.

  2. Использование CV или стратифицированной разбивки: Если вы разделяете данные на обучающую и тестовую выборки, возможно, произошел случайный отбор, и в вашей обучающей выборке остались только экземпляры одного класса. Убедитесь, что разделение данных позволяет сохранить оба класса в y_train. Использование стратифицированного разбиения может помочь:

    from sklearn.model_selection import train_test_split
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.2)
  3. Создание симметричных данных: Убедитесь, что ваши данные сбалансированы. Если у вас действительно присутствуют только экземпляры одного класса в какой-то колонке, возможно, стоит подумать о создании дополнительных данных (например, синтетических), чтобы ваш классификатор был обучен на сбалансированной выборке.

  4. Проверьте выходные данные после обработки: Если вы отфильтровали или изменили данные перед обучением, убедитесь, что ни одна часть обработки данных (например, удаление выбросов) не привела к потере классов.

В качестве примера, корректное использование ClassifierChain может выглядеть следующим образом:

import numpy as np
from sklearn.multioutput import ClassifierChain
from sklearn.linear_model import LogisticRegression

# Пример данных
X_train = np.array([[1], [2], [3], [4]])
y_train = np.array([[0, 1], [1, 0], [1, 0], [0, 1]])

# Обучение модели
cc_clf = ClassifierChain(LogisticRegression(penalty='l1', C=1, dual=False, solver="liblinear"))
cc_clf.fit(X_train, y_train)

Убедитесь, что вы проверили каждый из этих аспектов, чтобы избежать ошибки и успешно обучить вашу модель с использованием ClassifierChain.

Оцените материал
Добавить комментарий

Капча загружается...