使用过NetflixPrize数据集的同学一定知道,NetflixPrize的Probe数据是包含在历史数据中的。做训练当然要将预测数据集分离出来~
一直在使用Hadoop平台,所以写了一个hadoop程序将Probe提取出来:
1)写了一个自定义的Writable,在MapReduce的排序中比较有用,使用Text的排序感觉很不爽。
2)使用到了两个比较实用的方法:
在新版的API中 org.apache.hadoop.mapreduce中,这两个函数是
void setup(Context context)
void cleanup (Context context)
自定义的Mapper和Reducer都可以继承这两个方法。setup在数据处理前调用一次,所以在这里你可以做一些数据的加载或初始化;cleanup是在数据处理后调用一次,可以用来收集一些你觉得有用的数据和你想做的事情:-)
在 Hadoop的新版的API中源代码里,你可以比较清楚地看到Mapper和Reducer的工作过程,参见org.apache.hadoop.mapreduce.mapper和org.apache.hadoop.mapreduce.reducer。
在 Hadoop的旧版的API中,你可以直接看到的就不多了~ 新版本的API给使用者更多的执行细节,这样会给开发带来了很大的便利,所以Hadoop开发者还是比较推荐新版API的。不过旧版本的API也有完成相同功能的函数
void configure(JobConf job);
void close()
configure在数据处理前调用一次,close是在数据处理后调用一次。
言归正传,开始处理数据集。
1.数据集是以小文件的形式存在 training_set文件夹下,hadoop不太擅长处理大量的小文件,所以我们可以使用脚本将小文件合并一下(在附件中)。个人感觉脚本效果比hadoop处理效果好一些:-),大家也可以试试hadoop的方法合并。可以参考
http://coderplay.javaeye.com/blog/468623
脚本使用方法: ./preprocess.sh training_set
2.上传到HDFS上:
mkdir netfix_all
cp netflix.data netflix_all/
hadoop fs -put netflix_all Netflix_All
3.使用 hadoop 分离预测集。
1) 自己写了一个UserItem类,比较简单,可以参考《hadoop权威指南》中的TextPair类来写。不过需要注意的是,你使用的是 org.apache.hadoop.mapreduce 还是 org.apache.hadoop.mapred的API(旧版本API),使用旧版本的话注意在自定义的类中还要加上一个方法 public static UserItem read(DataInput in),这个在书上是没有的,假如你都采用 org.apache.hadoop.mapreduce的API,是没有问题的。采用 org.apache.hadoop.mapred的API的话,这个方法就应该加上,否则执行时会出问题。
2) 预测集分离分为两道MapReduce任务:第一道直接输出训练集,将预测集保存在容器中,在Map任务结束后以mapid为文件名保存预测集到本地。第二道任务将预测集合并成一个文件。
OK,完成!附上脚本和代码~