1

Mahout で事前に計算されたアイテム間の類似性でパフォーマンスの問題が発生しています。

400 万人のユーザーがほぼ同じ量のアイテムを持っており、約 1 億のユーザー アイテムの好みがあります。ドキュメントの TF-IDF ベクトルのコサイン類似度に基づいて、コンテンツ ベースのレコメンデーションを行いたいと考えています。これをオンザフライで計算するのは遅いため、次のように、最も類似した上位 50 のドキュメントのペアごとの類似性を事前に計算しました。

  1. 以前seq2sparseは TF-IDF ベクターを作成していました。
  2. 以前mahout rowIdは mahout マトリックスを作成していました
  3. 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 のファイルがロードされました。ファイルはIntWritableVectorWritablehashMap キー値を使用してシリアル化され、ItemItemSimilarityマトリックス内のすべてのベクトル値に対してキーを繰り返さなければならないことはわかっていますが、これは少し多すぎると思いませんか?

前もって感謝します。

4

1 に答える 1

2

事前計算された値の Collection を使用して推奨事項を計算するのに必要な時間について、私は訂正します。どうやらlong startTime = System.nanoTime();、 の前ではなく、コードの一番上に を置いたようList<RecommendedItem> recommendations = cachingRecommender.recommend(userID, howMany);です。これにより、データセットと事前計算されたアイテム間の類似性をメイン メモリにロードするのに必要な時間がカウントされました。

しかし、私はメモリ消費の背後に立っています。カスタムを使用し、事前に計算された類似度のItemSimilaritya をロードして改善しました。HashMap<Long, HashMap<Long, Double>必要なスペースを削減するために、trove ライブラリを使用しました。

詳細コードはこちら。カスタム ItemSimilarity:

public class TextItemSimilarity implements ItemSimilarity{

    private TLongObjectHashMap<TLongDoubleHashMap> correlationMatrix;

    public WikiTextItemSimilarity(TLongObjectHashMap<TLongDoubleHashMap> correlationMatrix){
        this.correlationMatrix = correlationMatrix;
    }

    @Override
    public void refresh(Collection<Refreshable> alreadyRefreshed) {
    }

    @Override
    public double itemSimilarity(long itemID1, long itemID2) throws TasteException {
        TLongDoubleHashMap similarToItemId1 = correlationMatrix.get(itemID1);   
        if(similarToItemId1 != null && !similarToItemId1.isEmpty() &&  similarToItemId1.contains(itemID2)){
            return similarToItemId1.get(itemID2);
        }   
        return 0;
    }
    @Override
    public double[] itemSimilarities(long itemID1, long[] itemID2s) throws TasteException {
        double[] result = new double[itemID2s.length];
        for (int i = 0; i < itemID2s.length; i++) {
            result[i] = itemSimilarity(itemID1, itemID2s[i]);
        }
        return result;
    }
    @Override
    public long[] allSimilarItemIDs(long itemID) throws TasteException {
        return correlationMatrix.get(itemID).keys();
    }
}

使用しているデータ セットを合わせた総メモリ消費量Collection<GenericItemSimilarity.ItemItemSimilarity>は 30GB で、使用時TLongObjectHashMap<TLongDoubleHashMap>とカスタムTextItemSimilarityの場合、必要なスペースは 17GB です。タイム性能は を使用して0.05秒、 を使用しCollection<GenericItemSimilarity.ItemItemSimilarity>て0.07秒TLongObjectHashMap<TLongDoubleHashMap>です。また、パフォーマンスに大きな役割を果たしていると信じていCandidateItemsStrategyますMostSimilarItemsCandidateItemsStrategy

スペースを節約したい場合は trove HashMap を使用し、パフォーマンスを少しだけ向上させたい場合はCollection<GenericItemSimilarity.ItemItemSimilarity>.

于 2013-09-06T13:46:47.897 に答える