PersonalizeのAutoML機能を使ったレシピの自動選択を試してみた

2020.03.04

Personalizeでは過去のユーザの行動によるアイテムとのインタラクションデータを元にしたレコメンドが可能です。 ソリューションを作成するにあたり、データや目的に応じたレシピを選択する必要がありますが、AutoMLを用いることでデータに応じて適切なUSER_PERSONALIZATION用のレシピを自動的に選択してくれます。今回はこのAutoML機能を試してみます。

やってみる

コールドスタート用のサンプルノートブックで作成したデータセットグループとデータセットをそのまま用いて、AutoML機能を試してみます。

  • データセット: MovieLens 1M Dataset | GroupLens
  • スキーマ
    • Interactions: USER_ID, ITEM_ID, EVENT_VALUE, TIMESTAMP, EVENT_TYPE
    • Items: ITEM_ID, GENRE
  • 対象レシピ: HRNN-Coldstart
  • やること
    • ソリューション作成
    • ソリューションバージョン作成
    • ソリューションやソリューションバージョンの結果の確認

ソリューション作成

まずはライブラリ/モジュールを読み込み、作成済みのデータセットグループのARNを指定します。

import boto3
import pandas as pd
personalize = boto3.Session().client('personalize')
dataset_group_arn = 'arn:aws:personalize:ap-northeast-1:123456789:dataset-group/DEMO-temporal-metadata-dataset-group-15107' # データセット等がすでに作成ずみのデータセットグループ

AutoMLを有効化し、対象のレシピと用いる評価指標を指定して、ソリューションを作成します。 対象のレシピを指定しない場合にはHRNNが指定されます。評価指標を指定しない場合はprecision_at_25が指定されます。 今回は対象レシピとしてHRNNHRNN-MetadataHRNN-Coldstartを指定し、評価指標としてnormalized_discounted_cumulative_gain_at_5を指定します。

response = personalize.create_solution(
    name='automl-test',
    datasetGroupArn=dataset_group_arn,
    performAutoML=True,
    event_type=''
    solutionConfig={
        'autoMLConfig': {
            'metricName': 'normalized_discounted_cumulative_gain_at_5',
            'recipeList': [
                'arn:aws:personalize:::recipe/aws-hrnn',
                'arn:aws:personalize:::recipe/aws-hrnn-coldstart',
                'arn:aws:personalize:::recipe/aws-hrnn-metadata'
            ]
        }
    }
)
solution_arn = response['solutionArn']

マネジメントコンソールの場合

マネジメントコンソールからもAutoMLを用いたソリューションを作成できます。マネジメントコンソールの場合、比較対象のレシピとしてHRNN-Coldstartは選択することができないようです。評価指標も選択できないため、自動的にprecision_at_25が用いられます。

ソリューションバージョン作成

ソリューションバージョンを作成します。ソリューションバージョンを1つ作成することで、元となるソリューションバージョンと指定したレシピそれぞれのソリューションバージョンが自動的に作成されます。レシピごとのソリューションバージョンでは、自動的にハイパーパラメータ最適化(HPO)が実行されます。

response = personalize.create_solution_version(
    solutionArn=solution_arn
)

今回の場合だと一時間ちょっとくらいでジョブが完了しました。

結果の確認

ジョブが完了したら、ソリューションやソリューションバージョンの情報を確認してみます。 まずは、ソリューションについて確認してみます。

personalize.describe_solution(solutionArn=solution_arn)

autoMLResultにautoMLの結果、最も良かったレシピが記載されています。今回の場合だと、HRNNになっています。

続いて、各ソリューションバージョンとそれぞれの評価指標を確認します。

solution_versions = personalize.list_solution_versions(solutionArn=solution_arn)['solutionVersions']
solution_versions = sorted(solution_versions, key=lambda x: x['creationDateTime'])
solution_version_arns = [x['solutionVersionArn'] for x in solution_versions]
metrics_data = {}
solution_versions_data = {}
for solution_version_arn in solution_version_arns:
    version = solution_version_arn.split('/')[-1]
    solution_version = personalize.describe_solution_version(solutionVersionArn=solution_version_arn)['solutionVersion']
    solution_versions_data[version] = solution_version
    
    recipe = solution_version['recipeArn'].split('/')[-1]
    response = personalize.get_solution_metrics(solutionVersionArn=solution_version_arn)
    metrics_data[recipe] = response['metrics']

solution_versions_df = pd.DataFrame.from_dict(solution_versions_data, orient='index')
metrics_df = pd.DataFrame.from_dict(metrics_data, orient='index')

評価指標をみてみます。

metrics_df

多くの指標においてHRNNが最も高く、HRNN-Coldstartが最も低くなっています。HRNN-Coldstartが他と比べて圧倒的に低くなっているのは、ユーザとのインタラクション数が少ないコールドアイテムをレコメンドに含めようとする、レシピの特性によるものだと思われます。

各ソリューションバージョンを確認します。

solution_versions_df = pd.DataFrame.from_dict(solution_versions_data, orient='index')

1つのソリューションバージョンにはソリューション情報が記載されており、それ以外のソリューションバージョンにはソリューション情報が記載されていません。これはAutoMLジョブの元となるソリューションバージョンと実際に各レシピに基づいてHPOを実行するソリューションバージョンの違いだと思われます。 この元となるソリューションバージョンは各レシピのソリューションバージョンの内、最も評価指標が良かったものへのエイリアスになっているようです。今回の場合だと、HRNNレシピの評価指標が良かったため、recipeArnとしてHRNNが指定されています。

また、学習に要した時間も記載されています。今回は38.16時間のようです。0.24 * 38.16 = 9.1584なので、およそ9ドルの費用がかかったことが分かります。 実際にかかった時間と差異がありますが、これは各ソリューションバージョン内で、HPOのために並列でジョブを実行しているためだと思われます。

さいごに

PersonalizeのAutoMLを試してみた内容を紹介しました。AutoMLによってデータセットに合ったレシピを知ることができ、尚且つハイパーパラメータが最適化されたソリューションバージョンも作成できます。並列実行によって、普通のレシピ実行時と大差ない実行時間で最適化されたソリューションバージョンを作成し、そのままリアルタイムレコメンドやバッチレコメンドに利用できるのは便利そうです。ただし、データセットを更新し、同じソリューションでソリューションバージョンを再作成した場合でも、指定してある各レシピに対してHPOが実行されるため、費用面で注意が必要です。また、最適化されたハイパーパラメータがどのような値かは確認できないため、その結果をもとにソリューションを作成するといったことは現在のところできなさそうです。

参考