1

Mahout は、コンテンツ間の類似性を判断する方法を提供しますか?

Web アプリケーションの一部としてコンテンツ ベースのレコメンデーションを作成したいと考えています。Mahout がユーザー評価マトリックスを取得し、それに基づいてレコメンデーションを作成するのが得意であることは知っていますが、共同 (評価ベースの) レコメンデーションには興味がありません。2 つのテキストがどの程度一致しているかをスコア化し、ユーザー プロファイルにユーザー用に保存したテキストに最もよく一致するアイテムを推奨したいと考えています。

Mahout のドキュメントを読みましたが、主に共同 (評価ベース) の推奨事項を促進しているように見えますが、コンテンツベースの推奨事項は促進していないようです... これは本当ですか?

4

1 に答える 1

10

それは完全に真実ではありません。Mahout にはコンテンツ ベースのレコメンダーはありませんが、コンテンツに基づいてアイテム間の類似性を計算するためのアルゴリズムがあります。最も人気のあるものの 1 つは、TF-IDF とコサイン類似度です。ただし、計算はオンザフライではなく、オフラインで行われます。コンテンツに基づいてペアごとの類似性をより高速に計算するには、hadoop が必要です。これから書く手順は MAHOUT 0.8 用です。0.9で変更されたかどうかはわかりません。

ステップ 1. テキスト ドキュメントを seq ファイルに変換する必要があります。MAHOUT-0.8 ではこのコマンドを失いましたが、0.9 では次のようになります (MAHOUT のバージョンを確認してください)。

$MAHOUT_HOME/bin/mahout seqdirectory
--input <PARENT DIR WHERE DOCS ARE LOCATED> --output <OUTPUT DIRECTORY>
<-c <CHARSET NAME OF THE INPUT DOCUMENTS> {UTF-8|cp1252|ascii...}>
<-chunk <MAX SIZE OF EACH CHUNK in Megabytes> 64>
<-prefix <PREFIX TO ADD TO THE DOCUMENT ID>>

ステップ 2. 次のように、シーケンス ファイルをスパース ベクトルに変換する必要があります。

$MAHOUT_HOME/bin/mahout seq2sparse \
   -i <SEQ INPUT DIR> \
   -o <VECTORS OUTPUT DIR> \
   -ow -chunk 100 \
   -wt tfidf \
   -x 90 \
   -seq \
   -ml 50 \
   -md 3 \
   -n 2 \
   -nv \
   -Dmapred.map.tasks=1000 -Dmapred.reduce.tasks=1000

どこ:

  • チャンクは、ファイルのサイズです。
  • x辞書ファイルの一部と見なされる用語の最大数。-x 未満の場合は、ストップ ワードと見なされます。
  • wtは重み付けスキームです。
  • md用語が辞書ファイルの一部とみなされるドキュメントの最小数。頻度の低い用語は無視されます。
  • n Lp 空間で使用する正規化値。正規化の詳細な説明は、セクション 8.4 に記載されています。デフォルトのスキームは、重みを正規化しないことです。2 は、クラスタリングと類似度で使用している余弦距離に適しています。
  • nv を使用して名前付きベクトルを取得し、さらにデータ ファイルを検査しやすくします。

ステップ 3. ベクトルから行列を作成します。

$MAHOUT_HOME/bin/mahout rowid -i <VECTORS OUTPUT DIR>/tfidf-vectors/part-r-00000 -o <MATRIX OUTPUT DIR>

ステップ 4. 上記のマトリックスの各行について、同様のドキュメントのコレクションを作成します。これにより、コレクション内の各ドキュメントに最も類似した 50 個のドキュメントが生成されます。

 $MAHOUT_HOME/bin/mahout rowsimilarity -i <MATRIX OUTPUT DIR>/matrix -o <SIMILARITY OUTPUT DIR> -r <NUM OF COLUMNS FROM THE OUTPUT IN STEP 3> --similarityClassname SIMILARITY_COSINE -m 50 -ess -Dmapred.map.tasks=1000 -Dmapred.reduce.tasks=1000

これにより、コンテンツに基づいた上位 50 個のファイルを使用して、各アイテム間の類似性を持つファイルが生成されます。

ここで、推奨プロセスで使用するには、リソースの量に応じて、ファイルを読み取るか、データベースにロードする必要があります。を使用してメインメモリにロードしましCollection<GenericItemSimilarity.ItemItemSimilarity>た。これが私のために仕事をした2つの簡単な機能です:

public static Collection<GenericItemSimilarity.ItemItemSimilarity> correlationMatrix(final File folder, TIntLongHashMap docIndex) throws IOException{
        Collection<GenericItemSimilarity.ItemItemSimilarity> corrMatrix = 
                new ArrayList<GenericItemSimilarity.ItemItemSimilarity>();

        ItemItemSimilarity itemItemCorrelation = null;

        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(conf);

        int n=0;
        for (final File fileEntry : folder.listFiles()) {
            if (fileEntry.isFile()) {
                if(fileEntry.getName().startsWith("part-r")){

                    SequenceFile.Reader reader = new SequenceFile.Reader(fs, new Path(fileEntry.getAbsolutePath()), conf);

                    IntWritable key = new IntWritable();
                    VectorWritable value = new VectorWritable();
                    while (reader.next(key, value)) {

                        long itemID1 = docIndex.get(Integer.parseInt(key.toString()));

                        Iterator<Element> it = value.get().nonZeroes().iterator();

                        while(it.hasNext()){
                            Element next = it.next();
                            long itemID2 =  docIndex.get(next.index());
                            double similarity =  next.get();
                            //System.out.println(itemID1+ " : "+itemID2+" : "+similarity);

                            if (similarity < -1.0) {
                                similarity = -1.0;
                            } else if (similarity > 1.0) {
                                similarity = 1.0;
                            }


                            itemItemCorrelation = new GenericItemSimilarity.ItemItemSimilarity(itemID1, itemID2, similarity);

                            corrMatrix.add(itemItemCorrelation);
                        }
                    }
                    reader.close();
                    n++;
                    logger.info("File "+fileEntry.getName()+" readed ("+n+"/"+folder.listFiles().length+")");
                }
            }
        }

        return corrMatrix;
    }


public static TIntLongHashMap getDocIndex(String docIndex) throws IOException{
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(conf);

        TIntLongHashMap map = new TIntLongHashMap();
        SequenceFile.Reader docIndexReader = new SequenceFile.Reader(fs, new Path(docIndex), conf);

        IntWritable key = new IntWritable();
        Text value = new Text();
        while (docIndexReader.next(key, value)) {
            map.put(key.get(), Long.parseLong(value.toString()));
        }

        return map;
    }

最後に、推奨クラスでこれを呼び出します。

TIntLongHashMap docIndex = ItemPairwiseSimilarityUtil.getDocIndex(filename);
TLongObjectHashMap<TLongDoubleHashMap> correlationMatrix = ItemPairwiseSimilarityUtil.correlatedItems(folder, docIndex);

filenamedocIndex ファイル名はどこfolderにあり、アイテム類似性ファイルのフォルダーはどこにありますか。結局のところ、これはアイテムベースのレコメンデーションにすぎません。

これがあなたを助けることを願っています

于 2014-04-03T07:40:15.383 に答える