TypeScriptでAmazon Personalizeのレコメンドを取得する
Amazon Personalizeのワークショップで、「ドキュメントにNode.jsの使い方載ってないんですよねー」という話を聞いたので、とりあえずまとめてみました。 必要なライブラリ みんな大好きaws-sdkを入れ […]
目次
Amazon Personalizeのワークショップで、「ドキュメントにNode.jsの使い方載ってないんですよねー」という話を聞いたので、とりあえずまとめてみました。
必要なライブラリ
みんな大好きaws-sdkを入れればOKです。バージョン2.515.0以上をインストールしましょう。
$ npm i -S aws-sdk
TypeScriptの設定についてはお好みで準備しましょう。
レコメンドはPersonalizeRuntimeを使う
aws-sdkにはPeronalize系のクラスが3つ入っています。
ざっと型を見る限りではおおよそ以下のような認識で良さそうです。
- Personalize: Amazon Personalizeのリソースそのものを操作するクラス(データセットの追加やキャンペーン・ソリューションの追加など)
- PersonalizeRuntime: CampaignのARNなどを指定してレコメンドの結果を取得するクラス(今回使うもの)
- PersonalizeEvents: ユーザー操作などのイベントをトラッキングするためのクラス(多分Amplifyにはこれが入ってる)
今回はレコメンド結果を取得することが目的なので、PersonalizeRuntimeだけ使えばOKです。
getRecommendationsとgetPersonalizeRanking
PersonalizeRuntimeには2つのメソッドが用意されています(2019/08時点)
これは推論のレシピタイプによって使い分ける必要があります。
レシピタイプ | メソッド | userIdパラメーター | itemIdパラメーター | inputListパラメーター |
USER_PERSONALIZATION | getRecommendations | 必須 | 省略可能 | 不要 |
RELATED_ITEMS | getRecommendations | 不要 | 必須 | 不要 |
PERSONALIZED_RANKING | getPersonalizeRanking | 必須 | 不要 | 必須 |
TypeScriptではgetRecommendationsの引数に注意
getRecommendationsを利用する際、userId / itemIdの引数それぞれがoptionalで定義されていることに注意が必要です。
レシピタイプによって必要なパラメーターが異なるため、TypeScriptなどの型バリデーションに頼っていると「そのレシピでは必要なパラメーターだったのでエラーになる」というケースが考えられます。
getRecommendationsのサンプル
作成したcampaignのARN + 推論したいitem_id or user_idを渡してやればOKです。
import {
PersonalizeRuntime
} from 'aws-sdk'
const client = new PersonalizeRuntime({
region: 'ap-northeast-1'
})
const params: PersonalizeRuntime.Types.GetRecommendationsRequest = {
campaignArn: 'arn:aws:personalize:ap-northeast-1:99999:campaign/sims',
itemId: '1'
}
client.getRecommendations(params).promise()
.then(data => console.log(data))
.catch(e => console.log(e))
レスポンスでは、item_idのリストが返ってきます。
{ itemList:
[ { itemId: '3114' },
{ itemId: '648' },
{ itemId: '588' },
{ itemId: '34' },
{ itemId: '780' },
{ itemId: '788' },
{ itemId: '364' },
{ itemId: '1073' },
{ itemId: '1270' },
{ itemId: '595' },
{ itemId: '987654' } ] }
numResults
に数字を入れることで、取得する件数を制御することも可能です。デフォルトは25件で、100件まで増やすことができます。
getPersonalizeRankingのサンプル
getPersonzalizeRankingでは、ランキングとして並び替えたいアイテムのIDをリストにしたものと、user_id + CampaignのARNを渡します。
import {
PersonalizeRuntime
} from 'aws-sdk'
const client = new PersonalizeRuntime({
region: 'ap-northeast-1'
})
const params: PersonalizeRuntime.Types.GetPersonalizedRankingRequest = {
campaignArn: 'arn:aws:personalize:ap-northeast-1:372284591230:campaign/ranking',
inputList: [
'999', '565', '1', '20', '34', '50', '1234', '987654'
],
userId: '1'
}
client.getPersonalizedRanking(params).promise()
.then(data => console.log(data))
.catch(e => console.log(e))
レスポンスでは、item_idを1位から順に並び替えたリストが返ってきます。
{ personalizedRanking:
[ { itemId: '1' },
{ itemId: '1234' },
{ itemId: '20' },
{ itemId: '50' },
{ itemId: '34' },
{ itemId: '999' },
{ itemId: '565' },
{ itemId: '987654' } ] }
終わりに
おそらく他の言語でもクラスやメソッド名はほぼ同じじゃないかなと思います。
WordPressで使う場合だと、get_posts()
の戻り値をgetPersonalizeRankinしてやればよさそうです。
多分こんな感じのコードでいけるはず。動かしてないので普通にSyntaxErrorとかでると思いますが。
<?php
require 'vendor/autoload.php';
use Aws\PersonalizeRuntime\PersonalizeRuntimeClient;
// get user id
$user = wp_get_current_user();
$user_id = $user->ID;
// get post ids
$posts = get_posts( $args );
$input_list = [];
foreach( $posts as $post ) {
$input_list[] = $post->ID;
}
// Instantiate an Amazon S3 client.
$client = new PersonalizeRuntimeClient([
'version' => 'latest',
'region' => 'us-west-2'
]);
$result = $client->getPersonalizedRanking([
'campaignArn' => '<string>',
'inputList' => $input_list,
'userId' => $user_id,
]);