1. Qiita
  2. 投稿
  3. Python
  • 7
    いいね
  • 0
    コメント

かれこれ一年ほど,「機械学習よくわかんないけどscikit-learnなら使えます(テヘペロ」などとほざいて生きてきた.
しかし,このたびscikit-learnすらまともに使いこなせていないことが発覚し,ゆるふわ機械学習エンジニアと名乗ることもできなくなった.

というわけで,忸怩たる思いでscikit-learnについて学び直すことにした.
$HOME/Desktop/memo.mdにメモを書き溜めていたが誤ってrmしてしまったのでQiitaを使ってみる.
新しく学びを得たら随時追加していく.

(間違いがあったらご指摘頂けると幸いです.どうかよろしくお願いします.)

素性の次元削減

k個の素性を選択する.
SelectKBestの第一引数は関数でchi2のほかにもf_classifなどが使える.

from sklearn.feature_selection.univariate_selection import SelectKBest, chi2

fselect = SelectKBest(chi2 , k=2000)

参考: How do I properly use SelectKBest, GridSearchCV, and cross-validation in the sklearn package together?

前処理 -> 学習 をシームレスに

前処理が必要なデータを扱うとき,前処理や素性の抽出を model.fit() の中でできるとコードが綺麗になりそう.
Pipelineというシステムがこれを実現してくれる.名前のままである.

Before

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import LinearSVC

# build the feature matrices
ngram_counter = CountVectorizer(ngram_range=(1, 4), analyzer='char')
X_train = ngram_counter.fit_transform(data_train)
X_test  = ngram_counter.transform(data_test)

# train the classifier
classifier = LinearSVC()
model = classifier.fit(X_train, y_train)

# test the classifier
y_test = model.predict(X_test)

After

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import LinearSVC

# build the pipeline
ppl = Pipeline([
              ('ngram', CountVectorizer(ngram_range=(1, 4), analyzer='char')),
              ('clf',   LinearSVC())
      ])

# train the classifier
model = ppl.fit(data_train)

# test the classifier
y_test = model.predict(data_test)

コードは下記のブログ記事から引用したが,記事の下のほうにFeatureUnionというのもある.

参考: Using Pipelines and FeatureUnions in scikit-learn

自作学習器でもscikit-learnのエコシステムに乗りたい

scikit-learn が提供していないモデルを使う必要が出てきたら,自分で実装をしなければならない.
モデルを実装したあと,評価するために cross validation や grid search をする必要がある.
scikit-learn の model_selectionのレールに乗れたらこのへんの実装をさぼることができる.
これは,モデルの実装の際に BaseEstimator を継承することで達成できる.

下記の参考記事で示されているコードを引用する.

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

ちなみに, ClassifierMixin , RegressorMixin を継承するとscikit-learn側で実装された model.score が使える.
レールには積極的に乗って行きたい.

参考: scikit-learn で最低限の自作推定器(Estimator)を実装する