首页 > 代码库 > hadoop1-商品推荐之商品关联性最简易建模1
hadoop1-商品推荐之商品关联性最简易建模1
1、如题,这是自己通过在QQ交流上得到的一个想法。
2、
数据文件 1.txt:
001={001,002,004,006,008} 003={003,002,001,009,004}
002={002,003,005,006,008,009,007} 004={004,005,006,009,008,007}
005={005,003,007,008,001,002} 006={006,001,004,009,005,008}
说明:
1、 每一个数字代表一个商品Id
2、 每一行中有两个商品,每个商品ID后={}内部代表的是从001这个商品直接跳转到{里面商品}的记录。商品自身属于一个跳转
如: 001——》002
001——》004
…..
得到对应的记录为:001={001,002,004,006,008}
3、每一行两个商品对应的{}相同的商品ID为表示一个关联
如:001={001,002,004,006,008} 003={003,002,001,009,004}
对应关联的有:001,002,004亦即3个关联
3、 要求reduce输出为001:003=3
即:商品001和商品003的关联性为3
设计目的:
通过两两商品的关联性对比,得到商品的最优推荐(比较简单的啊)。
思路分析:
1、 map端:得到商品A和商品B的ID组合为key,
同时分割行得到关联商品交集的数量作为value输出
2、reducer端原样输出,不做处理(可以使用默认的reducer)
设计代码:
package product;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import org.apache.hadoop.conf.Configuration;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.lib.input.FileInputFormat;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import org.apache.hadoop.util.GenericOptionsParser;public class SimpleRelation { public static class Map extends Mapper<LongWritable, Text, Text, IntWritable>{ private static Text k = new Text(); private static IntWritable v = new IntWritable(0); protected void map(LongWritable key, Text value, Context context) throws java.io.IOException ,InterruptedException { // line demo :"001={001,002,004,006,008}\t003={003,002,001,009,004}" String line = value.toString(); //分割为两个商品信息 String[] splits = line.split("\t"); if(splits.length != 2) return; //对每个商品信息进行分割 String[] proc1 = splits[0].split("="); String[] proc2 = splits[1].split("="); k.set(proc1[0]+":"+proc1[0]); v.set(getSameNum(proc1[1],proc2[1])); context.write(k, v); }; //取得交集的数量,此部分或可以优化 private int getSameNum(String str1, String str2) { //str1 = "{001,002,004,006,008}" str2 = "{003,002,001,009,004}" //取交集即可。 //取得对应的list集合,Arrays.asList返回的是固定大小的list,仅能查,不能修改,所以上面采用手工赋值的方式 List<String> proc1 = new ArrayList<String>(); String[] temp = str1.substring(1, str1.length()-1).split(","); for (String s : temp) { proc1.add(s); } List<String> proc2 = Arrays.asList(str2.substring(1, str2.length()-1).split(",")); //该方法从列表中移除未包含在指定 proc2 中的所有元素。 proc1.retainAll(proc2); return proc1.size(); } } // 仅使用map即可得到解决,reducer采用系统默认的即可 public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs(); if(otherArgs.length != 2){ System.err.println("Usage:SimpleRelation"); System.exit(2); } Job job = new Job(conf,"SimpleRelation"); job.setJarByClass(SimpleRelation.class); job.setMapperClass(Map.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); }}
程序输出:
[root@hadoop ~]# hadoop dfs -cat /output/*
001:001 3
002:002 5
005:005 3
当然程序比较简单,毕竟是自己设计的,不过往下会一步步应用我们所学的。