机器学习全生命周期研究
Posted Cloud Native Community
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习全生命周期研究相关的知识,希望对你有一定的参考价值。
本文是英文原著翻译,译者沈建军,并结合了其他文献的一个有益集成。中文在英文简述的后面。第一篇已发布:机器学习全生命周期研究(一)
机器学习全生命周期是笔者根据 medium 的系列文章作为主线条,然后集合了其他参考资料的概念,要点,作为项目的指导手册所做的详细翻译。本系列旨在高屋建瓴的给出一个轮廓,细节部分例如探索性的数据分析,会根据整理的外文资料再给出详细的博文。旨在一同学习的道路上的学者共享,共勉。
We’ll follow the general machine learning workflow step-by-step 第二部分:
pandas pdnumpy np
pdpdpdpd imputerimputervalues training features values testing features scalerscaler
现在,每个字段的最小值为 0,最大值为 1. 缺省值插补和字段缩放是几乎所有机器学习管道中都需要的两个步骤,因此了解它们的工作原理是个好主意!
在 Scikit-Learn 中实现机器学习模型 (Implementing Machine Learning Models in Scikit-Learn)在我们花费所有工作清理和格式化数据之后,实际创建,培训和预测模型相对简单。我们将使用 Python 中的 Scikit-Learn 库,它具有出色的文档和一致的模型构建语法。一旦您知道如何在 Scikit-Learn 中创建一个模型,您就可以快速实现各种算法。
我们可以用 Gradient Boosting Regressor 来说明模型创建,训练(使用.fit)和测试(使用.predict)的一个例子:
sklearnygradient_boostednpy_testmaeloss n_estimators max_depth min_samples_leaf min_samples_split max_features param_distributions cvn_iter scoring n_jobs verbose return_train_score random_stateymax_depth min_samples_leafdefault_modelfinal_modelmodel performance on the test MAE model performance on the test MAE ys ms per loop stddevof runsloop eachys s per loop stddevof runsloop each)
这展示了机器学习的一个基本方面:它始终是一种平衡的游戏。我们必须始终保持准确性与可解释性,偏差与方差 [17],准确性与运行时间等的平衡。正确的取舍最终将取决于业务场景。在我们的例子中,相对而言,运行时间增加了 12 倍,但从绝对意义上说,并不是那么重要。
一旦我们得到最终预测,我们就可以对它们进行调查,看看它们是否表现出任何明显的偏差。左边是预测值和实际值的密度图,右边是残差的直方图:
模型预测似乎遵循实际值的分布,尽管密度峰值更接近训练集的中值(66)而不是密度的真实峰值(接近 100)。残差几乎是正态分布,尽管我们看到一些大的负值,其中模型预测远低于真实值。我们将在下一篇文章中深入研究解释模型的结果。
结论 (Conclusion)
在本文中,我们介绍了机器学习工作流程中的几个步骤:
• 填补缺失值和缩放特征• 评估和比较几种机器学习模型• 使用随机网格搜索和交叉验证进行超参数调整• 评估测试集上的最佳模型
这项工作的结果显示,机器学习适用于使用可用数据预测建筑物能源的星级得分的任务。使用梯度增强回归算法,我们能够将测试集上的分数预测到真实值的 9.1 分之内。此外,我们看到超参数调整可以在投入的时间方面以显着的成本提高模型的性能。这是我们在开发机器学习解决方案时必须考虑的众多权衡之一。
在第三篇文章(此处提供 [18])中,我们将查看我们创建的黑盒子,并尝试了解我们的模型如何进行预测。我们还将确定影响能源星级水平的得分的最重要因素。虽然我们知道我们的模型是准确的,但我们想知道为什么它会做出预测,以及它告诉我们的问题!
一如既往,我欢迎反馈和建设性的批评,可以通过我的 Twitter 账号联系我 @koehrsen_will[19]。
参考文献
•Hands-On Machine Learning with Scikit-Learn and Tensorflow (Jupyter Notebooks for this book are available online for free)![20]•An Introduction to Statistical Learning[21]•Kaggle:[22] The Home of Data Science and Machine Learning•Datacamp:[23] Good beginner tutorials for practicing data science coding•Coursera:[24] Free and paid courses in many subjects•Udacity:[25] Paid programming and data science courses
引用链接
[1]
人工智能全过程,一步一步,第一部分: https://towardsdatascience.com/a-complete-machine-learning-walk-through-in-python-part-one-c62152f39420[2]
人工智能全过程,一步一步,第二部分: https://towardsdatascience.com/a-complete-machine-learning-project-walk-through-in-python-part-two-300f1f8147e2[3]
人工智能全过程,一步一步,第三部分: https://towardsdatascience.com/a-complete-machine-learning-walk-through-in-python-part-three-388834e8804b[4]
在 Github 里: https://github.com/WillKoehrsen/machine-learning-project-walkthrough[5]
统计学习简介: http://www-bcf.usc.edu/~gareth/ISL/[6]
用 Scikit-Learn 和 TensorFlow 熟练掌握机器学习: http://shop.oreilly.com/product/0636920052289.do[7]
什么是超参数?它们与参数有何不同: https://machinelearningmastery.com/difference-between-a-parameter-and-a-hyperparameter/[8]
欠拟合 (underfit) 和过度拟合 (overfit): https://towardsdatascience.com/overfitting-vs-underfitting-a-conceptual-explanation-d94ee20ca7f9[9]
高偏差: https://en.wikipedia.org/wiki/Bias–variance_tradeoff[10]
高方差,high variance: https://en.wikipedia.org/wiki/Bias–variance_tradeoff[11]
Epistasis Lab 的 TPOT: https://epistasislab.github.io/tpot/[12]
遗传编程: https://en.wikipedia.org/wiki/Genetic_programming[13]
随机森林等套袋算法: https://machinelearningmastery.com/bagging-and-random-forest-ensemble-algorithms-for-machine-learning/[14]
梯度提升方法: http://blog.kaggle.com/2017/01/23/a-kaggle-master-explains-gradient-boosting/[15]
XGBoost: https://xgboost.readthedocs.io/en/latest/model.html[16]
机器学习的递减收益定律: http://www.picnet.com.au/blogs/guido/2018/04/13/diminishing-returns-machine-learning-projects/[17]
偏差与方差: https://machinelearningmastery.com/gentle-introduction-to-the-bias-variance-trade-off-in-machine-learning/[18]
此处提供: https://towardsdatascience.com/a-complete-machine-learning-walk-through-in-python-part-three-388834e8804b[19]
@koehrsen_will: https://twitter.com/koehrsen_will[20]
Hands-On Machine Learning with Scikit-Learn and Tensorflow (Jupyter Notebooks for this book are available online for free)!: http://shop.oreilly.com/product/0636920052289.do[21]
An Introduction to Statistical Learning: http://www-bcf.usc.edu/~gareth/ISL/[22]
Kaggle:: https://www.kaggle.com/[23]
Datacamp:: https://www.datacamp.com/[24]
Coursera:: https://www.coursera.org/[25]
Udacity:: https://www.udacity.com/
关于云原生社区
云原生社区是国内最大的独立第三方云原生终端用户和泛开发者社区,由 CNCF 大使、开源意见领袖共同发起成立于 2020 年 5 月 12 日,提供云原生专业资讯,促进云原生产业发展。云原生社区基于成员兴趣创建了多个 SIG(特别兴趣小组),如 Kubernetes、Istio、Envoy、Dapr、OAM、边缘计算、机器学习、可观察性、稳定性、安全等。点击了解我们。
Spark发行版笔记9:Spark Streaming源码解读之Receiver生成全生命周期彻底研究和思考
本节的主要内容:
一、Receiver启动的方式设想
二、Receiver启动源码彻底分析
Receiver的设计是非常巧妙和出色的,非常值得我们去学习、研究、借鉴。
在深入认识Receiver之前,我们有必要思考一下,如果没有Spark、Spark Streaming,我们怎么实现Reciver?数据不断接进来,我们该怎么做?该怎么启动Receiver呢?......
首先,我们找到数据来源的入口,入口如下:
数据来源kafka、socket、flume等构建的都是基于InputDStream的,输入数据来源很关键,没有输入数据来源就无法产生数据,batchDuration就无法获取数据,RDD就无流处理数据及其它故事了。
我们从研究soketTexStream的receiverInputDstream来研究Receiver:
Receiver不断持续的接收外部数据源流入的数据、并将不断接收到数据的元数据汇报给Driver,每个batchDuration会根据汇报的数据生成不同的Job并执行相应的RDD transformation操作。
设想设计一个Receiver:
Receiver是Spark Streaming应用程序启动的一部分,他是随着Spark Streaming启动的时候启动的。怎么启动Receivers?
一个应用程序可以启动多个Receiver,分析源码的DStream Graph:
从上面的源码中分析得出:
通过ArrayBuffer数组来存储InputDStream对象列表,根据Receiver的个数,可以推导出InputDStream对象可以有多个,OutputStream也可以有多个。
如果Spark Streaming应用程序处理的后业务逻辑有多个输出,则会有多个不同的inputStream数据来源,会创建多个InputDStream对象,我们的实验代码只创建一个inputStream。
默认情况下假设:
1、只有一个Partition,我们启动一个Job RDD的transformation触发Job、并执行Job,因为Job只有一个分片Partition,而Partition只有一个Receiver成员,Reciever对象里面有一条或多条数据。
2、多个inputStream则需要启动多个Receiver,每个Receiver相当于一个Partition,从Spark Core的普通调度角度,在同一个executor上需要启动多个Receiver,只是RDD不同的Partition。
注意:
1、启动Receiver角度分析:
只要集群存在,Receiver就不能失败,如果启动Receiver失败,不同Partition代表不同的Receiver,在一个executor上启动Receivers,每个task代表一个Partition,其中一个task失败导致整个Job失败(虽然有stage有重试),而集群存在,我们的Receivers一定要启动成功。
2、运行Receiver角度分析:
运行过程中也有可能基于每个task启动一个executor的方式,task有可能失败,例如:executor挂掉了,则每个task为单位启动额Receiver也会挂掉,影响接收数据。
所以从启动角度不希望Receiver启动失败;在运行时Receiver的失败,不希望影响已有的工作。
作为Spark Streaming应用程序启动的Job,这个Job失败的话对整个应用程序是致命的问题。
启动应用程序的不同的Receiver,采用RDD的不同Partition代表不同Receiver,启动时通过Partition的执行层面是不同task,每个task启动执行时就需要启动Receiver,实现方式简单,实际就借助Spark Core上的Job的方式,但有弊端:
1、Job启动不成功。
2、运行过程Receiver失败,影响执行,task重试,重试失败,整个Job就失败,导致整个Spark应用就失败了,但Spark Streaming是需要在 7*24小时执行的。
Spark Streaming采用的方式是怎么样的?
Spark Streaming的start方法入手:
Receiver的启动是在JobScheduler的start方法中启动的。
ReceiverTracker类中的start方法:
ReceiverTracker类里面有个RPC消息通信体,ReceiverTracker需要监控整个集群中的Receiver,集群中Receiver汇报接收数据和生命周期给ReceiverTracker。
启动Receiver的执行线程时会判断receiverInputStreams对象列表,只有在其不能为空时才能启动Receiver,Receiver启动需要依赖输入数据流,如果没有receiverInputStreams就不会启动Receiver。
在看launchReveivers方法:
基于receiverInputStreams获得具体receivers实例,在具体的worker nodes上启动了receivers,基于receiverInputStreams,receiverInputStreams是在driver端的,
Spark Streaming作业都是基于RDD的方式,不会认识receiverInputStreams,其就相当于原数据或源对象,都是逻辑级别的,怎么分配到worker nodes上让其物理级别执行。
这个过程其实就是一个简单的Master和Slave结构。
一个inputDStream输入的数据来源只产生一个Receiver,通过getReceiver方法返回的是一个Receiver对象,此方法细节必须在其子类中实现:
receiverInputStreams从DStream Graph对象中获取,Receivers会封装完内部的receiver,并给entpoint 发送消息,RPC通信对象接收到这些信息。
那么Endpoint是哪里来的?是在start方法中是构建的:
Receiver要运行在哪些executor上:
这个方法启动一个Receiver,在已经计划好的executor上去运行,而不是让Spark Core自己来分配,不是通过Spark Core上的RDD task的分配方式,
而是Spark Streaming框架自己决定每个Receiver在哪些executor上执行,没有依赖Spark Core上task的分配方式。
Driver层面自己强制指定TaskLocation。
终止启动Receiver意味着不需要重新启动一个Spark Job。
上图这个函数在具体的worker node上启动Receiver的函数。
假设重新启动Receiver则需要重新Job Schduler,而不是taskScheduler的重试。
启动Receiver失败不会启动重试,从启动Job角度来看。
启动ReceiverSuperVisorImpl时Receiver会监听器和接收数据。
看ReceiverSuperVisorImpl的父类start方法,父类反过来调用其子类的onstart方法:
为了启动Receiver,其内部启动了一个Spark Context对象,通过此对象调用了submitJob方法启动了一个Spark作业,这个作业只会启动一个Receiver,
只会启动一个Receiver,每个Receiver的启动都会触发一个Spark Context对象的submitJob方法来启动Job:
每次循环每一个Rceciver时,都会启动一个Spark Job来负责,而不是说所有的Rcecivers都是交给一个Spark Job来负责,有如下考虑:
- Rceciver失败导致应用程序失败。
- 作业运行时有任务倾斜的问题,Spark Core的调度方式有可能会在同一台机器上运行多个Rceciver。
- 作业运行过程中Rceciver失败了导致整个Spark Job失败,进而导致应用程序的失败,代价太大。
每次循环每一个Rceciver时,都会启动一个Spark Job来负责,则一个Job的失败只会影响一个Job的运行,从而最大程度负载均衡。
再看作业的失败,作业失败后会执行restartReceiver方法的代码,给自己发消息,又会把刚才的过程走一遍:
每个Job里面是启动一个Receiver,也就是说每个Job里面就只有一个任务,并且只会在一台机器上运行一个task,最大程度负载均衡。
在启动很多Receiver时用了线程池来处理,可以并发启动Receiver,Receiver之间没有直接关系,可以并发启动、执行。
把Receiver放在哪些位置上,由receiverScheduleringPolicy策略来调度,尽量均匀分配。
在看runDummySparkJob方法:
为了保证Executor活着,其内部自己跑一个Spark Job作业,产生50个Receviers、并发度20的小任务,此Spark Streaming应用程序会跑在所有机器上,确保其均匀的运行。
新浪微博:http://weibo.com/ilovepains
微信公众号:DT_Spark
博客:http://blog.sina.com.cn/ilovepains
手机:18610086859
QQ:1740415547
邮箱:18610086859@vip.126.com
Spark发行版笔记9
以上是关于机器学习全生命周期研究的主要内容,如果未能解决你的问题,请参考以下文章
Spark Streaming源码解读之生成全生命周期彻底研究与思考
Spark Streaming源码解读之流数据不断接收全生命周期彻底研究和思考
Spark Streaming源码解读之Receiver生成全生命周期彻底研究和思考
第10课:Spark Streaming源码解读之流数据不断接收全生命周期彻底研究和思考