開源 sk-dist,超參數調優僅需 3.4 秒,sk-learn 訓練速度提升 100 倍!

  • 2019 年 10 月 4 日
  • 筆記

作者 | Evan Harris

譯者 | Monanfei

編輯 | Jane

出品 | AI科技大本營(ID:rgznai100)

這篇文章為大家介紹了一個開源項目——sk-dist。在一台沒有並行化的單機上進行超參數調優,需要 7.2 分鐘,而在一百多個核心的 Spark 群集上用它進行超參數調優,只需要 3.4 秒,把訓練 sk-learn 的速度提升了 100 倍。

sk-dist 簡介

sk-dist 是一個開源項目,它使用 Spark 來分發 scikit-learn 元估計器。常見的元估計器有決策樹(隨機森林和其他的隨機樹),超參數調優器(格網搜索和隨機搜索),以及多類別處理技術(一對多和一對一)。

sk-dist 的主要動機是填補傳統機器學習在模型分散式訓練上的空白。除去神經網路和深度學習,我們發現在單個數據集上訓練單個模型並不怎麼花時間,反而當我們使用元估計器(例如網格搜索或集合等),在數據集的多次迭代上訓練模型的多次迭代花費了大量時間。

使用 sk-dist 的例子

以手寫數字數據集為例,我們事先對影像進行了編碼,以便於進行適當的分類。我們可以在一台機器上飛速的訓練一個支援向量機,數據集有1797 條記錄,整個訓練過程不到 1 秒鐘。但是,超參數調整卻需要在訓練集的不同子集上進行大量的訓練工作。

如下圖所示,我們構建了一個參數網格,本次超參數調優總共需要 1050 個訓練任務。在具有一百多個核心的 Spark 群集上使用 sk-dist 進行超參數調優,我們只需要 3.4 秒,而在一台沒有並行化的單機上進行超參數調優,卻需要 7.2 分鐘。

  import time  from 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 運行格網搜索的流程:

對於 Ibotta 傳統機器學習的實際應用,我們經常發現自己處於以下類似情況:使用多個簡單的分類器對中小型數據(100k~1M)進行多次迭代,企圖解決超參數調優、集合模型和多類別問題。

目前的解決方案

現在,分散式的傳統機器學習元估計訓練有兩個主流解決方案。第一個,也是最簡單的一個:使用 joblib 實現 scikit-learn 內置元估計器的並行化。這和 sk-dist 非常相似,但是該方法卻存在一個很大的限因素:處理性能受到單機資源的限制。即使在一台具有數百個內核的機器上實行並行化,它的性能與使用 spark 的 sk-dist 相比,也要遜色許多。這是因為 Spark 具有執行器的精細記憶體規範,優秀的容錯能力,以及成本控制選項,例如為工作節點使用專門的實例。

另一個現存的解決方案是 Spark ML。它是Spark的本地機器學習庫,支援許多與 scikit-learn 相同的演算法,用於分類和回歸問題。它還具有樹集合和網格搜索等元估計,以及對多類別問題的支援。雖然這聽起來很完美,似乎能夠解決分散式 scikit-learn 機器學習問題,但是它並不能用我們感興趣的並行方式進行訓練。

如上圖所示,Spark ML 將針對分布在許多執行程式上的數據訓練單個模型。當數據量很大,並且不適合單機記憶體時,該方法很有效。但是,當數據很小時,scikit-learn 可能在單機上表現欠佳。此外,當訓練隨機森林模型時,Spark ML 會按順序訓練每個決策樹。無論分配給任務的資源有多大,該任務的掛起時間都將與決策樹的數量成線性比例。

對於網格搜索,Spark ML 採用了並行參數,該參數將並行訓練單個模型。但是,每個單獨的模型仍在跨執行器的分布數據上進行訓練。如果純粹沿著模型的維度而不是數據的分布,那麼任務的總並行性能只能發揮一小部分。

因此,我們希望有一個新的解決方案,將我們的數據分布在與 Spark ML不同的維度上。當我們使用小型或中型數據時,將數據擬合到記憶體中將不再是問題。在隨機森林的例子中,我們希望將訓練數據完整地派送給每個執行器,在每個執行器上擬合一個獨立的決策樹,並將那些擬合好的決策樹收回,從而集成隨機森林。通過沿著該維度實行並行化,執行速度可以比串列分發數據和訓練決策樹快幾個數量級。網格搜索和多類別等其他元估計技術也應該採用這種類似的並行方式。

sk-dist 的特點

鑒於這些現有解決方案的局限性,sk-dist 應時而生。sk-dist 最重要的是分發模型,而不是數據。

儘管 sk-dist 主要關注元估計器的分散式訓練,d但它還包括使用 Spark 進行 scikit-learn 模型分散式預測的模組、幾個無需使用 Spark 的前/後處理 scikit-learn 變換器、以及使用或不使用Spark 的靈活的特徵編碼器。

  • 分散式訓練:使用 Spark 分發元估計器訓練。支援以下演算法:使用網格搜索和隨機搜索的超參數調優,使用隨機森林的樹集成,其他樹和隨機樹嵌入,以及一對多、一對一的多類別問題策略。
  • 分散式預測:使用 Spark DataFrames 分配擬合後的 scikit-learn 估計器進行預測。通過攜帶型的 scikit-learn 估計器,該方法使得大尺度的分散式預測成為可能。這些估計器可以與 Spark 一起使用,也可以不與 Spark 一起使用。
  • 特徵編碼:使用 Encoderizer 對特徵進行靈活編碼。 Encoderizer 可以使用或不使用Spark 並行化。它將推斷數據類型和形狀,自動選擇並應用最佳的默認特徵變換器,對數據進行編碼。作為一個完全可訂製的特徵聯合編碼器,它還具有使用 Spark 進行分散式變換的附加優勢。

sk-dist 的適用情形

並非所有的機器學習問題都適合使用 sk-dist,以下是決定是否使用 sk-dist 的一些指導原則:

  • 傳統的機器學習: 廣義線性模型,隨機梯度下降,最近鄰,決策樹和樸素貝葉斯等方法與 sk-dist 配合良好。這些模型都已在 scikit-learn 中集成,用戶可以使用 sk-dist 元估計器直接實現。
  • 中小型數據:大數據無法與 sk-dist 一起使用。值得注意的是,訓練分布的維度是沿著模型的軸,而不是數據。數據不僅需要適合每個執行器的記憶體,還要小到可以廣播。根據 Spark 的配置,最大廣播量可能會受到限制。
  • Spark 的使用:sk-dist 的核心功能需要運行Spark。對於個人或小型數據科學團隊而言,從經濟上來講可能並不可行。此外,為了以經濟有效的方式充分利用 sk-dist,需要對 Spark 進行一些調整和配置,這要求使用者具備一些 Spark 的基礎知識。

值得引起注意的是,雖然神經網路和深度學習在技術上可以與 sk-dist 一起使用,但這些技術需要大量的訓練數據,有時需要專門的硬體設施才能工作。深度學習不是 sk-dist 的目標,因為它違反了上面的(1)和(2)。作為替代技術, Amazon SageMaker 可以配合神經網路或深度學習進行使用。

原文:

https://medium.com/building-ibotta/train-sklearn-100x-faster-bec530fc1f45