1. 程式人生 > >mahout評估一個簡單的推薦程式

mahout評估一個簡單的推薦程式

上一篇建立了一個簡單的推薦引擎,現在就來評估下

程式碼如下:

package test.mahout.recommendation;

import java.io.File;
import java.io.IOException;

import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.common.RandomUtils;

public class EvaluateRecommeder {
    public static void main(String[] args) throws IOException, TasteException
    {
        RandomUtils.useTestSeed();//生成可重複的結果
        DataModel model = new FileDataModel(new File("F:/mahout/mahout_test/intro.csv"));
        RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();//利用平均差值進行評估

        //RecommenderEvaluator evaluator = new RMSRecommenderEvaluator();//均方根
        RecommenderBuilder builder = new RecommenderBuilder(){//構建待評估的推薦程式

            @Override
            public Recommender buildRecommender(DataModel model)
                    throws TasteException {
                // TODO Auto-generated method stub
                UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
                UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, model);
                return new GenericUserBasedRecommender(model, neighborhood, similarity);
            }
            
        };
        /*double evaluate(RecommenderBuilder recommenderBuilder,
        DataModelBuilder dataModelBuilder,如果為空,就用預設的datamodel,除非使用了特殊的datamodel實現,需要插入到評估過程中的datamodelbuilder
        DataModel dataModel,測試的資料集
        double trainingPercentage,每一個使用者用來做訓練推薦的百分比
        double evaluationPercentage用來訓練推薦的使用者的百分比,可用於僅通過龐大資料集總的很小一部分資料來生成一個精度較低但更快的評估,希望快速測試recommender中的小更改時很有用)
        throws TasteException
        */
        //提供builder,recommender是由builder對datamodel根據百分比訓練出來的
        double score = evaluator.evaluate(builder, null, model, 0.7, 1.0);
        System.out.println(score);
    }
}

執行出來的結果如下:

十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.model.file.FileDataModel <init>
資訊: Creating FileDataModel for file F:\mahout\mahout_test\intro.csv
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.model.file.FileDataModel processFile
資訊: Reading file info...
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.model.file.FileDataModel processFile
資訊: Read lines: 21
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.model.GenericDataModel <init>
資訊: Processed 5 users
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator evaluate
資訊: Beginning evaluation using 0.7 of FileDataModel[dataFile:F:\mahout\mahout_test\intro.csv]
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.model.GenericDataModel <init>
資訊: Processed 5 users
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator getEvaluation
資訊: Beginning evaluation of 4 users
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator execute
資訊: Starting timing of 4 tasks in 2 threads
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.eval.StatsCallable call
資訊: Average time per recommendation: 0ms
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.eval.StatsCallable call
資訊: Approximate memory used: 2MB / 16MB
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.eval.StatsCallable call
資訊: Unable to recommend in 9 cases
NaN
十一月 17, 2014 3:20:42 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator evaluate
資訊: Evaluation result: NaN

輸出為NaN,由日誌可知,有9個案例都無法進行推薦。

原因可能是選取的訓練比例不合理。

故增大訓練比例的值,改為0.8 仍是NaN,

改為0.9 結果輸出:

十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.model.file.FileDataModel <init>
資訊: Creating FileDataModel for file F:\mahout\mahout_test\intro.csv
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.model.file.FileDataModel processFile
資訊: Reading file info...
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.model.file.FileDataModel processFile
資訊: Read lines: 21
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.model.GenericDataModel <init>
資訊: Processed 5 users
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator evaluate
資訊: Beginning evaluation using 0.9 of FileDataModel[dataFile:F:\mahout\mahout_test\intro.csv]
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.model.GenericDataModel <init>
資訊: Processed 5 users
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator getEvaluation
資訊: Beginning evaluation of 3 users
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator execute
資訊: Starting timing of 3 tasks in 2 threads
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.eval.StatsCallable call
資訊: Average time per recommendation: 5ms
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.eval.StatsCallable call
資訊: Approximate memory used: 2MB / 16MB
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.eval.StatsCallable call
資訊: Unable to recommend in 2 cases
十一月 17, 2014 3:37:05 下午 org.apache.mahout.cf.taste.impl.eval.AbstractDifferenceRecommenderEvaluator evaluate
資訊: Evaluation result: 1.0
1.0

即使evaluator在選擇測試資料時引入許多隨機量,結果仍然是相同的,因為RandomUtils.useTestSeed()的呼叫會強調每次選擇相同的隨機值。這僅僅是為了獲得可重複的結果而被用在這樣的示例或者單元測試中。不要在實際程式碼中這樣用。