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,
    ]);

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark