2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DataLiner 1.2.0をリリースしたので新たに追加した前処理を紹介します

Last updated at Posted at 2020-05-04

はじめに

機械学習の前処理ライブラリDataLiner 1.2.0をリリースしました。
今回は新たに6つほど前処理を追加しましたので紹介したいと思います。

GitHub: https://github.com/shallowdf20/dataliner
PyPI: https://pypi.org/project/dataliner/
Document: https://shallowdf20.github.io/dataliner/preprocessing.html

インストール

pipを使ってインストールします。

! pip install -U dataliner

データ準備

いつも通りTitanicのデータを使用します。

import pandas as pd
import dataliner as dl

df = pd.read_csv('train.csv')
target_col = 'Survived'

X = df.drop(target_col, axis=1)
y = df[target_col]
PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1 3 Braund, Mr. Owen Harris male 22 1 0 A/5 21171 7.250 NaN S
2 1 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38 1 0 PC 17599 71.283 C85 C
3 3 Heikkinen, Miss. Laina female 26 0 0 STON/O2. 3101282 7.925 NaN S
4 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 0 113803 53.100 C123 S
5 3 Allen, Mr. William Henry male 35 0 0 373450 8.050 NaN S

では、早速見ていきましょう。

AppendArithmeticFeatures

データに含まれる特徴量同士で四則演算を行い、演算に使った特徴量よりも評価指標が高い特徴量を新たに追加します。
評価はロジスティック回帰で行われます。デフォルトではかけ算、評価指標はAUCですが、足し算、引き算や割り算、Accuracyなども利用可能です。
利用前に欠損値を補完する必要があります。

process = make_pipeline(
    dl.ImputeNaN(),
    dl.AppendArithmeticFeatures(metric='roc_auc', operation='multiply')
)
process.fit_transform(X, y)
PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked PassengerId_multiply_Age PassengerId_multiply_SibSp PassengerId_multiply_Parch Pclass_multiply_Age
1 3 Braund, Mr. Owen Harris male 22 1 0 A/5 21171 7.250 B96 B98 S 22 1 0 66
2 1 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38 1 0 PC 17599 71.283 C85 C 76 2 0 38
3 3 Heikkinen, Miss. Laina female 26 0 0 STON/O2. 3101282 7.925 B96 B98 S 78 0 0 78
4 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 0 113803 53.100 C123 S 140 4 0 35
5 3 Allen, Mr. William Henry male 35 0 0 373450 8.050 B96 B98 S 175 0 0 105

このように新しい特徴量が追加されます。

RankedEvaluationMetricEncoding

各カテゴリーをダミー変数化した上で、それぞれのカテゴリ列と目的変数でロジスティック回帰を行います。
その結果の評価指標(デフォルトではAUC)を使ってランキングを作成し、その順位で元々のカテゴリーをエンコードします。
各カテゴリに5 foldのロジ回帰をフィットする関係上、カーディナリティの高い特徴量では計算量が膨大になるため事前に
DropHighCardinalityやGroupRareCategoryなどを使ってカーディナリティを下げておくことを推奨します。

process = make_pipeline(
    dl.ImputeNaN(),
    dl.RankedEvaluationMetricEncoding()
)
process.fit_transform(X, y)
PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1 3 640 2 22 1 0 288 7.250 1 1
2 1 554 1 38 1 0 284 71.283 77 2
3 3 717 1 26 0 0 256 7.925 1 1
4 1 803 1 35 1 0 495 53.100 112 1
5 3 602 2 35 0 0 94 8.050 1 1

尚、ランキングを出力させることでカテゴリ変数内の各カテゴリーがどのくらい重要かを確認することもできます。

process['rankedevaluationmetricencoding'].dic_corr_['Embarked']
Category Rank Evaluation_Metric
S 1 0.5688
C 2 0.5678
Q 3 0.4729

AppendClassificationModel

入力データを元に分類器を学習させ、その予測結果を新たな特徴量として追加します。
modelはsklearn準拠モデルであれば何でも使用可能です。また、predict_probaメソッドが実装されていれば
引数probability=Trueを与えることでラベルの代わりにスコアを追加できます。
モデルを学習させるので基本的に欠損値補完とカテゴリ変数の処理が必要になります。

process = make_pipeline(
    dl.ImputeNaN(),
    dl.TargetMeanEncoding(),
    dl.AppendClassificationModel(model=RandomForestClassifier(n_estimators=300, max_depth=5),
                                 probability=False)
)
process.fit_transform(X, y)
PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Predicted_RandomForestClassifier
1 3 0.3838 0.1889 22 1 0 0.3838 7.250 0.3039 0.3390 0
2 1 0.3838 0.7420 38 1 0 0.3838 71.283 0.3838 0.5536 1
3 3 0.3838 0.7420 26 0 0 0.3838 7.925 0.3039 0.3390 1
4 1 0.3838 0.7420 35 1 0 0.4862 53.100 0.4862 0.3390 1
5 3 0.3838 0.1889 35 0 0 0.3838 8.050 0.3039 0.3390 0

probability=Trueだとこうなります。クラス1に対するスコアが付与されます。

PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Predicted_RandomForestClassifier
1 3 0.3838 0.1889 22 1 0 0.3838 7.250 0.3039 0.3390 0.1497
2 1 0.3838 0.7420 38 1 0 0.3838 71.283 0.3838 0.5536 0.8477
3 3 0.3838 0.7420 26 0 0 0.3838 7.925 0.3039 0.3390 0.5401
4 1 0.3838 0.7420 35 1 0 0.4862 53.100 0.4862 0.3390 0.8391
5 3 0.3838 0.1889 35 0 0 0.3838 8.050 0.3039 0.3390 0.1514

AppendEncoder

DataLinerに含まれる各種Encoderはカテゴリ列をエンコードした数値で直接置き換えます。
しかし場合によっては置き換えず新しい特徴量として利用したい場合もあるかと思います。(TargetMeanEncoderなど)
その場合は、Encoderをこのクラスでラップしてあげることで特徴量として追加されるようになります。

process = make_pipeline(
    dl.ImputeNaN(),
    dl.AppendEncoder(encoder=dl.TargetMeanEncoding())
)
process.fit_transform(X, y)
PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked Name_TargetMeanEncoding Sex_TargetMeanEncoding Ticket_TargetMeanEncoding Cabin_TargetMeanEncoding Embarked_TargetMeanEncoding
1 3 Braund, Mr. Owen Harris male 22 1 0 A/5 21171 7.250 B96 B98 S 0.3838 0.1889 0.3838 0.3039 0.3390
2 1 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38 1 0 PC 17599 71.283 C85 C 0.3838 0.7420 0.3838 0.3838 0.5536
3 3 Heikkinen, Miss. Laina female 26 0 0 STON/O2. 3101282 7.925 B96 B98 S 0.3838 0.7420 0.3838 0.3039 0.3390
4 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 0 113803 53.100 C123 S 0.3838 0.7420 0.4862 0.4862 0.3390
5 3 Allen, Mr. William Henry male 35 0 0 373450 8.050 B96 B98 S 0.3838 0.1889 0.3838 0.3039 0.3390

AppendClusterTargetMean

データでクラスタリングを行い、クラスター番号を振ります。(ここまではAppendClusterと同一)
その後、各クラスター番号をクラスタ内の目的変数の平均で置き換え、新たな特徴量として追加します。
欠損値の補完とカテゴリ変数の処理が必要になります。

process = make_pipeline(
    dl.ImputeNaN(),
    dl.TargetMeanEncoding(),
    dl.AppendClusterTargetMean()
)
process.fit_transform(X, y)
PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked cluster_mean
1 3 0.3838 0.1889 22 1 0 0.3838 7.250 0.3039 0.3390 0.3586
2 1 0.3838 0.7420 38 1 0 0.3838 71.283 0.3838 0.5536 0.3586
3 3 0.3838 0.7420 26 0 0 0.3838 7.925 0.3039 0.3390 0.3586
4 1 0.3838 0.7420 35 1 0 0.4862 53.100 0.4862 0.3390 0.3586
5 3 0.3838 0.1889 35 0 0 0.3838 8.050 0.3039 0.3390 0.3586

PermutationImportanceTest

特徴量選択手法の一種です。ある特徴量のデータをランダムにシャッフルした場合としなかった場合で、
モデル予測結果の評価指標がどのぐらい悪化するかという観点で特徴量選択を行います。
データをランダムにシャッフルしても評価指標にあまり影響がない場合は、その特徴量は効いていないとして削除します。

process = make_pipeline(
    dl.ImputeNaN(),
    dl.TargetMeanEncoding(),
    dl.PermutationImportanceTest()
)
process.fit_transform(X, y)
Pclass Sex Age SibSp Ticket Fare Cabin Embarked
3 0.1889 22 1 0.3838 7.250 0.3039 0.3390
1 0.7420 38 1 0.3838 71.283 0.3838 0.5536
3 0.7420 26 0 0.3838 7.925 0.3039 0.3390
1 0.7420 35 1 0.4862 53.100 0.4862 0.3390
3 0.1889 35 0 0.3838 8.050 0.3039 0.3390

Name, PassengerIdとParchが削除されました。以下のようにして削除された特徴量を確認することもできます。

process['permutationimportancetest'].drop_columns_

['PassengerId', 'Name', 'Parch']

他にもしきい値thresholdを調整することで感度を調整できます。詳しくはDocument参照。

おわりに

上記が新しく追加した前処理です。RankedEvaluationMetricEncodingはたまにTargetMeanEncoding以上の精度が出たりするのでよく試します。
またPermutationImportanceTestはBorutaやStep-wise法と比べても高速に実行できる割に意外と差がなかったりするので
DropLowAUCよりは真面目に(?)特徴量選択したい場合に使ってみるのもありかと思います。

リリース記事:
[Ver1.1.9更新] 機械学習用データ前処理ライブラリDataLinerを作ってみた

1.2以前の前処理については以下で紹介しています。
Titanicデータを前処理ライブラリDataLinerで処理してみる(Drop編)
Titanicデータを前処理ライブラリDataLinerで処理してみる(Encoding編)
Titanicデータを前処理ライブラリDataLinerで処理してみる(変換編)
Titanicデータを前処理ライブラリDataLinerで処理してみる(Append編)

2
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?