使用hadoop实现关联商品统计
转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/40184581
近期几天一直在看hadoop相关的书籍,眼下略微有点感觉,自己就仿照着WordCount程序自己编写了一个统计关联商品。
需求描写叙述:
依据超市的销售清单,计算商品之间的关联程度(即统计同一时候买A商品和B商品的次数)。
数据格式:
超市销售清单简化为例如以下格式:一行表示一个清单,每一个商品採用 "," 切割,例如以下图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2ppbWFubWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
需求分析:
採用hadoop中的mapreduce对该需求进行计算。
map函数主要拆分出关联的商品,输出结果为 key为商品A,value为商品B,对于第一条三条结果拆分结果例如以下图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2ppbWFubWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
这里为了统计出和A、B两件商品想关联的商品。所以商品A、B之间的关系输出两条结果即 A-B、B-A。
reduce函数分别对和商品A相关的商品进行分组统计,即分别求value中的各个商品出现的次数,输出结果为key为商品A|商品B。value为该组合出现的次数。针对上面提到的5条记录,对map输出中key值为R的做下分析:
通过map函数的处理,得到例如以下图所看到的的记录:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2ppbWFubWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
reduce中对map输出的value值进行分组计数,得到的结果例如以下图所看到的
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2ppbWFubWFu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
将商品A B作为key,组合个数作为value输出,输出结果例如以下图所看到的:
对于需求的实现过程的分析到眼下就结束了。以下就看下详细的代码实现
代码实现:
关于代码就不做具体的介绍。具体參照代码之中的凝视吧。
package com; import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
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 org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; public class Test extends Configured implements Tool{ /**
* map类,实现数据的预处理
* 输出结果key为商品A value为关联商品B
* @author lulei
*/
public static class MapT extends Mapper<LongWritable, Text, Text, Text> {
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException{
String line = value.toString();
if (!(line == null || "".equals(line))) {
//切割商品
String []vs = line.split(",");
//两两组合。构成一条记录
for (int i = 0; i < (vs.length - 1); i++) {
if ("".equals(vs[i])) {//排除空记录
continue;
}
for (int j = i+1; j < vs.length; j++) {
if ("".equals(vs[j])) {
continue;
}
//输出结果
context.write(new Text(vs[i]), new Text(vs[j]));
context.write(new Text(vs[j]), new Text(vs[i]));
}
}
}
}
} /**
* reduce类,实现数据的计数
* 输出结果key 为商品A|B value为该关联次数
* @author lulei
*/
public static class ReduceT extends Reducer<Text, Text, Text, IntWritable> {
private int count; /**
* 初始化
*/
public void setup(Context context) {
//从參数中获取最小记录个数
String countStr = context.getConfiguration().get("count");
try {
this.count = Integer.parseInt(countStr);
} catch (Exception e) {
this.count = 0;
}
}
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException{
String keyStr = key.toString();
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
//利用hash统计B商品的次数
for (Text value : values) {
String valueStr = value.toString();
if (hashMap.containsKey(valueStr)) {
hashMap.put(valueStr, hashMap.get(valueStr) + 1);
} else {
hashMap.put(valueStr, 1);
}
}
//将结果输出
for (Entry<String, Integer> entry : hashMap.entrySet()) {
if (entry.getValue() >= this.count) {//仅仅输出次数不小于最小值的
context.write(new Text(keyStr + "|" + entry.getKey()), new IntWritable(entry.getValue()));
}
}
}
} @Override
public int run(String[] arg0) throws Exception {
// TODO Auto-generated method stub
Configuration conf = getConf();
conf.set("count", arg0[2]); Job job = new Job(conf);
job.setJobName("jobtest"); job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class); job.setMapperClass(MapT.class);
job.setReducerClass(ReduceT.class); FileInputFormat.addInputPath(job, new Path(arg0[0]));
FileOutputFormat.setOutputPath(job, new Path(arg0[1])); job.waitForCompletion(true); return job.isSuccessful() ? 0 : 1; } /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
if (args.length != 3) {
System.exit(-1);
}
try {
int res = ToolRunner.run(new Configuration(), new Test(), args);
System.exit(res);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
上传执行:
将程序打包成jar文件,上传到机群之中。
将測试数据也上传到HDFS分布式文件系统中。
命令执行截图例如以下图所看到的:
执行结束后查看对应的HDFS文件系统,例如以下图所看到的:
到此一个完整的mapreduce程序就完毕了,关于hadoop的学习。自己还将继续~
使用hadoop实现关联商品统计的更多相关文章
- 基于Hadoop的地震数据分析统计
源码下载地址:http://download.csdn.net/detail/huhui_bj/5645641 opencsv下载地址:http://download.csdn.net/detail/ ...
- 使用bash关联数组统计单词
使用bash关联数组统计单词 从bash 4开始支持关联数组,使用前需要声明,即 declare -A map map[key1]=value1 map[key2]=value2 map=([key1 ...
- Hadoop Mapreduce 案例 wordcount+统计手机流量使用情况
mapreduce设计思想 概念:它是一个分布式并行计算的应用框架它提供相应简单的api模型,我们只需按照这些模型规则编写程序,即可实现"分布式并行计算"的功能. 案例一:word ...
- Hadoop入门实例——WordCount统计单词
首先要说明的是运行Hadoop需要jdk1.6或以上版本,如果你还没有搭建好Hadoop集群,请参考我的另一篇文章: Linux环境搭建Hadoop伪分布模式 马上进入正题. 1.启动Hadoop集群 ...
- hadoop fs:du & count统计hdfs文件(目录下文件)大小的用法
hadoop fs 更多用法,请参考官网:http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html 以下是我的使用hadoop fs -du统计文 ...
- 初学Hadoop之中文词频统计
1.安装eclipse 准备 eclipse-dsl-luna-SR2-linux-gtk-x86_64.tar.gz 安装 1.解压文件. 2.创建图标. ln -s /opt/eclipse/ec ...
- 初学Hadoop之WordCount词频统计
1.WordCount源码 将源码文件WordCount.java放到Hadoop2.6.0文件夹中. import java.io.IOException; import java.util.Str ...
- 023_数量类型练习——Hadoop MapReduce手机流量统计
1) 分析业务需求:用户使用手机上网,存在流量的消耗.流量包括两部分:其一是上行流量(发送消息流量),其二是下行流量(接收消息的流量).每种流量在网络传输过程中,有两种形式说明:包的大小,流量的大小. ...
- Eclipse上运行第一个Hadoop实例 - WordCount(单词统计程序)
需求 计算出文件中每个单词的频数.要求输出结果按照单词的字母顺序进行排序.每个单词和其频数占一行,单词和频数之间有间隔. 比如,输入两个文件,其一内容如下: hello world hello had ...
随机推荐
- 关于HTML5服务器发送事件(SSE)
最近在看 W3School 上关于 HTML 5 的教程.在看到 HTML 5 服务器发送事件 ( SSE, server-sent event ) 时,没怎么弄明白示例代码是怎么回事,寻找其他教程, ...
- modprobe
1.1 简介 Linux命令:modprobe .功能说明:自动处理可载入模块.语 法:modprobe [-acdlrtvV][--help][模块文件][符号名称 = 符号值].补充说明:modp ...
- linux 端口设置结构体 struc
目录(?)[-] 一 输入模式 三输出模式 四控制模式 六特殊的控制字符 字符 TIME和MIN值 通过shell访问终端模式 终端速度 其他函数 使用termios结构的密码程序 termi ...
- Denoise Autoencoder简单理解
自编码器通过学习隐含特征来表达原始数据,那什么是denoise autoencoder呢? 关于Autoencoder参考:http://blog.csdn.net/on2way/article/de ...
- csu 1798(树上最远点对,线段树+lca)
1798: 小Z的城市 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 60 Solved: 16[Submit][Status][Web Board] ...
- 【hdoj_1715】大菲波数(大数+100000000进制)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1715 本题采用大数加法即可解决.采用100000000进制速度更快. C++代码如下: #include& ...
- Web前端开发最佳实践(3):前端代码和资源的压缩与合并
一般在网站发布时,会压缩前端HTML.CSS.JavaScript代码及用到的资源文件(主要是图片文件),目的是加快文件在网络中的传输,让网页更快的展现.当然,CDN分发.缓存等方式也是加快代码或资源 ...
- loadrunner场景执行出现:Failed to Initialize. Reason: TimeOut
问题1: Failed to Initialize. Reason: TimeOut LoadRunner的异常原因(Failed to Initialize. Reason: TimeOut) ...
- mysql 事务回滚
begindeclare t_error integer default 0; //添加变量t_error并赋初始值为0declare continue handler for sqlexcepti ...
- 洛谷P2922 [USACO008DEC] 秘密消息Secret Message [Trie树]
洛谷传送门,BZOJ传送门 秘密消息Secret Message Description 贝茜正在领导奶牛们逃跑.为了联络,奶牛们互相发送秘密信息. 信息是二进制的,共有M(1≤M≤5 ...