本博客为作者原创,如需转载请注明参考
 
        在深入理解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. pyDash:一个基于 web 的 Linux 性能监测工具

    pyDash 是一个轻量且基于 web 的 Linux 性能监测工具,它是用 Python 和 Django 加上 Chart.js 来写的.经测试,在下面这些主流 Linux 发行版上可运行:Cen ...

  2. Docker安装Jenkins

    1.下载镜像 docker pull jenkins 2.生成一个容器 docker run -d --name myjenkins -p 8081:8080 -p 50000:50000  --vo ...

  3. 【深度学习系列】用PaddlePaddle进行车牌识别(一)

    小伙伴们,终于到了实战部分了!今天给大家带来的项目是用PaddlePaddle进行车牌识别.车牌识别其实属于比较常见的图像识别的项目了,目前也属于比较成熟的应用,大多数老牌厂家能做到准确率99%+.传 ...

  4. asp.net core 使用 swagger 生成接口文档

    参考地址:http://www.cnblogs.com/daxnet/p/6181366.html http://www.jianshu.com/p/fa5a9b76f3ed 微软参考文档:https ...

  5. python调用百度语音(语音识别-斗地主语音记牌器)

    一.概述 本篇简要介绍百度语音语音识别的基本使用(其实是斗地主时想弄个记牌器又没money,抓包什么的又不会,只好搞语音识别的了) 二.创建应用 打开百度语音官网,产品与使用->语音识别-> ...

  6. 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)

    最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...

  7. 使用canvas编写时间轴插件

    使用canvas编写时间轴插件 背景 项目中有一个视频广场的功能,需要一个时间轴类似视频播放中进度条功能一样显示录像情况,并且可以点击.拖动.放大缩小展示时间轴,获取到时间轴的某个时间.原来的时间轴是 ...

  8. MySQL之表的数据类型

    一 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 详细参考: http://www.runoob.com/mysql/mysql-data ...

  9. FFmepg 如何在 window 上使用?

    下载FFmepg官网库直接使用即可. avdevice.lib avcodec.lib avfilter.lib avformat.lib avutil.lib postproc.lib swresa ...

  10. 蓝桥杯 求最大值 dp

    这题很暴力的一个DP,d[i][j]表示前i个数对选择一些Ai的和为j的最大Bi和. 状态转移方程: dp[i][j]=max(dp[i][j],dp[i-1][j-sc[i].a]+sc[i].b) ...