Python
AWS
S3
機械学習
レコメンド

Amazon Personalizeでユーザの商品購入動向をもとにレコメンドしよう 〜フルマネージド機械学習サービスの素晴らしさとは〜

本日ついに待望のAmazonPersonalizeがGAされました!

機械学習の知識不要で、アプリケーションを使用しているユーザに対して開発者が個別のレコメンデーションを簡単に作成できるという優れものらしく、これを使えばSageMakerなどの機会学習基盤を自前で構築する必要がなくなりそうです。参照:公式ブログ

東京リージョンでも使用可能ですのでさっそく検証してみようかと思います:muscle:


Amazon Personalizeコンソール

コンソール画面を開いてみましょう。まだ日本語対応はできていないようですね。

右も左もわからない状態ですがとりあえずGet startedから開始しましょう。

image.png


DataSetグループの作成

解析する対象のデータセットを入力します。まずは user-item interaction dataの作成から始めます。

ユーザの購入動向がわかればいいので、ユーザID, 購入アイテムID, 購入時刻といった情報が必要でしょうか。

image.png

新しくスキーマを作成していきます。

image.png

スキーマの定義は以下の通りです。

簡単のために、USER_ID, ITEM_ID, TIMESTAMPとしてみました。


SchemaDefinition

{

"type": "record",
"name": "Interactions",
"namespace": "com.amazonaws.personalize.schema",
"fields": [
{
"name": "USER_ID",
"type": "string"
},
{
"name": "ITEM_ID",
"type": "string"
},
{
"name": "TIMESTAMP",
"type": "long"
}
],
"version": "1.0"
}


データセット(CSVファイル)を用意する

データフォーマットの詳細に関してはこちらの公式ドキュメントを参照してください。

実際に稼働しているサービスからデータを引っこ抜いてくるのがいいんでしょうが、今回はサンプルとして乱数を使ってテストデータを生成してみます。


generate_data.py

import random

for i in range(10000):
user_id = random.randrange(1, 300)
item_id = random.randrange(1, 500)
timestamp = random.randrange(886324817, 1086324817)
print(str(user_id) + ',' + str(item_id) + ',' + str(timestamp))


bash

$ python generate_data.py >> data.csv


以下のようなデータが出来上がります。正直1000レコード程度で何がわかるんだという気もしますがユーザ数を300としているのでデータの分散度合いはまぁまぁいいんじゃないでしょうか。


data.csv

USER_ID,ITEM_ID,TIMESTAMP

181,333,1026614155
187,235,1025344422
191,219,1085141557
290,154,1048393159
55,66,1040676271
135,85,914594952
113,100,1006765257
240,286,931923683
187,225,939639985
203,318,1062057637
101,377,934623475

作成したCSVファイルはS3にアップロードしておきます。

適当なバケット(今回はamazon-personalize-sample-bucket)を作成してアップロードしましょう。

# バケットの作成

$ aws s3 mb s3://amazon-personalize-sample-bucket
make_bucket: amazon-personalize-sample-bucket
# ファイルのアップロード
$ aws s3 cp data.csv s3://amazon-personalize-sample-bucket


CSVファイルを取り込む

Create user-item interaction dataの項目に入力を完了し、次の画面に進むと解析対象のCSVファイルを選択をすることになります。

image.png

AmazonPersonalizeが使用するIAMロールを新規に作りましょう。

image.png

先ほど用意したバケット名を入力してIAMロールを作成してください。

image.png

以上で完了です。

image.png

入力が完了するとUpload datasetsの作成が開始されます。

image.png

失敗しました。

:sweat: :thought_balloon: Get startedにしたがって進めていたのにには失敗するなんて不親切だなぁ

image.png


S3にアクセス権限を付与する

どうやらS3に対する権限が無いようです。ドキュメントにしたがってS3にバケットポリシーをつけます。


Insufficient privileges for accessing data in S3. Please look at https://docs.aws.amazon.com/personalize/latest/dg/getting-started.html#gs-upload-to-bucket and fix bucket policy on amazon-personalize-sample-bucket.


image.png

{

"Version": "2012-10-17",
"Id": "PersonalizeS3BucketAccessPolicy",
"Statement": [
{
"Sid": "PersonalizeS3BucketAccessPolicy",
"Effect": "Allow",
"Principal": {
"Service": "personalize.amazonaws.com"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::amazon-personalize-sample-bucket",
"arn:aws:s3:::amazon-personalize-sample-bucket/*"
]
}
]
}

image.png

S3に対するアクセス権限が設定できたので、再度データセットの作成を行います。


ソリューションの作成

問題なく10~15分ほどで、データセットの解析が完了しました。

次にソリューションを作っていきます。

ソリューションを使用すると、ユーザに対する推奨項目(レコメンド商品)を生成できます。

推奨項目を生成するために機械学習をしますが、そのために必要な基盤となるインフラはAWSがマネージドで用意してくれるのでとても楽チンです。

このソリューションはデータセットについてトレーニングされたカスタムモデルで構成されています。

では進めていきましょう。

image.png

image.png

レコメンドアルゴリズム(レシピ)の選択をします。

いくつか用意されていますね。今回はaws-hrnnにしてみましょう。

各モデルの概要は以下のような感じです。(公式ドキュメント参照)

レシピ
説明

PersonalizedReranking
検索結果または選別リストのパーソナライズされた
再ランク付けに使用

SIMS
アイテムの検出可能性を高めるために
詳細ページで使用高速パフォーマンス。

DeepFM
高速なトレーニングと推論に推奨。
全般的に良好なパフォーマンス。

FFNN
高速なトレーニングと推論に推奨。
大規模なデータセットに応じたスケーラビリティ。

HRNN
ユーザーの行動が時間の経過に伴って
変化する場合に推奨 (進化していくインテントの問題)。

HRNN-coldstart
カタログに新しいアイテムを追加する頻度が高く、
アイテムを即座にレコメンデーションに表示する場合に推奨。

HRNN-metadata
高品質のメタデータが使用できる場合は、
メタデータ以外のモデルよりパフォーマンスが向上。
トレーニング時間が長びく可能性がある。

Popularity-baseline
他のパーソナライゼーションレシピを
比較するためのベースラインとして使用。

image.png

ハイパーパラメータのチューニング項目が出てきますが、デフォルト値のままでOKです。

先に進みましょう。

image.png

image.png

データ量にも依存しますが、作成まで30分ほどかかります。

image.png


キャンペーンを作成する

ソリューションの作成が完了しました。最後にAPIとしてこのソリューションをしようするためのエンドポイントをデプロイしましょう。

このAPIエンドポイントのことをキャンペーンと呼ぶようです。SageMakerと同じような感覚でAPIエンドポイントをデプロイできますね。

image.png

必要な項目を入力して作成すればOKです。簡単ですね。

Mininum provisioned transactions per-secondは1にしておきましょう。利用ケースに応じて調整すれば良いです。

image.png

Detailタブを確認するとステータスを見ることができます。

image.png

10分ほどするとActiveになります。しばらく待ちましょう。

image.png


レコメンデーションを取得する

キャンペーンを作成すると、アプリに組み込むことで、レコメンデーションを取得できます。

レコメンデーションを取得するには、GetRecommendations API を呼び出します。

必要なキャンペーンの Amazon リソースネーム (ARN)、ユーザー ID、アイテム ID (省略可能) を渡すと、ユーザーへのレコメンドアイテムのリストが GetRecommendations から返却されます。

公式に従い、次のコードを使用してレコメンデーションを取得します。

アイテムIDは省略し、ユーザIDを指定することでレコメンド商品のリストを返却させてみます。


get_recommendation.py

import boto3

personalizert = boto3.client('personalize-runtime', region_name='us-west-2')

response=personalizert.get_recommendations(
campaignArn="arn:aws:personalize:ap-northeast-1:<AWS_ACCOUNT_ID>:campaign/my-campaign",
userId='100')

print("Recommended items")

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


以下が実行結果です。

いい感じですね。ユーザIDが100のユーザさんに対するレコメンド商品の一覧が取得できました。


bash

$ python get_recommendations.py

Recommended items
281
292
159
31
18
260
230
484
276
160
201
180
364
275
212
241
98
45
147
498
402
133
464
453
56

ざっとハンズオン的に解説をしてみましたが

記事を書く作業を含め2時間程度で学習と結果取得まで簡単にできてしまいました。

AmazonPersonalizeを使うことで、SageMakerや自前の機械学習基盤を使って苦労していたのが一気に無くなりそうですね!

AWS公式のハンズオンもあるようですのでキャッチアップしていき、ぜひ有効活用していきたいところです。