一、好友推介概述 |
好友推荐算法在实际的社交环境中应用较多,比如qq软件中的“你可能认识的好友”或者是Facebook中的好友推介。常见的好友推介算法有六度分割理论,三元闭包论 和最基本的好友推介算法。在这简单介绍最简单的好友推介算法。
假设用户A有好友A1,A2,A3,则A1,A2,A3相互之间都可能通过好友A认识,是潜在的好友关系。如果用户B有好友A1,A2,B1,则A1,A2,B1相互之间都可能通过好友B认识。如下图所示
如上图所示,A1,A2在潜在好友列表中出现2次,说明A1,A2有2个共同好友,在上图中即为A,B。当两个潜在好友如果共同好友越多,则他们可能认识的可能性就越大,彼此之间推介机会就越高。算法简单介绍如下:首先需要遍历所有用户的好友列表生成两两间的潜在好友列表,计算所有用户潜在好友列表中同一对潜在好友出现的次数。如上图例子中A1,A2出现次数为2次。注意:A1:A2与A2:A1为相同的一对潜在好友,计算时应进行累加。再次计算同一个用户的潜在好友列表和出现的次数,如图中A1用户,A1与A2出现2次,A1与A3出现1次,A1与B1出现1次。如果只能给每个用户推介一个好友的话,A2与A1认识的可能性更大,优先推介A2。注意:还需要除去已经是该用户好友的潜在好友列表。如果A1与A2已经是好友关系了,则不需要再次推介。
二、MapReduce程序实现 |
2.1 实验数据
备注:每个名字之间用”\t”分隔符隔开。
2.2 潜在好友列表统计
2.2.1 类型定义
由于A1:A2与A2:A1是同一个潜在好友列表,为了能够方便的统计,故统一按照字典排序,输出A1:A2格式。
package friendsToFriends;
import org.apache.hadoop.io.Text;
/**
*
* @author liu
* 说明:好友a:b之间与好友b:a之间是一样的,为了在reduce阶段,key相同可以自动合并,
* 故采用字典排序统一规范好友之间的名字列表
*/
public class Fof extends Text{
public Fof(){
super();
}
public Fof(String a,String b){
super(getFof(a, b));
}
//统一确定a与b的排序格式
public static String getFof(String a,String b){
int r = a.compareTo(b);
if(r<0){
return a+"\t"+b;
}else{
return b+"\t"+a;
}
}
}
2.2.2 Map类定义
//map函数,统计好友之间的FOF关系列表(FOF关系:潜在好友关系)
static class FofMapper extends Mapper<Text, Text, Fof, IntWritable>{
@Override
protected void map(Text key, Text value,
Context context)
throws IOException, InterruptedException {
String user = key.toString(); //用户
String[] friends = StringUtils.split(value.toString(), '\t'); //用户所有的好友列表