やりたいこと
scikit-learn はPythonのほぼデファクトの機械学習ライブラリです.scikit-learnの利点としては多くのアルゴリズムが実装されていることもそうですが,一貫した形で設計されており様々なアルゴリズムを共通したかたちで扱えることです.scikit-learnにないアルゴリズムを新たに実装したり,他のライブラリを使用するときにsciki-learnの他の推定器と同様に扱えるよう実装すれば,もともと実装されている推定器同様にクロスバリデーションで性能を評価したりグリッドサーチでパラメータを最適化したりできます.ここでは最低限の推定器の実装を示します.ここでは識別器または回帰器をターゲットとして考えます(クラスタリングとか教師なし学習とかは考えない).
べたな実装
from sklearn.base import BaseEstimator
class MyEstimator(BaseEstimator):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
def fit(self, x, y):
return self
def predict(self, x):
return [1.0]*len(x)
def score(self, x, y):
return 1
def get_params(self, deep=True):
return {'param1': self.param1, 'param2': self.param2}
def set_params(self, **parameters):
for parameter, value in parameters.items():
setattr(self,parameter, value)
return self
sklearn.base.BaseEstimatorを継承して推定器クラスを定義します.メソッドの中身は適宜書き換えて下さい.
実行例
Cross validation:
x = [[2,3],[4,5],[6,1],[2,0]]
y = [0.0,9.4,2.1,0.9]
estimator = MyEstimator()
cross_validation.cross_val_score(estimator,x,y,cv=3)
Result:
array([ 1., 1., 1.])
Grid search:
gs = grid_search.GridSearchCV(estimator, {'param1': [0,10], 'param2': (1, 1e-1, 1e-2)})
gs.fit(x,y)
gs.best_estimator_, gs.best_params_, gs.best_score_
Result:
(MyEstimator(), {'param1': 0, 'param2': 1}, 1.0)
cross_validation
cross_validationを行なう為には訓練データを学習するfitメソッドとテストデータを入力しそこから推定した値と正解の値を比較してスコアを出力するscoreメソッドが必要です.
fit(self, x, y)
入力xに対して出力がyとなるように学習する関数です.
predict(self, x)
入力xに対して出力がy_predを返す関数です.cross_validationをするだけならpredictは必要ありませんが,多くの場合score内部でpredictを呼ぶでしょう.sklearnbase.ClassifierMixinやscikit-learn.base.RegressionMixinを多重継承することでpredictのみを実装することで,実装済みのscore関数が使えます.
score(self, x, y)
入力xに対して出力y_predを推定し,y_predと正解yとを比較してスコア(誤差とかラベルが一致しているかなど)を返す関数です.
grid_search
grid_searchを行う為には,上で定義したように学習してスコアを計算する他にパラメータを操作する必要があります.データに依存しないパラメータを取得するメソッドget_paramsとパラメータをセットするメソッドset_paramsを実装します.
get_params(self, deep=True)
get_paramsメソッドはパラメータのkeyがattribute名.valueが値であるような辞書を返すようにします.
set_params(self, **parameters)
パラメータのセッタです.get_params同様に辞書で渡します.
Mixinについて
識別モデルの場合sklearn.base.ClassifierMixin,回帰モデルの場合sklearn.base.RegressorMixinを多重継承することで実装済のメソッドが使える.
これらを継承すると
sklearn.base.ClassifierMixin- attribute
_estimator_typeにclassifierまたはregressorをセット - 定義済み
scoreメソッドが使える.scoreメソッド内でpredictメソッドを呼ぶのでpredictメソッドは実装する必要がる. - スコアはaccuracy
sklearn.base.RegressorMixin- attribute
_estimator_typeにregressorをセット - 定義済み
scoreメソッドが使える.scoreメソッド内でpredictメソッドを呼ぶのでpredictメソッドは実装する必要がる. - スコアは決定係数 $R^2$
releaseにむけて
sklearn.utils.estimator_checks.check_estimatorで自前のestimatorがsklearnに適合するかどうかがチェックできます.ちなみにこの記事で示したサンプルだと入力のvalidationができていないというエラーをはきます.自分が使うぶんには問題はないでしょうけど.
まとめ
- 自前のestimatorクラスは
sklearn.base.BaseEstimatorを継承してつくる -
cross_validationするためにはfit,scoreメソッドが必要 -
grid_searchするためには,さらにget_params,set_paramsメソッドが必要 -
ClassifierMixinまたはRegressorMixinを定義すると自分で実装したpredictを使ってスコアを計算する,scoreメソッドが使える.
参考
ここに書いたものはほぼ
sklearn.baseモジュールのAPI Reference
公式サイトの開発者向け情報
を参考にしています.