0


大数据商品推荐系统

  1. 引言

1.1 目的

Hadoop是一个开发和运行处理大规模数据的软件平台,是Appach的一个用java语言实现开源软件框架,实现在大量计算机组成的集群中对海量数据进行分布式计算,同时它也是当前最流行的云计算平台。本次课程设计通过Hadoop云计算平台实现一个商品推荐系统,希望通过编写本次课程设计,能够对Hadoop有一个基本的了解。

1.2 背景

随着科技与信息技术的迅猛发展,社会进入了一个全新的高度信息化的时代,互联网无处不在,影响了人类生活的方方面面,并彻底改变了人们的生活方式。在面对庞大且复杂的互联网信息时往往感到无从下手,使得在互联网中找寻有用信息的成本巨大,产生了所谓的“信息过载”问题。搜索引擎和推荐系统的产生为解决“信息过载”问题提供了非常重要的技术手段。推荐系统不需要用户提供明确的需求,而是通过分析用户的历史行为来对用户的兴趣进行建模,从而主动给用户推荐可能满足他们兴趣和需求的信息。

近年来,在电商领域中各种各样的网购平台发展迅速,网上购物已成为许多人选购商品的基本途径。同时随着C2C经营模式的普及,越来越多的人纷纷在网上开店,网购平台上每时每刻都有新商家入驻,商品上下架,伴随着海量的商品信息更新。如何实时准确地收集并更新大量数据,怎样让消费者在网购平台快速找到自己心目中的商品,这些问题使网购平台所使用的商品搜索引擎面临着巨大挑战。

面对海量购物数据,单机运行处理的模式不论从效率或处理能力上来讲,都已经满足不了如今数据挖掘的需求以及不便于用户购物。为了方便用户在购物过程中购物,通过其购买信息与购买物品对其推荐相关物品。

2 需求分析

商品推荐系统是对用户的历史行为进行挖掘,对用户兴趣信息进行建模,并对用户未来行为进行预测,从而建立用户和内容的关系,满足用户对商品的推荐需求的一种智能系统。通过对主要的推荐算法进行比较分析,模拟实现了基于用户行为的智能推荐系统,提高了推荐算法的有效性。商品推荐系统是为了更精准的为用户推荐他们想要的内容,如果一个用户在浏览商品信息的时候,通过对用户数据的记录,和已经存在的其他的用户记录进行分析,从而为用户推荐相应的数据。

用户行为数据的处理。商品推荐系统用户、商品行为主要是用户的购买行为。

购买行为包含了丰富的用户购买商品,如何处理这些购买商品是推荐系统实现的关键。

推荐系统的推荐质量。推荐系统的最终目的是推荐,所以推荐质量是整个系统设计的最终目的。

3 系统设计

3.1系统架构设计

系统总体架构如图3.1所示,包括客户端、服务器、数据库和Hadoop集群。客户端面向用户,通过购物软件HTTP请求发送给服务器,并解析来自服务器的响应,用直观的方式展现给客户。

服务器是系统后台的“出入口”,大部分的业务逻辑都在服务器中实现。服务器会和数据库交互,将需要持久化的数据存储到数据库,客户端传来的查询任务也由服务器去完成。数据库和文件系统一样,是数据持久化的地方。用户的推荐商品指数会保存到数据库,服务器和Hadoop集群都会访问数据库。Hadoop集群会将原始数据文件拷贝到HDFS中,方便MapReduce访问,执行的结果保存到数据库中,供服务器使用。

图3.1系统架构设计

3.2系统层次架构设计

为保证系统的扩展性以及可维护性,基于Hadoop的商品推荐系统采用分层架构设计。分层架构设计可以很好的将业务逻辑区分开,使开发人员专注每层的开发从而降低系统的开发风险。其主要分为5层:界面表示层、应用功能层、服务提供层、数据访问层和数据资源层。系统层次架构如图3.2所示。

图3.2系统层次架构设计

3.3系统功能模块设计

基于Hadoop的商品推荐系统,以商品推荐为基础,采集分析和分析用户、商品行为数据,以推荐为最终目标。为用户提供智能的个性化推荐服务。本项目采用hadoop上HDFS集群,通过MapReduce程序以作业的方式对数据进行处理和分析,其主要的功能如图3.3所示。

图3.3系统功能模块设计

3.4系统数据库设计

数据库是数据持久化的重要方式,本次课程设计的系统中需要持久化的数据是推荐运算结果。本次采用MySQL数据库。数据表结构results 表用于保存推荐运算的最终结果数据,由MapReduce负责插入到数据库中。

图3.4系统数据库设计

字段名称

数据类型

说明

id

int(11)

id

uid

varchar(20)

用户id

gid

varchar(20)

商品id

expect

int(10)

推荐指数

表3.4系统数据库设计

4.系统开发

4.1源程序清单

**4.11 **计算用户购买商品的列表:

文件名

类名

UserByList.java

UserByList

UserByListMapper

UserByListReducer

由原始数据提供计算

** 4.12 **计算商品的共现关系:

文件名

类名

CommonCount.java

CommonCount

CommonCountMapper

CommonCountReducer

根据第一步的计算结果计算

4.13 计算用户的购买向量:

文件名

类名

GoodByList.java

GoodByList

GoodByListMapper

GoodByListReducer

第1步的结果或者最原始数据。

4.14 推荐结果:

文件名

类名

MultiplyMatrix.java

MultiplyMatrixMapper1

MultiplyMatrixMapper2

MultiplyMatrixReducer

算法模型:推荐矩阵=(相似度矩阵*用户购买向量)

商品共现矩阵乘以用户购买向量,形成临时的推荐结果。

4.15 数据去重:

文件名

类名

CutRepeat.java

CutRepeat

CutRepeatMapper

CutRepeatReducer

数据去重,在推荐结果中去掉用户已购买的商品信息

4.16推荐结果存储于数据库中:

文件名

类名

ConnMysql.java

ConnMysqlMapper<LW,Text,Text,Text>

ConnMysqlReducer<Text,Text,Key,NullWritable>

CREATE TABLE results

将计算后的推荐结果储存于数据库中

MySQL数据库,grms.result

4.17构建对象:

文件名

类名

JobControl.java

JobControl

运行推荐结果

4.2功能实现

4.21计算用户购买商品的列表:

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;

4.22计算商品的共现关系:

    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;

4.23计算用户的购买向量:

    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;

4.24计算用户的购买向量:

    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;

4.25推荐结果:

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;

4.26数据去重:

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;

4.27推荐结果存储于数据库中:

//重写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");

5.系统测试

5.1测试方法

收集数据后进行代码测试

5.2测试结果

5.21计算用户购买商品的列表

5.22计算商品的共现次数(共现矩阵)

5.23计算用户的购买向量

5.24推荐结果:

5.25数据去重:

5.25推荐结果入库


本文转载自: https://blog.csdn.net/weixin_48579084/article/details/136507311
版权归原作者 ArondightEX 所有, 如有侵权,请联系我们删除。

“大数据商品推荐系统”的评论:

还没有评论