Amazon Personalizeを使ってみた
Amazon Personalizeとは
amazon.comで使用されてきたレコメンデーションエンジンを抽象化することで各社のプロダクトに簡単に導入できるようにするAWSサービスである。
現時点ではプレビューなので使用するには申請が必要となる
登場人物
登場する用語・要素としては以下の通りである
・Dataset
datasetにはUsers, Items, Interactionsという3つのtypeがある。ecのamazonをイメージしてもらうとわかりやすい。UsersはそのままユーザーでUSER_IDが必要となる。その他にサービス毎に存在する特徴を必要に応じて付与する。Itemsは商品である。これもITEM_IDが必須でその他に必要に応じて特徴を付与する。Interactionsは「誰が、どの商品を、いつ買ったか」というデータでUSER_ID, ITEM_ID, TIMESTAMPが必要となる。
・Dataset groups
これが一番トップ概念である。Users, Items, Interactionsで一つのグループであり、このgroupに対してレコメンドモデルを作成していく
・Schema
スキーマはApache Avroフォーマットで記述する(なんでavroが採用されてるのかはよくわからない...)。データ自体はヘッダー付きのcsvを用いる
・Dataset import job
S3のパスを指定してそれぞれ3つのdatasetのデータを読み込む
・Solution
レコメンドモデルのことである。使用するアルゴリズムはsagemakerと同じように事前定義のモデル(recipeと呼ばれる)がいくつかある。Bring Your Own Recipe(BYOR)も用意されているが、今回はそこには触れていない。
Dataset groupに対して様々なrecipeを組み合わせて複数のSolutionを作成することができる
・Campaign
学習したレコメンドモデル(Solution)を指定して(sagemakerでいう)エンドポイントを作成できる。クライアントはこのCampaignに対してgetRecommendations APIを使用してレコメンデーションを取得する
動かしてみる
プレビューのため一部マネジメントコンソールが不安定だったため、CLIのセットアップをおすすめする。データは映画の視聴データであるhttps://grouplens.org/datasets/movielens/のml-latest-small.zipを利用した。
ratings.csvのヘッダー名を以下のように変更し、ratingを削除する。USER_ID, ITEM_ID, TIMESTAMPはPersonalizeのスキーマの決まりである
USER_ID,ITEM_ID,TIMESTAMP
1,1,964982703
1,3,964981247
1,6,964982224
...
s3バケットを作成しアップロードする。今回は3つのdatasetに対してディレクトリを分けた。s3バケットにはバケットポリシーの設定が必要である。https://docs.aws.amazon.com/personalize/latest/dg/data-prep-upload-s3.html
ではDataset groupを作成していく。input typeとしてはuser-item interactionを選択する。コンソールだと次にinteractionのdatasetを作成する。スキーマは以下のように設定する。
{
"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"
}
最後にdataset import jobを作成する。job名は何でも良い。service roleはとりあえず自動作成されるものに従いつつ、data locationには先程のratings.csvをアップロードしたディレクトリを指定する。今回は一つのファイルした置かなかったが、おそらく複数ファイルに分割されていてもimportできるはず。
次にUsersとItemsをimportする。Usersはデータとしてなかったのでとりあえず適当に以下のようなスキーマで作成した。csvのヘッダーはスキーマに合わせる
{
"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"
}
------------------
USER_ID,AGE,GENDER
1,23,female
2,26,male
3,43,female
...
同様にItemsはmovies.csvを利用して以下のように作成した。これまでと同じくヘッダーはスキーマに合わせる
{
"type": "record",
"name": "Items",
"namespace": "com.amazonaws.personalize.schema",
"fields": [
{
"name": "ITEM_ID",
"type": "string"
},
{
"name": "TITLE",
"type": "string"
},
{
"name": "GENRE",
"type": "string",
"categorical": true
}
],
"version": "1.0"
}
------------
ITEM_ID,TITLE,GENRE
1,Toy Story (1995),Adventure|Animation|Children|Comedy|Fantasy
2,Jumanji (1995),Adventure|Children|Fantasy
3,Grumpier Old Men (1995),Comedy|Romance
avroに詳しくなくcategoricalの項目はなにか間違っているような気がするが、とりあえず動かしてみることを目的にしているのでそのまま進むことにする。。。
dataset import jobが終了したら(これがそれなりに時間かかった)、次はSolutionを作成する。便利なことにrecipe選択にAutomatic(AutoML)というのがあり、おそらくimportしたデータセットの特徴やスキーマによってrecipeを自動選択してくれる。今回はDeepFM, FFNN, HRNNがサジェストされた。
Factorization Machines(FM)は各特徴量を交互作用(ex. 20代男性)させたものもファクターとして使用するもので、DeepFMはその交互作用とDNNでのhidden layerを足し合わせてoutputとするアルゴリズムである。直感や経験では見い出せない特徴を扱えると考えるとよいかと。
FFNNはFeed Forward Neural Network、いわゆるニューラルネットワークである。
HRNNはHierarchical Recurrent Neural Networkで時系列データを扱える。今回のデータだと過去にはどんな映画を見ていて最近はこんな映画を見ている、といったところを加味してレコメンドすることに期待したい。
その他のモデルはhttps://docs.aws.amazon.com/personalize/latest/dg/working-with-predefined-recipes.htmlを参照。
マネジメントコンソールでrecipe selectionをAutomaticにしてsolution versionを作成すると違った組み合わせのモデルを複数学習する。
今回は4つほど作成されたのだが、solution configは以下のものを用いてcampaignを作成する。(おそらく3つのアルゴリズムそれぞれで学習し、それを組み合わせてるので計4つ?)
{
"autoMLConfig": {
"metricName": "precision_at_25",
"recipeList": [
"arn:aws:personalize:::recipe/aws-hrnn",
"arn:aws:personalize:::recipe/aws-deepfm",
"arn:aws:personalize:::recipe/aws-ffnn"
]
}
}
campaignを作成するのだが、マネジメントコンソールからだとsolutionで選択する。API的にはsolution-version-arnを指定するものである。solutionにlatest versionがあり、マネコンからそれが選択される模様。
campaignが作成されたらあとはそれに対してuser_idを投げてみたりして遊んで見る
ただUsersかInteractionsに含まれてるUser IDでなければrecommendationを取得できないはずだが、出来てしまった。。どこかでなにか間違えているのか、プレビューゆえの不具合なのか、はわからない。。
まとめ
とりあえずUSER_ID, ITEM_ID, Interactionsといういくつかのスキーマの決まりにさえ従えば、csvに特徴をブチ込んでとりあえずレコメンドエンジンを作成する、ということが簡単にできるようになります!!!
まだ精度だったりのところは全然検証していないので次は実データで色々触ってみようかと思います。
この記事が気に入ったらサポートをしてみませんか?