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

Я изучаю машинное обучение и создаю свою первую модель на наборе данных #mnist.

Может ли кто-нибудь помочь мне здесь? Я пробовал Stratified Fold, kfold и другие методы решения этой проблемы.

Версия Pandas «0.25.1», версия Python 3.7, с использованием дистрибутива Anaconda.

from  sklearn.model_selection import train_test_split
train_set ,test_set = train_test_split(mnist,test_size = 0.2, random_state = 29)
from sklearn.linear_model import SGDClassifier
sgd_clf = SGDClassifier(random_state=29)
sgd_clf.fit(X_train,y_train_5)

X_train, y_train = train_set.drop('label',axis = 1), train_set[['label']]
X_test, y_test = test_set.drop('label',axis = 1),test_set[['label']]

y_train_5 = (y_train == 5) #True for all 5's and false otherwise
y_test_5 = (y_train == 5)

from sklearn.model_selection import cross_val_predict

print(X_train.shape)
print(y_train_5.shape)
cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method="decision_function")

Последняя строка блока кода выдает ошибку:

RuntimeWarning: Number of classes in training fold (2) does not match total number of classes (1). Results may not be appropriate for your use case. To fix this, use a cross-validation technique resulting in properly stratified folds
  RuntimeWarning)
ValueError                                Traceback (most recent call last)
<ipython-input-39-da1ad024473a> in <module>
      3 print(X_train.shape)
      4 print(y_train_5.shape)
----> 5 cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method="decision_function")

~\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\model_selection\_validation.py in cross_val_predict(estimator, X, y, groups, cv, n_jobs, verbose, fit_params, pre_dispatch, method)
    787     prediction_blocks = parallel(delayed(_fit_and_predict)(
    788         clone(estimator), X, y, train, test, verbose, fit_params, method)
--> 789         for train, test in cv.split(X, y, groups))
    790 
    791     # Concatenate the predictions

~\AppData\Local\Continuum\anaconda3\lib\site-packages\joblib\parallel.py in __call__(self, iterable)
    919             # remaining jobs.
    920             self._iterating = False
--> 921             if self.dispatch_one_batch(iterator):
    922                 self._iterating = self._original_iterator is not None
    923 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\joblib\parallel.py in dispatch_one_batch(self, iterator)
    757                 return False
    758             else:
--> 759                 self._dispatch(tasks)
    760                 return True
    761 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\joblib\parallel.py in _dispatch(self, batch)
    714         with self._lock:
    715             job_idx = len(self._jobs)
--> 716             job = self._backend.apply_async(batch, callback=cb)
    717             # A job can complete so quickly than its callback is
    718             # called before we get here, causing self._jobs to

~\AppData\Local\Continuum\anaconda3\lib\site-packages\joblib\_parallel_backends.py in apply_async(self, func, callback)
    180     def apply_async(self, func, callback=None):
    181         """Schedule a func to be run"""
--> 182         result = ImmediateResult(func)
    183         if callback:
    184             callback(result)

~\AppData\Local\Continuum\anaconda3\lib\site-packages\joblib\_parallel_backends.py in __init__(self, batch)
    547         # Don't delay the application, to avoid keeping the input
    548         # arguments in memory
--> 549         self.results = batch()
    550 
    551     def get(self):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\joblib\parallel.py in __call__(self)
    223         with parallel_backend(self._backend, n_jobs=self._n_jobs):
    224             return [func(*args, **kwargs)
--> 225                     for func, args, kwargs in self.items]
    226 
    227     def __len__(self):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\joblib\parallel.py in <listcomp>(.0)
    223         with parallel_backend(self._backend, n_jobs=self._n_jobs):
    224             return [func(*args, **kwargs)
--> 225                     for func, args, kwargs in self.items]
    226 
    227     def __len__(self):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\model_selection\_validation.py in _fit_and_predict(estimator, X, y, train, test, verbose, fit_params, method)
    887             n_classes = len(set(y)) if y.ndim == 1 else y.shape[1]
    888             predictions = _enforce_prediction_order(
--> 889                 estimator.classes_, predictions, n_classes, method)
    890     return predictions, test
    891 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\model_selection\_validation.py in _enforce_prediction_order(classes, predictions, n_classes, method)
    933                                  'is not supported for decision_function '
    934                                  'with imbalanced folds. {}'.format(
--> 935                                     len(classes), n_classes, recommendation))
    936 
    937         float_min = np.finfo(predictions.dtype).min

ValueError: Only 2 class/es in training fold, but 1 in overall dataset. This is not supported for decision_function with imbalanced folds. To fix this, use a cross-validation technique resulting in properly stratified folds

person Anuj Mahawar    schedule 06.12.2019    source источник


Ответы (1)


Я столкнулся с похожей проблемой и при дальнейшем расследовании обнаружил предупреждающее сообщение с журналом ошибок.

DataConversionWarning: вектор-столбец y был передан, когда ожидался массив 1d. Измените форму y на (n_samples, ), например, с помощью ravel().

Есть два способа решить эту проблему:

  1. Используйте подсказку в предупреждающем сообщении и измените код следующим образом:

    cross_val_predict(sgd_clf, X_train, y_train_5.values.ravel(), cv=3, 
    method="decision_function")
    
  2. Также, используя подсказку от - A column-vector y was passed when a 1d array was expected.; Я отпустил свою ошибку и сделал следующее:

    • Even in your error log- Number of classes in training fold (2) does not match total number of classes (1)
    • Я предполагаю, что y_train_5 здесь является DataFrame (вероятно, вы работаете над публикацией Орельена)
    • Ожидаемый тип для y_train_5 — это объект типа массива (что означает, что shaoe будет (n,) или one-dimensional), но DataFrame в вашем случае является двумерным (n,1).
    • Все, что вам нужно сделать, это передать объект Series для вашего вектора-столбца как-
      #P6#
      #P7#
    • Попробуйте запустить ниже в консоли.
    > y_train_5.iloc[:,0].shape
    (n,)
    
    cross_val_predict(sgd_clf, X_train, y_train_5.iloc[:,0], cv=3, 
    method="decision_function")
    
    
person Karan Chopra    schedule 15.02.2020