在 Python中處理大型機器學習資料集的簡單方法

在 Python中處理大型機器學習資料集的簡單方法

本文的目標受眾:

想要對大量資料集執行 Pandas/NumPy 操作的人。

希望使用Python在大資料上執行機器學習任務的人。

本文將使用 。csv 格式的檔案來演示 python 的各種操作,其他格式如陣列、文字檔案等也是如此。

為什麼我們不能將 pandas 用於大型機器學習資料集呢?

我們知道 Pandas 使用計算機記憶體 (RAM) 來載入您的機器學習資料集,但是,如果您的計算機有8 GB 的記憶體 (RAM),那麼為什麼 pandas 仍然無法載入 2 GB 的資料集呢?原因是使用 Pandas 載入 2 GB 檔案不僅需要 2 GB RAM,還需要更多記憶體,因為總記憶體需求取決於資料集的大小以及您將在該資料集上執行的操作。

以下是載入到計算機記憶體中的不同大小的資料集的快速比較:

在 Python中處理大型機器學習資料集的簡單方法

此外,Pandas只使用作業系統的一個核心,這使得處理速度很慢。換句話說,我們可以說pandas不支援並行(將一個問題分解成更小的任務)。

假設電腦有 4 個核心,下圖是載入 CSV 檔案的時候 pandas 使用的核心數:

在 Python中處理大型機器學習資料集的簡單方法

普遍不使用 pandas 處理大型機器學習資料集的主要原因有以下兩點,一是計算機記憶體使用量,二是缺乏並行性。在 NumPy 和 Scikit-learn中,對於大資料集也面臨同樣的問題。

為了解決這兩個問題,可以使用名為Dask的python庫,它能夠使我們在大型資料集上執行pandas、NumPy和ML等各種操作。

Dask是如何工作的?

Dask是在分割槽中載入你的資料集,而pandas通常是將整個機器學習資料集作為一個dataframe。在Dask中,資料集的每個分割槽都被認為是一個pandas dataframe。

在 Python中處理大型機器學習資料集的簡單方法

Dask 一次載入一個分割槽,因此您不必擔心出現記憶體分配錯誤問題。

以下是使用 dask 在計算機記憶體中載入不同大小的機器學習資料集的比較:

在 Python中處理大型機器學習資料集的簡單方法

Dask 解決了並行性問題,因為它將資料拆分為多個分割槽,每個分割槽使用一個單獨的核心,這使得資料集上的計算更快。

假設電腦有 4 個核心,以下是 dask 在載入 5 GB csv 檔案時的方式:

在 Python中處理大型機器學習資料集的簡單方法

要使用 dask 庫,您可以使用以下命令進行安裝:

pip install dask

Dask 有幾個模組,如dask。array、dask。dataframe 和 dask。distributed,只有在您分別安裝了相應的庫(如 NumPy、pandas 和 Tornado)後才能工作。

如何使用 dask 處理大型 CSV 檔案?

dask。dataframe 用於處理大型 csv 檔案,首先我嘗試使用 pandas 匯入大小為 8 GB 的資料集。

import pandas as pddf = pd。read_csv(“data。csv”)

它在我的 16 GB 記憶體膝上型電腦中引發了記憶體分配錯誤。

現在,嘗試使用 dask。dataframe 匯入相同的 8 GB 資料

在 Python中處理大型機器學習資料集的簡單方法

dask 只用了一秒鐘就將整個 8 GB 檔案載入到 ddf 變數中。

讓我們看看 ddf 變數的輸出。

在 Python中處理大型機器學習資料集的簡單方法

如您所見,執行時間為 0。5 秒,這裡顯示已劃分為 119 個分割槽。

您還可以使用以下方法檢查資料幀的分割槽數:

在 Python中處理大型機器學習資料集的簡單方法

預設情況下,dask 將我的 8 GB CSV 檔案載入到 119 個分割槽(每個分割槽大小為 64MB),這是根據可用的物理記憶體和電腦的核心數來完成的。

還可以在載入 CSV 檔案時使用 blocksize 引數指定我自己的分割槽數。

在 Python中處理大型機器學習資料集的簡單方法

現在指定了一個字串值為 400MB 的 blocksize 引數,這使得每個分割槽大小為 400 MB,讓我們看看有多少個分割槽

在 Python中處理大型機器學習資料集的簡單方法

關鍵點:使用 Dask DataFrames 時,一個好的經驗法則是將分割槽保持在 100MB 以下。

使用以下方法可呼叫dataframe的特定分割槽:

在 Python中處理大型機器學習資料集的簡單方法

也可透過使用負索引來呼叫最後一個分割槽,就像我們在呼叫列表的最後一個元素時所做的那樣。

讓我們看看資料集的形狀:

在 Python中處理大型機器學習資料集的簡單方法

您可以使用 len() 檢查資料集的行數:

在 Python中處理大型機器學習資料集的簡單方法

Dask 已經包含了示例資料集。我將使用時間序列資料向您展示 dask 如何對資料集執行數學運算。

在 Python中處理大型機器學習資料集的簡單方法

匯入dask。datasets後,ddf_20y 載入了從 2000 年 1 月 1 日到 2021 年 12 月 31 日的時間序列資料。

讓我們看看我們的時間序列資料的分割槽數。

在 Python中處理大型機器學習資料集的簡單方法

20 年的時間序列資料分佈在 8035 個分割槽中。

在 pandas 中,我們使用 head 列印資料集的前幾行,dask 也是這樣。

在 Python中處理大型機器學習資料集的簡單方法

讓我們計算一下 id 列的平均值。

在 Python中處理大型機器學習資料集的簡單方法

dask不會列印dataframe的總行數,因為它使用惰性計算(直到需要時才顯示輸出)。為了顯示輸出,我們可以使用compute方法。

在 Python中處理大型機器學習資料集的簡單方法

假設我想對資料集的每一列進行歸一化(將值轉換為0到1之間),Python程式碼如下:

在 Python中處理大型機器學習資料集的簡單方法

迴圈遍歷列,找到每列的最小值和最大值,並使用簡單的數學公式對這些列進行歸一化。

關鍵點:在我們的歸一化示例中,不要認為會發生實際的數值計算,它只是惰性求值(在需要之前永遠不會向您顯示輸出)。

為什麼要使用 Dask 陣列?

Dask 將陣列分成小塊,其中每個塊都是一個 NumPy 陣列。

在 Python中處理大型機器學習資料集的簡單方法

dask。arrays 用於處理大陣列,以下Python程式碼使用 dask 建立了一個 10000 x 10000 的陣列並將其儲存在 x 變數中。

在 Python中處理大型機器學習資料集的簡單方法

呼叫該 x 變數會產生有關陣列的各種資訊。

檢視陣列的特定元素

在 Python中處理大型機器學習資料集的簡單方法

對dask 陣列進行數學運算的Python示例:

在 Python中處理大型機器學習資料集的簡單方法

正如您所看到的,由於延遲執行,它不會向您顯示輸出。我們可以使用compute來顯示輸出:

在 Python中處理大型機器學習資料集的簡單方法

dask 陣列支援大多數 NumPy 介面,如下所示:

數學運算:+, *, exp, log, 。。。

sum(), mean(), std(), sum(axis=0), 。。。

張量/點積/矩陣乘法:tensordot

重新排序/轉置:transpose

切片:x[:100, 500:100:-2]

使用列表或 NumPy 陣列進行索引:x[:, [10, 1, 5]]

線性代數:svd、qr、solve、solve_triangular、lstsq

但是,Dask Array 並沒有實現完整 NumPy 介面。

你可以從他們的官方文件中瞭解更多關於 dask。arrays 的資訊。

什麼是Dask Persist?

假設您想對機器學習資料集執行一些耗時的操作,您可以將資料集持久化到記憶體中,從而使數學運算執行得更快。

從 dask。datasets 匯入了時間序列資料

在 Python中處理大型機器學習資料集的簡單方法

讓我們取資料集的一個子集並計算該子集的總行數。

在 Python中處理大型機器學習資料集的簡單方法

計算總行數需要 27 秒。

我們現在使用 persist 方法:

在 Python中處理大型機器學習資料集的簡單方法

持久化我們的子集總共花了 2 分鐘,現在讓我們計算總行數。

在 Python中處理大型機器學習資料集的簡單方法

同樣,我們可以對持久化資料集執行其他操作以減少計算時間。

在 Python中處理大型機器學習資料集的簡單方法

persist應用場景:

資料量大

獲取資料的一個子集

對子集應用不同的操作

為什麼選擇 Dask ML?

Dask ML有助於在大型資料集上使用流行的Python機器學習庫(如Scikit learn等)來應用ML(機器學習)演算法。

什麼時候應該使用 dask ML?

資料不大(或適合 RAM),但訓練的機器學習模型需要大量超引數,並且調優或整合技術需要大量時間。

資料量很大。

在 Python中處理大型機器學習資料集的簡單方法

正如你所看到的,隨著模型大小的增加,例如,製作一個具有大量超引數的複雜模型,它會引起計算邊界的問題,而如果資料大小增加,它會引起記憶體分配錯誤。因此,在這兩種情況下(紅色陰影區域)我們都使用 Dask 來解決這些問題。

如官方文件中所述,dask ml 庫用例:

對於記憶體問題,只需使用 scikit-learn(或其他ML 庫)。

對於大型模型,使用 dask_ml。joblib 和scikit-learn estimators。

對於大型資料集,使用 dask_ml estimators。

讓我們看一下 Dask。distributed 的架構

在 Python中處理大型機器學習資料集的簡單方法

Dask 讓您能夠在計算機叢集上執行任務。在 dask。distributed 中,只要您分配任務,它就會立即開始執行。

簡單地說,client就是提交任務的你,執行任務的是Worker,排程器則執行兩者之間通訊。

python -m pip install dask distributed –upgrade

如果您使用的是單臺機器,那麼就可以透過以下方式建立一個具有4個worker的dask叢集

在 Python中處理大型機器學習資料集的簡單方法

如果需要dashboard,可以安裝bokeh,安裝bokeh的命令如下:

pip install bokeh

就像我們從 dask。distributed 建立客戶端一樣,我們也可以從 dask。distributed 建立排程程式。

要使用 dask ML 庫,您必須使用以下命令安裝它:

pip install dask-ml

我們將使用 Scikit-learn 庫來演示 dask-ml 。

假設我們使用 Grid_Search 方法,我們通常使用如下Python程式碼

在 Python中處理大型機器學習資料集的簡單方法

使用 dask。distributed 建立一個叢集:

在 Python中處理大型機器學習資料集的簡單方法

要使用叢集擬合 scikit-learn 模型,我們只需要使用 joblib

在 Python中處理大型機器學習資料集的簡單方法