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

# はじめに
機械学習用のデータ前処理ライブラリDataLinerを作りました。

機械学習モデリングを行う際、データ加工・特徴量エンジニアリングの部分で使われる処理を前処理一覧としてまとめたものになります。
scikit-learnのtransformerに準拠しているので、単体でfit_transformすることもpipelineに流し込むこともできます。
まだまだ詰め込みきれていない機能や前処理があるので今後も定期的にアップデートしていきますが、他にもバグ報告・FIXや新機能・新しい前処理のプルリクなどを頂けると励みになります。

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

# インストール
pipを使ってインストールします。
Anacondaを使ってPython環境を構築している方はAnaconda Promptで以下のコードを実行してみてください。

```
! pip install -U dataliner
```

# データ準備
みんな大好きTitanicのDatasetsを例に使ってみます。尚、Xはpandas.DataFrame, yはpandas.Seriesである必要があり、違うデータタイプの場合はエラーを吐きます。
それでは、処理を行うデータを準備します。

```python
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]
```
こんな感じの見覚えのあるデータがXに格納されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627325/6f8f8212-8dcc-3b35-f744-29a88ebebe7c.png)

# 使い方
では、早速使ってみます。まずはカテゴリ数が多すぎる特徴量を自動的に消してくれるDropHighCardinalityを使ってみます。

```python
dhc = dl.DropHighCardinality()
dhc.fit_transform(X)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627325/fc9f6ccf-20cf-b41a-0b72-78c96e185caf.png)
NameやTicketといったカテゴリ数が非常に多い特徴量が削除されているのがわかります。
余談ですが、Titanicの場合はこれらの列から情報をひねり出して精度を上げに行くと思います。

次は、おなじみTarget Encodingをやってみます。事前確率としてy全体の平均を用いてスムージングを行うバージョンとなっています。

```python
tme = dl.TargetMeanEncoding()
tme.fit_transform(X, y)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627325/d5c12e22-04e3-9915-9882-96d597597d4a.png)
自動でカテゴリカル変数の列を認識し、各カテゴリーを目的変数を使ってEncodingしてくれました。

また、多くのデータサイエンティストの方々は効率化のためにPipelineを使われていると思います。
もちろんDataLinerの各クラスも同様に使用することができます。

```python
from sklearn.pipeline import make_pipeline

process = make_pipeline(
    dl.DropNoVariance(),
    dl.DropHighCardinality(),
    dl.BinarizeNaN(),
    dl.ImputeNaN(),
    dl.OneHotEncoding(),
    dl.DropHighCorrelation(),
    dl.StandardScaling(),
    dl.DropLowAUC(),
)

process.fit_transform(X, y)
```
諸々の処理を行った結果、こうなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627325/7c13d046-35bb-1431-70d6-55b1681c0f0d.png)

Titanicでは評価用にあらかじめhold outされているtest.csvというデータがあるので、読み込んで同じ処理をかけてみます。

```python
X_test = pd.read_csv('test.csv')
process.transform(X_test)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627325/ae99e844-7d5e-0fa6-e13b-572583f2f284.png)

以上になります。

# 含まれているもの
現時点では以下になります。今後のアップデートで機能拡充・処理も増やしていきたいと思っています。

**5/3追記:**
それぞれのクラスの紹介記事を書きました。
<a href="https://qiita.com/shallowdf20/items/eb35a9cf3c24403debb1">Titanicデータを前処理ライブラリDataLinerで処理してみる(Drop編)</a>
<a href="https://qiita.com/shallowdf20/items/e07d4ce0650b24e505d6">Titanicデータを前処理ライブラリDataLinerで処理してみる(Encoding編)</a>
<a href="https://qiita.com/shallowdf20/items/f58cec788a10e504c33c">Titanicデータを前処理ライブラリDataLinerで処理してみる(変換編)</a>
<a href="https://qiita.com/shallowdf20/items/b066ad6c5d55b97b33d7">Titanicデータを前処理ライブラリDataLinerで処理してみる(Append編)</a>

**BinarizeNaN** - 欠損値が含まれる列を見つけ、その列が欠損していたかどうかという新しい特徴量を作成します
**ClipData** - 数値データをqパーセンタイルで区切り、上限以上・下限以下の値を上限・下限で置き換えます
**CountRowNaN** - 各データの行方向の欠損値の合計値を新しい特徴量として作成します
**DropColumns** - 指定した列を削除します
**DropHighCardinality** - カテゴリ数の多い列を削除します
**DropHighCorrelation** - ピアソンの相関係数がしきい値を超えた特徴量を削除します。削除の際、目的変数に対してより相関の高い特徴量を残します。
**DropLowAUC** - 全特徴量に対して、yを目的変数としたロジスティック回帰を特徴量1つずつで行い、AUCがしきい値を下回った特徴量を削除します。
**DropNoVariance** - 1種類のデータしか含まれない特徴量を削除します。
**GroupRareCategory** - カテゴリ列のうち、出現頻度の低いカテゴリーをグルーピングします。
**ImputeNaN** - 欠損値を補完します。デフォルトでは数値データは平均、カテゴリカル変数は最頻値で補完されます。
**OneHotEncoding** - カテゴリ変数をダミー変数化します。
**TargetMeanEncoding** - カテゴリ変数の各カテゴリーを、目的変数の平均をスムージングしたもので置き換えます。
**StandardScaling** - 数値データを平均0分散1となるよう変換します。
**MinMaxScaling** - 数値データを0から1の範囲にスケールします
**CountEncoding** - カテゴリ値を出現回数で置き換えます
**RankedCountEncoding** - カテゴリ値の出現回数でランキングを作り、その順位で置き換えます。複数カテゴリーが同じ回数出現する場合などに有効です
**FrequencyEncoding** - カテゴリ値を出現頻度で置き換えます。尚、ランキング版はRankedCountEncodingと同じになるので用意していません。
**RankedTargetMeanEncoding** - カテゴリ値毎に目的変数の平均でランキングを作り、その順位でさらに置き換えたバージョンです。
**AppendAnomalyScore** - Isolation Forestによる異常値スコアを特徴量として追加します
**AppendCluster** - KMeansを行い、その結果のクラスターを特徴量として追加します。データのスケーリング推奨
**AppendClusterDistance** - KMeansを行い、その結果の各クラスターとの距離を特徴量として追加します。データのスケーリング推奨
**AppendPrincipalComponent** - 主成分分析を行い、主成分を特徴量として追加します。データのスケーリング推奨
**AppendArithmeticFeatures** - データに含まれる特徴量同士で四則演算を行い、演算に使った特徴量よりも評価指標が高い特徴量を新たに追加します。(ver1.2.0)
**RankedEvaluationMetricEncoding** - 各カテゴリーをダミー変数化した上で、それぞれのカテゴリ列と目的変数でロジスティック回帰を行います。その結果の評価指標(デフォルトではAUC)を使ってランキングを作成し、その順位で元々のカテゴリーをエンコードします。(ver1.2.0)
**AppendClassificationModel** - 入力に対し分類器を学習させその予測結果のラベルまたはスコアを特徴量として追加します。(ver1.2.0)
**AppendEncoder** - DataLinerに含まれる各Encoderの処理結果を、置き換えるのではなく特徴量として追加します。(ver1.2.0)
**AppendClusterTargetMean** - クラスタリングを行った後の各クラスタ内での目的変数平均を特徴量として追加します。(ver1.2.0)
**PermutationImportanceTest** - ある特徴量のデータをランダムにシャッフルした場合としなかった場合で、モデル予測結果の評価指標がどのぐらい悪化するかという観点で特徴量選択を行います。(ver1.2.0)
**UnionAppend** - DataLinerのAppend〇〇クラスを、直列ではなく並列で処理して出力結果の特徴量を結合して元の特徴量に追加します。クラスはリストで与える必要があります。(ver1.3.1)
**load_titanic** - titanicデータを読み込みます。(ver1.3.1)

# さいごに
自分が何度も繰り返している処理をまとめたものの、もしかしたら他の方にも同様のニーズがあるのでは？と思い公開しました。
無数にある前処理のうち、主要なものがまとまったライブラリとなればいいなと思っています。

繰り返しになりますが、バグ報告やFIX、新機能や新しい処理のプルリク待ってます！！