/GRMS

基于Hadoop的商品推荐系统

Primary LanguageJava

基于Hadoop的商品推荐系统

基于特征: 基于行为:具有了一定的历史特征。 基于用户: 基于商品:

推荐结果=用户的购买向量*物品的相似度矩阵

物品的相似度:物品的共现次数

1.项目名:GRMS 2.添加Maven依赖:pom.xml 3.创建包: com.briup.bigdata.project.grms |--step1 |--step2 |--... |--utils 4.将集群上的四个xml配置文件放到resources目录中。 5.在HDFS集群的根目录下创建目录: /grms |--rawdata |-----matrix.txt |--step1 |--... 6.开始编程。 原始数据: 10001 20001 1 10001 20002 1 10001 20005 1 10001 20006 1 10001 20007 1 10002 20003 1 10002 20004 1 10002 20006 1 10003 20002 1 10003 20007 1 10004 20001 1 10004 20002 1 10004 20005 1 10004 20006 1 10005 20001 1 10006 20004 1 10006 20007 1

a.计算用户购买商品的列表

​ 类名:UserBuyGoodsList.java

​ UserBuyGoodsList ​ UserBuyGoodsListMapper ​ UserBuyGoodsListReducer ​ 结果数据: ​ 10001 20001,20005,20006,20007,20002 ​ 10002 20006,20003,20004 ​ 10003 20002,20007 ​ 10004 20001,20002,20005,20006 ​ 10005 20001 ​ 10006 20004,20007

b.计算商品的共现关系

​ 文件:GoodsCooccurrenceList.java

​ 类名:GoodsCooccurrenceList ​ GoodsCooccurrenceListMapper ​ GoodsCooccurrenceListReducer ​ 数据来源:第1步的计算结果 ​ 计算结果: ​ 20001 20001 ​ 20001 20001 ​ 20001 20002 ​ 20001 20005 ​ 20001 20006 ​ 20001 20007 ​ 20001 20001 ​ 20001 20006 ​ 20001 20005 ​ 20001 20002 ​ 20002 20007 ​ 20002 20001 ​ 20002 20005 ​ 20002 20006 ​ 20002 20007 ​ 20002 20002 ​ 20002 20006 ​ 20002 20005 ​ 20002 20002 ​ 20002 20001 ​ 20002 20002 ​ 20003 20003 ​ 20003 20004 ​ 20003 20006 ​ 20004 20004 ​ 20004 20007 ​ 20004 20004 ​ 20004 20006 ​ 20004 20003 ​ 20005 20002 ​ 20005 20006 ​ 20005 20005 ​ 20005 20001 ​ 20005 20005 ​ 20005 20006 ​ 20005 20007 ​ 20005 20001 ​ 20005 20002 ​ 20006 20005 ​ 20006 20003 ​ 20006 20004 ​ 20006 20001 ​ 20006 20002 ​ 20006 20006 ​ 20006 20002 ​ 20006 20006 ​ 20006 20007 ​ 20006 20006 ​ 20006 20001 ​ 20006 20005 ​ 20007 20006 ​ 20007 20004 ​ 20007 20007 ​ 20007 20002 ​ 20007 20007 ​ 20007 20005 ​ 20007 20001 ​ 20007 20002 ​ 20007 20007

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

​ 文件:GoodsCooccurrenceMatrix.java

​ 类名:GoodsCooccurrenceMatrix ​ GoodsCooccurrenceMatrixMappper ​ GoodsCooccurrenceMatrixReducer ​ 数据来源:第2步的结果 ​ 计算结果: ​ 20001 20001:3,20002:2,20005:2,20006:2,20007:1 ​ 20002 20001:2,20002:3,20005:2,20006:2,20007:2 ​ 20003 20003:1,20004:1,20006:1 ​ 20004 20003:1,20004:2,20006:1,20007:1 ​ 20005 20001:2,20002:2,20005:2,20006:2,20007:1 ​ 20006 20001:2,20002:2,20003:1,20004:1,20005:2,20006:3,20007:1 ​ 20007 20001:1,20002:2,20004:1,20005:1,20006:1,20007:3

d.计算用户的购买向量

​ 文件:UserBuyGoodsVector.java

​ 类名:UserBuyGoodsVector ​ UserBuyGoodsVectorMapper ​ UserBuyGoodsVectorReducer ​ 源数据:第1步的结果或者最原始数据。 ​ 计算结果: ​ 20001 10001:1,10004:1,10005:1 ​ 20002 10001:1,10003:1,10004:1 ​ 20003 10002:1 ​ 20004 10002:1,10006:1 ​ 20005 10001:1,10004:1 ​ 20006 10001:1,10002:1,10004:1 ​ 20007 10001:1,10003:1,10006:1

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

​ 文件:MultiplyGoodsMatrixAndUserVector.java

​ 类名:MultiplyGoodsMatrixAndUserVectorFirstMapper ​ MultiplyGoodsMatrixAndUserVectorSecondMapper ​ 文件:MultiplyGoodsMatrixAndUserVectorReducer ​ 思考:文件的来源,来自于两个文件,第一个是第3步的结果(物品的共现矩阵),第二个文件是第4步的结果(用户的购买向量)。所以在一个MR程序中,需要使用两个自定义Mapper分别处理,然后定义一个自定义Reducer来处理这两个Mapper的中间结果。 ​ 1.保证两个Mapper的Key要相同。 ​ 2.两个Mapper的数据输出的Key和Value的数据类型是一致的。 ​ 3.在作业配置中,对于Mapper端的配置需要使用MultipleInputs.addInputPath(job,数据的输入路径,数据输入的格式控制器.class,执行的Mapper类.class); ​ 原始数据:第3步和第4步的结果数据。 ​ 计算结果: ​ 10001,20001 2 ​ 10001,20001 2 ​ 10001,20001 3 ​ 10001,20001 1 ​ 10001,20001 2 ​ 10001,20002 3 ​ 10001,20002 2 ​ 10001,20002 2 ​ 10001,20002 2 ​ 10001,20002 2 ​ 10001,20003 1 ​ 10001,20004 1 ​ 10001,20004 1 ​ 10001,20005 2 ​ 10001,20005 2 ​ 10001,20005 2 ​ 10001,20005 1 ​ 10001,20005 2 ​ 10001,20006 2 ​ 10001,20006 3 ​ 10001,20006 2 ​ 10001,20006 1 ​ 10001,20006 2 ​ 10001,20007 2 ​ 10001,20007 1 ​ 10001,20007 1 ​ 10001,20007 3 ​ 10001,20007 1 ​ 10002,20001 2 ​ 10002,20002 2 ​ 10002,20003 1 ​ 10002,20003 1 ​ 10002,20003 1 ​ 10002,20004 1 ​ 10002,20004 2 ​ 10002,20004 1 ​ 10002,20005 2 ​ 10002,20006 3 ​ 10002,20006 1 ​ 10002,20006 1 ​ 10002,20007 1 ​ 10002,20007 1 ​ 10003,20001 2 ​ 10003,20001 1 ​ 10003,20002 3 ​ 10003,20002 2 ​ 10003,20004 1 ​ 10003,20005 2 ​ 10003,20005 1 ​ 10003,20006 2 ​ 10003,20006 1 ​ 10003,20007 2 ​ 10003,20007 3 ​ 10004,20001 2 ​ 10004,20001 2 ​ 10004,20001 3 ​ 10004,20001 2 ​ 10004,20002 3 ​ 10004,20002 2 ​ 10004,20002 2 ​ 10004,20002 2 ​ 10004,20003 1 ​ 10004,20004 1 ​ 10004,20005 2 ​ 10004,20005 2 ​ 10004,20005 2 ​ 10004,20005 2 ​ 10004,20006 2 ​ 10004,20006 3 ​ 10004,20006 2 ​ 10004,20006 2 ​ 10004,20007 2 ​ 10004,20007 1 ​ 10004,20007 1 ​ 10004,20007 1 ​ 10005,20001 3 ​ 10005,20002 2 ​ 10005,20005 2 ​ 10005,20006 2 ​ 10005,20007 1 ​ 10006,20001 1 ​ 10006,20002 2 ​ 10006,20003 1 ​ 10006,20004 2 ​ 10006,20004 1 ​ 10006,20005 1 ​ 10006,20006 1 ​ 10006,20006 1 ​ 10006,20007 1 ​ 10006,20007 3

f.对第5步计算的推荐的零散结果进行求和

​ 文件:MakeSumForMultiplication.java

​ MakeSumForMultiplication ​ MakeSumForMultiplicationMapper ​ MakeSumForMultiplicationReducer ​ 原始数据:第5步的计算结果 ​ 计算结果: ​ 10001,20001 10 ​ 10001,20002 11 ​ 10001,20003 1 ​ 10001,20004 2 ​ 10001,20005 9 ​ 10001,20006 10 ​ 10001,20007 8 ​ 10002,20001 2 ​ 10002,20002 2 ​ 10002,20003 3 ​ 10002,20004 4 ​ 10002,20005 2 ​ 10002,20006 5 ​ 10002,20007 2 ​ 10003,20001 3 ​ 10003,20002 5 ​ 10003,20004 1 ​ 10003,20005 3 ​ 10003,20006 3 ​ 10003,20007 5 ​ 10004,20001 9 ​ 10004,20002 9 ​ 10004,20003 1 ​ 10004,20004 1 ​ 10004,20005 8 ​ 10004,20006 9 ​ 10004,20007 5 ​ 10005,20001 3 ​ 10005,20002 2 ​ 10005,20005 2 ​ 10005,20006 2 ​ 10005,20007 1 ​ 10006,20001 1 ​ 10006,20002 2 ​ 10006,20003 1 ​ 10006,20004 3 ​ 10006,20005 1 ​ 10006,20006 2 ​ 10006,20007 4

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

​ 文件:DuplicateDataForResult.java

​ 类名:DuplicateDataForResultFirstMapper ​ DuplicateDataForResultSecondMapper ​ DuplicateDataForResultReducer ​ 数据来源: ​ 1.FirstMapper处理用户的购买列表数据。 ​ 2.SecondMapper处理第6的推荐结果数据。 ​ 计算结果: ​ 10001 20004 2 ​ 10001 20003 1 ​ 10002 20002 2 ​ 10002 20007 2 ​ 10002 20001 2 ​ 10002 20005 2 ​ 10003 20006 3 ​ 10003 20005 3 ​ 10003 20001 3 ​ 10003 20004 1 ​ 10004 20007 5 ​ 10004 20004 1 ​ 10004 20003 1 ​ 10005 20006 2 ​ 10005 20002 2 ​ 10005 20005 2 ​ 10005 20007 1 ​ 10006 20006 2 ​ 10006 20002 2 ​ 10006 20005 1 ​ 10006 20003 1 ​ 10006 20001 1

h.将推荐结果保存到MySQL数据库中

​ 注意: ​ 1.保证表提前存在。 ​ grms.results(uid varchar(20), ​ gid varchar(20), ​ exp int) ​ 2.通过MR程序将HDFS集群上的数据保存到MySQL数据库中的时候,只能将最终输出的Key值保存到数据库中。 ​ 3.自定义最终输出的Key的数据类型。自定义的类实现WritableComparable<自定义的类>,但是作为将数据从HDFS集群输出到MySQL数据库中的Key,还要实现DBWritable接口。 ​ readFields(ResultSet rs) ​ write(PrepareStatement ps)

​ A impl WC,DBW{ ​ private String uid; ​ private String gid; ​ private int exp;

​ readFields(ResultSet rs){ ​ uid=rs.getString(1); ​ }

​ write(PrepareStatement ps){ ​ ps.setString(1,uid); ​ ps.setString(2,gid); ​ ps.setInt(1,exp); ​ } ​ } ​ 4.在作业配置中,需要使用DBConfiguration.setConfiguration()指定连接数据库的相关参数。 ​ 参数1:和当前作业相关的配置对象,Configuration对象要通过Job对象来获取; ​ 参数2:"com.mysql.jdbc.Driver" ​ 参数3:"jdbc:mysql://ip:port/grms" ​ 参数4和5:"用户名"和"密码"。 ​ 5.数据输出的格式控制需要使用DBOutputFormat。 ​ DBOutputFormat.setOutput();有三个参数: ​ 参数1:Job对象。 ​ 参数2:数据库表名 ​ 参数3:可变长参数,指的是往数据库中插入的列名。 ​ insert into 数据库表名 values(?,?,?); ​ 文件:SaveRecommendResultToDB.java ​ 类名:SaveRecommendResultToDBMapper<LW,Text,Text,Text> ​ SaveRecommendResultToDBReducer<Text,Text,自定义的Key,NullWritable> ​ 数据来源:第7步的结果数据。 ​ 数据去向:MySQL数据库,grms.result

i.构建作业流对象(JobControl),让程序自行提交作业

​ 文件:GoodsRecommendationManagementSystemJobController.java ​ 类名:GoodsRecommendationManagementSystemJobController ​ 1.分别创建step1到step8的Job对象,然后进行各自的作业配置。 ​ Job job1=Job.getIns(); ​ 2.创建8个ControlledJob对象,将上一步的Job对象转化成可被控制的作业。 ​ ControlledJob cj1=new CJ(); ​ cj1.setJob(job1); ​ cj2.setJob(job2); ​ 3.对可被控制的作业添加依赖关系。 ​ cj2.addDepe...(cj1); ​ 4.构建JobControl对象,将8个可被控制的作业逐个添加。 ​ JobControl jc=new JobControl(""); ​ 5.构建线程对象,并启动线程,执行作业。 ​ Thread t=new Thread(jc); ​ t.start();