Amazon SageMaker の因数分解機を使った、ムービーレコメンダーを構築する
レコメンドは機械学習 (ML) の中でも最も一般的なアプリケーションのひとつです。このブログ記事では、因数分解機に基づいた動画レコメンドモデルを構築する方法を紹介します。これは組み込みアルゴリズムのひとつで、Amazon SageMaker の中でもよく使われている MovieLens データセットです。
因数分解機について
因数分解機 (Factorization Machines, FM) は、2010 年に導入された教師あり機械学習技術です ( 研究論文、PDF ) 。FM は、行列因数分解を使うと問題次元数の削減が可能なことから名付けられました。。
FM は分類や回帰に使用でき、線形回帰などの従来のアルゴリズムよりも大規模な疎データセットにおいて、計算効率がより大幅に向上できます。そのため、FM がレコメンドに広く使用されているのです。実際のレコメンドの数は非常に少ないものの ( ユーザーは利用可能なアイテム全てを評価しません )、ユーザー数とアイテム数はとても多いのが普通です。
以下に簡単な例を示します。密なユーザー行列 ( 次元 4×2 ) と密なアイテム行列 (2×4) に、疎な評価行列 ( 次元 4×4) を組み込む場合です。ご覧のように、因数の数 (2) が評価行列 (4) の列数よりも小さいです。さらに、この乗算によって、評価行列の全てのブランク値を埋めることができます。これを利用して、新しいアイテムをどのユーザーにもレコメンドすることができるのです。
出典 : data-artisans.com
この記事では、FM を使用して、ムービーレコメンダーを構築します。Companion Jupyter ノートブックは Amazon S3 または Github からダウンロードできます。
MovieLens データセット
このデータセットは、レコメンド構築のはじめの一歩としてはよいでしょう。いろんなサイズがあります。このブログ記事では、1682 本の映画で 943 人のユーザーから、ml100k : 100,000 の評価を使用します。ご覧のように、ml100kの評価行列は、考えうる 1,586,126 (943*1682) のうち 100,000 の評価しかないので、非常にまばらです ( 正確に言うと、93.6%) 。
データセットの最初の 10 行は次のとおりです。 : ユーザー 754 は映画 595 に 2 つ星の評価を与えました。
ユーザー ID 数、ムービー ID、評価、タイムスタンプ754 595 2 879452073932 157 4 891250667751 100 4 889132252101 820 3 877136954606 1277 3 878148493581 475 4 87964185013505 882140001457 595 882397575111 321 3 891680076123 657 4 879872066
データセットの準備
前で説明したように、FM は高次元のデータセットで最もよく機能します。結果として、ユーザー ID とムービー ID ( タイムスタンプは無視します ) を one-hot エンコードすることになります。したがって、データセットの各サンプルは、ユーザー ID とムービー ID に対して 2 つの値のみを 1 に設定すると、2,625 ブーリアンベクトル (943+1682) になります。
バイナリ ( つまり、好きか好きでないか ) のレコメンダーを構築します。4 つ星と 5 つ星の評価は 1 に設定します。それより低い評価は 0 に設定します。
最後にもうひとつ、Amazon SageMaker の FM 実装では、トレーニングとテストデータを float32 テンソルで、protobuf 形式で保存する必要があります。( 複雑そうですよね。でも Amazon SageMaker SDK にはこうしたことをやってくれる便利なユーティリティ関数があるので、そんなに心配しなくて大丈夫です。 )
ハイレベルビュー
実装するための手順は次のとおりです。
やってみましょう。
MovieLens データセットの読み込み
ml-100k には複数のテキストファイルが含まれていますが、ここでは 2 つのファイルを使用してモデルを構築します。
どちらのファイルも同じタブ区切り形式です。
結果として、次のデータ構造を構築することになります。
確認 : 各サンプルは、単一の one-hot エンコード機能ベクトルでなければなりません。ユーザー ID、ムービー ID、および追加する可能性のある機能には、one-hot エンコードした値を連結する必要があります。異なるベクトルのリストを作成するのは (1 つはユーザー ID 用、もう 1 つはムービー ID 用など )正しいやり方ではありません。
このトレーニング行列は今のところ、よりまばらです : 237,746,250 の値 (90,570*2,625) 全てのうち、181,140 だけがゼロではありません (90,570*2) 。言い換えれば、この行列は 99.92% の疎行列です。これを密度が高い行列として保存すると、ストレージとコンピューティング能力を大量に浪費することになります。
これを避けるには、サンプルには scipy.lil_matrix 疎行列、ラベルには Numpy 配列を使います。
クラスあたりのサンプル数がほぼ同じであることを確認しましょう。不均衡なデータセットは、分類子にとって深刻な問題となります。
print(np.count_nonzero(Y_train)/nbRatingsTrain)0.55print(np.count_nonzero(Y_test)/nbRatingsTest)0.58
やや不均衡ですが、まあいいでしょう。次へ進みましょう。
protobuf ファイルへの書き込み
次に、トレーニングセットとテストセットを Amazon S3 に保存してある 2 つの protobuf ファイルに書き出します。幸いにも、write_spmatrix_to_sparse_tensor() ユーティリティ関数に任せることができます。サンプルとラベルを、インメモリ protobuf でエンコードした疎な多次元配列 (AKA テンソル ) に書き込みます。
その後、バッファを Amazon S3 にコミットします。このステップが完了したら、データ準備は完了です。今からトレーニングジョブに取り組みます。
トレーニングのためのトラブルシューティングのヒント
注 : 最新の Amazon SageMaker SDK へのアップグレード
source activate python2pip install -U sagemaker
Amazon S3 でのトレーニングセットは以下の通りです。: 5.5MB 疎行列だけなんて、最高 !
$ aws s3 ls s3://jsimon-sagemaker-us/sagemaker/fm-movielens/train/train.protobuf2018-01-28 16:50:29 5796480 train.protobuf
トレーニングジョブの実行
AWS リージョンで利用可能な FM コンテナを基にしたエスティメーターをまず作成します。それから、FM 特有のハイパーパラメータ ( 全リストはドキュメントの中にあります。 ) をいくつか設定する必要があります。 :
ここで使用している他のものは、オプションです ( 説明も必要ないでしょう ) 。
最後に、トレーニングジョブを実行しましょう。fit() API の呼び出しに必要なことは、Amazon S3 でホストするトレーニングとテストセットの両方を通過するだけです。シンプルかつレガントですね。
数分で、トレーニングは完了です。トレーニングログは Jupyter ノートブックか Amazon CloudWatch Logs のどちらかにあるのでチェックしてください。(/ aws / sagemaker / trainingjobs ロググループの中です ) 。
50 エポック後の検査精度は 71.5% で、F1 値 ( バイナリ分類子の典型的なメトリック ) は 0.75 (1 は完全な分類子を示します) となります。すごい値ではありませんが、疎行列と protobuf で興奮したので、ハイパーパラメータをそれほど調整することはしませんでした。もちろん、今回の例より優れた方法で行うことは可能です。
[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : binary_classification_accuracy[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : 0.7159[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : binary_classification_cross_entropy[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : 0.581087609863[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : binary_f_1.000[01/29/2018 13:42:41 INFO 140015814588224] #test_score (algo-1) : 0.74558968389
最後に、モデルのデプロイをカバーします。
モデルのデプロイ
モデルのデプロイに必要なのは、単純な API コールのみです。その昔 (6 か月ほど前 ) には、AWS でもかなりの作業が必要でした。ここでは deploy() を呼び出すだけです。
モデルの HTTP エンドポイントを、predict() API のおかげで、呼び出す準備が整いました。リクエストとレスポンスデータの両方のフォーマットは JSON です。このため、単純なシリアライザを用意して、疎行列サンプルを JSON に変換する必要があります。
これで、どのユーザーのどんな映画でも分類できます。新しいデータセットを作成して、トレーニングおよびテストセットと同じ方法でそれを処理し、predict() 使用して結果を得ます。また、さまざまな予測閾値 ( あるスコアより上の 1 に予測を設定し、その下に 0 を設定する ) を試して、最も効果的なレコメンドをもたらす値を確認してください。MovieLens のデータセットには映画のタイトルも含まれているため、もっといろいろと試してみることができます。
まとめ
組み込みアルゴリズムは、トレーニングコードを書く必要がなく、すばやく作業を完了するのに優れた方法です。かなりのデータ準備が必要ですが、このブログの記事で見たように、非常に大規模なトレーニングジョブを迅速かつスケーラブルにできるところがポイントです。
Amazon SageMaker の組み込みアルゴリズムに関して他にも興味があれば、こちらが過去の関連記事です。:
レコメンドシステムについて、もっと詳しく知りたい方のために、下記にいくつかおもしろいリソースを載せておきます。
いつも、読んでいただきありがとうございます。Twitter で、喜んで質問にお答えします。
AWS の同僚たちが素晴らしいアドバイスとデバッグのヒントをくれました。Sireesha Muppala、Yuri Astashanok、David Arpin、そして Guy Ernest、どうもありがとう。
Julien は EMEA の人工知能およびMachine Learning のエバンジェリストです。彼は、開発者や企業のアイデアを実現させるための支援を中心として活動しています。彼は余暇時間に、JRR Tolkien の作品を何度も読んでいます。