Java Mahout:在一个推荐程序中使用两个数据模型
我正试图用两组布尔偏好数据创建一个简单的推荐引擎。我想使用一个数据集来计算用户相似度和用户邻域,然后使用这些邻域从第二组布尔偏好数据中提出建议 我似乎能做到这一点,但问题是,当我去计算推荐时,如果用户有基于第一个数据集的邻居,但在第二个数据集中不存在(尽管他们的邻居存在),则不会产生推荐 以下是推荐的生成器代码:Java Mahout:在一个推荐程序中使用两个数据模型,java,machine-learning,mahout,Java,Machine Learning,Mahout,我正试图用两组布尔偏好数据创建一个简单的推荐引擎。我想使用一个数据集来计算用户相似度和用户邻域,然后使用这些邻域从第二组布尔偏好数据中提出建议 我似乎能做到这一点,但问题是,当我去计算推荐时,如果用户有基于第一个数据集的邻居,但在第二个数据集中不存在(尽管他们的邻居存在),则不会产生推荐 以下是推荐的生成器代码: recommenderBuilder = new RecommenderBuilder() { public Recommender buildRecommender(
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);
}
};
这是培训模型文件的一个示例
1,111
2,222
2,111
2,222
3,111
3,222
1,91
1,92
2,91
以及推荐模型文件
1,111
2,222
2,111
2,222
3,111
3,222
1,91
1,92
2,91
运行此命令建议用户2使用92,但在到达用户3时抛出一个NoSuchUserException
索尔。。。是否有任何方法可以根据在另一个数据集上计算的相似性从一个数据集生成建议,而不需要所有用户都出现在第二个数据集中
以下是我目前正在使用的完整代码:
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) );
}
};
}
私有数据模型训练模型;
私有数据模型推荐模型;
私人推荐人评估人;
私人推荐人陈述评估人2;
私人推荐建造商推荐建造商;
私有数据模型生成器模型生成器;
@凌驾
PropertieSet()引发IOException、TasteException后的公共无效{
trainingModel=新的GenericBooleanPrefDataModel(
GenericBooleanPrefDataModel.toDataMap(新文件数据模型(新文件(“/music.csv”))
);
recommendationModel=新的GenericBooleanPrefDataModel(
GenericBooleanPrefDataModel.toDataMap(新文件(“/movies.csv”))
);
evaluator=新平均值AbsoluteDifferenceCommanderEvaluator();
evaluator2=新的GenericRecommenderIRStatSealuator();
recommenderBuilder=新的recommenderBuilder(){
公共推荐程序构建推荐程序(DataModel模型)抛出TasteException{
用户相似性=新的对数相似性(训练模型);
UserNeighborhood=新的NearestNusernighborhood(10,0.7,相似性,模型);
返回新的GenericBooleanPrefUserBasedRecommiter(模型、邻域、相似性);
}
};
modelBuilder=新的DataModelBuilder(){
公共数据模型buildDataModel(FastByIDMap训练数据){
返回新的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);
}
}
@覆盖
public void testData()抛出TasteException{
double score=evaluator.evaluate(推荐构建者、模型构建者、培训模型,0.9,1.0);
System.out.println(“计算分数:+分数”);
试一试{
IRStatistics=evaluator2.evaluate(
recommenderBuilder,modelBuilder,trainingModel,null,2,
0.0,
1
);
System.out.println(“调用:+stats.getRecall());
System.out.println(“精度:+stats.getPrecision());
}捕获(可丢弃的t){
系统输出打印项次(“投掷”+t);
}
列表建议=recommenderBuilder.buildRecommender(RecommensionModel).recommend(1,2);
System.out.println(“用户1”);
对于(RecommendedItem建议:建议){System.out.println(建议);}
建议=recommenderBuilder.BuilderRecommender(RecommensionModel).recommend(2,2);
System.out.println(“用户2”);
对于(RecommendedItem建议:建议){System.out.println(建议);}
试一试{
建议=recommenderBuilder.BuilderRecommender(RecommensionModel).recommend(3,2);
System.out.println(“用户3”);
对于(RecommendedItem建议:建议){System.out.println(建议);}
}捕获(可丢弃的t){
系统输出打印项次(“投掷”+t);
}
}
生成此输出:
计算得分:0.7033357620239258召回率:1.0精度:1.0用户1
用户2推荐编辑项[项目:9222,值:0.8516679]
抛出org.apache.mahout.cf.taste.common.NoSuchUserException:3
你可以做你所描述的,以及大致描述它的方式。支持用户相似性度量的数据集实际上可能不同于提出建议的数据集。用户相似性度量实际上可以基于您喜欢的任何东西
然而,它确实需要能够为用于提出建议的数据集中的任何一对生成用户相似性。我建议您在
UserSimilarity
实现中的特殊情况下,当一个用户未知时,返回0或其他值。我考虑过这一点。但这是否意味着实际使用了推荐数据集中用户的相似性?第二个数据集非常稀疏和嘈杂,因此我不希望其中的模式影响如何选择建议。基于用户的rec算法本质上只是一个加权平均算法,其中权重是相似的。是的,它们会被使用,即使它们的来源完全无关。无论它们来自何处,都与rec算法无关。如果我试图做的是根据数据集A确定用户1和2是相似的,然后向用户2建议用户1喜欢的数据集B中的所有内容;我的方法能做到这一点吗?是的,但是用户1和2需要存在于A和B中。(或者,你的代码需要帮助它假装它们存在。)推荐者所做的不仅仅是推荐其他人喜欢的任何东西——它是许多用户的加权平均数。我想这就是你的意思,谢谢。是的,我只是简单化了。尽管数据集只有2个用户,布尔值