Amazon Web Services ブログ

Amazon SageMaker の因数分解機械アルゴリズムを拡張し、レコメンデーション上位 x 件を予測しています。

Amazon SageMaker により、機械学習ワークロードで複雑なビジネス上の問題に対応するために必要な柔軟性が向上します。組み込みアルゴリズムを使用すると、すぐに開始できます。 このブログ記事では、組み込みの因数分解機アルゴリズムを拡張してレコメンデーション上位 x 件を予測する方法について、概説します。

この手法は、ユーザーに対し一定数のレコメンデーションをバッチ処理で生成する場合に最適です。例えば、この手法を使用して、ユーザーと製品購入に関する大量の情報から、あるユーザーが購入しそうな上位 20 製品を生成することができます。その後、将来的にダッシュボードへの表示やパーソナライズメールマーケティングなどで利用するため、このレコメンデーションをデータベースに保存できます。AWS Batch または AWS Step Functions を使用して、このブログで概説する手順を自動化し、定期的な再トレーニングや予測を行うこともできます。

因数分解機は、汎用教師あり学習アルゴリズムで、分類と回帰の両方のタスクに使用できます。このアルゴリズムは、レコメンデーションシステムのエンジンとして設計されました。このアルゴリズムでは、二次係数を低ランク構造に制限しながら、特徴について二次関数を学習することで協調フィルタリング手法を拡張します。この制限は、過学習を避け、また非常にスケーラブルであるため、大きな疎データによく適してします。これにより、入力特徴が何百万である一般的なレコメンデーションの問題に対するパラメーターが、何兆とあるのではなく、何百万となるようにします。

因数分解機のモデル方程式は、つぎのように定義されます。

次のようなモデルパラメータが推定されます。

ここでは、n は入力サイズ、k は潜在空間のサイズです。これらの推定されるモデルパラメータを使用して、モデルを拡張します。

モデルの拡張

Amazon SageMaker の因数分解機アルゴリズムを使うことにより、ユーザーと項目のようなペアについて、これらが合致する程度に基づき、そのペアのスコアを予測できます。レコメンデーションモデルの適用時、ユーザーを入力すると、そのユーザーの好みに合致する上位 x 件の項目リストを返すようにしたい場合がよくあります。アイテム数が多くなければ、可能性のあるアイテムすべてに対しユーザーと項目のモデルをクエリすることができます。ただし、この手法では項目数が多くなるとうまくスケールできません。このシナリオでは、Amazon SageMaker k 近傍法 (k-NN) アルゴリズムを使用して、上位 x 件の予測タスクを高速化できます。

以下の図は、このブログ記事で扱う手順のおおまかな概要を示しています。これには、因数分解機モデルの構築、モデルデータの再パッケージ化、k-NN モデルのフィッティング、および上位 x 件予測の作成が含まれます。

先に進めるため、手引きとなる Jupyter ノートブック をダウンロードすることもできます。以下の各セクションは、このノートブックのセクションと対応していますので、読みながら各ステップのコードを実行できます。

ステップ 1: 因数分解機モデルの構築

手引きとなる Jupyter ノートブックのパート 1 で、因数分解機モデルの構築手順を確認します。因数分解機モデルの構築に関する詳細は、因数分解機アルゴリズムのドキュメントを参照してください。

ステップ 2: モデルデータの再パッケージ化

Amazon SageMaker 因数分解機アルゴリズムでは、Apache MXNet 深層学習フレームワークを活用します。このセクションでは、MXNet を使用してモデルデータを再パッケージ化する方法を扱います。 

因数分解機モデルの抽出

まず、因数分解モデルをダウンロードしてから、解凍し、MXNet オブジェクトを作成します。MXNet オブジェクトの主要目的は、モデルデータの抽出です。

#Download FM model 
os.system('aws s3 cp '+{Model location} + './')

#Extract files from the model.Note: the companion notebook outlines the extraction steps.

モデルデータの抽出

因数分解機モデルには、ベクトルのリスト xu + xi を入力します。これは、映画のユーザー評価など、ラベルで結びつけられたユーザー u と項目 i を表します。結果として生じる入力行列には、ユーザー、項目、ならびに追加する必要があるその他の特徴についての、ホットエンコードされた疎な値が含まれます。

因数分解機モデルの出力は、3 つの n 次元配列で構成されます。

  • V – (N x k) 行列であり、ここでは
    • k は潜在空間のディメンション
    • N はユーザーと項目の総数
  • w – N 次元ベクトル
  • b – 単一の数字: バイアス項

下記のステップを完了して、MXNet オブジェクトの出力するモデルを抽出します。

#Extract model data
m = mx.module.Module.load('./model', 0, False, label_names=['out_label'])
V = m._arg_params['v'].asnumpy()
w = m._arg_params['w1_weight'].asnumpy()
b = m._arg_params['w0_weight'].asnumpy()

k-NN モデルを構築するためのデータの準備

因数分解機モデルから抽出したモデルデータを再パッケージ化して、k-NN モデルを構築できるようになりました。このプロセスでは、次の 2 つのデータセットを作成します。

  • 項目潜在行列 – k-NN モデルの構築用
  • ユーザー潜在行列 – 推論用
nb_users = <num users>
nb_movies = <num items>

# item latent matrix - concat(V[i], w[i]). 
knn_item_matrix = np.concatenate((V[nb_users:], w[nb_users:]), axis=1)
knn_train_label = np.arange(1,nb_movies+1)

#user latent matrix - concat (V[u], 1) 
ones = np.ones(nb_users).reshape((nb_users, 1))
knn_user_matrix = np.concatenate((V[:nb_users], ones), axis=1)

ステップ 3: k-NN モデルの適合

Amazon SageMaker で k-NN モデルを使用できるように、k-NN モデルの入力データの Amazon S3 へのアップロード、k-NN モデルの作成、保存が可能になりました。また、このモデルは、以降のステップで説明するとおり、バッチ変換を呼び出すのに役に立ちます。

k-NN モデルはデフォルトの index_type (faiss.Flat) を使用します。 このモデルは正確ですが、大量のデータセットの場合は遅くなる可能性があります。そのような場合には、異なる index_type パラメータを近似のより速い応答に使用してもかまいません。インデックスタイプの詳細については、k-NN documentation またはこの Amazon Sagemaker Examples notebook のどらかを参照してください。

#upload data
knn_train_data_path = writeDatasetToProtobuf(knn_item_matrix, bucket, knn_prefix, train_key, "dense", knn_train_label)

# set up the estimator
nb_recommendations = 100
knn = sagemaker.estimator.Estimator(get_image_uri(boto3.Session().region_name, "knn"),
    get_execution_role(),
    train_instance_count=1,
    train_instance_type=instance_type,
    output_path=knn_output_prefix,
    sagemaker_session=sagemaker.Session())

#set up hyperparameters
knn.set_hyperparameters(feature_dim=knn_item_matrix.shape[1], k=nb_recommendations, index_metric="INNER_PRODUCT", predictor_type='classifier', sample_size=nb_movies)
fit_input = {'train': knn_train_data_path}
knn.fit(fit_input)
knn_model_name =  knn.latest_training_job.job_name
print "created model: ", knn_model_name

# save the model so that you can reference it in the next step during batch inference
sm = boto3.client(service_name='sagemaker')
primary_container = {
    'Image': knn.image_name,
    'ModelDataUrl': knn.model_data,
}
knn_model = sm.create_model(
        ModelName = knn.latest_training_job.job_name,
        ExecutionRoleArn = knn.role,
        PrimaryContainer = primary_container)

ステップ 4: すべてのユーザーに対してレコメンデーション上位 x 件の予測

Amazon SageMaker のバッチ変換機能により、大規模なバッチ予測が可能です。この例として、ユーザー推定の入力データを Amazon S3 にアップロードすることから始めます。それから、バッチ変換をトリガーします。

#upload inference data to S3
knn_batch_data_path = writeDatasetToProtobuf(knn_user_matrix, bucket, knn_prefix, train_key, "dense")
print "Batch inference data path: ",knn_batch_data_path

# Initialize the transformer object
transformer =sagemaker.transformer.Transformer(
    base_transform_job_name="knn",
    model_name=knn_model_name,
    instance_count=1,
    instance_type=instance_type,
    output_path=knn_output_prefix,
    accept="application/jsonlines; verbose=true"
)

# Start a transform job:
transformer.transform(knn_batch_data_path, content_type='application/x-recordio-protobuf')
transformer.wait()

# Download output file from s3
s3_client.download_file(bucket, inference_output_file, results_file_name)

出力されたファイルにはすべてのユーザーに対する予測が記載されています。出力ファイルの各行の項目は JSON 行で、特定ユーザーの ID と距離が記載されています。

以下はユーザーの出力例です。推奨映画の ID をさらに活用するためにデータベースに保存できます。

Recommended movie IDs for user #1 : [509, 1007, 96, 210, 208, 505, 268, 429, 182, 189, 57, 132, 482, 165, 615, 527, 196, 269, 528, 83, 176, 166, 194, 520, 661, 246, 180, 659, 496, 173, 9, 435, 474, 192, 493, 48, 211, 656, 489, 181, 251, 124, 89, 510, 22, 183, 316, 185, 197, 23, 170, 168, 963, 190, 1039, 56, 79, 136, 519, 651, 484, 275, 654, 641, 523, 478, 302, 223, 313, 187, 1142, 134, 100, 498, 272, 285, 191, 515, 408, 178, 199, 114, 480, 603, 172, 169, 174, 427, 513, 657, 318, 357, 511, 12, 50, 127, 479, 98, 64, 483]

Movie distances for user #1 : [1.8703, 1.8852, 1.8933, 1.905, 1.9166, 1.9185, 1.9206, 1.9239, 1.928, 1.9304, 1.9411, 1.9452, 1.947, 1.9528, 1.963, 1.975, 1.9985, 2.0117, 2.0205, 2.0211, 2.0227, 2.0583, 2.0959, 2.0986, 2.1064, 2.1126, 2.1157, 2.119, 2.1208, 2.124, 2.1349, 2.1356, 2.1413, 2.1423, 2.1521, 2.1577, 2.1618, 2.176, 2.1819, 2.1879, 2.1925, 2.2463, 2.2565, 2.2654, 2.2979, 2.3289, 2.3366, 2.3398, 2.3617, 2.3654, 2.3855, 2.386, 2.3867, 2.4198, 2.4431, 2.46, 2.462, 2.4643, 2.4729, 2.4959, 2.5334, 2.5359, 2.5362, 2.542, 2.5428, 2.5934, 2.5953, 2.598, 2.6575, 2.6735, 2.6879, 2.7038, 2.7259, 2.7432, 2.8112, 2.8707, 2.871, 2.9378, 2.9728, 3.0175, 3.0231, 3.0254, 3.0259, 3.0325, 3.0414, 3.1033, 3.2729, 3.3406, 3.392, 3.3982, 3.4196, 3.4452, 3.4684, 3.4743, 3.6265, 3.7013, 3.7711, 3.7736, 3.8898, 4.0698]

複数の機能とカテゴリのシナリオ

このブログのフレームワークは、ユーザーと項目 ID を使用したシナリオに適用されます。ただし、データには、ユーザーや項目の機能など、追加の情報が含まれる可能性があります。たとえば、ユーザーの年齢、郵便番号、性別が分かっているかもしれません。項目については、カテゴリ、映画ジャンル、テキストの説明にある重要なキーワードが分かっているかもしれません。これらの複数の機能とカテゴリシナリオでは、以下を使用して、ユーザーと項目ベクターを抽出します。

  • ユーザーとユーザー機能を使用して xi をエンコード:
    ai =concat(VT · xi , wT · xi)
  • 項目と項目機能を使用して xu をエンコード:
    au =concat(VT · xu, 1)

それから、ai を使用して、推定するために k-NN モデルと au を構築します。

結論

Amazon SageMaker は開発者とデータサイエンティストに機械学習モデルを迅速に構築、トレーニング、デプロイするための柔軟性を与えます。上記のフレームワークを使用することで、バッチ方式でユーザーに対してレコメンデーション上位 x 件を予測するための推奨システムを構築でき、データベースに出力をキャッシュできます。場合によっては、予測に対してさらにフィルタリングをする必要があるかもしれません。つまり、ユーザー応答に基づいていくつかの予測を随時フィルターをし、取り除く必要がある場合があります。このフレームワークは柔軟性が十分高いので、そのようなユースケースに合わせて修正もできます。


著者について

Zohar Karnin は Amazon AI の主任科学者です。彼の対象とする研究分野は、大規模なオンライン機械学習アルゴリズムです。彼は Amazon SageMaker 用に無制限に拡張可能な機械学習アルゴリズムを開発しています。

 

 

 

 

Rama Thamman はシニアソリューションアーキテクトで、戦略的アカウントチームの一員です。彼は顧客と協業して、スケーラブルなクラウドと AWS ついての機械学習ソリューションを構築しています。