大数据Hadoop学习之——好友推荐_量化数据库 好友推荐-程序员宅基地

技术标签: 算法  好友推荐  mapreduce  hadoop  大数据  

一、算法说明

好友关系如图:

                                       

   1、直接相连的表示两个人是直接好友关系;

   2、两个人有相同的好友表示两个人是间接好友(当然可能两个人同时也是直接好友,如图hello和hive)。

   3、好友推荐列表就是按照两个用户的共同好友数量排名

 

二、MapReduce分析

1、分两步MapReduce计算完成;

2、第一步先得到用户的间接好友关系数目,注意有直接好友关系的用户需要过滤掉;

3、第二步根据间接好友关系数就可以得到用户推荐列表。

 

三、MapReduce实现

输入数据

tom hello hadoop cat
word hadoop hello hive
cat tom hive
mr hive hello
hive cat hadoop word hello mr
hadoop tom hive word
hello tom word hive mr

第一个是当前用户,后面的是其好友列表

 

第一步——计算好友间接关系数

一、mapper输出两种数据

        1、对各用户的好友列表好友俩俩组合,输出间接好友关系;

        2、当前用户和好友列表好友一一组合,输出直接好友关系。

注意!!!这里好友关系key需要顺序排序,避免重复记录,如hello:tom和tom:hello都表示同样两个人的关系。

public class FriendMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
	private final Text text = new Text();

	private final IntWritable mval = new IntWritable();

	@Override
	protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
		//样本数据:tom hello hadoop cat
		String[] users = StringUtils.split(value.toString(), ' ');
		for (int i = 1; i < users.length; i++) {
			//和好友组成直接关系,组合好友关系按顺序排列,确保user1和user2不会因为顺序问题,而被认为是两对关系
			text.set(MrCommUtil.orderConcat(users[0], users[i]));
			mval.set(0);
			context.write(text, mval);
			for (int j = i + 1; j < users.length; j++) {
				//列表好友俩俩组合间接关系
				text.set(MrCommUtil.orderConcat(users[i], users[j]));
				mval.set(1);
				context.write(text, mval);
			}
		}
	}

}

 

二、reducer统计同两个用户的间接关系数,并过滤已经是直接关系的一组用户。

public class FriendReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
	private final IntWritable rval = new IntWritable();

	@Override
	protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
		//数据样本
		//hadoop word	0
		//hadoop word	1
		//hadoop word	0
		int num = 0;
		for (IntWritable value : values) {
			if (value.get() == 0) {
				return;
			}
			num += 1;
		}
		rval.set(num);
		context.write(key, rval);
	}
}

 

三、输出结果集如下

cat:hadoop	2
cat:hello	2
cat:mr	1
cat:word	1
hadoop:hello	3
hadoop:mr	1
hive:tom	3
mr:tom	1
mr:word	2
tom:word	2

 

第二步——统计最佳推荐好友

一、mapper输入数据集为第一步的结果集,map把记录映射成正反两组

public class Friend2Mapper extends Mapper<LongWritable, Text, FriendRelation, IntWritable> {
	private final FriendRelation mkey = new FriendRelation();

	private final IntWritable mval = new IntWritable();

	@Override
	protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
		//数据样本:cat:hadoop	2
		String[] strs = StringUtils.split(value.toString(), '\t');
		String[] users = StringUtils.split(strs[0], ':');
		mkey.setFrom(users[0]);
		mkey.setTo(users[1]);
		int n = Integer.parseInt(strs[1]);
		mkey.setN(n);
		mval.set(n);
		context.write(mkey, mval);
		mkey.setFrom(users[1]);
		mkey.setTo(users[0]);
		context.write(mkey, mval);
	}
}

 

二、排序比价器根据第一个用户和关系数倒排序

public class Friend2SortComparator extends WritableComparator {

	public Friend2SortComparator() {
		super(FriendRelation.class, true);
	}

	@Override
	public int compare(WritableComparable a, WritableComparable b) {
		//排序先根据from,同from再根据n排倒序
		FriendRelation f1 = (FriendRelation) a;
		FriendRelation f2 = (FriendRelation) b;
		int i = f1.getFrom().compareTo(f2.getFrom());
		if (i == 0) {
			return -Integer.compare(f1.getN(), f2.getN());
		}
		return i;
	}
}

 

三、分组比较器根据第一个用户分组

public class Friend2GroupComparator extends WritableComparator {

	public Friend2GroupComparator() {
		super(FriendRelation.class, true);
	}

	@Override
	public int compare(WritableComparable a, WritableComparable b) {
		//分组只根据from分组
		FriendRelation f1 = (FriendRelation) a;
		FriendRelation f2 = (FriendRelation) b;
		int i = f1.getFrom().compareTo(f2.getFrom());
		return i;
	}

}

四、reduce取出关系数最大的推荐关系

public class Friend2Reducer extends Reducer<FriendRelation, IntWritable, Text, IntWritable> {
	private final Text rkev= new Text();
	private final IntWritable rval = new IntWritable();

	@Override
	protected void reduce(FriendRelation key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
		//样本数据:
		//cat:hadoop	2
		// cat:hello	2
		// cat:mr	1
		// cat:word	1
		int n = key.getN();
		//输出最大间接关系数的所有推荐
		for (IntWritable value : values) {
			if (n != value.get()) {
				break;
			}
			rkev.set(key.getFrom() + "->" + key.getTo());
			rval.set(key.getN());
			context.write(rkev, rval);
		}
	}
}

五、输出最终结果,用户推荐分最高的前两名

cat->hello	2
cat->hadoop	2
hadoop->hello	3
hello->hadoop	3
hive->tom	3
mr->word	2
tom->hive	3
word->mr	2
word->tom	2

 

六、完整代码及测试数据详见码云:hadoop-test传送门

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xdkb159/article/details/108143622

智能推荐

20、NanoDet训练、测试 以及使用ncnn部署Jetson Nano 进行目标检测和串口数据转发-程序员宅基地

文章浏览阅读6.5k次,点赞7次,收藏59次。基本思想:最近想尝试一下nano 上部署nanodet,于是记录一下训练过程,手中有一份labelme标注的数据集,于是开始了一波操作~首先将图片和json数据集转成xml (https://blog.csdn.net/sxj731533730/article/details/90046780),然后将xml数据集转成voc;import sysimport osimport jsonimport xml.etree.ElementTree as ETfrom PIL import Im_nanodet

code::blocks + wxWidgets 2.8 在ubuntu 10.04下的安装-程序员宅基地

文章浏览阅读930次。code::blocks + wxWidgets 2.8 在ubuntu 10.04下的安装p { margin-bottom: 0.21cm; }1、首先安装必要组件代码:安装编译器 sudo apt-get install build-essential

用java Swing做的小游戏&quot;像素鸟&quot;_java swing小游戏-程序员宅基地

文章浏览阅读4.4k次,点赞10次,收藏38次。最终效果 整个项目都是基于swing实现的。窗是口将图片加载到JPanel面板,然后将面板添加到到JFrame窗口实现显示。这个类是选择几只像素鸟的类,也是main函数里执行的方法,代码有详细的注释,这里就不废话了public class select extends JPanel { /** * */ private static final long serialVersio..._java swing小游戏

三分钟教你读懂支票是什么_支票的原理是什么-程序员宅基地

文章浏览阅读8.7k次。三分钟教你读懂支票是什么支票1、支票的概念及特点支票:出票人签发的,委托办理支票存款业务的银行或其他金融机构在见票时无条件支付确定金额给收款人或持票人的票据。支票必填项:支票字样、确定的金额、出票日期、无条件支付委托、付款人名称、出票人签章。支票选填项:付款地、出票地。支票结算特点:(1)简便,手续_支票的原理是什么

山东工商学院 计算机科学与技术,实验中心-山东工商学院计算机科学与技术学院...-程序员宅基地

文章浏览阅读148次。计算机教学实验中心成立于1999年,隶属计算机科学与技术学院。实验中心现有软件、电子、网络、通信、大学生科技创新、AR技术研究所等41间实验室,实验面积5600平方米,固定资产3500万元,教(职)工26人。实验中心以先进精良的设备条件、整洁舒适的教学环境、科学严谨的管理方式为计算机科学与技术学院、信息与电子工程学院、管理科学与工程学院等学院的实验教学、课程设计、毕业设计等实践环节和全院计算机公共..._计算机科学与技术实验教学中心 山东

CUDA ERROR: device-side assert triggered at 问题及解决思路-程序员宅基地

文章浏览阅读10w+次,点赞45次,收藏82次。cuda errorRuntimeError: cuda runtime error (59) : device-side assert triggered at ...我之前还以为是因为GPU抽风了引发的BUG,所以第一次没有在意,直接又重新开始运行了一次,但是第二次就发现程序在同样的地方断掉了,这也就想起来我以前看到的一个博客,里面有句话的大概意思是这样的:每次都在同样的地方出错的..._cuda error: device-side assert triggered

随便推点

Vue简明实用教程(04)——事件处理_vue html里面如何直接写事件函数-程序员宅基地

文章浏览阅读1.1k次,点赞4次,收藏5次。在Vue中可非常便利地进行事件处理,例如:点击事件、鼠标悬停事件等。_vue html里面如何直接写事件函数

南京邮电大学离散数学实验一(求主析取和主合取范式)-程序员宅基地

文章浏览阅读4.5k次,点赞15次,收藏67次。南京邮电大学离散数学实验一(求主析取和主合取范式)_离散数学实验

{spring.cloud.client.ipAddress}_spring.cloud.client.ip-address-程序员宅基地

文章浏览阅读1.5w次,点赞2次,收藏5次。1.在springcloud中服务的 Instance ID 默认值是:${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}},也就是:主机名:应用名:应用端口。如图12.可以自定义:eureka.instance...._spring.cloud.client.ip-address

单目标跟踪OTB、VOT数据集介绍_otb数据集官网-程序员宅基地

文章浏览阅读2.1w次,点赞6次,收藏63次。OTB分为:OTB50和OTB100官方下载链接为:OTB官方数据集网站http://cvlab.hanyang.ac.kr/tracker_benchmark/datasets.html百度云链接:链接:https://pan.baidu.com/s/1Ck51d7OQ8w8BGcTL9UtopA提取码:jn0k复制这段内容后打开百度网盘手机App,操作更方便哦其中50和100,分别..._otb数据集官网

Xcode修改模拟器Simulator系统版本_xcode模拟器切换ios版本-程序员宅基地

文章浏览阅读5.1k次。从Xcode菜单栏里打开Xcode -&gt; Preferences -&gt; Components -&gt; Simulators,下载对应版本的模拟器。由于模拟器相关文件较大,下载时间较长,需要耐心等待,下载完成后,对应版本的模拟器前面的下载按钮就会变成下载完成的样式。点击Xcode菜单栏 Window -&gt; Devices,然后可以看到设备列表,然而在模拟器列表(..._xcode模拟器切换ios版本

chatgpt赋能python:Python如何分离CSV的列_python的csv拆列-程序员宅基地

文章浏览阅读270次。CSV文件是一种以逗号或其他分隔符分隔的文件格式,用于存储表格数据。它可以用任何文本编辑器打开,并且非常适合在电子表格程序(例如Microsoft Excel或Google Sheets)中打开和处理。CSV文件通常由一组记录组成,每条记录包含一个或多个字段。字段之间使用逗号或其他指定的分隔符分隔。CSV文件中的第一行通常包含列标题,这些标题描述了每个字段的含义。Jack,19,UK本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。_python的csv拆列

推荐文章

热门文章

相关标签