摘自:http://blog.fens.me/mahout-recommendation-api/

测试程序:RecommenderTest.java

测试数据集:item.csv


1,101,5.0
1,102,3.0
1,103,2.5
2,101,2.0
2,102,2.5
2,103,5.0
2,104,2.0
3,101,2.5
3,104,4.0
3,105,4.5

测试程序:org.conan.mymahout.recommendation.job.RecommenderTest.java


package org.conan.mymahout.recommendation.job; import java.io.IOException;
import java.util.List; import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.common.RandomUtils; public class RecommenderTest { final static int NEIGHBORHOOD_NUM = 2;
final static int RECOMMENDER_NUM = 3; public static void main(String[] args) throws TasteException, IOException {
RandomUtils.useTestSeed();
String file = "datafile/item.csv";
DataModel dataModel = RecommendFactory.buildDataModel(file);
slopeOne(dataModel);
} public static void userCF(DataModel dataModel) throws TasteException{}
public static void itemCF(DataModel dataModel) throws TasteException{}
public static void slopeOne(DataModel dataModel) throws TasteException{} ...

每种算法都一个单独的方法进行算法测试,如userCF(),itemCF(),slopeOne()….

5. 基于用户的协同过滤算法UserCF

基于用户的协同过滤,通过不同用户对物品的评分来评测用户之间的相似性,基于用户之间的相似性做出推荐。简单来讲就是:给用户推荐和他兴趣相似的其他用户喜欢的物品。

举例说明:

基于用户的 CF 的基本思想相当简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到 K 邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。图 2 给出了一个例子,对于用户 A,根据用户的历史偏好,这里只计算得到一个邻居 – 用户 C,然后将用户 C 喜欢的物品 D 推荐给用户 A。

上文中图片和解释文字,摘自: https://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy2/

算法API: org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender


@Override
public float estimatePreference(long userID, long itemID) throws TasteException {
DataModel model = getDataModel();
Float actualPref = model.getPreferenceValue(userID, itemID);
if (actualPref != null) {
return actualPref;
}
long[] theNeighborhood = neighborhood.getUserNeighborhood(userID);
return doEstimatePreference(userID, theNeighborhood, itemID);
} protected float doEstimatePreference(long theUserID, long[] theNeighborhood, long itemID) throws TasteException {
if (theNeighborhood.length == 0) {
return Float.NaN;
}
DataModel dataModel = getDataModel();
double preference = 0.0;
double totalSimilarity = 0.0;
int count = 0;
for (long userID : theNeighborhood) {
if (userID != theUserID) {
// See GenericItemBasedRecommender.doEstimatePreference() too
Float pref = dataModel.getPreferenceValue(userID, itemID);
if (pref != null) {
double theSimilarity = similarity.userSimilarity(theUserID, userID);
if (!Double.isNaN(theSimilarity)) {
preference += theSimilarity * pref;
totalSimilarity += theSimilarity;
count++;
}
}
}
}
// Throw out the estimate if it was based on no data points, of course, but also if based on
// just one. This is a bit of a band-aid on the 'stock' item-based algorithm for the moment.
// The reason is that in this case the estimate is, simply, the user's rating for one item
// that happened to have a defined similarity. The similarity score doesn't matter, and that
// seems like a bad situation.
if (count <= 1) {
return Float.NaN;
}
float estimate = (float) (preference / totalSimilarity);
if (capper != null) {
estimate = capper.capEstimate(estimate);
}
return estimate;
}

测试程序:


public static void userCF(DataModel dataModel) throws TasteException {
UserSimilarity userSimilarity = RecommendFactory.userSimilarity(RecommendFactory.SIMILARITY.EUCLIDEAN, dataModel);
UserNeighborhood userNeighborhood = RecommendFactory.userNeighborhood(RecommendFactory.NEIGHBORHOOD.NEAREST, userSimilarity, dataModel, NEIGHBORHOOD_NUM);
RecommenderBuilder recommenderBuilder = RecommendFactory.userRecommender(userSimilarity, userNeighborhood, true); RecommendFactory.evaluate(RecommendFactory.EVALUATOR.AVERAGE_ABSOLUTE_DIFFERENCE, recommenderBuilder, null, dataModel, 0.7);
RecommendFactory.statsEvaluator(recommenderBuilder, null, dataModel, 2); LongPrimitiveIterator iter = dataModel.getUserIDs();
while (iter.hasNext()) {
long uid = iter.nextLong();
List list = recommenderBuilder.buildRecommender(dataModel).recommend(uid, RECOMMENDER_NUM);
RecommendFactory.showItems(uid, list, true);
}
}

程序输出:


AVERAGE_ABSOLUTE_DIFFERENCE Evaluater Score:1.0
Recommender IR Evaluator: [Precision:0.5,Recall:0.5]
uid:1,(104,4.333333)(106,4.000000)
uid:2,(105,4.049678)
uid:3,(103,3.512787)(102,2.747869)
uid:4,(102,3.000000)

mahout demo——本质上是基于Hadoop的分步式算法实现,比如多节点的数据合并,数据排序,网路通信的效率,节点宕机重算,数据分步式存储的更多相关文章

  1. 从本质上学会基于HarmonyOS开发Hi3861(主要讲授方法)

    引言:花半秒钟就看透事物本质的人,和花一辈子都看不透事物本质的人,注定是截然不同的命运 做开发也一样,如果您能看透开发的整个过程,就不会出现"学会了某个RTOS的开发,同样的RTOS开发换一 ...

  2. 伪基站,卒于5G——本质上是基于网络和UE辅助的伪基站检测,就是将相邻基站的CI、信号强度等信息通过测量报告上报给网络,网络结合网络拓扑、配置信息等相关数据,对所有数据进行综合分析,确认在某个区域中是否存在伪基站

    伪基站,卒于5G from:https://www.huxiu.com/article/251252.html?h_s=h8 2018-07-05 21:58收藏27评论6社交通讯     本文来自微 ...

  3. 基于Hadoop的改进Apriori算法

    一.Apriori算法性质 性质一: 候选的k元组集合Ck中,任意k-1个项组成的集合都来自于Lk. 性质二: 若k维数据项目集X={i1,i2,-,ik}中至少存在一个j∈X,使得|L(k-1)(j ...

  4. 基于FPGA的肤色识别算法实现

    大家好,给大家介绍一下,这是基于FPGA的肤色识别算法实现. 我们今天这篇文章有两个内容一是实现基于FPGA的彩色图片转灰度实现,然后在这个基础上实现基于FPGA的肤色检测算法实现. 将彩色图像转化为 ...

  5. 在Hadoop上运行基于RMM中文分词算法的MapReduce程序

    原文:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-count-on-hadoop/ 在Hadoop上运行基于RMM中文分词 ...

  6. 基于Hadoop的密码安全级别验证

    学习Hadoop有一段时间了,期间写过很多Demo,都是针对单个知识点做的验证,今天写个完整的应用程序——基于Hadoop的密码安全级别验证. 在很多网站上注册用户时输入密码都会在下方提示密码安全级别 ...

  7. [转] X-RIME: 基于Hadoop的开源大规模社交网络分析工具

    转自http://www.dataguru.cn/forum.php?mod=viewthread&tid=286174 随着互联网的快速发展,涌现出了一大批以Facebook,Twitter ...

  8. Hive -- 基于Hadoop的数据仓库分析工具

    Hive是一个基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库 ...

  9. 基于Hadoop的大数据平台实施记——整体架构设计[转]

    http://blog.csdn.net/jacktan/article/details/9200979 大数据的热度在持续的升温,继云计算之后大数据成为又一大众所追捧的新星.我们暂不去讨论大数据到底 ...

随机推荐

  1. TYVJ 1427 线段树的基本操作

    题意: 单点修改,区间最值 思路: 线段树 原题请戳这里 //By SiriusRen #include <cstdio> #include <cstring> #includ ...

  2. HTML5 audio 如何实现播放多个MP3音频

    <audio>标签是HTML5中的新标签,定义声音用于嵌入音频内容,比如音乐或其他音频流.用的比较多音频格式是.mp3. <audio>标签常用属性如下表 属性 值 描述 au ...

  3. 使用Custom scrollbar(彩色滚动条)插件实现WordPress滚动条变色的方法

    1.在插件中心关键词搜索Custom scrollbar 2.按照说明操作就行 查看演示:sheji.xinlvtian.com

  4. Oracle"TNS监听程序找不到符合协议堆栈要求的可用处理程序"解决方案

    问题描述:在使用ETL工具通过odbc方式连接Oracle进行数据抽取的过程中,Oracle 监听日志报错如下: 根本原因就是Oracle的process和session已经达到了甚至超过了最大值,解 ...

  5. 几个方便编程的C++特性

    前言: C++11的自动化特性给编程提供了不少方便,同时也给调试增加了很多负担,至于取舍看程序员的风格和侧重而定. auto:自动类型推断 在C++11之前,auto关键字用来指定存储期.在新标准中, ...

  6. linux VFS 之一 :虚拟文件系统的面向对象设计思想

    VFS的面向对象的思想,如下图: VFS在上层用户空间的进程与底层特定文件系统之间起到一个承上启下的作用, 对上:封装标准的系统调用接口给用户空间app,user space app不必关心特定文件系 ...

  7. div与div之间的拖拽

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. Drop it FreeCodeCamp

    function drop(arr, func) { // Drop them elements. for(var start=0 ;start<arr.length; start++){ if ...

  9. 洛谷P1850 换教室_数学期望_Floyd

    调了一下午QAQ-让我对数学期望的理解又提升了一个层次. 首先,我们发现 v<=300v<=300v<=300 , 这样我们就可以用 FloydFloydFloyd 算法来 O(n3 ...

  10. lsync 负载实现代码双向同步

    参考文件: https://www.zyku.net/centos/1713.html 检查错误命令: lsyncd -pidfile /tmp/lsyncd.pid  /etc/lsyncd.con ...