最近做了一个项目,要求找出二度人脉的一些关系,就好似新浪微博的“你可能感兴趣的人” 中,间接关注推荐;简单描述:即你关注的人中有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算法是一种挖掘关联规则的频繁项集算法,其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集. 关于这个算法有一个非常有名的故事:"尿布和啤酒".故事是 ...
随机推荐
- TortoiseSVN本地代码版本控制设置步骤。
1.下载安装TortoiseSVN客户端. 2.在某个盘创建空的文件夹作为项目代码的版本库.在空的文件夹内部右键鼠标TortoiseSVN->Create repository here 3.在 ...
- 转:ASP.NET MVC 3 and App_Code folder
问题: In ASP.NET Webform, App_Code is standardfolder to putting code and using it at run-time.But I th ...
- node c/c++扩展模块build失败.
"深入浅出nodejs 朴灵" 例子 c/c++扩展模块 http://diveintonode.org/ 在作者的帮助下,build成功. 下面贴出的hello.cc和bindi ...
- CICS定时
F+14个0-----给CICS传参数FM CICSServer svr; svr.GetRetCommData(&pMsgStr, &chMsgType); CICSS ...
- ubuntu12.10设置禁止锁屏和屏幕常亮
1.System Settings -> Brightness and Lock -> Turn off screen... set to "Never" 进入ubun ...
- Linux C 程序 两变量值交换(FIVE)
example:1.运算符: #include<stdio.h> int main(){ int a , b , c ,d ; a = ; b = a++;//先赋值给b,a再自增 c = ...
- MIT 2012分布式课程基础源码解析-事件管理封装
这部分的内容主要包括Epoll/select的封装,在封装好相应函数后,再使用一个类来管理相应事件,实现的文件为pollmgr.{h, cc}. 事件函数封装 可看到pollmgr.h文件下定一个了一 ...
- KISSY学习笔记(更新中)
序:身为一个JAVA开发工程师,前端代码我尽量是使用原生的JS来写的,或是使用一些JQ的开源组件(但是也只是使用,没有好好去研究过JQ这个框架).目前由于工作需要,必须要使用KISSY,打算借此机会, ...
- MVC 中 使用TagBuilder扩展HtmlHelper
TagBuilder就是标签建造器,我们就用它来建造属于我们自己标签生成函数. 无废话,直接上代码 例: using System.Web.Mvc; public static class HtmlE ...
- 图片上传iOS
//图片上传 - (void)upLoadImage{ if(self.frontImage && self.backImage){ //性别 NSString *sexStr; if ...