Amazon Personalizeを使ってみた

2019.07.07

最初に

前から気になっていた「Amazon Personalize」を試してみました。
こちらの内容をほとんどそのまま試してみただけなのですが、他にも気になっている人が「Amazon Personalize」のイメージを掴めるように、ブログ化しました。

目次

1.「Amazon Personalize」に出てくる単語について
2.やってみた
3.最後に

1.「Amazon Personalize」に出てくる単語について

まず最初に、今回のチュートリアルで出てくる「Amazon Personalize」の単語の意味を理解しておきましょう。
今回のチュートリアルでは、下記の流れでレコメンド結果を取得することができました。

「Dataset Group,recipeを指定(データセット、前処理、アルゴリズム、ハイパーパラメータ等を指定)」→「solutionを作成(モデルの学習)」→「Campaignの作成(solutionをdeploy)」→「Campaignにリクエストしてレコメンド結果を取得」

Dataset Group

「Dataset Group」は、「ユーザー情報」や「アイテム」等の学習に利用するデータセット達をグループとして整理したものをそう読んでいるようです。
要するに、「モデルの学習に利用する諸々のデータセット」ですね。

A dataset group is a collection of related datasets (Interactions, User, and Item). You create a dataset group by calling CreateDatasetGroup. You then create a dataset and add it to a dataset group by calling CreateDataset. The dataset group is used to create and train a solution by calling CreateSolution. A dataset group can contain only one of each type of dataset.

DatasetGroup

具体的には、「Interactions」、「Items」、「Users」の最大3種類のデータセットが利用できるようです。

A dataset group contains related datasets that supply data for training a model. A dataset group can contain at most three datasets, one for each type of dataset:
Interactions
Items
Users

参照:CreateDatasetGroup

それぞれのデータの特徴は名前の通りですが、一応公式ドキュメントを確認すると下記の通り記述があります。

Users – This dataset is intended to provide metadata about your users. This includes information such as age, gender, and loyalty membership, among others, which can be important signals in personalization systems.
Items – This dataset is intended to provide metadata about your items. This includes information such as price, SKU type, and availability, among others.
Interactions – This dataset is intended to provide historical interaction data between users and items.

参照:Datasets and Schemas

また、各データは下記の通り「最低限必要なカラム」や「事前に予約されたカラム名」がある点に注意してください。

参照:Datasets and Schemas

「Users」、「Items」データについては、「最低限指定する必要があるカラム」、「事前予約されたカラム」以外のカラムは1〜5カラムまで利用することができます。

The Users and Items schemas must have at least one metadata field. There is a limit of 5 metadata fields per dataset/schema. A metadata field is a field of type "string" with a "categorical" attribute, or any non-string type. The required fields and reserved keywords are not considered metadata.

参照:Datasets and Schemas

また、モデルの学習をするためには「Interactions」は必須となりますが、「Users」、「Items」は必須ではありません。
ちなみに、今回のチュートリアルでは「Interactions」データのみで検証を進めます。

To train a model (create a solution), a dataset group that contains an Interactions dataset is required.

参照:CreateDatasetGroup

「interaction」データは「最低1,000レコード以上」、「2回以上出現するユーザーが25人以上」といった最低要件がある点にご注意ください。

Note
The minimum data requirements to train a model are:
1000 records of combined interaction data (after filtering by eventType and eventValueThreshold, if provided)
25 unique users with at least 2 interactions each

参照:Recording Events

schema

「Users」、「Items」、「interaction」データについてそれぞれ「schema」を指定する必要があります。
「schema」は、各データの定義情報です。
例えば、下記は「Users」データの「schema」の例です。

{
  "type": "record",
  "name": "Users",
  "namespace": "com.amazonaws.personalize.schema",
  "fields": [
      {
          "name": "USER_ID",
          "type": "string"
      },
      {
          "name": "AGE",
          "type": "int"
      },
      {
          "name": "GENDER",
          "type": "string",
          "categorical": true
      }
  ],
  "version": "1.0"
}

参照:Recording Events

「Users」、「Items」データについては、「USER_ID」、「ITEM_ID」以外の文字列は全て「"categorical":true」と指定する必要があります。

The Users and Items dataset types are known as metadata types and are only used by certain recipes. For more information, see Using Predefined Recipes. For metadata datasets, all strings, except for USER_ID and ITEM_ID, must be marked as categorical in the schema, as shown in the following examples.

参照:Datasets and Schemas

solution

「学習済みのモデル」のことを「Amazon Personalize」では「solution」と呼んでいます。

A solution version is the term Amazon Personalize uses for a trained machine learning model that makes recommendations to customers. Creating a solution entails optimizing the model to deliver the best results for a specific business need.

参照:Creating a Solution

recipe

「recipe」は「solution」を作成するために利用されます。
「recipe」は「アルゴリズム(ハイパーパラメータも含む)、「特徴量の変換(前処理方法)」の2点からなるようです。

Amazon Personalize uses "recipes" to create these personalized solutions. A recipe in Amazon Personalize is made up of an algorithm with hyperparameters, and a feature transformation.

参照:Creating a Solution

Campaign

「solution(学習済モデル)」を、実際にAPIとして利用できるようにデプロイする必要があります。
「Amazon Personalize」では、「Campaign」を作成することで「solution」をデプロイすることになります。

A campaign is used to make recommendations for your users. You create a campaign by deploying a solution version

参照:Creating a Campaign

2.やってみた

2-1.データセットの準備

今回はMovieLensデータセットを利用しました。
単純にそのまま使うのではなく、少し前処理をして、S3にデータセットをアップロード、という流れです。

・ダウンロードしてきたデータ
(ユーザーが映画に対して、いつどのような評価をしたのか、というデータ。)

userId,movieId,rating,timestamp
1,2,3.5,1112486027
1,29,3.5,1112484676
1,32,3.5,1112484819
1,47,3.5,1112484727
1,50,3.5,1112484580
1,112,3.5,1094785740
1,151,4.0,1094785734
1,223,4.0,1112485573
1,253,4.0,1112484940

・前処理を施して、最終的に利用するデータ
前処理の内容としては、「データのシャッフル」→「ratingが閾値よりも大きいレコードに絞り込み」→「rating」カラムを削除→カラム名を変更→「10万レコードのみに絞り込み」、というものです。
(このデータは「Interaction」として利用します)

USER_ID,ITEM_ID,TIMESTAMP
87360,2329,1190294378
106248,2859,974759082
99171,2436,981700908
87127,589,950714849
125978,2165,928138954
81412,497,840646525
57734,1079,945213670
38762,5952,1340218602
96340,1597,1167711910

実際のコマンドはほぼほぼAWSブログに記述されている通りなのですが、一応掲載しておきます。
(私はSageMaker上で実行しました)

ダウンロードして

%%bash

curl -o ml-20m.zip http://files.grouplens.org/datasets/movielens/ml-20m.zip
unzip ml-20m.zip
rm ml-20m.zip

前処理

import pandas, boto3 
from sklearn.utils import shuffle
ratings = pandas.read_csv('./ml-20m/ratings.csv')
ratings = shuffle(ratings)
ratings = ratings[ratings['rating']>3.6]
ratings = ratings.drop(columns='rating')
ratings.columns = ['USER_ID','ITEM_ID','TIMESTAMP']
ratings = ratings[:100000]
ratings.to_csv('ratings.processed.csv',index=False)

S3にアップロード

!aws s3 cp ./ratings.processed.csv s3://<my-bucket>/<my-path>/

2-2.Dataset Groupの作成

実際にAWSコンソール画面上から「Dataset Group」を作成してみます。

「create dataset group」をクリックして、

データセットグループ名を指定します。

続いて、データセット名を指定します。
これは「Interaction」のデータセット名の指定ですね。

ここで「schema」を指定します。
ここでは、 「Interaction」データがどのようなデータか という定義を記述しています。
先ほどS3にアップロードしたデータの定義をこちらに記述します。

続いて、上記で指定したデータセットをIMPORTするJOB名を指定します。
「データセットが格納されているS3パス名」、「IAMロール」の2点を指定します。
さらっと「csvにしろ」と書いてある点は注意が必要ですね。

もし事前にIAMロールを用意していない場合は、この画面から新しくIAMロールを作成することができます。
データセットが格納されているS3パスへのアクセス権限がちゃんと付与されていることを確認してください。

無事、IMPORTするJOBまで作成できたら、下記の通りデータセットをIMPORTするJOBが始まります。

2-3.solutionを作成

データセットのインポートが完了したら、続いて「solution」を作成します。

早速コンソール画面上から作成してみます。
「recipe」については、自分でマニュアルで作成したものを利用する他に、データから自動的に判別してくれるもの(AutoML)も選択できました。
早速後者を選択してみます。

「solution」の作成には少し時間がかかります。
(モデルの学習等が実行されることになるので)

2-4.Campaignの作成

「solution」の作成が完了したら、続いて推論処理をするために「Campaign」を作成しましょう。
「Create new campaign」をクリックして、

「campaign名」、「solution」、「プロビジョニングさせておく、1秒あたりのスループット数」を指定します。

campaignが作成できたら、最後に推論処理をしてみましょう。

import boto3

## campaign、ユーザーIDの指定
campaign_arn = "<your-campaign-arn>"
user_id = '1'


def get_recommend(campaign_arn,user_id):
    personalizeRt = boto3.client('personalize-runtime')

    response = personalizeRt.get_recommendations(
        campaignArn = campaign_arn,
        userId = user_id)

    print("Recommended items")
    for item in response['itemList']:
        print (item['itemId'])

get_recommend(campaign_arn,user_id)

参照:Getting Recommendations

レコメンド結果を取得することができました。
特にレコメンドの数は指定していないのですが、複数のユーザーIDで実行してみたところ毎回「25」個の値が返却されました。

Recommended items
4034
1961
293
1219
50
1954
4963
8636
5902
1357
4878
4886
1080
919
48780
858
1307
1380
4027
1208
7153
3039
1073
2571
2115

返り値全体も記述しておきますが、なんとも素っ気ないですね。

{'ResponseMetadata': {'RequestId': '5365e3a1-c7ab-48b5-a3e6-ef849a2a8918', 'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'application/json', 'date': 'Sun, 07 Jul 2019 09:51:19 GMT', 'x-amzn-requestid': '5365e3a1-c7ab-48b5-a3e6-ef849a2a8918', 'content-length': '460', 'connection': 'keep-alive'}, 'RetryAttempts': 0}, 'itemList': [{'itemId': '4034'}, {'itemId': '1961'}, {'itemId': '293'}, {'itemId': '1219'}, {'itemId': '50'}, {'itemId': '1954'}, {'itemId': '4963'}, {'itemId': '8636'}, {'itemId': '5902'}, {'itemId': '1357'}, {'itemId': '4878'}, {'itemId': '4886'}, {'itemId': '1080'}, {'itemId': '919'}, {'itemId': '48780'}, {'itemId': '858'}, {'itemId': '1307'}, {'itemId': '1380'}, {'itemId': '4027'}, {'itemId': '1208'}, {'itemId': '7153'}, {'itemId': '3039'}, {'itemId': '1073'}, {'itemId': '2571'}, {'itemId': '2115'}]}

3.最後に

今回は、「Amazon Personalizeってどんな感じなんだろう」と前々から思っていたので、実際にチュートリアルを触ってみました。
一回触ってみることで、なんとなく「Amazon Personalize」ってどんなものなんだろう、というのが把握できました。

もし「Amazon Personalize」の料金体型が気になる方は、レコメンデーション用機械学習サービス、Amazon PersonalizeがGAになりました!もご参照ください。

参照

チュートリアル内容について
DatasetGroup
Recording Events CreateDatasetGroup
Creating a Solution
Creating a Campaign
movielensのデータセット
レコメンデーション用機械学習サービス、Amazon PersonalizeがGAになりました!