自作した(というかWrapしただけですが)学習器をcross_vali_score
に入れたら怒られました.
これをきっかけにいろいろ調べるとscikit-learn準拠の学習モデルを作成するためにはいくつか条件があると知りました.
これが最低限!みたいなサイトのコードをとりあえずコピペしてcheck_estimator
してみたのですが,大体の場合で怒られたので自分向けにまとめておきます.
versionによる差の可能性もありますね.
目次
- 動いたコードを紹介する前に
- 動いたコード
- この審査に通過すると何が良いのか.
- エラー集
- self.fuga = hogeとしたとき
- fit後に初めて確定する変数なのに '_' をつけ忘れた場合
- Xかyに妥当な値が入ってこなかったのにエラーにならなかったとき
- fitのreturnとしてselfを返さなかったとき
- predictするにあたって使う特徴量をcheck_arrayしなかった場合
- 予測結果を返さなかったとき
- 参考
動いたコードを紹介する前に¶
今回は回帰に限定しています.参考になる部分もあるかとは思いますが,分類器とは少しことなると思います.
たとえば回帰学習器はBaseEstimator, RegressorMixin
を継承する必要がありますが,分類器はBaseEstimator, ClassifierMixin
を継承する必要があります.
環境¶
python
import sys
print(sys.version)
3.7.9 | packaged by conda-forge | (default, Dec 9 2020, 20:58:55)
[Clang 11.0.0 ]
PC¶
import subprocess
print(subprocess.run('sw_vers', stdout = subprocess.PIPE).stdout.decode())
ProductName: Mac OS X
ProductVersion: 10.15.7
BuildVersion: 19H15
参考
package
import numpy, sklearn, lightgbm, pandas
print('\n'.join(map(lambda x:'{0}: {1}'.format(x.__name__, x.__version__), [numpy, sklearn, lightgbm, pandas])))
numpy: 1.16.4
sklearn: 0.22
lightgbm: 3.0.0
pandas: 1.1.3
動いたコード¶
学習器の内容を考えたわけではないのでlightgbmのLGBMRegressorをwrapして「自作学習器」とします.
(そもそもLGBMRegressor自体がscikit-learn準拠モデルなので単なる下位互換ですが.勉強のためということで.)
sklearn.utils.estimator_checks.check_estimator
という関数にclassをそのまま,またはインスタンスを入れて,何もエラーが出なければ準拠してる!って感じです.
今回「動いたコード」と言ったのはcheck_estimator
してエラーが起きなかった,と言う意味です.
起きたエラーものちほどまとめます.
モジュールのインポート¶
from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.utils.estimator_checks import check_estimator
from sklearn.utils import check_array, check_X_y
from sklearn.utils.validation import check_is_fitted
from lightgbm import LGBMRegressor
import numpy as np
自作学習器の定義¶
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(
class GBDT(RegressorMixin, BaseEstimator):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
super(BaseEstimator, self).__init__()
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
self.estimator_ = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す
return self.estimator_.predict(X)
自作学習器のcheck¶
check_estimator(GBDT) # check_estimator(GBDT())どちらでもOK
無事チェックを通過しました!!!
ここまで来るのに本当に時間がかかりました.
大体どれか一つを無くしたりミスしたりすると怒られます.
この審査に通過すると何が良いのか.¶
scikit-learnの便利なパッケージを使用することができます.よく言われているのはGridSearchCV
でしょうか.
ですが,ここでは例としてcross_val_score
を挙げます.実装が簡単なので
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_boston
import pandas as pd
boston = load_boston()
X = pd.DataFrame(boston['data'], columns = boston['feature_names'])
y = pd.Series(boston['target'], name = 'PRICE')
gbdt = GBDT(random_state = 334)
for i, score in enumerate(cross_val_score(gbdt, X, y, cv = 5, scoring = 'neg_root_mean_squared_error')):
print('RSE ({0}): {1:.2f}'.format(i, -score))
RSE (0): 3.00
RSE (1): 3.97
RSE (2): 4.26
RSE (3): 6.63
RSE (4): 5.00
便利ですね...
ちなみにfitとpredictできても準拠していないモデルだとこうなります.
エラー集¶
self.fuga = hogeとしたとき¶
今回はself.seed = random_state
の部分です.
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
# self.random_state = random_state
self.seed = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
# self.estimator_ = LGBMRegressor(random_state = self.random_state)
self.estimator_ = LGBMRegressor(random_state = self.seed)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す
return self.estimator_.predict(X)
check_estimator(GBDT())
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-11-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_no_attributes_set_in_init(name, estimator_orig)
2411 "Estimator %s should not set any attribute apart"
2412 " from parameters during init. Found attributes %s."
-> 2413 % (name, sorted(invalid_attr)))
2414 # Ensure that each parameter is set in init
2415 invalid_attr = set(init_params) - set(vars(estimator)) - {"self"}
AssertionError: Estimator GBDT should not set any attribute apart from parameters during init. Found attributes ['seed'].
fit後に初めて確定する変数なのに '_' をつけ忘れた場合¶
self.estimator_ を self.estimatorに置換しただけです.
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
# self.estimator_ = LGBMRegressor(random_state = self.random_state)
self.estimator = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
# self.estimator_.fit(X, y)
self.estimator.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
# check_is_fitted(self, 'estimator_')
check_is_fitted(self, 'estimator')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す
# return self.estimator_.predict(X)
return self.estimator.predict(X)
check_estimator(GBDT())
---------------------------------------------------------------------------
NotFittedError Traceback (most recent call last)
<ipython-input-13-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimators_dtypes(name, estimator_orig)
1340 for method in methods:
1341 if hasattr(estimator, method):
-> 1342 getattr(estimator, method)(X_train)
1343
1344
<ipython-input-12-777dad80e89c> in predict(self, X)
23 # fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
24 # check_is_fitted(self, 'estimator_')
---> 25 check_is_fitted(self, 'estimator')
26
27 # 入力されたXが妥当か判定
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/validation.py in check_is_fitted(estimator, attributes, msg, all_or_any)
950
951 if not attrs:
--> 952 raise NotFittedError(msg % {'name': type(estimator).__name__})
953
954
NotFittedError: This GBDT instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator.
NotFittedErrorが出るんですよね.fit後に確定するはずの変数が与えられていないからと言うことでしょうか?
Xかyに妥当な値が入ってこなかったのにエラーにならなかったとき¶
check_X_y
を入れなかったとき(今回はわかりやすさのためにコメントアウトしています.)になります.
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
self.estimator_ = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
# X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す
return self.estimator_.predict(X)
check_estimator(GBDT())
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-15-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimators_nan_inf(name, estimator_orig)
1402 raise exc
1403 else:
-> 1404 raise AssertionError(error_string_fit, estimator)
1405 # actually fit
1406 estimator.fit(X_train_finite, y)
AssertionError: ("Estimator doesn't check for NaN and inf in fit.", GBDT(random_state=1))
逆に言うとcheck_X_y
で形だけでなく不当なNanやinfを弾いてくれてるんですね.
fitのreturnとしてselfを返さなかったとき¶
これもわかりやすさのためにコメントアウトにしています.
仕様には一見問題なさそうだし,AssertionErrorには何も書いていないしで気づくかいな!って思いました.
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
self.estimator_ = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
# return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す
return self.estimator_.predict(X)
check_estimator(GBDT())
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-17-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimators_fit_returns_self(name, estimator_orig, readonly_memmap)
1987
1988 set_random_state(estimator)
-> 1989 assert estimator.fit(X, y) is estimator
1990
1991
AssertionError:
check_fittedしなかった場合¶
わかりやすさのためにコメントアウトしています.
fitされたかをこうやって判定していたんですね.(自分でtry-exceptとかで定義しなきゃいけないと思ってました.)
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
self.estimator_ = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
# check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す
return self.estimator_.predict(X)
check_estimator(GBDT())
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-19-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimators_unfitted(name, estimator_orig)
2003 'predict_log_proba'):
2004 if hasattr(estimator, method):
-> 2005 assert_raises(NotFittedError, getattr(estimator, method), X)
2006
2007
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/unittest/case.py in assertRaises(self, expected_exception, *args, **kwargs)
754 context = _AssertRaisesContext(expected_exception, self)
755 try:
--> 756 return context.handle('assertRaises', args, kwargs)
757 finally:
758 # bpo-23890: manually break a reference cycle
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/unittest/case.py in handle(self, name, args, kwargs)
176 self.obj_name = str(callable_obj)
177 with self:
--> 178 callable_obj(*args, **kwargs)
179 finally:
180 # bpo-23890: manually break a reference cycle
<ipython-input-18-eebd7f8f95e3> in predict(***failed resolving arguments***)
26
27 # 予測結果を返す
---> 28 return self.estimator_.predict(X)
AttributeError: 'GBDT' object has no attribute 'estimator_'
predictするにあたって使う特徴量をcheck_arrayしなかった場合¶
わかりやすさのためにコメントアウトしています.
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
self.estimator_ = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
# X = check_array(X)
# 予測結果を返す
return self.estimator_.predict(X)
check_estimator(GBDT())
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-21-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimators_nan_inf(name, estimator_orig)
1419 traceback.print_exc(file=sys.stdout)
1420 else:
-> 1421 raise AssertionError(error_string_predict, estimator)
1422
1423 # transform
AssertionError: ("Estimator doesn't check for NaN and inf in predict.", GBDT(random_state=1))
check_X_y
のときと同じ文言ですね.
予測結果を返さなかったとき¶
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
self.estimator_ = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す
# return self.estimator_.predict(X)
check_estimator(GBDT())
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-23-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_fit_score_takes_y(name, estimator_orig)
1306 func = getattr(estimator, func_name, None)
1307 if func is not None:
-> 1308 func(X, y)
1309 args = [p.name for p in signature(func).parameters.values()]
1310 if args[0] == "self":
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/base.py in score(self, X, y, sample_weight)
422 y_pred = self.predict(X)
423 # XXX: Remove the check in 0.23
--> 424 y_type, _, _, _ = _check_reg_targets(y, y_pred, None)
425 if y_type == 'continuous-multioutput':
426 warnings.warn("The default value of multioutput (not exposed in "
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/metrics/_regression.py in _check_reg_targets(y_true, y_pred, multioutput, dtype)
84 check_consistent_length(y_true, y_pred)
85 y_true = check_array(y_true, ensure_2d=False, dtype=dtype)
---> 86 y_pred = check_array(y_pred, ensure_2d=False, dtype=dtype)
87
88 if y_true.ndim == 1:
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator)
560 if force_all_finite:
561 _assert_all_finite(array,
--> 562 allow_nan=force_all_finite == 'allow-nan')
563
564 if ensure_min_samples > 0:
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/validation.py in _assert_all_finite(X, allow_nan, msg_dtype)
58 msg_err.format
59 (type_err,
---> 60 msg_dtype if msg_dtype is not None else X.dtype)
61 )
62 # for object dtype data, we only check for NaNs (GH-13254)
ValueError: Input contains NaN, infinity or a value too large for dtype('float64').
ちなみに変な形でreturnされるときもerrorになります.
# BaseEstimator(get_params, set_paramsメソッドを継承), RegressorMixin(scoreの初期設定など)を継承
class GBDT(BaseEstimator, RegressorMixin):
def __init__(self, random_state = None):
# self.hoge = hogeとしなければいけない.つまりself.fuga = hogeだと怒られる
self.random_state = random_state
def fit(self, X, y):
# fitしたあとに確定する値は変数名 + '_' としなければならない.
self.estimator_ = LGBMRegressor(random_state = self.random_state)
# 入力されたXとyが良い感じか判定(サイズが適切かetc)
X, y = check_X_y(X, y)
# 本来だったらここからが何かしら操作を書く部分.今回はLGBMRegressorをfitする.
self.estimator_.fit(X, y)
# 慣例と聞いたはずなのにこれをreturnしないと怒られる.審査が厳しい.
return self
def predict(self, X):
# fitが行われたかどうかをインスタンス変数が定義されているかで判定(第二引数を文字列ではなくてリストで与えることでより厳密に判定可能)
check_is_fitted(self, 'estimator_')
# 入力されたXが妥当か判定
X = check_array(X)
# 予測結果を返す(変な値が返ることになっていると,)
return [0]
check_estimator(GBDT())
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-25-28d841130f8e> in <module>
----> 1 check_estimator(GBDT())
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_estimator(Estimator, generate_only)
425 for estimator, check in checks_generator:
426 try:
--> 427 check(estimator)
428 except SkipTest as exception:
429 # the only SkipTest thrown currently results from not
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/_testing.py in wrapper(*args, **kwargs)
325 with warnings.catch_warnings():
326 warnings.simplefilter("ignore", self.category)
--> 327 return fn(*args, **kwargs)
328
329 return wrapper
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/estimator_checks.py in check_fit_score_takes_y(name, estimator_orig)
1306 func = getattr(estimator, func_name, None)
1307 if func is not None:
-> 1308 func(X, y)
1309 args = [p.name for p in signature(func).parameters.values()]
1310 if args[0] == "self":
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/base.py in score(self, X, y, sample_weight)
422 y_pred = self.predict(X)
423 # XXX: Remove the check in 0.23
--> 424 y_type, _, _, _ = _check_reg_targets(y, y_pred, None)
425 if y_type == 'continuous-multioutput':
426 warnings.warn("The default value of multioutput (not exposed in "
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/metrics/_regression.py in _check_reg_targets(y_true, y_pred, multioutput, dtype)
82
83 """
---> 84 check_consistent_length(y_true, y_pred)
85 y_true = check_array(y_true, ensure_2d=False, dtype=dtype)
86 y_pred = check_array(y_pred, ensure_2d=False, dtype=dtype)
~/.pyenv/versions/anaconda3-2019.03/envs/CP/lib/python3.7/site-packages/sklearn/utils/validation.py in check_consistent_length(*arrays)
210 if len(uniques) > 1:
211 raise ValueError("Found input variables with inconsistent numbers of"
--> 212 " samples: %r" % [int(l) for l in lengths])
213
214
ValueError: Found input variables with inconsistent numbers of samples: [30, 1]
0 件のコメント:
コメントを投稿