CWYAlpha

Just another WordPress.com site

Thought this was cool: 推荐系统介绍——Mahout笔记之一

leave a comment »


准备开始看Mahout in action~
Mahout是Java写的知名推荐系统工具之一,看的目的不是使用Mahout,目的是通过这份资料了解Mahout是怎么做的。

首先看第二章,推荐系统介绍。
Mahout可以处理的User ID和Item ID需要是整数,打分(Preference)可以是任意数值,大的数值代表更喜欢。
输入文件需要是csv格式,每行三个数字分别代表:User ID, Item ID, Preference
例如

1
2
1,101,5.0
2,101,2.0

代表1号用户给101号物品打5.0分,2号用户给101号物品打2.0分。
有了数据文件,就可以利用Mahout写一个简单的推荐系统代码了。

1
2
3
4
5
6
7
8
9
10
11
DataModel model = new FileDataModel(new File("intro.csv"));
//建立DataModel对象存储数据文件
UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
//计算用户相似度矩阵
UserNeighborhood neighborhood = new NearestNUserNeighborhood (2, similarity, model);
//对每个用户找出2个最相似用户
Recommender recommender =
 new GenericUserBasedRecommender(model, neighborhood, similarity);
//建立UserCF推荐系统
List<RecommendedItem> recommendations = recommender.recommend(1, 1);
//为用户1推荐1个Item

以上是一个简单例子,留个印象,可以先不用纠结。
然后就是需要一个推荐系统精确度衡量标准,衡量标准有MAE(误差绝对值的平均值)和RMSE(误差平方求平均再开根)等。
可以同样看一个简单例子,Mahout衡量推荐系统精确度的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
RandomUtils.useTestSeed();
//用来使得每次随机都一样,仅限用于测试,不要在实际中使用
DataModel model = new FileDataModel(new File("intro.csv"));
RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
//使用MAE作为衡量标准,如果用RMSE则是 RMSRecommenderEvaluator
RecommenderBuilder builder = new RecommenderBuilder() {
  @Override
  public Recommender buildRecommender(DataModel model) throws TasteException {
    UserSimilarity similarity = new PearsonCorrelationSimilarity (model);
    UserNeighborhood neighborhood = new NearestNUserNeighborhood (2, similarity, model);
    return new GenericUserBasedRecommender (model, neighborhood, similarity);
  }
};
double score = evaluator.evaluate(builder, null, model, 0.7, 1.0);
//随机使用70%数据做为训练,另外30%作为测试,
//最后一个参数1.0表示使用全部的数据,如果数据太大,
//可以只用一部分数据去近似衡量推荐系统准确度,
//在仅有小改动之后做部分数据测试比较快捷。

然后除了这种精确度衡量方式,Mahout还提供其他方式。这主要是因为:在实际推荐系统中,很多情况下并没有必要准确预测打分,而只需要对待推荐物品排序,由最好到最差,就足够了。另外还有一个原因是,对于部分问题,输入数据是布尔类型的,也即我们只知道用户是否偏好,但是没有打分。
Mahout提供了精确率(Precision)和召回率(recall)两种方案:精确率是指推荐排名前列中,有多少是好的推荐(good recommendation);召回率是指好的推荐中,有多少个排在推荐排名前列。
这样我们还需要定义什么是好的推荐。
先来看看代码:

1
2
3
4
5
6
7
RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator ();
IRStatistics stats = evaluator.evaluate(
    recommenderBuilder, null, model, null, 2, //推荐2个,计算准确率和召回率
    GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 
    1.0);
System.out.println(stats.getPrecision());//输出准确率
System.out.println(stats.getRecall()); //输出召回率

假设有这样的一组数据

1
2
3
4
5
6
5,101,4.0
5,102,3.0
5,103,2.0
5,104,4.0
5,105,3.5
5,106,4.0

再假设前三行出现在测试集中,则由于101物品的分数高,所以他是好的推荐(good recommendation),而102和103都是有效的,但不是好的。但是这又有一个问题,分数到多少算分数高?你可以传进一个参数自己指定一个阈值(threshold),也可以让系统指定。
系统指定阈值的方案为:计算用户打分的均值和标准差,则阈值=均值+标准差。这样通常有大约16%的打分被选中(假设打分呈正态分布)。
文中指出了这种方式存在的问题,推荐的物品其实并不必要是已知的才说明推荐得好。一个更复杂的情况是如果输入数据是布尔类型(只知道是否喜欢),则无法选择阈值,只能是从喜欢的物品中随机选择一些用于测试。
文中还使用了GroupLens数据实际测试做例子,这里就不关注了。

from Dora Blog: http://diaorui.net/?p=305

Written by cwyalpha

七月 2, 2012 在 8:38 上午

发表在 Uncategorized

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: