一:流程分析
好友推荐简介
好友推荐功能大家都比较熟悉,在这里就不作介绍了。重点介绍以下算法:通过计算共同好友来确定两人的好友关系
如图所示:用户A里面有4个好友,用户B里面也有4个好友,将两个join起来形成共同好友的结果,结果里面有重复的就说明两人认识的可能行极大。
此方法需要考虑的情况:
1.join的时候只join自己的好友,但是目前没有想到更好的方法将自己ID和自己好友的ID联系在一起(不能全join,这样数据量太大了)
2.一条结果可能代表两个关系,但是如何在结果里面将自己已经存在好友关系的数据剔除掉(较少输出的数据方便查询)
结论:通过别人的关系来确定你和第三人之间的共同好友,例如上图中是通过shell,yarn在AB用户中出现的次数来确定,shell和yarn之前的关系。
代码
数据:中间有一行空行
A:spring mybatis shell yarn
B:spring mybatis hadoop
C:spring hadoop
代码:
package org.example; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.IOException; class WordcountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); if(line.equals("") || line.length() == 0) return; //去掉空行 String user = line.split(":")[0]; String[] firends = line.split(":")[1].split(" "); for (int i = 0; i < firends.length; i++) { context.write(new Text(user+":"+firends[i]),new IntWritable(0)); for (int j = i+1; j < firends.length; j++) { context.write(new Text(firends[i]+":"+firends[j]),new IntWritable(1)); } } } } class WordcountReducer extends Reducer<Text,IntWritable,Text,IntWritable> { @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0;boolean isFriend = false; for (IntWritable value:values){ if(value.get() == 0) { isFriend = true;break; } else{ sum+=value.get(); } } if(!isFriend) context.write(key,new IntWritable(sum)); } } public class WordcountDriver { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { Configuration conf = new Configuration(); conf.set("fs.defaultFS", "file:///"); FileSystem fs= FileSystem.get(conf); String outputPath = "/software/java/data/output/"; if(fs.exists(new Path(outputPath))) fs.delete(new Path(outputPath),true); Job job = Job.getInstance(conf); job.setJarByClass(WordcountDriver.class); job.setMapperClass(WordcountMapper.class); job.setReducerClass(WordcountReducer.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.setInputPaths(job, new Path("/software/java/data/input/")); FileOutputFormat.setOutputPath(job, new Path(outputPath)); //将job配置的参数,以及job所用的java类所在的jar包提交给yarn去运行 //job.submit(); boolean res = job.waitForCompletion(true); } }
推荐上的思考
这种算法对于好友多的人来说是友好的,但是对于好友只有两个甚至一个人的情况就会推荐不出来好友。抖音做的就比较好,他会用你好友的列表的人推荐给你
题外话:
最近逛淘宝的时候发现:淘宝推荐的东西,就是我以前买过东西类似的,意思就是说我以前买了100快的东西,现在推荐出来的差不多都是100多的,我想提升一下品质买一个200快的衣服,但是他不给我推荐。个人感觉这也是需要提升的吧。