天天看點

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&Spark MLLib中拟牛頓法L-BFGS的源碼實作

本文簡要描述線性回歸算法在spark mllib中的具體實作,涉及線性回歸算法本身及線性回歸并行處理的理論基礎,然後對代碼實作部分進行走讀。

機器學習算法是的主要目的是找到最能夠對資料做出合了解釋的模型,這個模型是假設函數,一步步的推導基本遵循這樣的思路

<code></code>

假設函數

為了找到最好的假設函數,需要找到合理的評估标準,一般來說使用損失函數來做為評估标準

根據損失函數推出目标函數

現在問題轉換成為如何找到目标函數的最優解,也就是目标函數的最優化

具體到線性回歸來說,上述就轉換為:

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作

那麼如何求得損失函數的最優解,針對最小二乘法來說可以使用梯度下降法。

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作

 如何解決這些問題呢?可以采用收縮方法(shrinkage method),收縮方法又稱為正則化(regularization)。 主要是嶺回歸(ridge regression)和lasso回歸。通過對最小二乘估計加 入罰限制,使某些系數的估計為0。

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作

上面講述了一些數學基礎,在将這些數學理論用代碼來實作的時候,最主要的是把握住相應的假設函數和最優化算法是什麼,有沒有相應的正則化規則。

對于線性回歸,這些都已經明确,分别為

y = a*x + b 假設函數

随機梯度下降法

嶺回歸或lasso法,或什麼都沒有

那麼spark mllib針對線性回歸的代碼實作也是依據該步驟來組織的代碼,其類圖如下所示

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作

函數調用路徑

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作

train-&gt;run,run函數的處理邏輯

利用最優化算法來求得最優解,optimizer.optimize

根據最優解建立相應的回歸模型, createmodel

runminibatchsgd是真正計算gradient和loss的地方

 上述代碼中最需要引起重視的部分是aggregate函數的使用,先看下aggregate函數的定義

aggregate函數有三個入參,一是初始值zerovalue,二是seqop,三為combop.

seqop seqop會被并行執行,具體由各個executor上的task來完成計算

combop combop則是串行執行, 其中combop操作在jobwaiter的tasksucceeded函數中被調用

為了進一步加深對aggregate函數的了解,現舉一個小小例子。啟動spark-shell後,運作如下代碼

仔細觀察一下運作時的日志輸出, aggregate送出的job由一個stage(stage0)組成,由于整個資料集被分成兩個partition,是以為stage0建立了兩個task并行處理。

講完了aggregate函數的執行過程, 回過頭來繼續講組成seqop的gradient.compute函數。

leastsquaregradient用來計算梯度和誤差,注意cmopute中cumgraident會傳回改變後的結果。這裡計算公式依據的就是cost-function中的▽q(w)

在上述代碼中頻繁出現breeze相關的函數,你一定會很好奇,這是個什麼新鮮玩藝。

說 開 了 其 實 一 點 也 不 稀 奇, 由 于 計 算 中 有 大 量 的 矩 陣(matrix)及 向量(vector)計算,為了更好支援和封裝這些計算引入了breeze庫。

breeze, epic及puck是scalanlp中三大支柱性項目, 具體可參數www.scalanlp.org

根據本次疊代出來的梯度和誤差對權重系數進行更新,這個時候就需要用上正則化規則了。也就是下述語句會觸發權重系數的更新

以嶺回歸為例,看其更新過程的代碼實作。

計算出權重系數(weights)和截距intecept,就可以用來建立線性回歸模型linearregressionmodel,利用模型的predict函數來對觀測值進行預測

 注意linearregression的構造函數需要權重(weights)和截距(intercept)作為入參,對新的變量做出預測需要調用predictpoint。

在spark-shell中執行如下語句來親自體驗一下吧。

再次強調,找到對應的假設函數,用于評估的損失函數,最優化求解方法,正則化規則。

本文就拟牛頓法l-bfgs的由來做一個簡要的回顧,然後就其在spark mllib中的實作進行源碼走讀。

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作
Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作

l-bfgs算法中使用到的正則化方法是squaredl2updater。

算法實作上使用到了由scalanlp的成員項目breeze庫中的breezelbfgs函數,mllib中自定義了breezelbfgs所需要的difffunctions.

Apache Spark源碼走讀(十一)淺談mllib中線性回歸的算法實作&amp;Spark MLLib中拟牛頓法L-BFGS的源碼實作

runlbfgs函數的源碼實作如下:

costfun函數是算法實作中的重點

繼續閱讀