Sklearn: NotFitedError: Этот экземпляр SVC еще не установлен.Мягкое голосование по калибровочным классификаторам - PullRequest
0 голосов
/ 05 октября 2018

Я пытался использовать мягкое голосование для калибровочных классификаторов на склеарне.Поскольку мягкое голосование пока не имеет опции prefit, я попытался заставить VotingClassifier.fit() позвонить CalibratedClassifierCV.fit().Вот мой код:

data = load_breast_cancer()

# Data spliting.
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25)

# Base classifiers.
clf_svm = svm.SVC(gamma=0.001, probability=True)
clf_svm.fit(X_train, y_train)

clf_lr = LogisticRegression(random_state=0, solver='lbfgs')
clf_lr.fit(X_train, y_train)

svm_isotonic = CalibratedClassifierCV(clf_svm, cv='prefit', method='isotonic')
svm_isotonic.fit(X_val, y_val)

lr_isotonic = CalibratedClassifierCV(clf_lr, cv='prefit', method='isotonic')
lr_isotonic.fit(X_val, y_val)

eclf_soft2 = VotingClassifier(estimators=[
    ('svm', svm_isotonic), ('lr', lr_isotonic)], voting ='soft')
eclf_soft2.fit(X_val, y_val)

Однако я получил несколько странных ошибок:

Traceback (most recent call last):
  File "/home/ubuntu/projects/faceRecognition/faceVerif/util/plot_calibration.py", line 127, in <module>
    main(parse_arguments(sys.argv[1:]))
  File "/home/ubuntu/projects/faceRecognition/faceVerif/util/plot_calibration.py", line 120, in main
    eclf_soft2.fit(X_val, y_val)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/ensemble/voting_classifier.py", line 189, in fit
    for clf in clfs if clf is not None)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 779, in __call__
    while self.dispatch_one_batch(iterator):
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 625, in dispatch_one_batch
    self._dispatch(tasks)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 588, in _dispatch
    job = self._backend.apply_async(batch, callback=cb)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/_parallel_backends.py", line 111, in apply_async
    result = ImmediateResult(func)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/_parallel_backends.py", line 332, in __init__
    self.results = batch()
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 131, in __call__
    return [func(*args, **kwargs) for func, args, kwargs in self.items]
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 131, in <listcomp>
    return [func(*args, **kwargs) for func, args, kwargs in self.items]
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/ensemble/voting_classifier.py", line 31, in _parallel_fit_estimator
    estimator.fit(X, y)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/calibration.py", line 157, in fit
    calibrated_classifier.fit(X, y)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/calibration.py", line 335, in fit
    df, idx_pos_class = self._preproc(X)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/calibration.py", line 290, in _preproc
    df = self.base_estimator.decision_function(X)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py", line 527, in decision_function
    dec = self._decision_function(X)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py", line 384, in _decision_function
    X = self._validate_for_predict(X)
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/svm/base.py", line 437, in _validate_for_predict
    check_is_fitted(self, 'support_')
  File "/home/ubuntu/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py", line 768, in check_is_fitted
    raise NotFittedError(msg % {'name': type(estimator).__name__})
sklearn.exceptions.NotFittedError: This SVC instance is not fitted yet. Call 'fit' with appropriate arguments before using this method.

У меня вопрос, как исправить эту ошибку, или есть какое-нибудь альтернативное решение, пожалуйста?

Заранее спасибо.

1 Ответ

0 голосов
/ 05 октября 2018

VotingClassifier будет клонировать поставленные оценки (и их внутренние оценки, как в этом случае), а затем попытаться соответствовать им.Но в CalibratedClassifierCV вы используете cv='prefit', что предполагает, что вы уже установили оценки.Это приводит к конфликту и этой ошибке.

Объяснение:

VotingClassifier имеют две внутренние оценки

  • ('svm', svm_isotonic),
  • ('lr', lr_isotonic)

Когда вы звоните eclf_soft2.fit, сначала будут clone svm_isotonic и lr_isotonic.Клонирование этих CalibratedClassifierCV оценок затем клонирует их базовые оценки clf_svm и clf_lr.

Это клонирование происходит таким образом, что копируются только значения параметров, а не фактические атрибуты, извлеченные из предыдущих вызовов fit().По сути, ваши клонированные clf_svm и clf_lr теперь не подходят.

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

Но если вы хотите использовать VotingClassifier только для его возможностей мягкого голосования в объединенной системе двух оценщиков CalibratedClassifierCV, это можно сделать легко.

Принимая идеи из моего другого ответа напохожий вопрос:

Вы можете сделать это:

import numpy as np

# Define functions
def custom_fit(estimators, X, y):
    for clf in estimators:
        clf.fit(X, y)

def custom_predict(estimators, X, voting = 'soft', weights = None):

    if voting == 'hard':
        pred = np.asarray([clf.predict(X) for clf in estimators]).T
        pred = np.apply_along_axis(lambda x:
                                   np.argmax(np.bincount(x, weights=weights)),
                                   axis=1,
                                   arr=pred.astype('int'))
    else:
        pred = np.asarray([clf.predict_proba(X) for clf in estimators])
        pred = np.average(pred, axis=0, weights=weights)
        pred = np.argmax(pred, axis=1)

    return pred


# Use them
estimators=[svm_isotonic, lr_isotonic]
custom_fit(estimators, X_val, y_val)

custom_predict(estimators, X_test)    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...