本博客为作者原创,如需转载请注明参考
 
        在深入理解Spark ML中的各类算法之前,先理一下整个库的设计框架,是非常有必要的,优秀的框架是对复杂问题的抽象和解剖,对这种抽象的学习本身,就是加深框架所面对的问题的理解的一种有效途径。纷繁复杂的机器学习问题,经过优秀框架的解析,变得简单清晰起来。
        基于面向对象语言的程序设计,本质上类似于搭积木,从一个最抽象、最简单的内容开始,一点一点的往上堆叠,形成一个对象的框架。比如Java中的Object,Python中的PyObject等等,这也是面向对象语言教给我们的一种解决问题的思路:剥洋葱,把外层非本质的核一个一个剥去,剩下的就是事物的本质与核心。
        那么,机器学习问题的核心是什么呢?Spark ML给出的答案是,参数。所有的机器学习模型、算法,说到底都是对参数的学习,都离不开参数。因此,在Spark ML框架中,最底层也是最抽象的类,就是Param,一个对象只要是能包含参数的,都可以叫做Param。
        在param文件夹下,包含了对参数类及其子类的代码。参数类的子类,主要分成两种,第一种是数据类型类,包括IntParam,DoubleParam,顾名思义,这些参数包含了某种数据类型的数据,第二种是参数集合Params,表示其中包含了许多参数,这个类就很了不起了,从它开始衍生出了很多实用的参数,比如HasRegParam,表示其中包含了正则化的参数,再比如HasMaxIter,表示其中包含了最大迭代次数的参数。看,机器学习模型的积木已经帮我们准备好了,从参数的角度来抽象各类机器学习问题,可以按照是否包含某个参数,对机器学习模型和算法进行拆解,一个算法需要什么参数,就在定义时,像搭积木一样,把对应的参数包括进来就好了。
        参数仅是静态的内容,如果要让这个对象有用,就需要让它具有一定的功能。最底层的具有功能性的类时PipelineStage,它实际上是一个Params,关于Pipeline的概念,我们稍后介绍,这里需要理解的是,虽然PipelineStage与Pipeline的名称很相似,但它们之间还隔了一层,完全不是一个层面上的东西。PipelineStage是一个抽象的阶段,它本身不具备任何功能,它的存在仅是为了给真正有功能的类一个公共的子类,与Param的其它子类相区分。
        接下来就到了我们日常使用时最常用的类,Transformer。一个类,只要它拥有将一个数据集转化成另外一个数据集的功能,它就是一个Transformer。注意,一个Transformer就是一个PipelineStage。
仅能完成数据转换,还不够,在机器学习中,最重要的事情是对数据的拟合,这里Estimator类正式登场,只要具有数据拟合的功能,即,只要能从数据中学习,就是Estimator,这个类里包含了我们最熟悉的一个函数,fit,是它赋予了所有Estimator从数据中学习的能力。
        到这里,我们在机器学习中最常见的“模型”的概念,就已经呼之欲出了。Model类本质上是一个Transformer,这个很好理解,一个训练得到的模型,本身的任务就是做预测,做数据转化的。Model的独特之处在于,它是由Estimator的fit方法生成的,一个Estimator在经过对数据的学习之后,就产生了一个Model,而一个Model中除了一个指向生成自己的Estimator的指针之外,真的什么都没有。
        这里我们再总结一下Transformer(简称T),Estimator(简称E),Model(简称M)三者之间的关系。T和E本质上都是PipelineStage,更本质的来说都是Param,而M本质上是一个T,但它是由E产生的,因此M是连接T和E之间的桥梁。
        下面要介绍的就是Pipeline,我们知道很多机器学习的任务,都不是一步能完成的,比如做分类,我们要先对数据进行预处理,进行分类,然后再对分类结果进行处理,才能得到想要的结果。于是Spark ML提供了一个非常棒的抽象,流水线(Pipeline),它的引入能使得机器学习的各个任务能像流水线一样被顺序执行,因此能提供非常简洁的编程接口。Pipeline本质上是一个E,它是由一个一个的PipelineStage组成的。通过上文我们知道,T和E都是PipelineStage,因此一个Pipeline中就包含了许多的T和E。由于Pipeline本质上是一个E,因此它在调用fit函数之后,会产生一个PipelineModel,这就是一个Model了。还记得Model的本质是Transformer吗?
        我们知道,机器学习中的问题可以简单分为两类,监督学习和非监督学习,监督学习的一个特点就是,能够对某个事情做出“预测”,而非监督学习更多的是挖掘数据中的一些内在本质特点,不能做出预测,因此,为了将监督学习的本质提炼出来,设计了一个Predictor类。
        能做出预测的类,需要有一些共同的参数,还记得刚才我们对于Param的分析吗?参数是区分各类机器学习算法的一种角度,PredictorParams就是有预测能力的监督学习模型拥有参数的一种抽象,而Predictor本质上是一个带有PredictorParams的Estimator,而每一个Estimator在调用fit函数之后都会产生一个Model,这里产生的就是一个PredictorModel,这是一个带有PredictorParams的Model。
       
        好了,今天就写到这里。写作也是整理思路的一种很好的方式,在刚才的写作中,对Spark ML的设计思路又有了新的认识。由于本人才疏学浅,以上的理解不免会有纰漏,还请大家不吝赐教。下次将跟大家一起分析下具体算法的设计。

Spark ML源码分析之一 设计框架解读的更多相关文章

  1. Spark ML源码分析之二 从单机到分布式

            前一节从宏观角度给大家介绍了Spark ML的设计框架(链接:http://www.cnblogs.com/jicanghai/p/8570805.html),本节我们将介绍,Spar ...

  2. Spark ML源码分析之三 分类器

            前面跟大家扯了这么多废话,终于到具体的机器学习模型了.大部分机器学习的教程,总要从监督学习开始讲起,而监督学习的众多算法当中,又以分类算法最为基础,原因在于分类问题非常的单纯直接,几乎 ...

  3. Spark ML源码分析之四 树

            之前我们讲过,在Spark ML中所有的机器学习模型都是以参数作为划分的,树相关的参数定义在treeParams.scala这个文件中,这里构建一个关于树的体系结构.首先,以Decis ...

  4. 第十一篇:Spark SQL 源码分析之 External DataSource外部数据源

    上周Spark1.2刚发布,周末在家没事,把这个特性给了解一下,顺便分析下源码,看一看这个特性是如何设计及实现的. /** Spark SQL源码分析系列文章*/ (Ps: External Data ...

  5. 【Spark SQL 源码分析系列文章】

    从决定写Spark SQL源码分析的文章,到现在一个月的时间里,陆陆续续差不多快完成了,这里也做一个整合和索引,方便大家阅读,这里给出阅读顺序 :) 第一篇 Spark SQL源码分析之核心流程 第二 ...

  6. Spring5源码分析(1)设计思想与结构

    1 源码地址(带有中文注解)git@github.com:yakax/spring-framework-5.0.2.RELEASE--.git Spring 的设计初衷其实就是为了简化我们的开发 基于 ...

  7. [转]Libev源码分析 -- 整体设计

    Libev源码分析 -- 整体设计 libev是Marc Lehmann用C写的高性能事件循环库.通过libev,可以灵活地把各种事件组织管理起来,如:时钟.io.信号等.libev在业界内也是广受好 ...

  8. 第十篇:Spark SQL 源码分析之 In-Memory Columnar Storage源码分析之 query

    /** Spark SQL源码分析系列文章*/ 前面讲到了Spark SQL In-Memory Columnar Storage的存储结构是基于列存储的. 那么基于以上存储结构,我们查询cache在 ...

  9. 第九篇:Spark SQL 源码分析之 In-Memory Columnar Storage源码分析之 cache table

    /** Spark SQL源码分析系列文章*/ Spark SQL 可以将数据缓存到内存中,我们可以见到的通过调用cache table tableName即可将一张表缓存到内存中,来极大的提高查询效 ...

随机推荐

  1. CentOS常用命令大全

    一:使用CentOS常用命令查看cpumore /proc/cpuinfo | grep "model name" grep "model name" /pro ...

  2. is there any way to stop auto block

    shadowsocks出现错误日志 tail /var/log/ssserver.log 2017-07-02 12:36:31 ERROR: block all requests from 10.4 ...

  3. ansible实践3-playbook条件判断

    --- - hosts: testhost   user: root   gather_facts: True   tasks:     - name: use when       shell: t ...

  4. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  5. angular2-qrcode (转)

    插件选择 angular2-qrcode npm install angular2-qrcode --savecnpm install angular2-qrcode --save 参考github ...

  6. Java经典编程题50道之三十

    有一个已经排好序的数组.现输入一个数,要求按原来的规律将它插入数组中. public class Example30 {    public static void main(String[] arg ...

  7. idea 打开自动编译以及查看Problem窗口

    1.打开perference 2.选择Build-Compile-Make Project Automatically自动构建项目

  8. UVA-10954 贪心+优先队列

    贪心策略:每次选取最小的两个数相加,将和作为新的数加入序列,再从里面取两个最小的数...直到只剩下一个数.优先队列正好对付这题. PS :以前在学校OJ做过几乎一毛一样的这题 AC代码: #inclu ...

  9. redis下载安装以及添加服务

    一.下载安装 从 github 下载:https://github.com/MSOpenTech/redis/releases 或者 https://github.com/ServiceStack/r ...

  10. linux lnmp搭建及解释

    lnmp的搭建linux nginx mysql(mariaDB) php 安装mysql依赖:yum -y install cmake(cmake编译工具)yum -y install gcc gc ...