- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
如何通过查看两个人有多少个共同的 friend 来建立一个友谊推荐系统,并使用mapreduce工作将他们推荐为 friend ?有点像facebook或linkedin所做的事情,显示推荐人员列表,并按共同 friend 的数量对其进行排名。
最佳答案
该解决方案来自我的博客,我在项目中使用了此代码。
完整版,请参见https://www.dbtsai.com/blog/hadoop-mr-to-implement-people-you-might-know-friendship-recommendation/
由于我不确定这是否是最佳解决方案,并且我也希望在stackoverflow中有一个文档,因此我在这里提出并回答了自己的问题。我希望获得社区的反馈。
最好的友谊推荐通常来自 friend 。关键思想是,如果两个人有很多共同的 friend ,但他们不是 friend ,则系统应建议他们彼此连接。
让我们假设友谊是无向的:如果A是B的 friend ,那么B也是A的 friend 。这是Facebook,Google +,Linkedin和几个社交网络中最常用的友谊系统。将其扩展到Twitter中使用的定向友谊系统并不困难;但是,在本文中,我们将重点关注无方向的案例。
输入数据将包含邻接列表,并以
1 0,2,3,4,5
2 0,1,4
3 0,1,4
4 1,2,3
5 1,6
6 5
0 4 (3: [3, 1, 2]),5 (1: [1])
1 6 (1: [5])
2 3 (3: [1, 4, 0]),5 (1: [1])
3 2 (3: [4, 0, 1]),5 (1: [1])
4 0 (3: [2, 3, 1]),5 (1: [1])
5 0 (1: [1]),2 (1: [1]),3 (1: [1]),4 (1: [1])
6 1 (1: [5])
static public class FriendCountWritable implements Writable {
public Long user;
public Long mutualFriend;
public FriendCountWritable(Long user, Long mutualFriend) {
this.user = user;
this.mutualFriend = mutualFriend;
}
public FriendCountWritable() {
this(-1L, -1L);
}
@Override
public void write(DataOutput out) throws IOException {
out.writeLong(user);
out.writeLong(mutualFriend);
}
@Override
public void readFields(DataInput in) throws IOException {
user = in.readLong();
mutualFriend = in.readLong();
}
@Override
public String toString() {
return " toUser: "
+ Long.toString(user) + " mutualFriend: "
+ Long.toString(mutualFriend);
}
}
public static class Map extends Mapper<LongWritable, Text, LongWritable, FriendCountWritable> {
private Text word = new Text();
@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line[] = value.toString().split("\t");
Long fromUser = Long.parseLong(line[0]);
List toUsers = new ArrayList();
if (line.length == 2) {
StringTokenizer tokenizer = new StringTokenizer(line[1], ",");
while (tokenizer.hasMoreTokens()) {
Long toUser = Long.parseLong(tokenizer.nextToken());
toUsers.add(toUser);
context.write(new LongWritable(fromUser),
new FriendCountWritable(toUser, -1L));
}
for (int i = 0; i < toUsers.size(); i++) {
for (int j = i + 1; j < toUsers.size(); j++) {
context.write(new LongWritable(toUsers.get(i)),
new FriendCountWritable((toUsers.get(j)), fromUser));
context.write(new LongWritable(toUsers.get(j)),
new FriendCountWritable((toUsers.get(i)), fromUser));
}
}
}
}
}
public static class Reduce extends Reducer<LongWritable, FriendCountWritable, LongWritable, Text> {
@Override
public void reduce(LongWritable key, Iterable values, Context context)
throws IOException, InterruptedException {
// key is the recommended friend, and value is the list of mutual friends
final java.util.Map<Long, List> mutualFriends = new HashMap<Long, List>();
for (FriendCountWritable val : values) {
final Boolean isAlreadyFriend = (val.mutualFriend == -1);
final Long toUser = val.user;
final Long mutualFriend = val.mutualFriend;
if (mutualFriends.containsKey(toUser)) {
if (isAlreadyFriend) {
mutualFriends.put(toUser, null);
} else if (mutualFriends.get(toUser) != null) {
mutualFriends.get(toUser).add(mutualFriend);
}
} else {
if (!isAlreadyFriend) {
mutualFriends.put(toUser, new ArrayList() {
{
add(mutualFriend);
}
});
} else {
mutualFriends.put(toUser, null);
}
}
}
java.util.SortedMap<Long, List> sortedMutualFriends = new TreeMap<Long, List>(new Comparator() {
@Override
public int compare(Long key1, Long key2) {
Integer v1 = mutualFriends.get(key1).size();
Integer v2 = mutualFriends.get(key2).size();
if (v1 > v2) {
return -1;
} else if (v1.equals(v2) && key1 < key2) {
return -1;
} else {
return 1;
}
}
});
for (java.util.Map.Entry<Long, List> entry : mutualFriends.entrySet()) {
if (entry.getValue() != null) {
sortedMutualFriends.put(entry.getKey(), entry.getValue());
}
}
Integer i = 0;
String output = "";
for (java.util.Map.Entry<Long, List> entry : sortedMutualFriends.entrySet()) {
if (i == 0) {
output = entry.getKey().toString() + " (" + entry.getValue().size() + ": " + entry.getValue() + ")";
} else {
output += "," + entry.getKey().toString() + " (" + entry.getValue().size() + ": " + entry.getValue() + ")";
}
++i;
}
context.write(key, new Text(output));
}
}
关于java - Hadoop M/R实现 “People You Might Know”友谊推荐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15035778/
当我对以下代码运行 javac 编译器时 - void method() { final int x; x = 1; x = 1; // (Intentional error
我有这个代码: private static final String EMAIL_INLINEIMAGE_TEMPLATE_NAME = "templateemail.html"; @Bean pu
我已经阅读了其他答案,但没关系,谢谢 Spring : pom.xml: org.thymeleaf thymeleaf 2.0.13
我正在尝试使用 php-facebook-sdk 并借助 curl Facebook API 创建广告。 我已经使用 curl 上传了我的视频,它返回了一个 ID。现在,该视频 ID 将用于添加广告,
我知道这是一个基本问题...但我会尽力解释。 我一直在使用 Deferred,但有人指出我将其用作反模式。基本上,我可以在子模块中使用 deferred。但是,如果这是一种反模式,那么实现这一目标的最
我是 Java 的新手。我正在编写一个程序来读取文件、计算其 SHA1 校验和并将结果写入另一个文件。出现任何错误时,我都会调用一个函数 err_exit(),它会向 stderr 打印一条消息,并通
我有一个名为 examList 的 HashMap,它存储学生参加的每门类(class)的考试成绩。这个 hashmap 的键是 courseID,值是一个数组列表 gradeList,其中包含学生在
我得到错误: TestCounter.java:115: variable counters might not have been initialized counters[i] = new Cou
我最近遇到了一个看起来像这样的例程: procedure TMyForm.DoSomething(list: TList; const flag: boolean); var local: int
我正在做一本关于阿克曼函数的书本练习。 不过我有一个问题。如果我声明结果但不初始化它,编译器会提示“变量结果可能尚未初始化”。 int result; 当我将其设置为默认值 0 时,它不会提示。 in
在使用 SpringBoot 开发 API 时,我必须制作一个 QueryBuilder为了构建一个可以使用 JDBC 从数据库获取结果的查询。 我的查询的初始结构看起来像 public static
public static double[] processUserInput(String data) { String[] arrayInString; doubl
我无法找到我得到的原因: variable might not have been initialized 示例1: class Test { public static void main(
这个问题已经有答案了: "Variable example might not have been initialized" in anonymous class (3 个回答) 已关闭 6 年前。
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我的编译器不会有它。 :( 现在怎么办?我必须完全重写整个应用程序吗? 要查看编译器拒绝的行,请执行 Ctrl+F 搜索 System.out.println(celsiusOutput + "C")
收到错误: Pay.java:81: error: variable hourlyWage might not have been initialized JOptionPane.showMessag
我正在结合现有的导入和导出功能,以减少在连接确实被拒绝的情况下用户被告知连接被拒绝的次数。我正在调用的库具有单独的导入和导出功能,以及组合的导入/导出功能。导出函数需要导出文件列表,而组合函数自己计算
是否有一个功能可以让我检查我收到“可能未初始化”错误的变量应该未初始化的路径?最好是 Java 原生的还是内置于 Intellij 中? 编辑:设法将我的代码减少到最小的失败示例 class MyFa
这个问题已经有答案了: How to avoid setting variable in a try statement (4 个回答) 已关闭 8 年前。 我正在尝试创建一种方法,为文件内的每个字符
我是一名优秀的程序员,十分优秀!