spark寫出分布式的訓練算法_利用 Spark 和 scikit-learn 將你的模型訓練加快 100 倍...

在 Ibotta,我們訓練了許多機器學習模型。這些模型為我們的推薦系統、搜索引擎、定價優化引擎、數據質量等提供動力。它們在與我們的移動應用程序交互時為數百萬用戶做出預測。

當我們使用 Spark 進行數據處理時,我們首選的機器學習框架是 scikit-learn。隨著計算機變得越來越便宜,機器學習解決方案的上市時間變得越來越關鍵,我們探索了加快模型訓練的各種方法。其中一個解決方案是將 Spark 和 scikit-learn 中的元素組合到我們自己的混合解決方案中。

sk-dist 的介紹

我們很高興地宣布我們的開源項目 sk-dist 的啟動。該項目的目標是為使用 Spark 分發 scikit 學習元估計器提供一個通用框架。元估計器的例子有決策樹集合(隨機林和額外隨機樹)、超參數調解器(網格搜索和隨機搜索)和多分類技術(一對多和多對一)。

我們的主要動機是填補傳統機器學習模型空間的空白。在神經網絡和深度學習的空間之外,我們發現我們的訓練模型的大部分計算時間并沒有花在訓練單個數據集的單個模型上。相反,大部分時間都花在使用元估計器在數據集上訓練模型的多次迭代上。

例子

讓我們談談手寫數字數據集。在這里,我們對手寫數字的圖像進行了適當的編碼、分類。我們可以很快在一臺機器上訓練 1797 條記錄的支持向量機,花費的時間不到一秒鐘。但超參數調整需要在訓練數據的不同子集上進行大量的訓練。

如下圖所示,我們已經構建了一個總計需要 1050 個訓練的參數網格。在擁有 100 多個核的 Spark 上使用 sk dist 只需 3.4 秒。這項工作的總時間是 7.2 分鐘,意思是在沒有并行化的單機上訓練要花這么長時間。import timefrom sklearn import datasets, svm

from skdist.distribute.search import DistGridSearchCV

from pyspark.sql import SparkSession # instantiate spark session

spark = (

SparkSession

.builder

.getOrCreate()

)

sc = spark.sparkContext # the digits dataset

digits = datasets.load_digits()

X = digits["data"]

y = digits["target"] # create a classifier: a support vector classifier

classifier = svm.SVC()

param_grid = {

"C": [0.01, 0.01, 0.1, 1.0, 10.0, 20.0, 50.0],

"gamma": ["scale", "auto", 0.001, 0.01, 0.1],

"kernel": ["rbf", "poly", "sigmoid"]

}

scoring = "f1_weighted"

cv = 10# hyperparameter optimization

start = time.time()

model = DistGridSearchCV(

classifier, param_grid,

sc=sc, cv=cv, scoring=scoring,

verbose=True

)

model.fit(X,y)

print("Train time: {0}".format(time.time() - start))

print("Best score: {0}".format(model.best_score_))------------------------------

Spark context found; running with spark

Fitting 10 folds for each of 105 candidates, totalling 1050 fits

Train time: 3.380601406097412

Best score: 0.981450024203508

這個例子演示了一個常見的場景,在這個場景中,將數據擬合到內存中并訓練單個分類器是很簡單的,但是適合超參數優化所需的匹配數量會迅速增加。下面是一個運行網格搜索問題的例子,和上面的 sk dist 示例類似:

帶sk-dist的網格搜索

對于 ibotta 傳統機器學習的實際應用,我們經常發現自己處于類似這樣的情況中:中小型數據(10k 到 1M 的記錄)和許多簡單分類器迭代以適應超參數調整、集成和多分類解決方案。

現有解決方案

傳統的機器學習元估計器訓練方法已經存在。第一個是最簡單的:scikit-learn 使用 joblib 內置的元估計器并行化。這與 sk-dist 的操作非常相似,但是它有一個主要的限制:性能受限于任何機器的資源。即使與理論上擁有數百個內核的單機相比,Spark 仍然具有一些優勢,如執行器的微調內存規范、容錯,以及成本控制選項,如對工作節點使用 spot 實例。

另一個現有的解決方案是 Spark ML,它是 Spark 的一個本地機器學習庫,支持許多與 scikit-learn 相同的算法來解決分類和回歸問題。它還具有諸如樹集合和網格搜索之類的元估計器,以及對多分類問題的支持。

分布在不同的維度上

如上所示,Spark ML 將針對分布在多個執行器上的數據來訓練單個模型。當數據量很大,以至于無法存入一臺機器上的內存時,這種方法可以很好地工作。然而,當數據量很小時,在單臺機器上這可能會比 scikit-learn 的學習效果差。此外,例如,當訓練一個隨機森林時,Spark ML 按順序訓練每個決策樹。此項工作的時間將與決策樹的數量成線性比例,和分配給該任務的資源無關。

對于網格搜索,Spark ML 實現了一個并行參數,該參數將并行地訓練各個模型。然而,每個單獨的模型仍在對分布在執行器之間的數據進行訓練。這項任務的總并行度只是純粹按照模型維度來的,而不是數據分布的維度。

最后,我們希望將我們的訓練分布在與 Spark ML 不同的維度上。當使用中小型數據時,將數據擬合到內存中不是問題。對于隨機森林的例子,我們希望將訓練數據完整地廣播給每個執行器,在每個執行者身上擬合一個獨立的決策樹,并將這些擬合的決策樹帶回給驅動器,以集合成一個隨機森林。這個維度比串行分布數據和訓練決策樹快幾個數量級。

特征

考慮到這些現有解決方案在我們的問題空間中的局限性,我們內部決定開發 sk-dist。歸根結底,我們希望發布的是模型,而不是數據。

雖然 sk-dist 主要關注元估計器的分布式訓練,但它也包括很多其它模塊,如 Spark 的 scikit-learn 模型的分布式預測模塊等。分布式訓練——使用 Spark 進行分布式元估計訓練,支持以下算法:帶網格搜索和隨機搜索的超參數優化、帶隨機林的樹集合、額外樹和隨機樹嵌入,以及一對一和一對多的多分類策略。

分布預測——具有 Spark 數據幀的擬合 scikit-learn 估計器的預測方法。這使得帶有 scikit-learn 的大規模分布式預測可以在沒有 Spark 的情況下進行。

特征編碼——分布特征編碼使用被稱為編碼器的靈活特征變換器來完成。不管有沒有 Spark,它都可以起作用。它將推斷數據類型,自動應用默認的特征變換器作為標準特征編碼技術的最佳實現。它還可以作為一個完全可定制的功能聯合,如編碼器,它的附加優勢是與 Spark 匹配的分布式 transformer。

用例

以下是判斷 sk-dist 是否適合解決你的機器學習問題的一些準則:傳統的機器學習方法,如廣義線性模型、隨機梯度下降、最近鄰、決策樹和樸素貝葉斯等,都能很好地應用于 sk-dist,這些方法都可以在 scikit-learn 中實現,并且可以直接應用于 sk-dist 元估計。

中小型數據、大數據不能很好地在 sk-dist 中起作用。記住,分布式訓練的維度是沿著模型的軸,而不是數據。數據不僅需要放在每個執行器的內存中,而且要小到可以傳播。根據 Spark 配置,最大傳播大小可能會受到限制。

Spark 定向和訪問——sk-dist 的核心功能需要運行 Spark。對于個人或小型數據科學團隊來說,這并不總是可行的。

這里一個重要的注意事項是,雖然神經網絡和深度學習在技術上可以用于 sk-dist,但這些技術需要大量的訓練數據,有時需要專門的基礎設施才能有效。深度學習不是 sk-dist 的最佳用例,因為它違反了上面的(1)和(2)。

開始

要開始使用 sk-dist,請查看安裝指南。代碼庫還包含一個示例庫,用于說明 sk-dist 的一些用例。歡迎所有人提交問題并為項目做出貢獻。

雷鋒網(公眾號:雷鋒網)雷鋒網雷鋒網

雷鋒網版權文章,未經授權禁止轉載。詳情見轉載須知。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282112.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282112.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282112.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

理解LinkedHashMap

1. LinkedHashMap概述:LinkedHashMap是HashMap的一個子類,它保留插入的順序,如果需要輸出的順序和輸入時的相同,那么就選用LinkedHashMap。LinkedHashMap是Map接口的哈希表和鏈接列表實現,具有可預知的迭代順序。此實現…

MySQL - 鎖

一、什么是鎖 鎖是數據庫系統區別于文件系統的一個關鍵特性。鎖機制用于管理對共享資源的并發訪問。 二、MySQL 不同存儲引擎支持的鎖機制 存儲引擎支持的鎖類型Myisam表鎖Innodb行鎖、表鎖Memory表鎖BDB頁鎖、表鎖表鎖:直接鎖住的是一個表,開銷小&…

數據庫時區那些事兒 - MySQL的時區處理

原文地址 當JVM時區和數據庫時區不一致的時候,會發生什么?這個問題也許你從來沒有注意過,但是當把Java程序容器化的時候,問題就浮現出來了,因為目前幾乎所有的Docker Image的時區都是UTC。本文探究了MySQL及其JDBC驅動…

java_函數的重載

函數的重載(Overload)概念:在同一個類中,允許存在一個以上的同名函數,只要他們的參數個數或者參數類型不同即可。函數功能一樣,僅僅是參與運算的未知內同不同時,可以定義多函數,卻使…

全新升級的AOP框架Dora.Interception[2]: 基于約定的攔截器定義方式

Dora.Interception(github地址,覺得不錯不妨給一顆星)有別于其他AOP框架的最大的一個特點就是采用針對“約定”的攔截器定義方式。如果我們為攔截器定義了一個接口或者基類,那么攔截方法將失去任意注冊依賴服務的靈活性。除此之外…

redis watch使用場景_redis不得不會的事務玩法

我們都知道redis追求的是簡單,快速,高效,在這種情況下也就拒絕了支持window平臺,學sqlserver的時候,我們知道事務還算是個比較復雜的東西,所以這吊毛要是照搬到redis中去,理所當然redis就不是那…

加快Android Studio的編譯速度

從Eclipse切換到Android Studio后,感覺Android Studio的build速度比Eclipse慢很多,以下幾個方法可以提高Android Studio的編譯速度使用Gradle 2.4Gradle 2.4對執行性能有很大的優化,但Android Studio現在默認使用的是Gradle 2.2,所以我們需要…

開發中 MySQL 規范

一、建表規范 1、數據庫名、表名、字段名必須使用小寫字母或數字,并且禁止以數字開頭 示例:goods_category、agent_operate_201812_log 2、數據庫名、表名、字段名要做到見名識意 示例:goods_category,不能 gc 3、配置表建議以 …

PaddleOCR在 Linux下的webAPI部署方案

很多小伙伴在使用OCR時都希望能采用API的方式調用,這樣就可以跨端跨平臺了。本文將介紹一種基于python的PaddleOCR識別WebAPI部署方案。喜歡的可以關注公眾號,獲取更多內容。一、 Linux環境下部署1.環境要求操作系統:CenterOS7;主…

影響程序員生涯的三個錯誤觀念,你千萬不要犯!

程序員在社會上,到底是怎樣一個生活群體?是否能找到自己方向?其實,路一直都在那里,只是你看不到而已! 當初的你,可能一直被一些技術牽著鼻子走,并不是自己在做著自己想做的&#xff…

心電圖計算心率公式_心電圖到底能反應啥問題,看過之后你也能當“醫生”

只要是經歷過健康體檢的健康人,或者做過手術的患者,基本都做過心電圖檢查。都說久病成醫,所以有些人對血、尿常規等各項檢查的結果都門清兒得很,最起碼看一眼也能說出個大概齊。偏偏心電圖這種常做的檢查,不但老病號如…

獲取正在運行的服務

手機上安裝的App,在后臺運行著很多不同功能的服務,最常見的例如消息推送相關的服務。如何查看這些服務?如何判斷某個服務是否正在運行?如何停止某一個服務呢?請看下面的方法: package com.example.servicel…

openstack的vnc啟動ssl

1、制作ssl證書# cd /etc/pki/tls/certs [rootwww certs]# make vnc.key Enter pass phrase:# 輸入密碼 Verifying - Enter pass phrase:#確認# 從private key 中刪除密碼# openssl rsa -in vnc.key -out vnc.key # make vnc.csr Country Name (2 letter code) [XX]:CN# 國家 S…

開發composer包

一、初始化&#xff08;生成composer.json文件&#xff09; composer init#輸入你要創建的composer包項目命名空間 Package name (<vendor>/<name>) [root/tiny-laravel]: #haveyb/tiny-laravel #輸入composer包的描述 Description []:#this is a tiny laravel h…

Linux本地yum源配置以及使用yum源安裝gcc編譯環境

本文檔是圖文安裝本地yum源的教程&#xff0c;以安裝gcc編譯環境為例。 適用范圍&#xff1a;所有的cetos,紅帽,fedroa版本 適用人群&#xff1a;有一點linux基礎的小白 范例系統版本&#xff1a;CentOS Linux release 7.3.1611 (Core) 范例環境&#xff1a;vmware 虛擬機 安裝…

word如何設置上標形式_如何在word中設置特殊頁碼

獲取更多業界資訊和深度好文● 點擊藍字關注我們 ●在日常工作中&#xff0c;我們編輯的word文檔經常需要設置頁碼&#xff0c;但有時文檔的第一頁是封面&#xff0c;第二頁才是正文&#xff0c;或者第二頁是目錄&#xff0c;第三頁才是正文&#xff0c;如下圖所示&#xff0c;…

[cf797c]Minimal string(貪心+模擬)

題意&#xff1a; 給出了字符串s的內容&#xff0c;字符串t&#xff0c;u初始默認為空&#xff0c;允許做兩種操作&#xff1a; 1、把s字符串第一個字符轉移到t字符串最后 2、把t字符串最后一個字符轉移到u字符串最后 最后要求s、t字符串都為空&#xff0c;問u字符串字典序最小…

發布composer包到 Packagist,并設置自動同步(從github到Packagist)

一、發布composer包 1、將我們寫好的項目包發布到github上 這一步不贅述&#xff0c;應該都會。 但是需要注意的是&#xff0c;我們一定要為我們的項目包打上tag之后再提交&#xff0c;否則 我們composer require時可能會報錯 Could not find a version of package。 # 設置…

教你在CorelDRAW中導入位圖

在CorelDRAW軟件中不能直接打開位圖圖像&#xff0c;在實際操作中&#xff0c;用戶需要使用導入位圖圖像的方法進行操作。導入位圖圖像時&#xff0c;可以導入整幅圖像&#xff0c;也可以在導入的過程中對圖像進行裁剪&#xff0c;或重新取樣圖像&#xff0c;導入整幅位圖圖像時…

.NET 6 中將 ASP.NET Core 注冊成 Windows Service

前言使用 Visual Studio 中的 Worker Service項目模板:我們很容易創建出 Windows Service&#xff1a;IHost host Host.CreateDefaultBuilder(args).UseWindowsService().ConfigureServices(services >{services.AddHostedService<Worker>();}).Build();await host.R…