Mahout で事前に計算されたアイテム間の類似性でパフォーマンスの問題が発生しています。
400 万人のユーザーがほぼ同じ量のアイテムを持っており、約 1 億のユーザー アイテムの好みがあります。ドキュメントの TF-IDF ベクトルのコサイン類似度に基づいて、コンテンツ ベースのレコメンデーションを行いたいと考えています。これをオンザフライで計算するのは遅いため、次のように、最も類似した上位 50 のドキュメントのペアごとの類似性を事前に計算しました。
- 以前
seq2sparse
は TF-IDF ベクターを作成していました。 - 以前
mahout rowId
は mahout マトリックスを作成していました - mahout を使用
rowSimilarity -i INPUT/matrix -o OUTPUT -r 4587604 --similarityClassname SIMILARITY_COSINE -m 50 -ess
して、最も類似した上位 50 の文書を作成しました
Hadoop を使用して、これらすべてを事前計算しました。400 万アイテムの場合、出力はわずか 2.5 GB でした。
次に、レデューサーによって生成されたファイルのコンテンツを をCollection<GenericItemSimilarity.ItemItemSimilarity> corrMatrix = ...
使用して読み込みdocIndex
、ドキュメントの ID をデコードしました。それらはすでに整数でしたが、rowId は 1 からデコードしたので、元に戻さなければなりません。
推奨事項として、次のコードを使用します。
ItemSimilarity similarity = new GenericItemSimilarity(correlationMatrix);
CandidateItemsStrategy candidateItemsStrategy = new SamplingCandidateItemsStrategy(1, 1, 1, model.getNumUsers(), model.getNumItems());
MostSimilarItemsCandidateItemsStrategy mostSimilarItemsCandidateItemsStrategy = new SamplingCandidateItemsStrategy(1, 1, 1, model.getNumUsers(), model.getNumItems());
Recommender recommender = new GenericItemBasedRecommender(model, similarity, candidateItemsStrategy, mostSimilarItemsCandidateItemsStrategy);
限られたデータ モデル (160 万アイテム) で試していますが、すべてのアイテム間の類似性をメモリにロードしました。40GBを使用してメインメモリにすべてをロードすることに成功しました。
一人のユーザーにレコメンドしたい時
Recommender cachingRecommender = new CachingRecommender(recommender);
List<RecommendedItem> recommendations = cachingRecommender.recommend(userID, howMany);
レコメンデーション プロセスの経過時間は554.938583083
数秒であり、レコメンデーションは生成されませんでした。今、私は推薦のパフォーマンスについて本当に心配しています. CandidateItemsStrategy
との数字で遊んでみましたがMostSimilarItemsCandidateItemsStrategy
、パフォーマンスの向上は見られませんでした。
レコメンデーション プロセスを高速化するために想定されるすべてを事前計算するという考えではありませんか? 誰かが私を助けて、どこが間違っているのか、何が間違っているのか教えてください。また、パーワイズの類似性をメイン メモリにロードすると、指数関数的に爆発するのはなぜですか? Collection<GenericItemSimilarity.ItemItemSimilarity>
mahout matrix?では、40GB のメイン メモリに 2.5GB のファイルがロードされました。ファイルはIntWritable
、VectorWritable
hashMap キー値を使用してシリアル化され、ItemItemSimilarity
マトリックス内のすべてのベクトル値に対してキーを繰り返さなければならないことはわかっていますが、これは少し多すぎると思いませんか?
前もって感謝します。