Sklearn: NotFittedError: This SVC instance is not fitted yet. Soft Voting on Calibration classifiers
Sklearn: NotFittedError: This SVC instance is not fitted yet. Soft Voting on Calibration classifiers
我尝试在 sklearn 上对校准分类器使用软投票。由于到目前为止软投票没有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.
我的问题是如何解决这个错误,或者有其他解决方案吗?
提前致谢。
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
现在不合适了。
不幸的是,没有简单的方法可以为您的用例设置此权利:适合投票分类器,而投票分类器又适合内部校准分类器但不适合基本分类器。
但是,如果您只想在两个 CalibratedClassifierCV 估计器的组合系统上使用 VotingClassifier 的软投票功能,这可以轻松完成。
借鉴我对类似问题的其他回答:
你可以这样做:
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)
我尝试在 sklearn 上对校准分类器使用软投票。由于到目前为止软投票没有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.
我的问题是如何解决这个错误,或者有其他解决方案吗?
提前致谢。
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
现在不合适了。
不幸的是,没有简单的方法可以为您的用例设置此权利:适合投票分类器,而投票分类器又适合内部校准分类器但不适合基本分类器。
但是,如果您只想在两个 CalibratedClassifierCV 估计器的组合系统上使用 VotingClassifier 的软投票功能,这可以轻松完成。
借鉴我对类似问题的其他回答:
你可以这样做:
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)