Amazon Redshift ML で機械学習モデル構築 #1 インフラ構築

## はじめに
サンプルデータを AWS Redshift にインポートし、Amazon Redshift ML で機械学習モデルを構築するまでの流れです。作成したばかりの AWS アカウントを想定しているので、周辺環境の設定内容で引っかかった方はご参照ください。

第1回の本記事は AWS環境の構築手順、第2回は機械学習モデルを作成するまでの手順をまとめました。

https://qiita.com/Catetin0310/items/aff58ddcce13e95efbcb


## ターゲット
- SQL をメインで利用するデータエンジニア/アナリスト
- Amazon Redshift を利用

## 利用サービス

#### Amazon SageMaker Autopilot
- 自動機械学習 (AutoML) プロセスの主要なタスクを自動化
- 最適なアルゴリズムを選択し、モデルのトレーニングとチューニングが容易
- 最低料金や初期費用なし
- 回帰、二項分類、複数クラスの分類をサポート

https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/autopilot-automate-model-development.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/f538fa85-8fb3-53cf-c010-c40c33584170.png)



#### Amazon Redshift ML
- SQL を利用して Redshift のデータから機械学習モデルをデプロイ
- 予測結果も Redshift から SQL で取得可能
- バックエンドでは Amazon SageMaker Autopilot が動作

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/terminology.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/3da57828-0949-7f54-c678-f70549f481e4.png)


## 利用データ概要
本記事ではこちらのウェブサイトの情報とデータを利用します。
イーコマースのログデータ元に組み上げられた単一の CSV データです。

https://blog.minethatdata.com/2008/03/minethatdata-e-mail-analytics-and-data.html

#### 背景

- 顧客をランダムに3つに分け、販促キャンペーンのメールを配信
    - メンズ商品のキャンペーン
    - レディース商品のキャンペーン
    - 配信なし
- ウェブサイトの訪問履歴や購入金額をトラッキング
- トラッキングの期間はキャンペーンメール配信から2週間

#### 目的
無作為にキャンペーンを打つのでは販促費の無駄になります。よって、

- 普段は購入する意欲は高くない
- 施策を打てば購入する可能性が大幅に上がる

といったユーザーに絞って販促費を投入できれば ROI が最大化できるはずです。
その手法の一つに Uplift Modeling があります。

https://qiita.com/0NE_shoT_/items/7b91474430c1f190c470

本記事では Uplift Modeling のロジックへの組み込みを想定し、特定のキャンペーンを打つべきユーザーを予測する機械学習モデルを作成します。なお、モデル作成には2020年12月にパブリックプレビューになった Amazon Redshift ML を用います。


#### データセット
- 過去12か月以内に物品を購入した64,000人の顧客情報
- [ダウンロードURL ](
http://www.minethatdata.com/Kevin_Hillstrom_MineThatData_E-MailAnalytics_DataMiningChallenge_2008.03.20.csv)
    - Windows であれば、リンクを右クリック > リンク先を保存

#### スキーマ

|カラム名|データ型|概要|
|:--|:--|:--|
|Recency|int4|前回の購入から経過した月数|
|History_Segment|varchar(256)|過去1年間の購入金額の区分|
|History|float (8)|過去1年間の購入金額|
|Mens|boolean|過去に男性向け製品を購入したかどうか|
|Womens|boolean|過去に女性向け製品を購入したかどうか|
|Zip_Code|varchar(256)|顧客の居住カテゴリ。Urban, Sunurban, Rural|
|Newbie|boolean|過去1年で新規顧客になったかどうか|
|Channel|varchar(256)|過去に顧客が購買した経路|
|Segment|varchar(256)|受け取ったキャンペーンメールの種類。Mens E-mail, Womens E-mail, No E-mail|
|Visit|boolean|過去2週間にウェブサイトを訪問したかどうか|
|Conversion|boolean|過去2週間に購買に至ったかどうか|
|Spend|float (8)|過去2週間の購入金額|






## AWS 環境構築
#### IAM role
Redshift ML 経由で SageMaker Autopilot を操作できるようにするため、対応する権限を設定します。

IAM > ロール > ロールの作成
![2021-03-10_14h21_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/54e220dc-3051-fe35-9289-33274fcd5570.png)

AWS サービス > Redshift と進み、
![2021-03-10_14h22_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/89b826c1-4b9a-bfa9-4f39-3426e540b7af.png)

画面下部の Reedshift - Customiable を選択
![2021-03-10_14h23_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/46ad4a35-7d09-bbe7-a514-37b75ca43398.png)

ロール名を任意で設定、ロールの作成をクリック
![2021-03-10_14h26_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/bc08ee74-27c2-248f-92b5-3613071154b8.png)

作成したロールを開き、アクセス権限のタブで AmazonS3ReadOnlyAccess と AmazonSageMakerFullAccess のポリシーアタッチ (ベストプラクティスに則って最小権限で実装する場合は本記事の下部のURL参照)
![2021-03-11_09h27_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/7e6e42d2-c5b9-0cbc-9b57-fe5e1be42792.png)

信頼関係のタブで、redshift と sagemaker を追加
![2021-03-11_12h04_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/3d615996-ea6e-df36-eab3-6f459085a979.png)

TrustedEntity

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "redshift.amazonaws.com",
          "sagemaker.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

最後に ```iam role arn``` をコピー
![2021-03-10_14h27_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/8af804cc-7104-2a5c-958e-9441bdb30604.png)


#### S3
今回はシンプルにするため、以下の用途をカバーする単一S3バケットを構築します。

- Redshift テーブル用データの保存
- Redshiftml Amazon S3 からデータを読み込むための Amazon ML アクセス許可の取得
- Amazon S3 に予測を出力するために Amazon ML のアクセス許可を得る

S3バケットをデフォルト値で構築、```S3 ARN``` をコピー
![2021-03-11_20h44_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/e67f68de-4d43-c862-43dd-44a9ca6c9bd6.png)

アクセス許可 > バケットポリシーと進み、Amazon Redshift と SageMaker Autopilot が利用できるように以下の通りバケットポリシーを変更。先ほど作成したロールをプリンシパルに設定

```json
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "{iam-role-arn}"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "{s3-arn}/*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "{iam-role-arn}"
            },
            "Action": "s3:ListBucket",
            "Resource": "{s3-arn}"
        }
    ]
}
```

実行権限が大きいので本番デプロイ時は以下を参照、権限を絞ることをお勧めします。

https://docs.aws.amazon.com/ja_jp/machine-learning/latest/dg/granting-amazon-ml-permissions-to-read-your-data-from-amazon-s3.html

https://docs.aws.amazon.com/ja_jp/machine-learning/latest/dg/granting-amazon-ml-permissions-to-output-predictions-to-amazon-s3.html


#### Redshift クラスタ
構築に ```iam role arn``` と ```S3 ARN``` が必要です。

設定 > サブネットグループと進み、任意で名称を設定、VPC のすべてのサブネットを追加、クラスターサブネットグループの作成をクリック
![2021-03-12_09h51_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/e7595c25-ed24-837f-2b19-2e7e984a960f.png)

クラスタ > クラスタの作成
![2021-03-10_14h56_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/f17afd78-cd45-8bb8-4101-22d2d7febe35.png)

クラスタ識別子を任意で入力。dc2.large が最も安価なクラスタだが Redshift ML は対応していないので注意 (2021年3月12日時点)
![2021-03-11_10h16_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/3e92fb68-fbee-b66a-9e20-38a7595fad8b.png)

Database Name、Port、Master User Name はデフォルト値でOK。Password を任意で入力。```Master USer Name``` と ```Password``` を控えておく。
![2021-03-10_15h05_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/eb3902a6-b026-199b-58cf-9a8b55d0b787.png)

クラスタのアクセス許可から先ほど作成した IAM ロールの ```iam role arn``` を選択、「IAM ロールを追加」を選択
![2021-03-11_10h05_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/dfd7c561-f237-47f9-369a-27b29dddcd77.png)

今回ローカルの SQL クライアントからクエリをたたく。追加設定のデフォルトを使用を解除し、ネットワークとセキュリティの項目で、パブリックアクセスの有効化にチェックを入れる
![2021-03-11_10h09_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/cd3981b5-f38b-5852-2c3b-dd3ca4b88733.png)

メンテナンスタブ > メンテナンストラックでプレビューの sql_preview を選択。ここまで設定が完了したらクラスタの作成へと進む 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/f2438c36-de7a-7756-a7b8-ac915ed7c03c.png)

デプロイが完了したら、```JDBC URL``` を控えておく
![2021-03-10_17h26_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/f66b1ef4-9b31-a966-2c34-6a66f0739e93.png)



#### VPC
Redshift クラスタをインターネット経由で操作できるよう、ネットワークを構成します。

先ほど作成したクラスタのプロパティから、VPC セキュリティグループと進む
![2021-03-10_16h40_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/757213bf-968b-c9e9-ec47-c1a3bc9bfd46.png)

デフォルトだと下記の状態。インバウンドルール > インバウンドルールを編集
![2021-03-10_16h42_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/0dd085dc-f139-e986-63fb-77e74fdc1ff8.png)

ルールの追加 > タイプを Redshift に選択 > マイIP と進み、ルールを保存をクリック。この作業でローカル環境から Redshift への接続が通るようになる。
![2021-03-10_16h43_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/09aced74-8976-42e5-7a44-d08d80faf14d.png)

アウトバウンドルールが以下の状態になっていることを確認
![2021-03-10_16h45_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/88fb4bb6-eae2-4d02-8aa3-21998f9837fa.png)

備考：Redshift クラスタの VPC サブネットのルートテーブルで、送信先 0.0.0.0/0 が blackhole になっている場合、SQL クライアントから接続する際、Connection Timeout が発生する。ルートの編集と進み、該当設定を再設定する
![2021-03-11_06h09_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/182208e2-1eb0-8633-3943-e44c0a7f21a8.png)

https://go-journey.club/archives/12101

#### インターネットゲートウェイ
インターネットに接続するためのゲートウェイがない場合は以下手順で構築します。

Redshift クラスタのプロパティから VPC と進み、別タブで開いておく
![2021-03-10_17h19_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/daa0b85a-002f-0fd8-9a02-62d72afbe154.png)

VPC ダッシュボード > インターネットゲートウェイ > インターネットゲートウェイの作成
![2021-03-10_17h18_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/73685fd6-30af-f987-dc7b-3ebe80570018.png)

任意でゲートウェイの名称を入力、作成をクリック
![2021-03-10_15h27_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/fd1ac931-dba3-1fa6-c566-378c1184eaa7.png)

作成したインターネットゲートウェイを Redshift クラスタが稼働しているのVPCにアタッチ
![2021-03-10_17h21_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/c3beca25-f9d8-d38e-6b27-3815326878c8.png)



#### データのアップロード
ダウンロードした CSV データを S3 にアップロード、```S3 URI``` をコピーしておく
![2021-03-11_05h33_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/911b8b0e-9f0b-4ad2-2577-3bb2cc60db46.png)

今回は SQL クライアントに DBeaver を用いる。

https://dbeaver.io/

DBeaber をインストールしたら、新しい接続を選択、Redshift へと進む

![2021-03-08_15h10_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/f0bae698-62f7-b271-c2de-03d43d5f59af.png)

JDBC ホスト、```Master USer Name``` 、 ```Password``` を入力し、終了をクリック
JDBC ホスト名は、```JDBC URL``` から ```dbc:redshift://``` と ```:5439/dev``` を除いた文字列となるので注意

![2021-03-08_15h14_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/0264b09e-40f2-0fdd-f8c6-4e06d9c92b84.png)


## まとめ

以下第2回の記事です

https://qiita.com/Catetin0310/items/aff58ddcce13e95efbcb


## 参考リンク


Amazon Redshift ML の紹介記事です。

https://aws.amazon.com/jp/blogs/big-data/create-train-and-deploy-machine-learning-models-in-amazon-redshift-using-sql-with-amazon-redshift-ml/

公式ドキュメント

https://aws.amazon.com/jp/premiumsupport/knowledge-center/redshift-cluster-private-public/

https://docs.aws.amazon.com/ja_jp/machine-learning/latest/dg/granting-amazon-ml-permissions-to-read-your-data-from-amazon-s3.html