Amazon SageMaker Data Wrangler を実際に使ってみた[re:Invent 2020]

# はじめに
**この記事は株式会社ナレッジコミュニケーションが運営する [Amazon AI by ナレコム Advent Calendar 2020](https://qiita.com/advent-calendar/2020/knowcom-amazonai) の 4日目にあたる記事になります。**

AWS が開催する [re:Invent 2020](https://aws.amazon.com/jp/about-aws/events/2020/reinvent/) で発表された Amazon SageMaker の新機能である Amazon SageMaker Data Wrangler を実際に触ってみました。

# Amazon SageMaker Data Wrangler

[Amazon SageMaker Data Wrangler](https://aws.amazon.com/jp/sagemaker/data-wrangler/)

![2020-12-03_15h26_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/9be8d5f7-5261-89fd-fcf0-ae851f3ea133.png)

SageMaker Data Wrangler とは **AWS の各種サービスからデータをインポートし、データの可視化（リアルタイムで！）や変換の処理を GUI 上で行えるサービス**のようです。

実際に行った処理をノートブックとしてエクスポートすることもできるので手元で処理して可視化して、処理して可視化して、、、という**縦長ノートブックとのにらめっこからオサラバ**できそうですね。

名前が似ている [AWS Data Wrangler](https://github.com/awslabs/aws-data-wrangler) というオープンソースの Python ライブラリがありますが、こちらとは別物のようです。
今回紹介されている Amazon SageMaker Data Wrangler はあくまでも SageMaker Studio の追加機能、という位置づけのようです。

SageMaker Data Wrangler の機能や使用方法について簡単にまとめると

**SageMaker Data Wrangler は SageMaker Studio の追加機能であり、**

- **ETL 処理をグラフィカルに記述する flow ファイルの作成**
- **インポートするデータの選択**
- **データの変換および分析の記述**
- **記述した処理をエクスポート**

**という流れで ETL 処理をサポートする機能**であるといえると思います。


# 実際に触ってみる。

今回は kaggle の [COVID-19 Dataset](https://www.kaggle.com/imdevskp/corona-virus-report?select=covid_19_clean_complete.csv) を用いて実際に Data Wrangler を使ってみました。

まずは Amazon SageMaker Studio に入ります。
![2020-12-03_16h02_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/7cc661c0-c530-ef72-271f-3850eebde387.png)

## データのインポート

Data Wrangler を使うには最初に flow ファイルを作成します。最初のランチャー画面にある「New data flow」の＋ボタンをクリックするか、
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/8f544b75-8554-a0d0-bfc9-7fae1971e410.png)

画面上部の「File」→「New」→「Flow」としてファイルを作成します。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/6898218e-1c78-c793-a7d2-eb133d835343.png)

flow ファイルを作成すると「untitled.flow」というデータが生成されます。（名前の変更もできます。）インポートできるデータソースとしては Amazon S3 と Amazon Athena が選択できます。「Add data source」をクリックしてみると Redshift が選択できるようになっていました。
![2020-12-03_16h15_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/0e162b14-0541-0e89-dfd0-78e197410777.png)

flow ファイルには4種類のタブがあり、それぞれ

- Import　→　データのインポート設定を行う
- Prepare　→　グラフィカルにデータ変換・分析のフローを記述する
- Analyze　→　分析結果の表示
- Export　→　エクスポートするコンポーネントを選択し、エクスポートする

ということが行えます。

S3 に事前にアップロードしておいたファイルをインポートしていきます。「Amazon S3」を選択すると、バケット選択画面になります。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/94a270c2-41cb-06eb-8f5b-f383355f012d.png)

バケットを選択して、アップロードするファイルを選択します。S3 からのアップロードは CSV または Parquet が対応しています。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/025c2b20-7731-5e02-861b-5a58bdf75f0a.png)

ファイルを選択すると画面下部にプレビュー画面が表示されます。拡張子がついていないファイルは画面右の「File Type」から CSV か Parquet を選択する必要があります。「Enable sampling」が有効になっている場合、インポートされるファイルが最大100MBに制限されます。設定が終わったら「Import dataset」をクリックします。
![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/7f54cf16-de76-14f8-4383-229562485457.png)

## データフローの作成

インポートが完了すると、Prepare タブに遷移し、今回作成するデータフローがグラフィカルに表示されます。
![image02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/c086ec26-0725-f9f9-168d-eefe6c31e461.png)


Data Wrangler はインポートされたデータのデータ型を自動で推測し、データフレームを作成します。表示されている「Data types」というコンポーネントが自動生成されるデータフレームになります。
生成されるコンポーネントはドラッグすることで動かすこともできます。
![image03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/cc07f85e-d171-d92b-97c6-b5f1e6579f93.png)

「Data types」の横にある＋ボタンをクリックすると後続の処理を追加できます。
![image04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/32e8f60f-aa2d-dd60-20eb-ea157f6c5ada.png)

後続処理として追加できるコンポーネントには次のものがあります。

### Edit data types
データインポート時に自動生成されたデータフレームの各カラムのデータ型の変更が行えます。「Type」のプルダウンから選択できます。
変更する型を指定したら「Preview」で変更後のデータフレームが表示され、よければ「Apply」します。
![スクリーンショット 2020-12-04 9.50.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/fd555fc5-751c-4d59-899d-b8590eaec68e.png)

### Add transform
読み込み時にデータフレームの変換処理を記述します。
![image05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/e8baf386-815e-48db-d6ab-cbbe8569b4b7.png)
変換できる処理は次のようになっています。

- Custom Transform
Python(Pandas, Pyspark)または SQL(Spark SQL) で変換処理を記述します。

- Custom formula
新しいカラムを Spark SQL でクエリ書いて追加します。

- Encode categorical
カテゴリのカラムをプルダウンで指定して One-hot encode または Ordinal encode します。欠損値の処理も Skip, Error, Keep, Replace with NaN から選択することができます。

- Featurize date/time
date/time の型のデータを数値やベクトル表現に変換できます。

- Featurize text
自然言語のカラムを Character statistics, vector に変換できます。Character statistics には単語数や文字数などがあり、新しい出力カラムが生成されます。

- Format string
文字列のフォーマット（大文字、小文字、右寄せ、左寄せなど）を指定して変換してくれます。

- Handle missing
欠損値の処理を指定します。変換の方法を impute, drop missing などから指定してそれぞれの方法に対して詳細な設定ができます。（impute ならカラムの型がなんであり、中央値か平均を代入する、など）

- Handle outliers
外れ値の処理をかけます。標準偏差や quantile などを指定してどのように処理するか設定します。

- Manage columns
カラムの移動、削除、複製、リネームなどを行います。

- Manage rows
ソートやシャッフルをすることができます。

- Manage vectors
数値データ列とベクトル列を Assemble や Flatten で処理できます。

- Parse column as type
データ型を指定してキャストします。

- Process numeric
標準化を行ったりロバストスケーラーや最大値最小値の範囲でスケーリングします。処理には Spark が使われているようです。

- Search and edit
データの検索と、検索した値の編集ができます。置換や区切り文字で分割もできます。

- Validate string
カラムに対して条件を指定して True または False で表現されるカラムを生成します。

追加した変換処理を Apply するとコンポーネントが追加されます。
![image06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/e016f8ac-44c3-e26b-b078-1bc81fa8808f.png)


### Add analysis
変換処理などを行ったデータを可視化できます。「Configure」タブではヒストグラムや散布図などを指定して表示させることができます。「Code」タブでは Pandas で記述できます。「Create」ボタンで描画した図を保存することができます。
![image07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/8254b1fa-2535-b0e5-8ce0-b96004d11db0.png)

保存された図は flow ファイルの「Analyze」タブに保存されています。この画面からも「Create new analysis」から新しい図を描画できます。
![image09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/960050f9-ed76-86c6-3b32-420504407e43.png)


### Join
２つのデータセットの結合が行えます。データセットが複数必要になるには「Import」タブから最初にデータをインポートした時と同じ手順で実施します。
「Join」をクリックしたデータフレームが左側として指定されます。

![image10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/44e0ae91-9e2b-4cd0-a939-82ed94451aa7.png)

右側にのデータフレームを指定すると結合後のフローが現れるので「Configure」すると、

![image11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/ae86060a-a36a-7eba-416e-7dfad69fd4df.png)

プレビュー画面が表示され、どのように結合を行うのかを指定します。設定したら「Apply」して「Add」します。

![image12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/d83c4b6b-de91-f56c-7fc4-84cbeff3d3fb.png)

生成したデータフレームがコンポーネントとして追加されました。

![image13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/01925cd6-a599-f3b6-51d0-ac3c9d045950.png)

### Concatenate
データの連結を行えます。手順としては Join の操作に準じています。

![image14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/e967c169-3213-fcb9-66e2-7520108619b1.png)

指定したら「Apply」して「Add」します。

![image15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/543ff9eb-a337-78a7-bfcc-80a0ce1ca95d.png)


## データフローのエクスポート
作成したデータフローをエクスポートします。まず「Export」タブに移動します。エクスポートしたいコンポーネントをクリックして「Export step」をクリックします。

![image16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/feabfa02-891a-bdbb-2e58-2d4fd0dfea46.png)

エクスポートの方法は現在４種類用意されています。

-  Data Wrangler Job
-  Pipeline
-  Python Code
-  Feature Store

Python Code では.py の拡張子を持つファイルとして生成されます。他の３つは SageMaker に統合されたノーブック形式でエクスポートします。
違いとしては

**Data Wrangler Job**
作成したデータフローを丸ごとコード化

**Pipeline**
作成したデータフローのコード + Pipeline という機能への統合するためのコードが追記

**Feature Store**
作成したデータフローのコード + Feature Store という機能への統合するためのコードが追記

という感じのようです。 とりあえず Data Wrangler Job としてエクスポートしてみます。

![image17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/7b2e967d-edf4-28f8-4bc2-f259b42926c1.png)

無事エクスポートできました！

![image18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618791/3a31d54c-ca7b-7e6a-0e8c-cb87d743983e.png)


# おわりに

データの様々な前処理が GUI 上でできるのは本当に便利だと思います。今後はこの機能を使い倒していきたいと思います。


また、Pipeline や Feature Store も今回の[re:Invent 2020](https://aws.amazon.com/jp/about-aws/events/2020/reinvent/)で紹介されていた機能なので検証してみたいと思っています。