MapReduce用户行为数据之购买率最高的商品

需求分析:
商品的购买率可以反映用户群体对商品的忠诚度和对商品描述的接受程度,利用Map统计出所有的商品,在Reduce中统计出每种商品的点击数和购买数,通过公式购买率=购买数/(点击数+购买数)来进行记录,在cleanup阶段统计出Top3。
测试数据:
在这里插入图片描述
在这里插入图片描述
结果:
在这里插入图片描述
可视化如下图3:
在这里插入图片描述
部分代码分析:
clean up阶段按升序输出Top5,则return的数据应为int型且大于0。为实现return的数据为int型,将购买率(float型)*1000相减后并转换为int型。即只比较到小数点后4位。
在这里插入图片描述
完整代码:
map阶段

package rateofpurchase;
import java.io.IOException;
import org.apache.hadoop.io.FloatWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class WordCountMapper extends Mapper<LongWritable,Text,Text,IntWritable>{
    Text k = new Text();
    IntWritable v = new IntWritable();
    @Override
    protected void map(LongWritable key, Text value, Context context) 
            throws IOException, InterruptedException {
        //1 获取一行
        String line = value.toString();
        
        //2 切割单词
        String[] fields = line.split("\t");
        
        //3 ite_ID为key,act_ID为value
        k.set(fields[2]);
        v.set(Integer.valueOf(fields[4]));
        
        //4 写出
        context.write(k, v);
    }
}

reduce阶段:

package rateofpurchase;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.FloatWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class WordCountReducer extends Reducer<Text,IntWritable,Text,FloatWritable>{
    FloatWritable v = new FloatWritable();
  
    Map<String,Float> map=new HashMap<String,Float>();

    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int buy=0;
        int click=0;
        float rate=0;
        // 1 累加求和
        for (IntWritable value : values) {            
            if(value.get()==1){
                buy+=1;
            }else{
                click+=1;
            }
        }
        
        rate=(float)buy/(float)(buy+click);    
   
        // 2 写出
//        context.write(key, new DoubleWritable(rate));
        String k=key.toString();
//        map.put(k, v);
        map.put(k,rate);
    }

    @Override
    protected void cleanup(Context context) throws IOException, InterruptedException {
        //这里将map.entrySet()转换成list
        List<Map.Entry<String,Float>> list=new LinkedList<Map.Entry<String,Float>>(map.entrySet());
        //通过比较器来实现排序
        Collections.sort(list, new Comparator<Map.Entry<String, Float>>(){
            //升序排序
            //例0.1278与0.2878比较 1278-2878<0 
            //例0.25783与0.25782比较 int(2578.3-2578.2)= 0 return 0;相等,即只比较到小数点后4位。 
            @Override
            public int compare(Map.Entry<String, Float> o1, Map.Entry<String, Float> o2) {
                return (int)((10000*o2.getValue())-(10000*o1.getValue()));
            }
        });
        
        for(int i=0;i<3;i++){
            context.write(new Text(list.get(i).getKey()),new FloatWritable(list.get(i).getValue()));
        }

    }
}

driver:

package rateofpurchase;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.FloatWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class RateOfPurchase {

    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException{
        Configuration conf = new Configuration();
        
        //1 获取job对象
        Job job = Job.getInstance(conf);
        
        //2 设置jar存储位置
        job.setJarByClass(RateOfPurchase.class);
        
        //3 关联map和reduce类
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);
        
        //4 设置Mapper阶段输出数据的key和value类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
        
        //5 设置最终数据输出的key和value类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(FloatWritable.class);
        
        //6 设置输入路径和输出路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        //7 提交job
        //job.submit();
        boolean result = job.waitForCompletion(true);
        System.exit(result? 0 : 1);
    }
    
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值