[英]Mahout: Using two DataModels in one Recommender
我正在嘗試使用兩組布爾偏好數據創建一個簡單的推薦引擎。 我想使用一個數據集來計算UserSimilarity和UserNeighborhoods,然后使用這些鄰域從第二組布爾偏好數據中提出建議。
我似乎正在工作,但是問題是,當我去計算推薦時,如果用戶基於第一個數據集有鄰居,但是在第二個數據集中不存在(盡管他們的鄰居在),則不會產生推薦。
這是RecommendationBuilder代碼:
recommenderBuilder = new RecommenderBuilder() {
public Recommender buildRecommender(DataModel recommendationModel) throws TasteException {
UserSimilarity similarity = new LogLikelihoodSimilarity(trainingModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, 0.7, similarity, recommendationModel);
return new GenericBooleanPrefUserBasedRecommender(recommendationModel, neighborhood, similarity);
}
};
這是trainingModel文件的示例
1,111
2,222
2,111
2,222
3,111
3,222
和commitmentModel文件
1,91
1,92
2,91
建議為用戶2運行92,但是在到達用戶3時拋出NoSuchUserException
。
Sol ...是否有任何方法可以根據在另一個數據集上計算出的相似性從一個數據集生成推薦,而無需讓所有用戶都出現在第二個數據集中?
這是我現在正在使用的完整代碼:
private DataModel trainingModel;
private DataModel recommendationModel;
private RecommenderEvaluator evaluator;
private RecommenderIRStatsEvaluator evaluator2;
private RecommenderBuilder recommenderBuilder;
private DataModelBuilder modelBuilder;
@Override
public void afterPropertiesSet() throws IOException, TasteException {
trainingModel = new GenericBooleanPrefDataModel(
GenericBooleanPrefDataModel.toDataMap(new FileDataModel(new File("/music.csv")))
);
recommendationModel = new GenericBooleanPrefDataModel(
GenericBooleanPrefDataModel.toDataMap(new FileDataModel(new File("/movies.csv")))
);
evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
evaluator2 = new GenericRecommenderIRStatsEvaluator();
recommenderBuilder = new RecommenderBuilder() {
public Recommender buildRecommender(DataModel model) throws TasteException {
UserSimilarity similarity = new LogLikelihoodSimilarity(trainingModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, 0.7, similarity, model);
return new GenericBooleanPrefUserBasedRecommender(model, neighborhood, similarity);
}
};
modelBuilder = new DataModelBuilder() {
public DataModel buildDataModel( FastByIDMap<PreferenceArray> trainingData ) {
return new GenericBooleanPrefDataModel( GenericBooleanPrefDataModel.toDataMap(trainingData) );
}
};
}
然后運行此方法
@Override
public void testData() throws TasteException {
double score = evaluator.evaluate(recommenderBuilder, modelBuilder, trainingModel, 0.9, 1.0);
System.out.println("calculated score: " + score);
try {
IRStatistics stats = evaluator2.evaluate(
recommenderBuilder, modelBuilder, trainingModel, null, 2,
0.0,
1.0
);
System.out.println("recall: " + stats.getRecall());
System.out.println("precision: " + stats.getPrecision());
} catch (Throwable t) {
System.out.println("throwing " + t);
}
List<RecommendedItem> recommendations = recommenderBuilder.buildRecommender(recommendationModel).recommend(1,2);
System.out.println("user 1");
for (RecommendedItem recommendation : recommendations) { System.out.println(recommendation);}
recommendations = recommenderBuilder.buildRecommender(recommendationModel).recommend(2,2);
System.out.println("user 2");
for (RecommendedItem recommendation : recommendations) { System.out.println(recommendation);}
try {
recommendations = recommenderBuilder.buildRecommender(recommendationModel).recommend(3,2);
System.out.println("user 3");
for (RecommendedItem recommendation : recommendations) { System.out.println(recommendation);}
} catch (Throwable t) {
System.out.println("throwing " + t);
}
}
產生以下輸出:
計算得分:0.7033357620239258召回:1.0精度:1.0用戶1用戶2 RecommendationItem [item:9222,值:0.8516679]拋出org.apache.mahout.cf.taste.common.NoSuchUserException:3
您可以做您正在描述的事情,以及大致如何描述它。 支持用戶相似性度量的數據集的確可能與提出建議的數據集不同。 用戶相似性指標實際上可以基於您喜歡的任何內容。
但是,它確實需要能夠對用於提出建議的數據集中的任何一對產生用戶-用戶相似性。 我建議您在UserSimilarity
實現中對此進行特殊處理,以在一個用戶未知時返回0或類似的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.