データの分析と前処理を簡単に！ Amazon SageMaker Data Wrangler を試してみた

## はじめに
機械学習モデルを学習する前に、たいてい不要な列を削除したり欠損値を補完したりなどのデータ前処理が必要です。Amazon SageMaker Data Wrangler を使うと、データの分析や前処理を GUI ベースで行い、適用した前処理を行うソースコードを Export して流用できるようにしたり、SageMaker の他の機能に組み込んだりすることができます。

## データの分析をやってみる
[Titanic](https://www.kaggle.com/c/titanic) のデータを使ってデータの分析をやってみます。
Amazon SageMaker Studio を開き、Launcher を表示します。New data flow（以下の図の黄色い矢印部分）をクリックして、SageMaker Data Wrangler を開始します。Amazon SageMaker Studio のセットアップ方法については [こちら](https://qiita.com/mariohcat/items/d8688d2a73517a0d8e1c) をご参照ください。
![スクリーンショット 2021-01-02 11.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/ea536976-c2ba-06c1-cb69-0bf00b0d6c3e.png)

まずデータソースを選択します。2021年1月現在、Amazon S3、Amazon Athena、Amazon Redshift を選択可能です。SageMaker Data Wrangler が起動するのに数分かかりますので、データソースを選択した際にエラ〜メッセージが表示されたらもう少し待ちます。
![スクリーンショット 2021-01-02 11.09.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/4a4c60b8-2693-a09d-abc3-1112b4f3793b.png)

データソースの選択で S3 を選択すると、S3 バケットの一覧が表示されます。データが保存されているバケット、フォルダをクリックして選択していきます。バケットやフォルダがたくさんあると探すのがちょっと大変かもしれません。
![スクリーンショット 2021-01-02 11.10.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/27ea35fe-2671-0d30-4738-b4111a81a8b8.png)

CSV ファイルを選択すると、このような画面が表示されます。
![スクリーンショット 2021-01-02 11.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/db9caf42-6223-455a-e512-018af368913d.png)

Data types アイコンの右にあるプラスアイコンをクリックし、Add analysis を選択してみます。
![スクリーンショット 2021-01-02 11.21.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/19ddf0a5-b0aa-15ee-4d4d-6cad21850529.png)

数秒して、分析の準備が完了しました。右側にチャートの設定画面がありますので、以下の設定で年齢のヒストグラムを作ってみます。

- Analysis name：Hist - age
- X axis：Age
- Color by：Sex
- Facet by：Survived
![スクリーンショット 2021-01-02 11.22.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/db17acd8-9964-939c-c681-9955fc63df13.png)


Preview ボタンをクリックすると、このようなヒストグラムが表示されました。横軸が年齢で、性別ごとに色づけされたヒストグラムです。生存したかどうかでグラフが分かれています。Survived=1 のグラフの方が青（female）が多いことが一目でわかります。このグラフを保存する場合は Create をクリックします。
![スクリーンショット 2021-01-02 14.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/2f28db3e-f343-5a5a-e2a6-244135544e2c.png)


Analyze タブで、いま作成したチャートが見えるようになりました。クリックすると作成したチャートが表示されます。
![スクリーンショット 2021-01-02 11.29.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/90e643a6-872b-1e70-3376-65ddb2ff62dc.png)

2021年1月現在、以下のチャートを作成可能です。

- Bias Report
- Histgram
- Quick Model
- Scatter Plot
- Table Summary
- Target Leakage

![スクリーンショット 2021-01-02 11.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/aa4d0930-4798-415d-5f1e-47ab4c001c10.png)

## すべてのチャートを作成してみる
Histgram のほかにどんなチャートを作成できるのかを確認していきます。
### Bias Report
以下のように設定して Check for Bias をクリックします。

- Analysis name：Bias - Sex
- Select the column your model predicts (target)：Survived
- Is your predicted column a value or threshold?：Value
- Predicted value(s)：1
- Select the column to analyze for bias：Sex
- Is your column a value or threshold?：Value

評価項目と評価結果の一覧が表示されます。
![スクリーンショット 2021-01-02 11.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/795022f6-6d06-bb29-9e6d-cf4a51e3ca21.png)

各項目をクリックすると詳細が表示されます。
![スクリーンショット 2021-01-02 11.48.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/3d4d7f03-b475-b6d0-afc3-67fc0d8b18f6.png)

#### クラス不均衡
**キーアイデア**
有利なグループが不利なグループよりも実質的に高い割合でデータセットに含まれているかどうかを検出する。

**このメトリクスの見方**
有利なグループAがデータセットの 8割（0.8）を占める場合 (fA)、不利なグループDは 2割（0.2）となり (fD)、クラスの不均衡は fA - fD = 0.6 となる。

正の値は、有利なグループが相対的にデータセットに過剰に存在していることを示し、Class Imbalance (CI) が 1 に近いほど有利なグループであることを示す。負の値は、有利なグループが相対的に過小に存在していることを示す。

**例**
中小企業向け融資データにおいて、男性がサンプルの 90％を占め、女性は 10％だった。これは、歴史的に見て、女性が融資を必要とする中小企業を男性ほど多く起業していないために起こっている可能性がある。この不均衡は、女性が融資を受けるべきではないとモデルに学習させる可能性がある。

**値の範囲**
[-1,+1]

**注意**
(1) モデルはサンプル数が少ないグループを犠牲にして、より大きな割合を占めるグループに優先的に適合する傾向がある。そのためサンプル数が不足しているグループの学習誤差が大きくなることがある。

(2) モデルは、データセットの中のサンプル数が少ないグループにオーバーフィットするリスクが高い。そのため、学習誤差が小さかったとしても、テストデータに対する誤差が高くなることがある。

(3) シナリオによっては多すぎるサンプル数と少なすぎるサンプル数のの両方が問題になることがある。たとえば、融資のケースでは、少なすぎるサンプル数は有害である可能性がある。刑事司法のケースでは、多すぎるサンプル数は有害になる可能性がある。

#### ラベルの正の比率の違い (DPL)
**キーアイデア**
学習データにおいて、あるクラスが望ましい結果（もしくは望ましくない結果）になる割合が有意に高いかどうかを検出する。

**このメトリクスの見方**
この指標は、学習中に不当なバイアスを引き起こす可能性のあるクラス間のラベルの不均衡を検出する。

正の値は、グループA のメンバーのうち、グループB に比べて望ましいクラスラベルを持っているメンバーの割合が高いことを示す。たとえば、グループA にいる 100人のメンバーのうちの 70人が positive（ローン受入、仕事のオファー、なんらかの許可）で、グループ B にいる 60人のメンバーのうち 30人が positive の場合、DPL は 70/100 - 30/60 = 0.20 となる。

**例**
例１：過去の貸出データでは、女性の 60％、男性の 55％がローンを返済していた。
DPL = 0.60 - 0.55 = 0.05

例2：商品評価データセットは、若いユーザーの 80％、年配のユーザーの 10％が音楽ジャンルG のレコメンドを気に入ったことを示す。
DPL = 0.80 - 0.10 = 0.70

例 3: ローンの平均金利(連続値ラベル)は、マイノリティ向けのローンでは 10%であったのに対し、非マイノリティ向けのローンでは 6%であった。
DPL = 0.10 - 0.06 = 0.04

**値の範囲**
２値、多値分類：[-1,+1]
連続値ラベル: [-inf, +inf]

**注意**
値の大きい DPL が問題のあるものであるかどうかは状況による。問題のあるケースでは、大きな DPL はデータに根本的な問題があることを示す可能性がある。たとえば DPLが高いデータセットは、(i) 特定のグループに対する歴史的な偏見（人種的偏見など）を反映しているかもしれない、(ii) 個人の嗜好の違い（政治的な二極化など）から発生する社会的に有害なフィルターバブルを示しているかもしれない。

機械学習モデルは、学習データの情報を可能な限り忠実に模倣しようとする。そのため、DPL が大きいデータセットで学習された機械学習モデルは、将来の予測に同じ不均衡を反映する可能性が高い。上の2つのシナリオでは、これは歴史的なバイアスを永続させ、既存のフィルターバブルを強化することを意味する。

#### ジェンセン・シャノン情報量 Jensen-Shannon Divergence (JS)
**キーアイデア**
JS は、異なるクラスの分布がどれだけ離れているかを測定する。すべてのクラスのラベル分布の平均を P とすると、ジェンセン・シャノン情報量は、平均分布 P から各クラスの確率分布の KL 情報量の平均である。このエントロピー測定は、多値ラベルと連続値の場合にも一般化する。

**このメトリクスの見方**
値が大きいほど分布間の距離が大きいことを示す。
少数派の申請者の 40％、非少数派の申請者の 50％が融資を受けている。平均的な確率分布は、P = (0.45, 0.55) （融資承認、融資拒否）である。

KLa = 0.5*ln(0.5/0.45) + 0.5*ln(0.5/0.55) = 0.0050

KLd = 0.4*ln(0.4/0.45) + 0.6*ln(0.6/0.55) = 0.0051

KL = 0.5*(0.0050+0.0051) = 0.00505

KL値は、各クラスのラベル分布の平均ラベル分布からの平均発散を示す。この例ではラベルは 2値なので、各式には 2つの項がある。

**例**
例1: 大学の入学試験では、志望者は不合格、補欠、合格の3つのカテゴリーに割り当てられる。3つのカテゴリすべてにおいて、有利なクラスと不利なクラスの分布がどの程度異なるかを計算する。

例 2: ローンの申請において、融資が承認されるか拒否されるかのどちらかになる。結果の分布がすべての人種や民族で同じかどうかを調べる。

**値の範囲**
２値、多値分類、連続値 >=0

**注意**
(1) JS はエントロピーに基づいて、異なる分布が互いにどの程度離れているかの尺度である

(2) JS は、KLラベル不均衡尺度に平滑化と対称性を加えて拡張したものである

(3) 参考：https://arxiv.org/abs/2008.07433


### Quick Model
データをすばやく評価し、各特徴の重要度スコアを作成します。特徴の重要度スコアは、ある特徴が目的変数を予測する際にどの程度有用であるかを示します。分類問題にはF1スコアが、回帰問題には平均二乗誤差（MSE）スコアが使われます。

以下のように設定して Preview をクリックします。

- Analysis name：Model - Survived
- Label：Survived

各特徴量の重要度が表示されました。生データをそのまま使用したため、Name が最も重要度が高いというグラフになっています。乗客の生存可否に名前は関係ない可能性が高いため、Name を削除した方が良さそうです。
![スクリーンショット 2021-01-02 16.03.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/62a82268-56ea-9713-6573-ab51ff84cdd2.png)

Name 列を削除します。Data Flow 画面でプラスボタンをクリックし、Add transform を選択します。
![スクリーンショット 2021-01-02 16.06.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/5f570815-a926-d821-1414-89cfaa980257.png)

右側のリストから Manage columns をクリックし、以下の設定にして Preview をクリックします。内容を確認し、よければ Add をクリックして変更を確定します。

- Transform：Drop column
- Column to drop：Name
![スクリーンショット 2021-01-02 16.07.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/ef31f612-7ce8-db6f-c643-e0b43512e734.png)

Data Flow が以下の図のように変化しました。
![スクリーンショット 2021-01-02 16.11.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/78df5aad-bcc7-3ad3-f78c-bb85a0af2b15.png)

もう1度 Quick Model を実行します。プラスアイコンをクリックして Add analysis を選択して Quick Model を実行します。性別が最も重要な特徴量として表示されました。
![スクリーンショット 2021-01-02 16.13.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/b3de5ae2-9326-dd4f-c7bb-a7b3d14f7014.png)

### Scatter Plot
データを散布図で可視化します。
以下のように設定して Preview をクリックします。

- Analysis name：Scatter Age, Fare
- X axis：Age
- Y axis：Fare
- Color by：Sex

ひとりの男性が非常に高額な運賃で乗船していたことがわかりました。
![スクリーンショット 2021-01-02 16.17.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/ba55e5b1-f3b1-f6c7-9804-c077eacaa352.png)

### Table Summary
以下のように設定して Preview をクリックします。

- Analysis name：Summary

数値データの場合、のデータ数、平均値、標準偏差、最小値、最大値が表示されます。文字列、ブール値、または日付/時刻データの場合、最頻値と登場回数が最も少ない値が表示されます。
![スクリーンショット 2021-01-02 16.19.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/ff3432cd-a738-9a41-b2ce-ebbe849c0a29.png)

### Target Leakage
ターゲットリーケージは、機械学習の学習データセットの中に、目的変数と強い相関があるが、実世界のデータ（推論時に使用できるデータ）には存在しないデータがある場合に発生します。例えば、データセットの中に、モデルで予測したい列の代替として機能する列があるかもしれません。

以下のように設定して Preview をクリックします。

- Max features：20
- Problem Type：classification
- Target：Survived

以下のようなグラフが表示されました。PassengerId が possibly redundant と判定されました。たしかに乗船者 ID は生存可否には関係がなさそうです。その他の特徴量は safe と判定されました。
![スクリーンショット 2021-01-02 16.22.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/9411df6c-bd10-2d48-4fb3-f67cbbe2e7da.png)

ここで表示されている予測メトリックは、891行のサンプルで、クロスバリデーションを介して各列について個別に計算された ROC です。スコアが 1 の場合完全な予測能力を示し、しばしばターゲット・リーケージと呼ばれるエラーを示します。原因は通常、目的変数列が重複して存在するなど、予測時には使用できない列を使用することです。スコアが 0.5 の場合、その列の情報だけでは、目的変数の予測に役立つ情報を提供できなかったことを示します。列単体では情報が得られなくても、他の特徴量と組み合わせると目的変数の予測に有用な場合もありますが、スコアが低い場合はその特徴量が冗長である可能性を示します。

## データの前処理をやってみる
先ほど Name 列を削除しましたが、今度はカテゴリ変数である Pclass を one-hot エンコーディングしてみます。Data Flow 画面でプラスアイコンをクリックして Add transform を選択します。Encode categorical を選択し、以下のように設定して Preview をクリックします。

- Transform：One-hot encode
- Input column：Pclass
- Invalid handling strategy：Keep
- Output style：Columns
- Output column：pclass
![スクリーンショット 2021-01-02 16.47.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/51a13026-ada4-e318-701b-b8b9c066a07d.png)

テーブルの一番右に列が追加されました。Add をクリックしたら、次は元々あった Pclass 列を削除します。Manage columns から Drop column を選択して Pclass を選択して Preview -> Add の順でクリックします。
![スクリーンショット 2021-01-02 16.50.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/4c281b53-5130-0303-f430-234cfe1a1164.png)

Name 列の削除、Pclass の one-hot エンコーディング、Pclass 列の削除を適用したことにより、Data Flow の画面は以下のようになりました。
![スクリーンショット 2021-01-02 16.55.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/e94c1c6c-0321-a7ca-4bdb-e304d459d785.png)

## 前処理の内容をエクスポートしてみる
Data Flow で Data types のアイコンをクリックすると、右上に Export step が表示されるのでクリックします。
![スクリーンショット 2021-01-02 17.01.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/8a105f89-1c89-420f-e2e6-768c934d6049.png)

4つの Export 先が表示されました。
![スクリーンショット 2021-01-02 17.01.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315319/077f8a94-b0f4-be6f-43b1-3b2317fe278f.png)

- Data Wrangler Job
    - Data Wrangler Job を起動して前処理を行うための Jupyter ノートブックを生成
- Pipeline
    - Data Flow のパイプラインを作成する Jupyter ノートブックを生成
- Python Code
    - Data Flow を実現する Python コードを生成
- Feature Store
    - Amazon SageMaker Feature Store の feature グループを作成し、オフラインもしくはオンライン feature store に追加するための Jupyter ノートブックを作成

## さいごに
本記事では、Amazon SageMaker Data Wrangler を使ってデータの分析と前処理を行う方法をご紹介しました。SageMaker Data Wrangler でデータの前処理を試行錯誤し、適用したい処理が確定したら所望の形で Export してシステムに組み込むと良いのではないでしょうか。

SageMaker Data Wrangler と似たサービスに [AWS Glue DataBrew](https://qiita.com/mariohcat/items/bdd83d10caa3da85c584) がありますが、こちらは とっつきやすい GUI を使ってぽちぽちとデータの前処理をする際に便利です。どちらを使うべきか迷うところではありますが、必要な機能がついている方、使いやすい方を使うのが良いと思います。