Amazon Web Services ブログ

Amazon SageMaker と R の使用

このブログ記事では、Amazon SageMakerおよびRを使って、Machine Learning (ML) モデルを構築してトレーニングを受け、デプロイし、予測を見積もる方法について説明します。モデルは、殻の成長線からアワビの年齢を予測します。reticulateパッケージは、Amazon SageMaker Python SDKの R インターフェイスとして使用され、Amazon SageMaker への API コールを行います。 reticulate パッケージは、R と Python オブジェクトを相互変換し、Amazon SageMaker は ML モデルをスケールして、トレーニングやデプロイできるサーバレスのデータサイエンス環境を提供します。

このブログ記事を読み進めるには、R に関する基本的な理解が必要で、次のtidyverseパッケージに精通している必要があります。 dplyrreadrstringr、および ggplot2RStudioを使ってコードを実行します。 Rstudio は、R と連携するための統合開発環境 (IDE) です。 商用ライセンスまたはAGPLv3のライセンスを取得できます。

AWS CloudFormation の起動

Amazon SageMaker を使って、Amazon Elastic Compute Cloud (Amazon Ec2) インスタンスに Rstudio をインストール、構成、および接続するには、次のAWS CloudFormationスタックを使用します。

このスタックを起動すると、次のリソースが作成されます。

  • 公開 Virtual Private Cloud (VPC)
  • Amazon EC2 インスタンス (t2.medium)
  • SSH アクセスのみを許可するセキュリティグループ
  • Amazon SageMaker のアクセス許可を持つ Amazon EC2 の AWS Identity and Access Management (IAM) ロール
  • Amazon SageMaker の IAM サービスロール
  • Rstudio のインストール
  • R パッケージの要求事項
  • Amazon SageMaker Python SDK のインストール

スタックを起動したら、次の手順に従って Rstudio の構成と接続をしてください。

  1. Select Template」ページで、「Next」を選択します。
  2. Specify Details」ページで、「KeyName」のキーペアを指定します。
  3. Options」ページで、「Next」を選択します。
  4. Review」ページで、「AWS CloudFormation によって、カスタム名を使って IAM リソースが作成される可能性があることを了解します。」のチェックボックスをオンにして、「Next」を選択します。
  5. スタックが CREATE_COMPLETE 状態に達すると、 「Outputs」を選択します
  6. Value」の SSH 文字列をコピーしてターミナルウィンドウに貼り付けます。

SSH コマンドは、新しいインスタンスに接続している間、ポート 8787 をコンピュータに転送します。接続したら、ブラウザウィンドウを開き、アドレスバーに localhost:8787 と入力します。

注意 Rstudio と必要な R パッケージのインストール中に、ターミナルに接続失敗のメッセージが表示されることがあります。インストールプロセスには約 15 分かかります。

次の認証情報でサインインします。

  • ユーザー名:rstudio
  • パスワード:rstudio

Amazon SageMaker Python SDK の Reticulating

まず、 reticulate をロードし、 Sagemaker の Python モジュールをインポートします。モジュールがロードされたら、Python の表記の代わりに、R の $ 表記を使用します 使用可能なクラスを表示します。

次の図のように、 Session クラスを使用します。

Session クラスは、Amazon SageMaker で以下の boto3 リソースを操作するための運営を提供します。

Session クラスで 使用できる オブジェクトを表示するには、次の図のように $ 表記を使用します。

データストレージの作成とアクセス

データ用の Amazon Simple Storage Service (Amazon S3) バケットを作成しましょう。Amazon SageMaker がバケットにアクセスする許可を得るために、IAM ロールが必要になります。

トレーニングデータ、モデルのバイナリファイル、およびトレーニングジョブの出力を保存する Amazon S3 バケットを指定します。

library(reticulate)
sagemaker <- import('sagemaker')
session <- sagemaker$Session()
bucket <- session$default_bucket()

注意 default_bucket 関数は、次の名前のように特有の Amazon S3 バケットを作成します。 sagemaker-<aws-region-name>-<aws account number>

Amazon SageMaker が Amazon S3 バケットにアクセスする許可を得るためには、IAMロールの ARN を指定します。

role_arn <- session$expand_role('sagemaker-service-role')

AWS CloudFormation スタックが、必要なポリシーに従って、 sagemaker-service-role という IAM ロールを自動的に作成しました。 expand_role 関数は、Amazon SageMaker の要求によって、このロールの ARN を取得します。

データセットのダウンロードとプロセス

モデルは、UCI Machine Learning リポジトリabalone データセットを使用します。まず、データをダウンロードし、 exploratory data analysis を開始します。Tidyverse パッケージを使って、データを読み込み、プロットし、Amazon SageMaker のデータ を ML 形式に変換します。

library(readr)
data_file <- 'https://archive.ics.uci.edu/ml/machine-learning-databases/abalone/abalone.data'
abalone <- read_csv(file = data_file, col_names = FALSE)
names(abalone) <- c('sex', 'length', 'diameter', 'height', 'whole_weight', 'shucked_weight', 'viscera_weight', 'shell_weight', 'rings')
head(abalone)

前のイメージは、 sex 因子データ型であるものの、現在は文字データ型(Fは雌、Mは雄、Iは幼生)であることを示しています。sex を因子に変更し、 データセットの統計的要約を表示しています。

abalone$sex <- as.factor(abalone$sex)
summary(abalone)

要約では、高さの最小値が 0 であることを 示しています。

Sex ごとに ringsheight との相互関係をエクスプロイトすることで、どのアワビの高さか視覚的に 調べます

library(ggplot2)
ggplot(abalone, aes(x = height, y = rings, color = sex)) + geom_point() + geom_jitter()


このプロットは、複数の外れ値を示しています。height が 0 の 2 つの幼生アワビと、他より高い雌と雄のアワビがいくつかあります。高さ 0 の幼生アワビを 2 つ取り除きましょう。

library(dplyr)
abalone <- abalone %>%
  filter(height != 0)

モデルトレーニングのためのデータセット準備

このモデルでは、トレーニング、テスト、および検証用にそれぞれ 1 つずつ、3 つのデータセットが必要です。最初に、 sexダミー変数に変換し、ターゲットの ringsを最初の列に移動させます。 Amazon SageMaker のアルゴリズムでは、ターゲットがデータセットの最初の列に存在する必要があります。

abalone <- abalone %>%
  mutate(female = as.integer(ifelse(sex == 'F', 1, 0)),
         male = as.integer(ifelse(sex == 'M', 1, 0)),
         infant = as.integer(ifelse(sex == 'I', 1, 0))) %>%
  select(-sex)
abalone <- abalone %>%
  select(rings:infant, length:shell_weight)
head(abalone)

このコードは、次のようなデータセットを生成します。

次に、ML アルゴリズムをトレーニングするデータの 70% をサンプリングします。残りの 30% をテスト用と検証用の 2 つに分けます。

abalone_train <- abalone %>%
  sample_frac(size = 0.7)
abalone <- anti_join(abalone, abalone_train)
abalone_test <- abalone %>%
  sample_frac(size = 0.5)
abalone_valid <- anti_join(abalone, abalone_test)

トレーニングおよび検証データを Amazon S3 にアップロードすると、モデルをトレーニングできます。まず、トレーニングと検証のデータセットを .csv 形式でローカルファイルシステムに書き込みます。

write_csv(abalone_train, 'abalone_train.csv', col_names = FALSE)
write_csv(abalone_valid, 'abalone_valid.csv', col_names = FALSE)

次に、2 つのデータセットを data キーの Amazon S3 バケットに アップロード します。

s3_train <- session$upload_data(path = 'abalone_train.csv', 
                                bucket = bucket, 
                                key_prefix = 'data')
s3_valid <- session$upload_data(path = 'abalone_valid.csv', 
                                bucket = bucket, 
                                key_prefix = 'data')

最後に、Amazon SageMaker アルゴリズムの Amazon S3 入力タイプを定義します。

s3_train_input <- sagemaker$s3_input(s3_data = s3_train,
                                     content_type = 'csv')
s3_valid_input <- sagemaker$s3_input(s3_data = s3_valid,
                                     content_type = 'csv')

モデルのトレーニング

Amazon SageMaker アルゴリズムは、Dockerコンテナを通して利用できます。XGBoost モデルをトレーニングするには、AWS リージョンの Amazon 伸縮自在なコンテナレジストリ (Amazon ECR) でトレーニングコンテナを指定します。

containers <- list('us-west-2' = '433757028032.dkr.ecr.us-west-2.amazonaws.com/xgboost:latest',
  'us-east-1' = '811284229777.dkr.ecr.us-east-1.amazonaws.com/xgboost:latest',
  'us-east-2' = '825641698319.dkr.ecr.us-east-2.amazonaws.com/xgboost:latest',
  'eu-west-1' = '685385470294.dkr.ecr.eu-west-1.amazonaws.com/xgboost:latest')
container <- containers[session$boto_region_name][[1]]

Docker でコンテナ化されたアルゴリズムのトレーニングができる Amazon SageMaker 見積もり を定義します。見積もりを作成するときは、次の引数を使用します。

  • image_name – トレーニングに使用するコンテナイメージ
  • role – 作成した Amazon SageMaker サービスのロール
  • train_instance_count – トレーニングに使用する Amazon EC2 インスタンスの数
  • train_instance_type – トレーニングに使用する Amazon EC2 インスタンスのタイプ
  • train_volume_size – トレーニング中に入力データを保存するために使用する Amazon Elastic Block Store (Amazon EBS) ボリュームのGBサイズ
  • train_max_run – トレーニングのタイムアウト秒数
  • input_mode – アルゴリズムがサポートする入力モード
  • output_path – トレーニング結果 (モデルのアーティファクトと出力ファイル) を保存する Amazon S3 の経路
  • output_kms_key – トレーニング出力を暗号化するための AWS Key Management Service (AWS KMS) キー
  • base_job_name – トレーニングジョブ名のプレフィックス
  • sagemaker_session – Amazon SageMaker API との相互作用を管理する Session オブジェクト
s3_output <- paste0('s3://', bucket, '/output')
estimator <- sagemaker$estimator$Estimator(image_name = container,
                                           role = role_arn,
                                           train_instance_count = 1L,
                                           train_instance_type = 'ml.m5.large',
                                           train_volume_size = 30L,
                                           train_max_run = 3600L,
                                           input_mode = 'File',
                                           output_path = s3_output,
                                           output_kms_key = NULL,
                                           base_job_name = NULL,
                                           sagemaker_session = NULL)

注意 Python の None に相当するのは Rの NULL です。

XGBoost のハイパーパラメータを指定し、モデルに適合させます。 トレーニングのラウンド数を 100 に設定します。これは、Amazon SageMaker 以外の XGBoost ライブラリを使用する場合のデフォルト値です。また、現在のタイムスタンプに基づいて入力データとジョブ名を指定します。

estimator$set_hyperparameters(num_round = 100L)
job_name <- paste('sagemaker-train-xgboost', format(Sys.time(), '%H-%M-%S'), sep = '-')
input_data <- list('train' = s3_train_input,
                   'validation' = s3_valid_input)
estimator$fit(inputs = input_data,
              job_name = job_name)

トレーニングが終了すると、Amazon SageMaker はモデルバイナリ (gzip tarball) を指定された Amazon S3 の出力経路にコピーします。このコマンドで Amazon S3 の完全な経路を取得します。

estimator$model_data

モデルのデプロイ

Amazon SageMaker を使用すると、コンシューマーが HTTPS 要求を使って、安全で簡単な API コールを発動させ、エンドポイントを提供することで、モデルをデプロイできます。
トレーニングしたモデルを ml.t2.medium インスタンスにデプロイしましょう。 詳細については、「Amazon SageMaker ML インスタンスタイプ」を参照してください。

model_endpoint <- estimator$deploy(initial_instance_count = 1L,
                                   instance_type = 'ml.t2.medium')

モデルによる予測の生成

テストデータを使って予測を生成します。エンドポイントに text/csv csv_serializer を指定して、コンマ区切りのテキストをJSON 形式でシリアル化して渡します。

model_endpoint$content_type <- 'text/csv'
model_endpoint$serializer <- sagemaker$predictor$csv_serializer

ターゲット列を削除し、最初の 500 回の観測値を列名のない行列に変換します。

abalone_test <- abalone_test[-1]
num_predict_rows <- 500
test_sample <- as.matrix(abalone_test[1:num_predict_rows, ])
dimnames(test_sample)[[2]] <- NULL

注意 エンドポイントの制限を超えないため、500 回の観測を選択しました。

エンドポイントから予測を生成し、コンマ区切りの文字列を変換します。

library(stringr)
predictions <- model_endpoint$predict(test_sample)
predictions <- str_split(predictions, pattern = ',', simplify = TRUE)
predictions <- as.numeric(predictions)

Rings の予測値をテストデータに列バインドします。

abalone_test <- cbind(predicted_rings = predictions, 
                      abalone_test[1:num_predict_rows, ])
head(abalone_test)    

予測年齢(殻の rings の数)は次のようになります。

エンドポイントの削除

モデルを終了したら、デプロイメント費用を避けるためにエンドポイントを削除します。

session$delete_endpoint(model_endpoint$endpoint)

まとめ

このブログ記事では、R と Amazon SageMaker を使って ML モデルを構築し、デプロイする方法を学びました。通常、このワークフローは Python で実行しますが、R を使っての実行方法もお見せしました。


今回のブログ投稿者について

Ryan Garner は AWS プロフェッショナルサービスのデータサイエンティストです。AWS のお客様が、R を使用してデータサイエンスや Machine Learning の問題を解決するのを、支援することに熱心です。