Mllib机器学习工具包在Hadoop上的使用

标签: 数据挖掘 Hadoop JNI Mlib | 发表时间:2010-12-22 08:17 | 作者:yuanhan 小丑鱼
出处:http://www.searchtb.com

         Hadoop是基于Java的数据计算平台,在我们公司得到了广泛应用。同样mllib也是我们算法组同学经常使用的一个机器学习工具包。但目前mllib工具包只提供了供C++程序调用的so链接库,没有可供java程序调用的jar包。由于这个需求有一定的普遍性,笔者将mllib做了进一步封装,并通过jni的方式把其封装成了可供java程序调用的接口。

1    结构示意图

2    对mllib的二次封装
        原始的mllib开发包对模型的处理(训练,加载,预测)都是per model的,对于每一个模型都需要写一些重复类似的代码。实际应用中我们的模型也一般都是多个的(分行业,或分类目来做),不太会只是用一个大而泛的模型。mllib没有提供一个类似于Manager的类来管理多个模型。所以笔者对mllib进行了二次封装,能够让大家比较方便的通过配置来管理多个模型,也让大家从需要了解mlllib最底层的接口中解放出来。
封装的Manager类:

class MlrManager
{
public:
    MlrManager();
    virtual ~MlrManager();
    //提供的两个接口
    //初始化函数,输入为配置文件,以配置文件为驱动来加载模型
    bool Init(const char* pConf);
    //预测函数,输入为特征数组和模型编号,输出为预测分数
    feature_t CalMlrScore(std::vector<feature_t>&amp;amp;amp; vecFeatures,int nModel);
private:
    feature_t GetMlrScore(std::vector<feature_t>&amp;amp;amp; vecFeatures,mllib::MlModel* pModel,ENUM_MODEL_TYPE enumModelType);
private:
    std::vector<mllib::MlModel*> m_vecModels;
    int m_nTotalModelNum;
    int m_nDefaultModelNum;
    ENUM_MODEL_TYPE m_enumModelType;
    mllib::MlModelManager m_modelManager;
};

MlrManager类被封装到了libMlrManagerJni.so链接库中,可供其它C++程序使用。
配置文件说明:

[PATH]
//设置root目录,后面的模型文件只需要指定相对这个root路径的相对路径即可
BASE_PATH = ./mlr_jni.tar/conf/
[MODEL]
//模型数目,指定了模型数目后,模型名就可以确定了:MODEL1 , MODEL2 .... MODEL${ TOTAL_MODEL_NUM }
TOTAL_MODEL_NUM = 4
//模型的类型(回归还是分类),不同的模型类型,预测时实现的方法是不一样的,一定要正确设置
#MODEL_TYPE = classification
MODEL_TYPE = regression
//指定具体某个模型使用的模型文件名称,不同的模型可以使用相同的模型文件。
MODEL1 = 1.model
MODEL2 = 2.model
MODEL3 = 3.model
MODEL4 = 3.model

MlrManager调用伪代码示例:

#include "MlrManager.h"
Main()
{
    MlrManager mlrMgr;
    mlrMgr.Init(confFile);
    vector<float> vecFeature(nFeatureSize);
    float fMlrScore = mlrMgr.CalMlrScore(vecFeature,1);
}

3    Jni封装成可供java调用的接口
3.1
封装后的java接口如下:

public class MlrManagerJni{
static {
    //load链接库libMlrManagerJni.so,如果找不到libMlrManagerJni.so,该类将初始化失败
    System.loadLibrary("MlrManagerJni");
}
    //接口初始化,输入为配置文件
    public native int mlr_init(String conf);
    //预测分数的接口,输入为特征字符串,特征分隔符,模型编号,输出为预测值
    public native float mlr_calc(String features,String spliter , int nModel);
    //释放接口
    public native int mlr_destroy();
}

         具体如何封装的这里就不细说了,jni封装技术可以参考 ( http://www.searchtb.com/2010/12/how-to-run-jni-in-hadoop.html 如何在Hadoop集群运行jni程序),使用者也不用关心这个。下面介绍一下如何使用这个封装的接口。
3.2   开发阶段
把mlr_jni.tar包拷贝到开发机上,解压出来,解压后的目录结构如下:

conf/
conf/mlr.conf
conf/1.model
conf/2.model
……
conf/N.model
lib/
lib/ libMlrManagerJni.so
lib/ mlrmgrjni.jar

         conf目录包含了mlr.conf配置文件,和一系列模型文件*.model。
         lib目录包含了libMlrManagerJni.so,mlrmgrjni.jar两个文件,libMlrManagerJni.so是封装了原始mllib的C++接口,mlrmgrjni.jar是封装了libMlrManagerJni.so的java接口。
在Eclipse项目配置选项里把mlrmgrjni.jar加到classpath中。

MlrManagerJni调用伪代码示例:

import mlr.MlrManagerJni;
Mapper()
{
    private MlrManagerJni m_mlrJni = new MlrManagerJni();
    public void configure(JobConf job)
    {
        //初始化接口
        m_mlrJni.mlr_init("./mlr_jni.tar/conf/mlr.conf")
    }
    public void map(){
        //接口调用
        fMlrScore = m_mlrJni.mlr_calc(strFeatures, MlrManager.FEATURE_SPLITER , nModel );
    )
    public void close() {
        //释放接口
        if (m_mlrJni != null) {
            m_mlrJni.mlr_destroy();
            m_mlrJni = null;
        }
    }
}
Run()
{
    //设置 lava.library.path路径,通过这个路径可以找到libMlrManagerJni.so链接库,MlrManagerJni接口初始化的时候需要加载这个链接库
    conf.set("mapred.child.java.opts","-Djava.library.path=./mlr_jni.tar/lib");
    //也可以通过如下这个方式来设置
    //conf.set("java.library.path","./mlr_jni.tar/lib");
}

3.3   运行阶段
        在运行环境中,把mlr_jni.jar拷贝到运行环境,解压出来。使用者把自己的模型文件拷贝到conf目录下,在mlr.conf文件中修改好相关配置,然后把conf目录和lib目录重新打包成mlr_jni.tar包。(注意这里的包名mlr_jni.tar是可以变的,但必须和java程序中有两处第8行和第25行指定的包名是一致的)。
调用:

hadoop jar -libjars ./lib/mlrmgrjni.jar mainClass -archives mlr_jni.tar …

-libjars mlrmgrjni.jar选项会把mlrmgrjni.jar这个jar包添加到Mapreduce程序的java classpath中。
-archives mlr_jni.tar选项,Hadoop Distributed Cache的机制将会把这个jar包拷贝到每一个task node上,供MapReduce程序使用。这个选项等同于在hadoop程序中显示调用

DistributedCache.addCacheArchive(“hdfs:///group/tbsc-dev/yuanhan/mlr_jni.tar#mlr_jni.tar”,conf);

3.4   常见错误
1)  Caused by: java.lang.NoClassDefFoundError: mlr/MlrManagerJni       
java.lang.ClassNotFoundException: mlr.MlrManagerJni
原因:hadoop 命令行调用的时候没有加-libjars ./lib/mlrmgrjni.jar选项
2)  Caused by: java.lang.UnsatisfiedLinkError: no MlrManagerJni in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1709)
原因:MlrManagerJni 接口初始化失败,不能加载libMlrManagerJni.so。
hadoop 命令行调用的时候没有加-archives mlr_jni.tar选项,可以在hadoop WebUI上看下job的xml配置文件,mapred.cache.archives选项是否包含mlr_jni.tar包,如下是一个包含了mlr_jni.tar包的例子:
mapred.cache.archives=hdfs://hdpnn:9000/home/hadoop/cluster-data/mapred/system/job_201012162127_130619/libjars/mlrmgrjni.jar,/home/hadoop/cluster-data/mapred/system/job_201012162127_130619/archives/mlr_jni.tar#mlr_jni.tar
还有可能是打mlr_jni.tar包的时候忘记把libMlrManagerJni.so文件放进lib目录中了。

BTW:相关工具包下载联系元涵本人~

相关 [mllib 机器学习 工具] 推荐:

Mllib机器学习工具包在Hadoop上的使用

- 小丑鱼 - 搜索技术博客-淘宝
         Hadoop是基于Java的数据计算平台,在我们公司得到了广泛应用. 同样mllib也是我们算法组同学经常使用的一个机器学习工具包. 但目前mllib工具包只提供了供C++程序调用的so链接库,没有可供java程序调用的jar包. 由于这个需求有一定的普遍性,笔者将mllib做了进一步封装,并通过jni的方式把其封装成了可供java程序调用的接口.

[转][转]机器学习工具:scikit-learn/Weka

- - heiyeluren的blog(黑夜路人的开源世界)
开源机器学习工具scikit-learn入门. Scikit-Learn是基于python的机器学习模块,基于BSD开源许可证. 这个项目最早由DavidCournapeau 在2007 年发起的,目前也是由社区自愿者进行维护. Scikit-Learn的官方网站是 http://scikit-learn.org/stable/,在上面可以找到相关的Scikit-Learn的资源,模块下载,文档,例程等等.

Google 开源机器学习数据集可视化工具 Facets

- - 开源中国社区最新新闻
ML 数据集可以包含数亿个数据点,每个数据点由数百(甚至数千)的特征组成,几乎不可能以直观的方式了解整个数据集. 为帮助理解、分析和调试 ML 数据集,谷歌开源了 Facets,一款可视化工具. Facets 包含两个部分 —— Facets Overview 和 Facets Dive ,允许用户以不同的粒度查看其数据的整体图像.

Spark MLlib中的协同过滤

- - JavaChen Blog
本文主要通过Spark官方的例子理解ALS协同过滤算法的原理和编码过程,然后通过对电影进行推荐来熟悉一个完整的推荐过程. 协同过滤常被应用于推荐系统,旨在补充用户-商品关联矩阵中所缺失的部分. MLlib当前支持基于模型的协同过滤,其中用户和商品通过一小组隐语义因子进行表达,并且这些因子也用于预测缺失的元素.

使用Spark MLlib给豆瓣用户推荐电影

- - 鸟窝
推荐算法就是利用用户的一些行为,通过一些数学算法,推测出用户可能喜欢的东西. 随着电子商务规模的不断扩大,商品数量和种类不断增长,用户对于检索和推荐提出了更高的要求. 由于不同用户在兴趣爱好、关注领域、个人经历等方面的不同,以满足不同用户的不同推荐需求为目的、不同人可以获得不同推荐为重要特征的个性化推荐系统应运而生.

机器学习五步走

- - 我爱机器学习
经常会有人问“我该如何在机器学习方面更进一步,我不知道我接下来要学什么了. 一般我都会给出继续钻研教科书的答案. 每当这时候我都会收到一种大惑不解的表情. 但是进步确实就是持续的练习,保持较强的求知欲,并尽你可能的完成具有挑战性的工作. 因为他是为数不多的几种可以让你真真让你获取坚实知识的媒介. 是的,你可以选择选一门课,注册MOOC,参加一些讨论班.

机器学习之路

- - 我爱机器学习
自从答应简二毛博士将自己的机器学习历程和心得分享给大家至今,转眼间半年已经过去了,感谢简博士分享和开源精神的鼓舞,这也正是本系列关于机器学习介绍博客的动力来源. 之前有些网友,师弟们问我,学习机器学习怎么入手,从看什么书开始. 如果你只愿意看一本书,那么推荐Bishop的PRML,全名Pattern Recognition and Machine Learning. 这本书是机器学习的圣经之作,尤其对于贝叶斯方法,介绍非常完善.

基于Spark MLlib平台的协同过滤算法---电影推荐系统

- - zzm
又好一阵子没有写文章了,阿弥陀佛...最近项目中要做理财推荐,所以,回过头来回顾一下协同过滤算法在推荐系统中的应用.     说到推荐系统,大家可能立马会想到协同过滤算法. 本文基于Spark MLlib平台实现一个向用户推荐电影的简单应用. 基于模型的协同过滤应用---电影推荐.     一、协同过滤算法概述.

[原]Spark MLlib系列(二):基于协同过滤的电影推荐系统

- -
随着大数据时代的到来,数据当中挖取金子的工作越来越有吸引力. 利用Spark在内存迭代运算、机器学习领域强悍性能的优势,使用spark处理数据挖掘问题就显得很有实际价值. 这篇文章给大家分享一个spark MLlib 的推荐实战例子. 我将会分享怎样用spark MLlib做一个电影评分的推荐系统.

Mahout实现的机器学习算法

- - ITeye博客
使用命令:mahout -h.   在Mahout实现的机器学习算法见下表:. EM聚类(期望最大化聚类). 并行FP Growth算法. 并行化了Watchmaker框架. 非Map-Reduce算法. 扩展了java的Collections类. Mahout最大的优点就是基于hadoop实现,把很多以前运行于单机上的算法,转化为了MapReduce模式,这样大大提升了算法可处理的数据量和处理性能.