Spark ML源碼分析之一 設計框架解讀


本博客為作者原創,如需轉載請注明http://www.cnblogs.com/jicanghai/p/8570805.html
 
        在深入理解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的設計思路又有了新的認識。由於本人才疏學淺,以上的理解不免會有紕漏,還請大家不吝賜教。下次將跟大家一起分析下具體算法的設計。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM