Personalizeのコールドアイテム用レシピで増分学習を試してみた

2020.02.28

Personalizeでは、ユーザとアイテムのインタラクションデータやメタデータを元にソリューション(ソリューションバージョン)を作成し、レコメンドを行うことができます。インタラクションデータが膨大な場合にはその分、ソリューションバージョンの作成にも時間がかかるため、短い頻度でソリューションバージョンを作成し直す場合には、そのソリューションバージョンの作成時間(≒モデルの学習時間)がネックになります。

Personalizeのコールドアイテム用のレシピである、HRNN-Coldstartはデータセットの増分のみ学習が可能な増分学習に対応しています。増分学習を利用することで学習するデータ量を減らすことができるため、ソリューションバージョンの作成時間を抑えられる可能性があります。今回はその増分学習を試してみたいと思います。

概要

ソリューションバージョン作成時に、trainingMode=UPDATEを指定することで増分学習となります。

create_solution_version_response = personalize.create_solution_version(
    solutionArn = solution_arn,
    trainingMode='UPDATE'
)

マネジメントコンソールからも次のようにtrainingModeを指定できます。

注意点

  • ソリューションの増分学習は現在、HRNN-Coldstartレシピにのみ対応しています
    • HRNN-Coldstart以外のレシピを指定したソリューションでソリューションバージョンを作成する場合は、trainingModeの選択や設定内容の確認をする画面はなく、ソリューションバージョンの作成がそのまま実行されます。
  • 増分学習を利用するには、一度はtrainingMode=FULLでソリューションバージョンを作成してある必要があります。
    • trainingModeを指定しない場合はFULLになるため、未指定でソリューションバージョンを作成しても大丈夫です
  • trainingMode=FULLでソリューションバージョン作成後に一度もデータセットのインポートジョブが実行されていない場合は、trainingMode=UPDATEでソリューションバージョン作成時にエラーになります
    • trainingMode=UPDATEで一度ソリューションバージョン作成後は、データセットのインポートジョブが実行されていなくてもエラーになりません

やってみる

  • データセット: MovieLens 1M Dataset | GroupLens
  • スキーマ
    • Interactions: USER_ID, ITEM_ID, EVENT_VALUE, TIMESTAMP, EVENT_TYPE
    • Items: ITEM_ID, GENRE
  • 対象レシピ: HRNN-Coldstart
  • やること
    • データ準備やPersonalizeのセットアップ
    • trainingMode=FULLでソリューションバージョン作成
    • インタラクションデータ追加
    • trainingMode=UPDATEでソリューションバージョン作成

準備

MovieLensのデータセットをダウンロードし、Personalizeで使えるように加工&アップロードします。その後、Personalizeのデータセットグループやデータセットの作成、データセットのインポート等を行います。具体的な処理内容は省略します。詳細については以下のノートブックをご参照ください。

ソリューション作成までで、上のノートブックと違う箇所はインタラクションデータを保存する処理です。 初回のソリューションバージョン作成時と2回目で差を出すために、インタラクションデータは最新1000件を抜いて保存しておきます。

df.sort_values('TIMESTAMP')[:-1000].to_csv('interactions.csv',index=False)

ソリューション作成

コールドスタート用のレシピを指定して、ソリューションを作成します。

recipe_arn = "arn:aws:personalize:::recipe/aws-hrnn-coldstart"
create_solution_response = personalize.create_solution(
    name = "DEMO-temporal-metadata-solution-"+suffix,
    datasetGroupArn = dataset_group_arn,
    recipeArn = recipe_arn,
    solutionConfig = {
        "featureTransformationParameters" : {
            'cold_start_max_duration' : '5',
            'cold_start_relative_from' : 'latestItem',
            'cold_start_max_interactions':'15'
        }
    }
    
)

solution_arn = create_solution_response['solutionArn']

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

では、ソリューションバージョンを作成します。初回は増分学習ができないので、通常通り作成します。

create_solution_version_response = personalize.create_solution_version(
    solutionArn = solution_arn
)

完了したら、ソリューションバージョン情報を取得し、学習時間を確認してみます。

personalize.describe_solution_version(solutionVersionArn='arn:aws:personalize:ap-northeast-1:xxxxxxxxxx:solution/DEMO-temporal-metadata-solution-xxxxxx/xxxxxxx')

フルトレーニングの場合は1.452時間だったようです。

データ追加

次はデータを抜かずに保存し、データセットにインポートします。

df.to_csv('interactions.csv',index=False)
interactions_filename = 'interactions.csv'
boto3.Session().resource('s3').Bucket(bucket).Object(interactions_filename).upload_file(interactions_filename)

create_dataset_import_job_response = personalize.create_dataset_import_job(
    jobName = "DEMO-temporal-dataset-import-job-"+suffix+'2',
    datasetArn = interactions_dataset_arn,
    dataSource = {
        "dataLocation": "s3://{}/{}".format(bucket, 'interactions.csv')
    },
    roleArn = role_arn
)

ソリューションバージョン作成(増分学習)

今回はtrainingMode=UPDATEを指定して、ソリューションバージョンを作成します。

create_solution_version_response = personalize.create_solution_version(
    solutionArn = solution_arn,
    trainingMode='UPDATE'
)

ソリューションバージョンの作成が完了したら、先ほどと同様に学習時間を確認します。

personalize.describe_solution_version(solutionVersionArn='arn:aws:personalize:ap-northeast-1:xxxxxxxxxx:solution/DEMO-temporal-metadata-solution-xxxxxx/xxxxxxx')

今回は1.014時間だったようです。

さいごに

Personalizeのコールドスタート用レシピのソリューションバージョン作成における、増分学習を試してみました。今回の検証は試行回数が1回なので意味のある比較ではないですが、増分学習によって学習時間を抑えられるかもしれないということがわかりました。ただし、増分学習(trainingMode=UPDATE)とフル学習(trainingMode=FULL)の場合でレコメンド内容や傾向に差が出る可能性もあります。日次で増分学習を行い、週次でフル学習を行うなど、必要に応じて使い分けるのが良さそうです。

参考