LoginSignup
2
6

More than 1 year has passed since last update.

FeatureUnionで特徴量結合するシンプルな方法

Posted at

Scikit-LearnのFeatureUnion関数が初見で結構わかりにくかったのでメモしておきます。「Marking imputed values」を見ていて?となり、学習しました。
これは特徴量エンジニアリング時に特徴量を一括処理をしてまとめてくれます。Piplelineモジュールに含まれており、有名なPipeline関数の兄弟みたいなものです。

FeatureUnionの簡易版でmaike_union関数があります。使うときは、どちらがいいか検討すべきですね。

シンプルな使い方

irisデータを読み込み、1列目の「sepal length (cm)」だけをDataframeに設定します。DataFrame化せずにNumpy配列のままでもOKですが、単純に私がNumpy慣れしていないので入れているだけです。

import pandas as pd
from sklearn import datasets
from sklearn.pipeline import FeatureUnion
from sklearn.preprocessing import FunctionTransformer

# Iris データセットを読み込み、1列目だけをDataFrameへ設定
iris = datasets.load_iris()
df = pd.DataFrame(iris.data[:, 0], columns=[iris.feature_names[0]])
print(df.head())
DataFrame最初の5行
   sepal length (cm)
0                5.1
1                4.9
2                4.7
3                4.6
4                5.0

FunctionTransformer関数使って以下の2種類の特徴量に変換しています。通常、変換をするので「変換」という言葉を使っていますが、今回の例では「1. raw」は単純にするために変換すらしていません。

  1. raw: ただ元の値を出すだけ
  2. double: 元の値を2倍
# 複数の特徴量を結合する
union = FeatureUnion([('1.raw', FunctionTransformer(lambda x: x)),
                      ('2.double', FunctionTransformer(lambda x: x*2))])
print(union.fit_transform(df)[:5])

結果セットを見るともとの値と2倍になった値が出ていますね。

FeatureUnion結果の5行
[[ 5.1 10.2]
 [ 4.9  9.8]
 [ 4.7  9.4]
 [ 4.6  9.2]
 [ 5.  10. ]]

以下の記事を見る限り、結果はDataFrameにはならないようです。Numpyに慣れていない私のような人間には使いにくい。

実際の使い方

「シンプルな使い方」では、使い方に焦点を当てたので実際にどんな使い方をするかです。
mnistの手書き数字データを引っ張ってきます。

from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from sklearn.naive_bayes import GaussianNB
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.model_selection import cross_validate
import pprint

digits = load_digits()
print(digits.data.shape)

1797レコードの8×8の手書きデータがあります。

データshape
(1797, 64)

PCAとLDAで特徴量削減をして、Gaussianナイーブベイズで分類します。このときにPCAとLDAで同時並列で特徴量を生成し、結合します。今回は使っていませんがFeatureUnionにはn_jobsというパラメータがあり、並列処理が可能です。

pca = PCA(n_components=30)
lda = LDA()
gnb = GaussianNB()

pca_lda_gnb = Pipeline([("reduction", FeatureUnion([("pca", pca),
                                                    ("lda", lda)])),
                        ("gnb", gnb)])
pprint.pprint(cross_validate(pca_lda_gnb, digits.data, digits.target, cv=3))

で、結果は以下のようなscoreと時間が出ます。

結果
{'fit_time': array([0.21725082, 0.16855884, 0.08645368]),
 'score_time': array([0.01812887, 0.00961113, 0.00560999]),
 'test_score': array([0.92821369, 0.93489149, 0.92153589])}

参考

以下の記事を参考にしました。

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6