web-dev-qa-db-ja.com

sklearnでカスタム推定量を記述し、それにクロス検証を使用する方法は?

クロスバリデーションによる新手法の予測誤差を確認したい。私のメソッドをsklearnの交差検証関数に渡すことができるかどうか、またどのように渡すかを知りたいです。

sklearn.cross_validation(cv=10).mymethodのようなものをお願いします。

関数である場合のmymethodの定義方法と、どの入力要素とどの出力も知る必要があります。

たとえば、最小二乗推定量の実装をmymethodと見なすことができます(もちろん、sklearnの実装ではありません)。

私はこのチュートリアル link を見つけましたが、あまりわかりません。

documentation では、

>>> import numpy as np
>>> from sklearn import cross_validation
>>> from sklearn import datasets
>>> from sklearn import svm

>>> iris = datasets.load_iris()
>>> iris.data.shape, iris.target.shape
((150, 4), (150,))

 >>> clf = svm.SVC(kernel='linear', C=1) 
 >>> scores = cross_validation.cross_val_score(
 ...    clf, iris.data, iris.target, cv=5)
 ...
 >>> scores      

しかし、問題は、sklearnに組み込まれた関数によって取得されたclfを推定値として使用していることです。 cross_validation.cross_val_score関数に渡すために、独自の推定器をどのように定義する必要がありますか?

したがって、たとえば、線形モデル$ y = x\beta $を使用する単純な推定器を考えます。ここで、betaはX [1、:] + alphaとして推定され、alphaはパラメーターです。コードをどのように完成させる必要がありますか?

class my_estimator():
      def fit(X,y):
          beta=X[1,:]+alpha #where can I pass alpha to the function?
          return beta
      def scorer(estimator, X, y) #what should the scorer function compute?
          return ?????

次のコードでエラーを受け取りました:

class my_estimator():
    def fit(X, y, **kwargs):
        #alpha = kwargs['alpha']
        beta=X[1,:]#+alpha 
        return beta

>>> cv=cross_validation.cross_val_score(my_estimator,x,y,scoring="mean_squared_error")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\scikit_learn-0.14.1-py2.7-win32.Egg\sklearn\cross_validation.py", line 1152, in cross_val_score
    for train, test in cv)
  File "C:\Python27\lib\site-packages\scikit_learn-0.14.1-py2.7-win32.Egg\sklearn\externals\joblib\parallel.py", line 516, in __call__
    for function, args, kwargs in iterable:
  File "C:\Python27\lib\site-packages\scikit_learn-0.14.1-py2.7-win32.Egg\sklearn\cross_validation.py", line 1152, in <genexpr>
    for train, test in cv)
  File "C:\Python27\lib\site-packages\scikit_learn-0.14.1-py2.7-win32.Egg\sklearn\base.py", line 43, in clone
    % (repr(estimator), type(estimator)))
TypeError: Cannot clone object '<class __main__.my_estimator at 0x05ACACA8>' (type <type 'classobj'>): it does not seem to be a scikit-learn estimator a it does not implement a 'get_params' methods.
>>> 
27
Donbeo

答えはsklearnの documentation にもあります。

次の2つを定義する必要があります。

  • fit(X, y)関数を実装する推定器、Xは入力のある行列、yは出力のベクトル

  • スコアラー関数、またはscorer(estimator, X, y)で使用できる呼び出し可能オブジェクト。指定されたモデルのスコアを返します

あなたの例を参照してください:まず第一に、scorerは推定器のメソッドであってはなりません。それは別の概念です。呼び出し可能を作成するだけです:

def scorer(estimator, X, y)
    return ?????  # compute whatever you want, it's up to you to define
                  # what does it mean that the given estimator is "good" or "bad"

またはより簡単な解決策:'mean_squared_error'または'accuracy'ドキュメントのこの部分 で利用可能な完全なリスト)をcross_val_score関数に渡して使用できます事前定義されたスコアラー。

別の可能性は、 make_scorer ファクトリ関数を使用することです。

2番目のものについては、 fit_params 関数のcross_val_scoredictパラメータを介してモデルにパラメータを渡すことができます(ドキュメントで説明されています)。これらのパラメーターはfit関数に渡されます。

class my_estimator():
    def fit(X, y, **kwargs):
        alpha = kwargs['alpha']
        beta=X[1,:]+alpha 
        return beta

何が欠けているかを明確に示すすべてのエラーメッセージを読んだ後、簡単な例を次に示します。

import numpy as np
from sklearn.cross_validation import cross_val_score

class RegularizedRegressor:
    def __init__(self, l = 0.01):
        self.l = l

    def combine(self, inputs):
        return sum([i*w for (i,w) in Zip([1] + inputs, self.weights)])

    def predict(self, X):
        return [self.combine(x) for x in X]

    def classify(self, inputs):
        return sign(self.predict(inputs))

    def fit(self, X, y, **kwargs):
        self.l = kwargs['l']
        X = np.matrix(X)
        y = np.matrix(y)
        W = (X.transpose() * X).getI() * X.transpose() * y

        self.weights = [w[0] for w in W.tolist()]

    def get_params(self, deep = False):
        return {'l':self.l}

X = np.matrix([[0, 0], [1, 0], [0, 1], [1, 1]])
y = np.matrix([0, 1, 1, 0]).transpose()

print cross_val_score(RegularizedRegressor(),
                      X,
                      y, 
                      fit_params={'l':0.1},
                      scoring = 'mean_squared_error')
24
BartoszKP