互联网社交好友推荐
项目背景
互联网行业中聊天交友软件为了能够良好的适应使用人群的习惯,与日常使用。同事为了提高用户的注册量,故而需要有效的推广方式和具有特色的功能来吸引人的眼球。通过好友推荐的方式能够根据现有用户的使用数据以及与其他同类型产品的合作可以通过计算分析出其好友圈内有望成为注册用户的人并进行推荐。
实验目的
- 了解掌握好友推荐算法的实现思路
- 完成实现好友推荐算法
#实现过程
已有的数据是每个人以及他的好友,无法直接从这个数据得到他的好友的好友,换一种思路,能够知道他的所有好友都有一个共同好友就是他,例如A 有两个好友 B 和 C,如果 B 和 C 不是好友那可以把 B 推荐给 C,因为 B 和 C 有一个共同好友。基于这种思路有了案例的实现方案。
第一个 Map,首先输出 key 为自己和每一个好友组合,value 标识已经是好友,另外还有输出key为好友的两两组合,value为1代表共同好友个数。 Reduce判断得到的数据的value 如果已经是共同好友就直接返回,否则就累加,就能得到每两个非好友的人的共同好友人数。
这个思路有个问题,Map的key为两个人的组合,但是组合A+B和组合B+A是一样的, 所以我们在写出数据之前,应该对数据进行排序,保证不会同时出现A+B 和 B+A。另外最后得到了每两个人的共同好友个数,但是应该排序才能得到应该推荐的好友是哪些。在 Reduce 进行排序的方法读者都懂,需要自定义输出类,实现 compareTo 方法,同时定义 GroupingComparator 类。
实验步骤
1、代码分析
第一个MapReduce实现类似 Wordcount,只不过每次输出之前要排序,保证A+B 和B+A 都能输出 A|B,另外直接好友多输出一个2标识已经是好友了。
第二个 MapReduce 先定义一个 FriendOfFriend 类,compareTo 方法先比较 id 然后比较共同好友数。另外自定义分组类,按照 id 分组
自定义一个 FriendOfFriend 的输出类,有 id,推荐好友 id,共同好友数量三个属性, Map 读进来的数据直接封装成这样的对象写出,他的分组 compareTo 方法先比较 id 然后比较共同好友数量,然后分组函数直接按 id 分组。在 reduce 的时候魅族数据就是 id 一样按照count 排序好的 FriendOfFriend 对象,直接写出。
2、创建项目
第一步:自定义一个 FriendOfFriend 的输出类
推荐好友 id,共同好友数量三个属性, Map 读进来的数据直接封装成这样的对象写出,他的分组 compareTo 方法先比较 id 然后比较共同好友数量,然后分组函数直接按 id 分组。在 reduce 的时候魅族数据就是 id 一样按照count 排序好的 FriendOfFriend 对象,直接写出。创建输出类命令如下。
mkdir /qq_recommendation
cd /qq_recommendation
vi FriendOfFriend.java
结果如下图所示。
代码如下
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.WritableComparable;
public class FriendOfFriend implements WritableComparable<FriendOfFriend> {
private String username;
private String fof;
private int count;
public String getUsername () {
return username;
}
public int getCount () {
return count;
}
public String getFof () {
return fof;
}
public void setCount(int count){
this.count = count;
}
public void setFof(String Fof){
this.fof = Fof;
}
public void setUsername(String Username){
this.username = Username;
}
public void readFields(DataInput arg0) throws IOException {
this.username=arg0.readUTF();
this.count=arg0.readInt();
this.fof=arg0.readUTF();
}
public void write(DataOutput arg0) throws IOException {
arg0.writeUTF(username);
arg0.writeInt(count);
arg0.writeUTF(fof);
}
/** * 相当于 Object对象equals */
@Override
public int compareTo(FriendOfFriend o) {
int result = this.username.compareTo(o.getUsername());
if(result == 0){
return Integer.compare(o.count, this.getCount());
}
return result;
}
}
结果下图所示。
第二步:创建分组类FriendRecommendGroup
创建用于对好友数据进行分组的的java代码,用来将具有相同好友的人分配到同一组中。创建分组类命令如下。
vi FriendRecommendGroup.java
结果如下图所