赞
踩
Hadoop是一个开发和运行处理大规模数据的软件平台,是Appach的一个用java语言实现开源软件框架,实现在大量计算机组成的集群中对海量数据进行分布式计算,同时它也是当前最流行的云计算平台。本次课程设计通过Hadoop云计算平台实现一个商品推荐系统,希望通过编写本次课程设计,能够对Hadoop有一个基本的了解。
近年来,在电商领域中各种各样的网购平台发展迅速,网上购物已成为许多人选购商品的基本途径。同时随着C2C经营模式的普及,越来越多的人纷纷在网上开店,网购平台上每时每刻都有新商家入驻,商品上下架,伴随着海量的商品信息更新。如何实时准确地收集并更新大量数据,怎样让消费者在网购平台快速找到自己心目中的商品,这些问题使网购平台所使用的商品搜索引擎面临着巨大挑战。
面对海量购物数据,单机运行处理的模式不论从效率或处理能力上来讲,都已经满足不了如今数据挖掘的需求以及不便于用户购物。为了方便用户在购物过程中购物,通过其购买信息与购买物品对其推荐相关物品。
商品推荐系统是对用户的历史行为进行挖掘,对用户兴趣信息进行建模,并对用户未来行为进行预测,从而建立用户和内容的关系,满足用户对商品的推荐需求的一种智能系统。通过对主要的推荐算法进行比较分析,模拟实现了基于用户行为的智能推荐系统,提高了推荐算法的有效性。商品推荐系统是为了更精准的为用户推荐他们想要的内容,如果一个用户在浏览商品信息的时候,通过对用户数据的记录,和已经存在的其他的用户记录进行分析,从而为用户推荐相应的数据。
用户行为数据的处理。商品推荐系统用户、商品行为主要是用户的购买行为。
购买行为包含了丰富的用户购买商品,如何处理这些购买商品是推荐系统实现的关键。
推荐系统的推荐质量。推荐系统的最终目的是推荐,所以推荐质量是整个系统设计的最终目的。
系统总体架构如图3.1所示,包括客户端、服务器、数据库和Hadoop集群。客户端面向用户,通过购物软件HTTP请求发送给服务器,并解析来自服务器的响应,用直观的方式展现给客户。
服务器是系统后台的“出入口”,大部分的业务逻辑都在服务器中实现。服务器会和数据库交互,将需要持久化的数据存储到数据库,客户端传来的查询任务也由服务器去完成。数据库和文件系统一样,是数据持久化的地方。用户的推荐商品指数会保存到数据库,服务器和Hadoop集群都会访问数据库。Hadoop集群会将原始数据文件拷贝到HDFS中,方便MapReduce访问,执行的结果保存到数据库中,供服务器使用。
图3.1系统架构设计
为保证系统的扩展性以及可维护性,基于Hadoop的商品推荐系统采用分层架构设计。分层架构设计可以很好的将业务逻辑区分开,使开发人员专注每层的开发从而降低系统的开发风险。其主要分为5层:界面表示层、应用功能层、服务提供层、数据访问层和数据资源层。系统层次架构如图3.2所示。
图3.2系统层次架构设计
基于Hadoop的商品推荐系统,以商品推荐为基础,采集分析和分析用户、商品行为数据,以推荐为最终目标。为用户提供智能的个性化推荐服务。本项目采用hadoop上HDFS集群,通过MapReduce程序以作业的方式对数据进行处理和分析,其主要的功能如图3.3所示。
图3.3系统功能模块设计
数据库是数据持久化的重要方式,本次课程设计的系统中需要持久化的数据是推荐运算结果。本次采用MySQL数据库。数据表结构results 表用于保存推荐运算的最终结果数据,由MapReduce负责插入到数据库中。
图3.4系统数据库设计
字段名称 | 数据类型 | 说明 |
id | int(11) | id |
uid | varchar(20) | 用户id |
gid | varchar(20) | 商品id |
expect | int(10) | 推荐指数 |
文件名 | 类名 |
UserByList.java | UserByList |
UserByListMapper | |
UserByListReducer | |
由原始数据提供计算 |
文件名 | 类名 |
CommonCount.java | CommonCount |
CommonCountMapper | |
CommonCountReducer | |
根据第一步的计算结果计算 |
文件名 | 类名 |
GoodByList.java | GoodByList |
GoodByListMapper | |
GoodByListReducer | |
第1步的结果或者最原始数据。 |
文件名 | 类名 |
MultiplyMatrix.java | MultiplyMatrixMapper1 |
MultiplyMatrixMapper2 | |
MultiplyMatrixReducer | |
算法模型:推荐矩阵=(相似度矩阵*用户购买向量) 商品共现矩阵乘以用户购买向量,形成临时的推荐结果。 |
文件名 | 类名 |
CutRepeat.java | CutRepeat |
CutRepeatMapper | |
CutRepeatReducer | |
数据去重,在推荐结果中去掉用户已购买的商品信息 |
文件名 | 类名 |
ConnMysql.java | ConnMysqlMapper<LW,Text,Text,Text> |
ConnMysqlReducer<Text,Text,Key,NullWritable> | |
CREATE TABLE `results` | |
将计算后的推荐结果储存于数据库中 MySQL数据库,grms.result |
文件名 | 类名 |
JobControl.java | JobControl |
运行推荐结果 |
public class UserByList extends Configured implements Tool{
//mapper
public static class UserByListMapper
extends Mapper<LongWritable,Text,Text,Text>{
@Override
protected void map(LongWritable key,Text value,Context context) throws IOException, InterruptedException {
String[] strs = value.toString().split("\t");
context.write(new Text(strs[0].trim()),new Text(strs[1].trim()));
}
}
//reduce
public static class UserByListReduce extends Reducer<Text,Text,Text,Text> {
@Override
protected void reduce(Text key,Iterable<Text> values,Context context) throws IOException, InterruptedException {
StringBuilder sb = new StringBuilder();
for (Text value:values){
sb.append(value.toString()).append(",");
}
String result = sb.substring(0,sb.length()-1);
context.write(key,new Text(result));
}
}
job.setMapperClass(UserByListMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job,input);
job.setReducerClass(UserByListReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job,output);
return job.waitForCompletion(true)?0:1;
job.setMapperClass(CommonCountMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job,input);
job.setReducerClass(CommonCountReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job,output);
return job.waitForCompletion(true)?0:1;
job.setMapperClass(GoodLikeMatrixMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job,input);
job.setReducerClass(GoodLikeMatrixReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job,output);
return job.waitForCompletion(true)?0:1;
job.setMapperClass(GoodByListMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job,input);
job.setReducerClass(GoodByListReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job,output);
return job.waitForCompletion(true)?0:1;
public static class MultiplyMatrixReduce extends Reducer<Text,Text,Text,IntWritable>{
@Override
protected void reduce(Text key,Iterable<Text> values,Context context) throws IOException, InterruptedException {
String[] str1 = null;
String[] str2 = null;
for (Text value:values){
String flag = value.toString().substring(0,1);
String result = value.toString().substring(1);
if (flag.equals("s")){
str1 = result.split(",");
}else if (flag.equals("t")){
str2 = result.split(",");
}
}
for (int i=0;i<str1.length;i++){
for (int j=0;j<str2.length;j++){
String u = str1[i].split(":")[0];
int uV = Integer.valueOf(str1[i].split(":")[1]);
String g = str2[j].split(":")[0];
int gV = Integer.valueOf(str2[j].split(":")[1]);
context.write(new Text(g+","+u),new IntWritable(uV*gV));
}
}
}
}
job.setMapperClass(MultiplyMatrixMapper1.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
MultipleInputs.addInputPath(job,input1,TextInputFormat.class,
MultiplyMatrixMapper1.class);
MultipleInputs.addInputPath(job,input2,TextInputFormat.class,
MultiplyMatrixMapper2.class);
job.setReducerClass(MultiplyMatrixReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job,output);
return job.waitForCompletion(true)?0:1;
public static class CutRepeatMapper1 extends Mapper<LongWritable,Text,Text,Text>{
@Override
protected void map(LongWritable key,Text value,Context context)
throws IOException, InterruptedException {
//原数据
String[] strs = value.toString().split("\t");
context.write(new Text(strs[0]+"\t"+strs[1]),
new Text("*"));
}
}
public static class CutRepeatMapper2 extends Mapper<LongWritable,Text,Text,Text>{
@Override
protected void map(LongWritable key,Text value,Context context)
throws IOException, InterruptedException {
//推荐数据
String[] strs = value.toString().split("\t");
String[] strs1 = strs[0].split(",");
context.write(new Text(strs1[0]+"\t"+strs1[1]),
new Text(strs[1]));
}
}
//reduce
public class CutRepeatReduce extends Reducer<Text,Text,Text,Text>{
@Override
protected void reduce(Text key,Iterable<Text> values,Context context)
throws IOException, InterruptedException {
Iterator<Text> iterator = values.iterator();
Text next = iterator.next();
if(!iterator.hasNext()){
context.write(key,new Text(next));
}
}
}
job.setMapperClass(CutRepeatMapper1.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
MultipleInputs.addInputPath(job,input1,TextInputFormat.class,
CutRepeatMapper1.class);
MultipleInputs.addInputPath(job,input2,TextInputFormat.class,
CutRepeatMapper2.class);
job.setReducerClass(CutRepeatReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job,output);
return job.waitForCompletion(true)?0:1;
//重写DBWriter
public static class TblsWritable implements Writable,DBWritable{
String uid;
String gid;
Integer expect;
public TblsWritable(){
}
public TblsWritable(String uid, String gid, Integer expect) {
this.uid = uid;
this.gid = gid;
this.expect = expect;
}
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeUTF(this.uid);
dataOutput.writeUTF(this.gid);
dataOutput.write(this.expect);
}
@Override
public void readFields(DataInput dataInput) throws IOException {
this.uid=dataInput.readUTF();
this.gid=dataInput.readUTF();
this.expect=dataInput.readInt();
}
@Override
public void write(PreparedStatement prep) throws SQLException {
prep.setString(1,this.uid);
prep.setString(2,this.gid);
prep.setInt(3,this.expect);
}
@Override
public void readFields(ResultSet rs) throws SQLException {
this.uid=rs.getString(1);
this.gid=rs.getString(2);
this.expect=rs.getInt(3);
}
}
DBConfiguration.configureDB(conf,
"com.mysql.jdbc.Driver",
"jdbc:mysql://60.205.212.196:3306/grms",
"root",
"123456");
收集数据后进行代码测试
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。