静かなる名辞

pythonとプログラミングのこと


【python】sklearnで「何もしない」モデルがほしい

 sklearnで「何もしない」モデルがあると、チョー便利。個人的にはそう思う。

 どうやって使うかというと、具体的には以前の記事で書いたFeatureUnionと組み合わせて使う。

 参考(以前の記事):【python】複数の特徴をまとめるFeatureUnion - 静かなる名辞

 たとえば、100次元の特徴量があったとき、「入力をそのまま出力する(何もしない)モデル」と「何らかの加工をして出力するモデル」を組み合わせたモデルに入力すれば、100次元+加工した特徴量の次元の新たな特徴量とすることができる。これが有効な場面はそれなりに多そう。

 ・・・なのだが、sklearnにはそれに当てはまるようなモデルは用意されてなさそうだし、ググっても出てこない。自分で書いている人はいた。

from sklearn.base import BaseEstimator, TransformerMixin

class IdentityTransformer(BaseEstimator, TransformerMixin):
    def __init__(self):
        pass
    
    def fit(self, input_array, y=None):
        return self
    
    def transform(self, input_array, y=None):
        return input_array*1

 引用元:sklearn Identity-transformer – Laurent H. – Medium

 原文通りだけど*1は要らないと思う。とにかく、同じようなことを考える人はいるものだ。簡単に書けるのもわかったけど、そのために自分でクラスを定義するのもなんだかなぁ、という気がする。もっと色々なメソッドに対応させようとすると面倒臭さが増していきそうなのも、あまりよくない。

 そこで改めてドキュメントを漁ったら、使えそうなのがあった。FunctionTransformerなるもの。

sklearn.preprocessing.FunctionTransformer — scikit-learn 0.20.1 documentation

 任意の関数を渡してTransformerを生成できるというなかなかのスグレモノである。こいつは関数が渡されないとき、入力をそのまま出力するとドキュメントに書いてある。使えそう。簡単に確認する。

>>> from sklearn.datasets import load_iris
>>> from sklearn.preprocessing import FunctionTransformer
>>> iris = load_iris()
>>> identity_transformer = FunctionTransformer()
>>> iris.data[:10]
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2],
       [5.4, 3.9, 1.7, 0.4],
       [4.6, 3.4, 1.4, 0.3],
       [5. , 3.4, 1.5, 0.2],
       [4.4, 2.9, 1.4, 0.2],
       [4.9, 3.1, 1.5, 0.1]])
>>> identity_transformer.fit_transform(iris.data[:10])
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2],
       [5.4, 3.9, 1.7, 0.4],
       [4.6, 3.4, 1.4, 0.3],
       [5. , 3.4, 1.5, 0.2],
       [4.4, 2.9, 1.4, 0.2],
       [4.9, 3.1, 1.5, 0.1]])

 使えた。

 本来の使い方ではないと思うけど、これがベター・・・なのかなぁ。もっと良いやり方を知っている方がいたら、教えてください。