Hadoop 系列(二)好友推荐及思考

一:流程分析

好友推荐简介

        好友推荐功能大家都比较熟悉,在这里就不作介绍了。重点介绍以下算法:通过计算共同好友来确定两人的好友关系

        

        如图所示:用户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快的衣服,但是他不给我推荐。个人感觉这也是需要提升的吧。

原文地址:https://www.cnblogs.com/wuxiaolong4/p/12731493.html