最近做了一个项目,要求找出二度人脉的一些关系,就好似新浪微博的“你可能感兴趣的人” 中,间接关注推荐;简单描述:即你关注的人中有N个人同时都关注了 XXX 。
在程序的实现上,其实我们要找的是:若 User1 follow了10个人 {User3,User4,User5,... ,User12}记为集合UF1,那么 UF1中的这些人,他们也有follow的集合,分别是记为: UF3(User3 follow的人),UF4,UF5,...,UF12;而在这些集合肯定会有交集,而由最多集合求交产生的交集,就是我们要找的:感兴趣的人。
我在网上找了些,关于二度人脉算法的实现,大部分无非是通过广度搜索算法来查找,犹豫深度已经明确了2以内;这个算法其实很简单,第一步找到你关注的人;第二步找到这些人关注的人,最后找出第二步结果中出现频率最高的一个或多个人,即完成。
但如果有千万级别的用户,那在运算时,就肯定会把这些用户的follow 关系放到内存中,计算的时候依次查找;先说明下我没有明确的诊断对比,这样做的效果一定没 基于hadoop实现的好;只是自己,想用hadoop实现下,最近也在学;若有不足的地方还请指点。
首先,我的初始数据是文件,每一行为一个follow 关系 ida+‘\t’+idb;表示 ida follow idb。其次,用了2个Map/Reduce任务。
Map/Reduce 1:找出 任意一个用户 的 follow 集合与 被 follow 的集合。如图所示:

代码如下:
Map任务: 输出时 key :间接者 A 的ID ,value:follow 的人的ID 或 被follow的人的ID
01 |
public void map(Text key, IntWritable values, Context context) throwsIOException,InterruptedException{ |
02 |
int value = values.get(); |
04 |
String[] _key = Separator.CONNECTORS_Pattern.split(key.toString()); |
06 |
//"f"前缀表示 follow;"b" 前缀表示 被follow |
07 |
context.write(new Text(_key[0]), new Text("f"+_key[1])); |
08 |
context.write(new Text(_key[1]), new Text("b"+_key[0])); |
Reduce任务: 输出时 key :间接者 A 的ID , value为 两个String,第一个而follow的所有人(用分割符分割),第二个为 被follow的人(同样分割)
01 |
protected void reduce(Text key, Iterable<TextPair> pairs, Context context) |
02 |
throws IOException,InterruptedException{ |
03 |
StringBuilder first_follow = new StringBuilder(); |
04 |
StringBuilder second_befollow = new StringBuilder(); |
06 |
for(TextPair pair: pairs){ |
07 |
String id = pair.getFirst().toString(); |
08 |
String value = pair.getSecond().toString(); |
09 |
if(id.startsWith("f")){ |
10 |
first_follow.append(id.substring(1)).append(Separator.TABLE_String); |
11 |
} else if(id.startsWith("b")){ |
12 |
second_befollow.append(id.substring(1)).append(Separator.TABLE_String); |
16 |
context.write(key, newTextPair(first_follow.toString(),second_befollow.toString())); |
其中Separator.TABLE_String为自定义的分隔符;TextPair为自定义的 Writable 类,让一个key可以对应两个value,且这两个value可区分。
Map/Reduce 2:在上一步关系中,若B follow A,而 A follow T ,则可以得出 T 为 B 的二度人脉,且 间接者为A ,于是找出 相同二度人脉的不同间接人。如图所示:

代码如下:
Map 任务:输出时 key 为 由两个String 记录的ID表示的 二度人脉关系,value 为 这个二度关系产生的间接人的ID
01 |
public void map(Text key, TextPair values, Context context) throwsIOException,InterruptedException{ |
02 |
Map<String, String> first_follow = new HashMap<String, String>(); |
03 |
Map<String, String> second_befollow = new HashMap<String, String>(); |
04 |
String _key = key.toString(); |
05 |
String[] follow = values.getFirst().toString().split(Separator.TABLE_String); |
07 |
String[] second = values.getSecond().toString().split(Separator.TABLE_String); |
09 |
for(String sf : follow){ |
11 |
first_follow.put(sf , _key ); |
15 |
for(String ss : second){ |
17 |
second_befollow.put(ss , _key ); |
21 |
for(Entry<String, String> f : first_follow.entrySet()){ |
22 |
for(Entry<String, String> b : second_befollow.entrySet()){ |
23 |
context.write(new TextPair(f.getKey() ,b.getKey()), new Text(key)); |
Reduce任务:输出时 key 仍然为二度人脉关系, value 为所有间接人 的ID以逗号分割。
01 |
protected void reduce(TextPair key, Iterable<Text> values, Context context) |
02 |
throws IOException, InterruptedException { |
04 |
StringBuilder resutl = new StringBuilder(); |
05 |
for (Text text : values){ |
06 |
resutl.append(text.toString()).append(","); |
09 |
context.write(key, new Text(resutl.toString())); |
到这步,二度人脉关系基本已经挖掘出来,后续的处理就很简单了,当然也基于二度人脉挖掘三度,四度:)
来自:http://my.oschina.net/BreathL/blog/75112
- 使用MapReduce实现二度人脉搜索算法
一,背景介绍 在新浪微博.人人网等社交网站上,为了使用户在网络上认识更多的朋友,社交网站往往提供类似“你可能感兴趣的人”.“间接关注推荐”等好友推荐的功能,其中就包含了二度人脉算法. 二,算法实现 原 ...
- 依据二度人脉推荐好友sql
friend表结构 DROP TABLE IF EXISTS FRIEND; create table friend( uid bigint not null comment ' ...
- hadoop计算二度人脉关系推荐好友
https://www.jianshu.com/p/8707cd015ba1 问题描述: 以下是qq好友关系,进行好友推荐,比如:老王和二狗是好友 , 二狗和春子以及花朵是好友,那么老王和花朵 或者老 ...
- MapReduce实现二度好友关系
一.问题定义 我在网上找了些,关于二度人脉算法的实现,大部分无非是通过广度搜索算法来查找,犹豫深度已经明确了2以内:这个算法其实很简单,第一步找到你关注的人:第二步找到这些人关注的人,最后找出第二步结 ...
- Spark 计算人员二度关系
1.一度人脉:双方直接是好友 2.二度人脉:双方有一个以上共同的好友,这时朋友网可以计算出你们有几个共同的好友并且呈现数字给你.你们的关系是: 你->朋友->陌生人 3.三度人脉:即你朋友 ...
- Hadoop MapReduce实现人员二度关系运算
1.一度人脉:双方直接是好友 2.二度人脉:双方有一个以上共同的好友,这时朋友网可以计算出你们有几个共同的好友并且呈现数字给你.你们的关系是: 你->朋友->陌生人 3.三度人脉:即你朋友 ...
- 静态频繁子图挖掘算法用于动态网络——gSpan算法研究
摘要 随着信息技术的不断发展,人类可以很容易地收集和储存大量的数据,然而,如何在海量的数据中提取对用户有用的信息逐渐地成为巨大挑战.为了应对这种挑战,数据挖掘技术应运而生,成为了最近一段时期数据科学的 ...
- 基于Spark GraphX计算二度关系
关系计算问题描述 二度关系是指用户与用户通过关注者为桥梁发现到的关注者之间的关系.目前微博通过二度关系实现了潜在用户的推荐.用户的一度关系包含了关注.好友两种类型,二度关系则得到关注的关注.关注的好友 ...
- 关联规则挖掘算法之Apriori算法
Apriori算法是一种挖掘关联规则的频繁项集算法,其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集. 关于这个算法有一个非常有名的故事:"尿布和啤酒".故事是 ...
随机推荐
- 二维树状数组——SuperBrother打鼹鼠(Vijos1512)
树状数组(BIT)是一个查询和修改复杂度都为log(n)的数据结构,主要用于查询任意两位之间的所有元素之和,其编程简单,很容易被实现.而且可以很容易地扩展到二维.让我们来看一道很裸的二维树状数组题: ...
- nodejs连接MySQL数据库
在github上搜索orm2 https://github.com/dresende/node-orm2: 在项目文件夹使用npm install orm下载下来,然后书写配置文件 var orm = ...
- javascript 第26节 jQuery对象
<html> <head> <title>jQuery</title> <!--导入jquery库--> <script type=& ...
- 关于Ionic的安装
Ionic是一个前端的框架,帮助开发者使用HTML5, CSS3和JavaScript做出原生应用. http://ionicframework.com/getting-started/ 这里介绍了如 ...
- SQLite cans and can'ts
SQLite 能做的 和 不能做的 1.SQLite_open/SQLite_open_v2
- What are the differences between small, minor, and major updates?
Following contents are excerpted from the this website and only used for knowledge sharing: Install ...
- C++ IO 详细用法
http://www.cnblogs.com/keam37/ keam所有 转载请注明出处 本文将分别从<iostream>,<sstream>,<fstream> ...
- Hibernate3.3 小记
//----------------事务(修改.删除.保存) Session s=getSession(); Transaction t=s.beginTransaction(); getSessio ...
- C# 解析带前缀的Xml节点内容
一般的xml文件相信大家都会解析了,但是遇到有命名空间的带前缀的xml,对于新手可能会有点问题.我这里在论坛解答的时候就遇到过一题,见怎么获取XML节点里面的内容,在线求教.这里给大家演示一下. 他的 ...
- Convert.ToInt32()与int.Parse()的区别 (转载)
Convert.ToInt32()与int.Parse()的区别(1)这两个方法的最大不同是它们对null值的处理:Convert.ToInt32(null)会返回0而不会产生任何异常,但int.Pa ...