當前位置:
首頁 > 知識 > 數據清洗&預處理入門完整指南

數據清洗&預處理入門完整指南

選自towardsdatascience

作者:Anne Bonner

機器之心編譯

參與:Tianci LIU、張倩

凡事預則立,不預則廢,訓練機器學習模型也是如此。數據清洗和預處理是模型訓練之前的必要過程,否則模型可能就「廢」了。本文是一個初學者指南,將帶你領略如何在任意的數據集上,針對任意一個機器學習模型,完成數據預處理工作。

數據預處理是建立機器學習模型的第一步(也很可能是最重要的一步),對最終結果有決定性的作用:如果你的數據集沒有完成數據清洗和預處理,那麼你的模型很可能也不會有效——就是這麼簡單。

人們通常認為,數據預處理是一個非常枯燥的部分。但它就是「做好準備」和「完全沒有準備」之間的差別,也是表現專業和業餘之間的差別。就像為度假做好事先準備一樣,如果你提前將行程細節確定好,就能夠預防旅途變成一場噩夢。

那麼,應該怎麼做呢?

本文將帶你領略,如何在任意的數據集上,針對任意一個機器學習模型,完成數據預處理工作。

第一步,導入

讓我們從導入數據預處理所需要的庫開始吧。庫是非常棒的使用工具:將輸入傳遞給庫,它則完成相應的工作。你可以接觸到非常多的庫,但在 PYTHON 中,有三個是最基礎的庫。任何時候,你都很可能最終還是使用到它們。這三個在使用 PYTHON 時最流行的庫就是 Numpy、Matplotlib 和 Pandas。Numpy 是滿足所有數學運算所需要的庫,由於代碼是基於數學公式運行的,因此就會使用到它。Maplotlib(具體而言,Matplotlib.pyplot)則是滿足繪圖所需要的庫。Pandas 則是最好的導入並處理數據集的一個庫。對於數據預處理而言,Pandas 和 Numpy 基本是必需的。

最適當的方式是,在導入這些庫的時候,賦予其縮寫的稱呼形式,在之後的使用中,這可以節省一定的時間成本。這一步非常簡單,可以用如下方式實現:

現在,可以通過輸入如下語句讀入數據集

這個語句告訴 Pandas(pd) 來讀入數據集。在本文中,我也附上數據集的前幾行數據。

我們有了數據集,但需要創建一個矩陣來保存自變數,以及一個向量來保存因變數。為了創建保存自變數的矩陣,輸入語句:

第一個冒號表示提取數據集的全部行,「:-1」則表示提取除最後一列以外的所有列。最後的「.values」表示希望提取所有的值。接下來,我們希望創建保存因變數的向量,取數據的最後一列。輸入語句:

記住,在查看數據集的時候,索引(index)是從 0 開始的。所以,如果希望統計列數,從 0 開始計數而不是 1。「[:, :3]」會返回 animal、age 和 worth 三列。其中 0 表示 animal,1 表示 age,2 表示 worth。對於這種計數方法,即使你沒見過,也會在很短的時間內適應。

如果有缺失數據會怎麼樣?

事實上,我們總會遇到數據缺失。對此,我們可以將存在缺失的行直接刪除,但這不是一個好辦法,還很容易引發問題。因此需要一個更好的解決方案。最常用的方法是,用其所在列的均值來填充缺失。為此,你可以利用 scikit-learn 預處理模型中的 inputer 類來很輕鬆地實現。(如果你還不知道,那麼我強烈建議你搞明白它:scikit-learn 包含非常棒的機器學習模型)。在機器學習中,你可能並不適應諸如「方法」、「類」和「對象」這些術語。這不是什麼大問題!

類就是我們希望為某目的所建立的模型。如果我們希望搭建一個棚子,那麼搭建規劃就是一個類。

對象是類的一個實例。在這個例子中,根據規劃所搭建出來的一個棚子就是一個對象。同一個類可以有很多對象,就像可以根據規劃搭建出很多個棚子一樣。

方法是我們可以在對象上使用的工具,或在對象上實現的函數:傳遞給它某些輸入,它返回一個輸出。這就像,當我們的棚子變得有點不通氣的時候,可以使用「打開窗戶」這個方法。

圖:Roman Kraft 發佈於 Unsplash

為了使用 imputer,輸入類似如下語句。

均值填充是默認的填充策略,所以其實不需要指定,加在此處是為了方便了解可以包含什麼信息。missing_values 的默認值是 nan。如果你的數據集中存在「NaN」形式的缺失值,那麼你應該關注 np.nan,可以在此查看官方文檔:

https://scikit-learn.org/stable/modules/generated/sklearn.impute.SimpleImputer.html

為了擬合這個 imputer,輸入:

我們只希望在數據存在缺失的列上擬合 imputer。這裡的第一個冒號表示包含所有行,而「1:3」則表示我們取索引為 1 和 2 的列。不要擔心,你很快就會習慣 PTYHON 的計數方法的。

現在,我們希望調用實際上可以替換填充缺失數據的方法。通過輸入以下語句完成:

多嘗試一些不同的填充策略。也許在某些項目中,你會發現,使用缺失值所在列的中位數或眾數來填充缺失值會更加合理。填充策略之類的決策看似細微,但其實意義重大。因為流行通用的方法並不一定就是正確的選擇,對於模型而言,均值也不一定是最優的缺失填充選擇。

畢竟,幾乎所有正閱讀本文的人,都有高於平均水平的手臂數。

圖:Matthew Henry 發佈於 Unsplash

如果包含屬性數據,會怎麼樣呢?

這是一個好問題。沒有辦法明確地計算諸如貓、狗、麋鹿的均值。那麼可以怎麼做呢?可以將屬性數據編碼為數值!你可能希望使用 sklearn.preprocessing 所提供的 LabelEncoder 類。從你希望進行編碼的某列數據入手,調用 label encoder 並擬合在你的數據上。

(還記得括弧里的數字所表示的含義嗎?「:」表示希望提取所有行的數據,0 表示希望提取第一列)

這就是將第一列中的屬性變數替換為數值所需的全部工作了。例如,麋鹿將用 0 表示,狗將用 2 表示,貓將用 3 表示。

你發現什麼潛在問題了嗎?

標註體系暗含以下信息:所使用的數值層級關係可能會影響模型結果:3 比 0 的數值大,但貓並不一定比麋鹿大。

圖:Cel Lisboa 發佈於 Unsplash

我們需要創建啞變數。

我們可以為貓創建一列數據,為麋鹿創建一列數據,……以此類推。然後,將每一列分別以 0/1 填充(認為 1=Yes,0 = No)。這表明,如果原始列的值為貓,那麼就會在麋鹿一列得到 0,狗一列得到 0,貓一列得到 1。

看上去非常複雜。輸入 OneHotEncoder 吧!

導入編碼器,並制定對應列的索引。

接著是一點擬合和轉換。

現在,你的那一列數據已經被替換為了這種形式:數據組中的每一個屬性數據對應一列,並以 1 和 0 取代屬性變數。非常貼心,對吧?如果我們的 Y 列也是如「Y」和「N」的屬性變數,那麼我們也可以在其上使用這個編碼器。

這會直接擬合併將 y 表示為編碼變數:1 表示「Y」,0 表示「N」。

訓練集與測試集的劃分

現在,你可以開始將數據集劃分為訓練集和測試集了。這已經在之前的圖像分類教程一文中論述過了。不過記得,一定要將你的數據分為訓練集和測試集,永遠不要用測試集來訓練!需要避免過擬合(可以認為,過擬合就像在一次測驗前,記憶了許多細節,但沒有理解其中的信息。如果只是記憶細節,那麼當你自己在家複習知識卡片時,效果會很好,但在所有會考察新信息的真實測驗中,都會不及格。)

現在,我們有了需要學習的模型。模型需要在數據上訓練,並在另外的數據上完成測試。對訓練集的記憶並不等於學習。模型在訓練集上學習得越好,就應該在測試集給出更好的預測結果。過擬合永遠都不是你想要的結果,學習才是!

Janko Ferli? 發佈於 Unsplash

首先,導入:

現在,可以創建 X_train、X_test、y_train 和 y_test 集合了。

一種常見的方法是將數據集按 80/20 進行劃分,其中 80% 的數據用作訓練,20% 的數據用作測試。這也是為何指定 test_size 為 0.2 的原因。你也可以根據自己的需求來任意劃分。你並不需要設置 random_state,這裡設置的原因是為了可以完全復現結果。

特徵縮放

什麼是特徵縮放?為什麼需要特徵縮放?

看看我們的數據。我們有一列動物年齡,範圍是 4~17,還有一列動物價值,範圍是$48,000-$83,000。價值一欄的數值不僅遠大於年齡一欄,而且它還包含更加廣闊的數據範圍。這表明,歐式距離將完全由價值這一特徵所主導,而忽視年齡數據的主導效果。如果歐式距離在特定機器學習模型中並沒有具體作用會怎麼樣?縮放特徵將仍能夠加速模型,因此,你可以在數據預處理中,加入特徵縮放這一步。

特徵縮放的方法有很多。但它們都意味著我們將所有的特徵放在同一量綱上,進而沒有一個會被另一個所主導。

導入相關庫開始:

創建一個需要縮放對象並調用 Standard Scaler

直接在數據集上進行擬合以及變換。獲取對象並應用方法。

不需要在測試集上進行擬合,只進行變換。

對於啞變數而言,是否需要進行縮放?

對於這個問題,有些人認為需要,有些則認為不需要。這取決於你對模型可解釋性的看重誠度。將所有數據縮放至同一量綱固然有好處,但缺點是,這丟失了解釋每個觀測樣本歸屬於哪個變數的便捷性。

對於 Y 呢?如果因變數是 0 和 1,那麼並不需要進行特徵縮放。這是一個具有明確相關值的分類問題。但如果其取值範圍非常大,那麼答案是你需要做縮放。

恭喜你,你已經完成了數據預處理的工作!

Roven發佈於 Unsplash

通過少量的幾行代碼,你已經領略了數據清洗和預處理的基礎。毫無疑問,在數據預處理這一步中,你可以加入很多自己的想法:你可能會想如何填充缺失值。思考是否縮放特徵以及如何縮放特徵?是否引入啞變數?是否要對數據做編碼?是否編碼啞變數……有非常多需要考慮的細節。現在,你已經完全了解了這些,可以親自動手試試了,準備數據吧!

本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。

------------------------------------------------

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

ICLR 2019 | 與膠囊網路異曲同工:Bengio等提出四元數循環神經網路

TAG:機器之心 |