基于MapReduce实现物品协同过滤算法(ItemCF)

该博客介绍如何基于MapReduce实现物品协同过滤(ItemCF)算法,应用于电子商务推荐系统。通过处理用户行为数据,构建同显矩阵和用户评分向量,最终计算推荐向量并进行排序,为用户提供个性化的商品推荐。
摘要由CSDN通过智能技术生成

一、背景

电子商务网站是个性化推荐系统重要地应用的领域之一,亚马逊就是个性化推荐系统的积极应用者和推广者,亚马逊的推荐系统深入到网站的各类商品,为亚马逊带来了至少30%的销售额。


二、ItemCF简介

基于item的协同过滤,通过用户对不同item的评分来评测item之间的相似性,基于item之间的相似性做出推荐。简单来讲就是:给用户推荐和他之前喜欢的物品相似的物品。如下说明:


注:基于物品的协同过滤算法,是目前商用最广泛的推荐算法。


三、案例

本次案例来自天池大数据竞赛,点击下载,数据字段如下说明:

    item_id:品牌数字ID;    user_id:用户标记;    action:用户对品牌的行为类型;    vtime:行为时间。

过程即为Co-occurrence Matrix(同显矩阵)和User Preference Vector(用户评分向量)相乘得到的这个Recommended Vector(推荐向量)。


R向量里面的R101, R104,R105和R107这四项值很大,但是我们可以忽略它们,因为用户已经对该物品购买过,也就是已经买过这些了,可以不推荐了,对于用户没有买过的几项里面选出最大(或者TopN)的物品推荐就可以了,上面R102,R103,R106里面选一个最大值103,103就是可以推荐的商品了。


四、代码

1. 去重
package com.zxl.mr.tuijian;

import java.io.IOException;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
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;

/**
 * @author ZXL
 * 去重复
 */
public class Step1 {
	public static boolean run(Configuration config, Map<String, String> paths){
		try {
			FileSystem fs = FileSystem.get(config);
			Job job = Job.getInstance(config);
			job.setJobName("step1");
			job.setJarByClass(Step1.class);
			job.setMapperClass(Step1_Mapper.class);
			job.setReducerClass(Step1_Reducer.class);
			
			job.setMapOutputKeyClass(Text.class);
			job.setMapOutputValueClass(NullWritable.class);
			
			FileInputFormat.addInputPath(job, new Path(paths.get("Step1Input")));
			Path outpath=new Path(paths.get("Step1Output"));
			if(fs.exists(outpath)){
				fs.delete(outpath,true);
			}
			FileOutputFormat.setOutputPath(job, outpath);
			
			boolean f= job.waitForCompletion(true);
			return f;
		} catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}
	
	static class Step1_Mapper extends Mapper<LongWritable, Text, Text, NullWritable>{
		protected void map(LongWritable key, Text value, 
				Context context)
				throws IOException, InterruptedException {
			if(key.get() != 0){
				context.write(value, NullWritable.get());
			}
		}
	}
	
	static class Step1_Reducer extends Reducer<Text, NullWritable, Text, NullWritable>{
		protected void reduce(Text key, Iterable<IntWritable> i,
				Context context)
				throws IOException, InterruptedException {
			context.write(key,NullWritable.get());
		}
	}
}
2. 获取所有用户的喜欢矩阵
package com.zxl.mr.tuijian;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
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;

/**
 * 按用户分组,计算所有物品出现的组合列表,得到用户对物品的喜爱度得分矩阵 
 * u13 i160:1, u14 i25:1,i223:1, u16 i252:1,
 * u21 i266:1, 
 * u24 i64:1,i218:1,i185:1, 
 * u26 i276:1,i201:1,i348:1,i321:1,i136:1,
 * 
 * @author ZXL
 */
public class Step2 {
	public static boolean run(Configuration config, Map<String, String> paths) {
		try {
			// config.set("mapred.jar",
			// "C:\\Users\\Administrator\\Desktop\\wc.jar");
			FileSystem fs = FileSystem.get(config);
			Job job = Job.getInstance(config);
			job.setJobName("step2");
			job.setJarByClass(StartRun.class);
			job.setMapperClass(Step2_Mapper.class);
			job.setReducerClass(Step2_Reducer.class);
			job.setMapOutputKeyClass(Text.class);
			job.setMapOutputValueClass(Text.class);

			FileInputFormat.addInputPath(job, new Path(paths.get("Step2Input&#
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值