使用hadoop生态圈mahout做推荐系统
之所以做这个方面的介绍,是为了给我的师弟师妹们铺路。使用分布式做推荐系统学习。
一、hadoop介绍
我就不去网上复制粘贴了,给出我个人的理解,其实就是分布式,在说什么是分布式之前,要说一下hadoop里面几个重要组成,HDFS,这个是hadoop的文件存储系统,就是我们传入的数据集什么的,什么放在这个上面,他其实是一个网站,YARN框架,这个其实是从Mapreduce中分离出来的,叫做资源管理调度系统,这个什么作用我暂时还没有用到,最后一个自然就是Mapreduce了,分布式运算框架。
二、mahout介绍
mahout是hadoop里面的一个专门用来做推荐系统,聚类算法,分类算法的一个分布式框架,由于底层用的是hadoop,因此处理数据的速度是非常之快的,mahout也是hadoop生态圈里面的重要组成成员,其实hadoop也是个非常好玩的命令,它的图标是一个大象,而他的生态圈里面的命令也很好玩,比如hive分布式数据库(蜜蜂),pig轻量级数据集(猪),zookeeper(动物园长),其他自己百度看看,可以了解一下。
三、mahout做推荐系统
工具准备
可以编写java语言的IDE,比如eclipse,myeclipse,intellij IDEA这三个,其他的不推荐,至于小伙伴问,为什么我做python的,要下载java的IDE,其实是因为,这个mahout是基于java的,只能用java去做,当然了,也不是没有python的,python的分布式是spark,但是spark好像并没有提供mahout这种专门的内置函数去做推荐系统,而是所有算法都需要自己去编写,另外spark的分布式了解周期也挺长的,对于代码基础比较差的同学,最好还是不要太花时间在这个上面。相比而言,mahout并不需要集群等的支持。
安装maven
这里推荐小伙伴们必须安装上maven,有的小伙伴们会问,为什么要用maven,直接导包就行了啊,那你要知道一个问题,mahout是非常大的,话说一次你导包,那么每次你都去网上下载相关的jar包么,时间浪费不起啊,因此小伙伴们必须装上maven,不会安装的小伙伴可以看我博客的maven那一块的分类,有专门介绍
代码编写
首先,我们打开IDE,点击左上角的file文件新建project,找到maven点开,找到maven project
然后下一步,后面的名字随便你自己取名。这里我们直接新建maven项目,建完项目之后,发现项目里面比正常的java项目多了一个pom.xml,这个是依赖包的配置,因为我们需要用mahout,那么就将mahout的相关配置导入进来,不会的小伙伴看我博客的maven介绍,这里我直接贴出配置代码:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mahout/mahout-core -->
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>0.9</version>
</dependency>
</dependencies>
到这里位置所有配置全部结束,现在开始我们正式的代码编写:
在我们新建的项目里面,新建.java的文件,然后把这些包导入进去:
import java.io.File;
import java.io.IOException;
import java.util.PrimitiveIterator;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.svd.ALSWRFactorizer;
import org.apache.mahout.cf.taste.impl.recommender.svd.SVDPlusPlusFactorizer;
import org.apache.mahout.cf.taste.impl.recommender.svd.SVDRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.impl.similarity.SpearmanCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
import org.apache.mahout.cf.taste.model.PreferenceArray;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.recommender.UserBasedRecommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
这个是我们需要用到的依赖包,有的包是用不到的,但是我当时为了看看其他算法的时候,直接导入进去了。接着编写如下代码:
public class userBase
{
public static void main( String[] args ) throws Exception
//这里要抛异常
{
long starTime = System.currentTimeMillis();
//这个是我用来计算程序运行时间的,存储开始时间
try {
DataModel model = new FileDataModel(new File("D:\\pythonsubject\\venv\\Recommend\\ml-100k\\base\\u1.base"));
//获取数据集,其中后面的路径是我们的数据集,他会帮我们把数据集转换成他需要使用的格式
DataModel model_test = new FileDataModel(new File("D:\\pythonsubject\\venv\\Recommend\\ml-100k\\test\\u1.test"));
//这个是用来做测试的数据集
// UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
UserSimilarity similarity = new SpearmanCorrelationSimilarity(model);
//计算相似度的接口,这里使用的是SpearmanCorrelationSimilarity,皮尔森相似度计算,另外还有曼哈顿相似度,余弦相似度,改进余弦相似度等等,接口不一样,这个需要大家去mahout的官方api去查看
UserNeighborhood neighborhood = new NearestNUserNeighborhood(10,0,similarity, model);
\\选取最近邻居
/*第二个参数是阈值,代表邻居相似度的最小取值,这里设置为0,表示选取大于0的相似度,求出相似度的范围其实是[-1,1]之间的,也就是不填的话默认全选,mae求得为0.85+
这里为了缩小到正常得mae值,我们设置阈值为0,负值代表负相关,我们这里不选取。另外第一个参数天总用户数就行,超出了也没有关系,源码处理得是非常好的,
int numUsers = dataModel.getNumUsers();
this.n = n > numUsers ? numUsers : n;也就是你超出了就自动选取数据集得用户个数
*/
UserBasedRecommender recommender = new GenericUserBasedRecommender(model, neighborhood, similarity);
//基于用户的推荐算法接口,GenericUserBasedRecommender,除了这种还有其他的推荐算法接口,比如基于物品的,等等,建议大家去查看api
// UserBasedRecommender recommender = new GenericBooleanPrefUserBasedRecommender(model, neighborhood, similarity);
double MAE = 0;
int count = 0;
LongPrimitiveIterator userIds = model_test.getUserIDs();
//创建迭代器,获取所有测试集里面的用户id
for (int i=0; i<model_test.getNumUsers(); i++){
long userId = userIds.nextLong();
//由于是迭代器,使用nextlong()可以每次取一个数据
// System.out.println(userId);
PreferenceArray preferences = model_test.getPreferencesFromUser(userId);
//相似用户
// System.out.println(preferences);
for (int j=0; j<preferences.length(); j++){
Preference preference = preferences.get(j);
//获取相似用户所有信息
// System.out.println(preference.getValue());
//以下为计算Mae的算法,这里就不做介绍了,给出mae的概念,平均差值,就是预测值与真实值的平均差值的绝对值
float predict = Float.NaN;
try{
predict = recommender.estimatePreference(preference.getUserID(), preference.getItemID());}
catch (Exception e){
System.out.println("*****************");
System.out.println(preference.getUserID());
System.out.println(preference.getItemID());
System.out.println("*****************");
}
// float predict = Double.NaN;
// double predict = recommender.estimatePreference(preference.getUserID(), preference.getItemID());
if (!Double.isNaN(predict)){
double temp = Math.abs(predict-preference.getValue());
MAE += temp;
count++;
System.out.println("用户"+preference.getUserID()+"对电影"+preference.getItemID()+"的预测值为:"+predict);
}
}
}
System.out.println("平均误差值MAE="+MAE/count);
} catch (IOException e) {
e.printStackTrace();
}catch (TasteException e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间为:"+(float)(endTime-starTime)/1000+"s");
}
}
对于相似度算法的选取,以及推荐算法的选取,还是看大家自己去探索,具体的大概步骤就是:给出数据集生成模型,使用相似度算法计算相似度,设置最近邻居,使用推荐算法,下面自己编写算法,得到自己想要的结果。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1990858822@qq.com
文章标题:使用hadoop生态圈mahout做推荐系统
本文作者:XIAOK Z
发布时间:2019-09-01, 15:22:11
最后更新:2019-09-01, 16:01:14
原始链接:http://yoursite.com/2019/09/01/使用hadoop生态圈mahout做推荐系统/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。