您的位置:首页 > 其它

Mahout in Action 读书笔记chapter4 进行推荐

2014-07-11 22:08 316 查看

http://blog.csdn.net/feitongxunke​

​这一章主要介绍:

1.深入介绍item-based和user-based。

2.介绍这两种算法背后的相似性度量。

3.在Mahout中实现其他推荐算法,slope-one,基于SVD和基于聚类的算法。

1.理解探索基于用户推荐

1.1算法过程

[code]for(用户u尚未表达的偏好)每个物品i

for(对i有偏好的)每个其他用户v

计算u和v之间的相似度s

按权重为s将v对i的偏好并入平均值

return 值最高的物品(按加权平均排序)

[/code]
这种方法还是太慢了,一般应用过程中会计算出一个最相似用户邻域,然后仅仅考虑这些用户的评价:
[code]for 每个其他用户w

计算用户u和用户w的相似度s

按相似度排序后,将位置考前的用户作为邻域n

for(n中用户有偏好,而u中用户无偏好的)每个物品i

for(n中用户对i有偏好)每个其他用户v

计算用户u和用户v的相似度

按权重s将v对i的偏好并入平均值

[/code]

1.2基于GenericUserBasedRecommender实现算法

这里就不放出代码了,因为前面章节有,在chapter2里面。这里大致介绍下它的构成。

DataModel数据模型

UserSimilarity用户间的相似性度量

UserNeighborhood用户邻域的定义

Recommender推荐引擎

1.3尝试GroupLens数据集

这里要谈谈这个GroupLens数据集,这个数据集很大,载入内存的时候会出现OutOfMemoryError,这个时候需要添加几个参数,如下:

-server -d64 -Xmx768M -XX:+UseParallelGC -XX:+UseParallelOldGC,书中还提到了-XX:+NewRatio=12不过这个我添加进去,出现错误。

1.4探究邻域

接下来要谈谈邻域的问题,之前的推荐系统里面有个语句是NearestNUserNeighborhood第一个参数就是可以修改邻域的大小,可以改成10,100等等。当然我们也可以用阈值来设置邻域,这个时候就是ThresholdUserNeighborhood,第一个参数就是一个比例,这里用的是标准皮尔逊相关系数作为相似性的度量,这个阈值可以在(-1,1)之间。

2.探索相似度

下面少谈公式,公式可以百度,主要谈谈这些相似度应用场景以及实际环境表达的含义。

2.1基于皮尔逊相关系数的相似度

皮尔逊相关系数是一个在-1到1之间的数,他度量两个一一对应的数列之间的线性相关程度。在统计学中就是两个序列协方差与二者方差乘积的比值。协方差计算的是来两个序列变化趋势一直的绝对量,什么意思呢,就是指两个序列,相对于各自的均值点向同一方向移动得越远,协方差就越大,除以方差就是为了归一化。在我们这里可以度量两个用户针对同一物品偏好值变化趋势的一致性。
缺点也很明显,他没有没有考虑两个用户同时给出偏好值的物品数目,两个评价200个商品的用户肯定比两个只评价2个商品的用户相似。还有就是如果两个用户交集很少也是不能计算相关性的,当然这种情况两个用户相关性也可以看做很小。还有种情况是任何一个序列出现偏好值相同的情况,相关系数都是未定义的。
这个时候我们可以通过加权来解决上述问题,加权的目的就是使基于较多物品计算相关系数时,使正相关值向1移动,负相关向-1移动,如果基于较少的物品计算相关系数则可以让相关值向偏好值的均值移动。如果需要使用加权,可以在PearsonCorrelationSimilarity中加入第二个参数Weighting.WEIGHTED即可。

2.2欧氏距离定义

欧式距离很简单,也是非常常见的距离定义方式,这里可以计算出任何用户的相似度,当用户之间交集很少时,这里的相似度并不靠谱。函数名字是EuclideanDistanceSimilarity。

2.3余弦相似性度量

这里计算的是两个向量夹角余弦值,函数名字是CosineMeasureSimilarity。

2.4斯皮尔曼相关系数

这个是皮尔逊相关系数的变体,这个相关系数基于的是偏好值的相对排名,这里只保留了偏好值最本质的东西,它们的顺序。这个斯皮尔曼相关系数速度很慢,学术价值大于实用价值。SpearmanCorrelationSimilarity。

2.5忽略偏好值基于谷本系数计算相似度

这个完全抛弃了偏好,只关心用户是否表达过偏好。TanimotoCoefficientSimilarity,称之为谷本系数,也叫Jaccard系数。它是两个用户共同表达过偏好的物品数目/至少一个用户表达过偏好的物品数目。一般只有当偏好值为布尔或是没有偏好值可用采用此方法。

2.6基于对数似然比更好地计算相似度

LogLikelihoodSimilarity,对数似然比的相似度。它是一种不考虑具体偏好值的度量方法。它试图反映两个用户由于机缘巧合发生重叠的不可能性。这种相似度往往优于基于谷本系数的相似度。具体的数学推导可以去看看。

3.基于物品的推荐

算法流程:
[code]for(用户u尚未表达偏好的)每个物品i:

for(用户u表达偏好的)每个物品j:

计算i和j之间的相似度s

按权重为s将u对j的偏好并入平均值

return 值最好的物品(按加权平均排序)

[/code]
这里要用GenericItemBasedRecommender来取代GenericUserBasedRecommender,下面放出核心代码非常简洁:
[code]public Recommender buildRecommender(DataModel model) throws TasteException {

ItemSimilarity similarity = new PearsonCorrelationSimilarity(model);

return new GenericItemBasedRecommender(model, similarity);

}

[/code]
这里没有计算物品邻域的步骤,这是因为这里计算物品i和j的相似度,其中j已经是用户表达过偏好的了。常常user数目大于item数目,因此基于物品的算法速度运行很快。

4.Slope-one推荐算法

slope-one是基于新物品与用户评估过的物品之间的平均偏好值差异来预测用户对新物品的偏好值。举个例子吧:

人们对A物品打分比B物品高一分

人们对A物品打分和C物品一样

假设现在有个用户B物品打分4分,C物品打分3分,则这个用户对A物品打分按照B物品打是5分,按照C物品是3分,这个时候取个平均值,就是(5+3)/2=4分。

算法流程如下:
[code]//预处理,完成所有物品对之间的偏好值差异

for每个物品i

for每个其他物品j

for对i和j均有偏好的每个用户u

将物品对(i与j)间的偏好值差异加入u的偏好

//最终算法

for用户u未表达过偏好的每个物品i

for用户u表达过偏好的每个物品j

找到j与i之间的平均偏好值差异

添加该差异u对j的偏好值

添加其至平均值

return值最好的物品(按平均差异排序)

[/code]
优点十分明显,在线部分执行很快,我们可以预先计算好物品之间偏好值的差异,如果一个偏好值发生改变,只需更新部分值即可。有个缺点就是物品对之间的偏好值差异所需要的内存是物品数的平方,因此内存增长很快。

放点代码出来吧:
[code]public Recommender buildRecommender(DataModel model)throws TasteException {

DiffStorage diffStorage = new MemoryDiffStorage( model, Weighting.UNWEIGHTED, Long.MAX_VALUE);

return new SlopeOneRecommender( model,Weighting.UNWEIGHTED,Weighting.UNWEIGHTED,diffStorage);

}

[/code]
当然mahout0.9已经没有这个算法了,我没有找到。去网上搜了下,0.8中就没有了。

5.其他算法

5.1基于奇异值分解的推荐算法

SVD原理很简单,是一种降维的手段,用来提取特征,得到小的数据集。第一个参数是特征个数,第二个参数是拉姆达,用来控制正则化分解器,最后一个参数是需要执行的训练步骤数。
[code]import org.apache.mahout.cf.taste.common.TasteException;

import org.apache.mahout.cf.taste.common.Weighting;

import org.apache.mahout.cf.taste.eval.IRStatistics;

import org.apache.mahout.cf.taste.eval.RecommenderBuilder;

import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator;

import org.apache.mahout.cf.taste.impl.eval.GenericRecommenderIRStatsEvaluator;

import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;

import org.apache.mahout.cf.taste.impl.model.GenericDataModel;

import org.apache.mahout.cf.taste.impl.model.file.*;

import org.apache.mahout.cf.taste.impl.neighborhood.*;

import org.apache.mahout.cf.taste.impl.recommender.*;

import org.apache.mahout.cf.taste.impl.recommender.svd.ALSWRFactorizer;

import org.apache.mahout.cf.taste.impl.recommender.svd.SVDRecommender;

import org.apache.mahout.cf.taste.impl.similarity.*;

import org.apache.mahout.cf.taste.model.*;

import org.apache.mahout.cf.taste.neighborhood.*;

import org.apache.mahout.cf.taste.recommender.*;

import org.apache.mahout.cf.taste.similarity.*;

import org.apache.mahout.common.RandomUtils;


import java.io.*;

class RecommenderIntro {

public static void main(String[] args) throws Exception {

RandomUtils.useTestSeed();

DataModel model = new GenericDataModel(GenericDataModel.toDataMap(new FileDataModel(new File("/Users/ericxk/Downloads/ml-100k/ub.base"))));

RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator();

RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {

public Recommender buildRecommender(DataModel model)throws TasteException {

return new SVDRecommender(model,new ALSWRFactorizer(model,10,0.05,10));

}

};

IRStatistics stats = evaluator.evaluate(recommenderBuilder, null, model, null, 2, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);

System.out.println(stats.getPrecision());

System.out.println(stats.getRecall());

}

}

[/code]

5.2基于线性插值物品的推荐算法

这个很简单就是knn,不常用,因为速度慢。
[code]ItemSimilarity similarity = new LogLikelihoodSimilarity(model);

Optimizer optimizer = new NonNegativeQuadraticOptimizer();

return new KnnItemBasedRecommender(model, similarity, optimizer, 10);

[/code]

5.3基于聚类的推荐算法

这个运行很快,因为可以一来就把簇分好,但是缺点也很明显,因为同一簇的是一样的推荐,不够个性化。
[code]UserSimilarity similarity = new LogLikelihoodSimilarity(model);

ClusterSimilarity clusterSimilarity = new FarthestNeighborClusterSimilarity(similarity);

return new TreeClusteringRecommender(model, clusterSimilarity, 10);

[/code]

5.4还有其他的么?

当然还有不过Mahout正在紧密锣鼓添加中,常见的还有基于内容,关联规则,基于模型等等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: