我们知道FileDataModel可以装载一个偏好值文件,其实FileDataModel还支持动态更新装在的数据,增量更新文件命名规则如下:
假如主数据文件为:intro.txt ,则增量更新文件的命名应为intro.1.txt ,intro.2.txt如此跟进。
当调用refresh()方法时,会自动装在更新文件并更新现有偏好值数据。
但是一般不会单独刷新DataModel组件,一般都是连带刷新所有的依赖组件,比如similarity组件和neighborhood组件,所以一般调用推荐引擎的refresh(null)方法,将所有组件都一起刷新。
以下给了一个简单的demo示例:
package com.besttone.mahout.demo.recommender;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import org.apache.mahout.cf.taste.common.TasteException;
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.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
public class TestRefreshRecommender {
/**
* @param args
* @throws IOException
* @throws TasteException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, TasteException,
InterruptedException {
// TODO Auto-generated method stub
// 装载数据文件,实现存储,并为计算提供所需的用户ID,物品ID,偏好值
DataModel dataModel = new FileDataModel(new File(
MyFirstRecommender.class.getResource("intro.txt").getPath()));
// 相似度 度量方式,采用皮尔逊相关系数度量,也可以采用其他度量方式
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
// 用户邻居,与给定用户最相似的一组用户
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2,
similarity, dataModel);
// 输出与userid=1最相似的两个userid
// long[] neighborhoods = neighborhood.getUserNeighborhood(1);
// for (long l : neighborhoods) {
// System.out.println(l);
// }
// 推荐引擎,合并这些组件,实现推荐
Recommender recommender = new GenericUserBasedRecommender(dataModel,
neighborhood, similarity);
BufferedReader reader = new BufferedReader(new FileReader(
MyFirstRecommender.class.getResource("version.txt").getPath()));
String initVersion = reader.readLine();
reader.close();
while (true) {
// 为userID为1的用户推荐2个item
List<RecommendedItem> items = recommender.recommend(1, 2); // 输出推荐的物品
for (RecommendedItem recommendedItem : items) {
System.out.println(recommendedItem);
}
Thread.sleep(5000);
reader = new BufferedReader(new FileReader(MyFirstRecommender.class
.getResource("version.txt").getPath()));
String version = reader.readLine();
reader.close();
if (!version.equals(initVersion)) {
// 如果版本发生变更,刷新推荐引擎
recommender.refresh(null);
initVersion = version;
}
}
}
}
我这里实现的是简单的通过一个version.txt文件中的版本号的不同来告诉推荐引擎需要进行更新了,如果在web系统中,可能将触发推荐引擎刷新的判断条件写到数据库中,当你上传了一个偏好值更新文件后,更新数据库对应的最后更新时间字段,然后可以每隔5分钟或者多长时间比对一下当前保存的更新时间和数据库中的最后更新时间是否一致来触发刷新推荐引擎。