[英]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.