Python數(shù)據(jù)清洗&預(yù)處理入門教程
凡事預(yù)則立,不預(yù)則廢,訓(xùn)練機(jī)器學(xué)習(xí)模型也是如此。數(shù)據(jù)清洗和預(yù)處理是模型訓(xùn)練之前的必要過(guò)程,否則模型可能就廢了。本文是一個(gè)初學(xué)者指南,將帶你領(lǐng)略如何在任意的數(shù)據(jù)集上,針對(duì)任意一個(gè)機(jī)器學(xué)習(xí)模型,完成數(shù)據(jù)預(yù)處理工作。
人們通常認(rèn)為,數(shù)據(jù)預(yù)處理是一個(gè)非??菰锏牟糠帧5褪亲龊脺?zhǔn)備和完全沒(méi)有準(zhǔn)備之間的差別,也是表現(xiàn)專業(yè)和業(yè)余之間的差別。就像為度假做好事先準(zhǔn)備一樣,如果你提前將行程細(xì)節(jié)確定好,就能夠預(yù)防旅途變成一場(chǎng)噩夢(mèng)。
本文將帶你領(lǐng)略,如何在任意的數(shù)據(jù)集上,針對(duì)任意一個(gè)機(jī)器學(xué)習(xí)模型,完成數(shù)據(jù)預(yù)處理工作。
導(dǎo)入
讓我們從導(dǎo)入數(shù)據(jù)預(yù)處理所需要的庫(kù)開(kāi)始吧。庫(kù)是非常棒的使用工具:將輸入傳遞給庫(kù),它則完成相應(yīng)的工作。你可以接觸到非常多的庫(kù),但在 Python 中,有三個(gè)是最基礎(chǔ)的庫(kù)。任何時(shí)候,你都很可能最終還是使用到它們。這三個(gè)在使用 Python 時(shí)最流行的庫(kù)就是 Numpy、Matplotlib 和 Pandas。Numpy 是滿足所有數(shù)學(xué)運(yùn)算所需要的庫(kù),由于代碼是基于數(shù)學(xué)公式運(yùn)行的,因此就會(huì)使用到它。Maplotlib(具體而言,Matplotlib.pyplot)則是滿足繪圖所需要的庫(kù)。Pandas 則是最好的導(dǎo)入并處理數(shù)據(jù)集的一個(gè)庫(kù)。對(duì)于數(shù)據(jù)預(yù)處理而言,Pandas 和 Numpy 基本是必需的。
最適當(dāng)?shù)姆绞绞?,在?dǎo)入這些庫(kù)的時(shí)候,賦予其縮寫的稱呼形式,在之后的使用中,這可以節(jié)省一定的時(shí)間成本。這一步非常簡(jiǎn)單,可以用如下方式實(shí)現(xiàn):
import numpy as np import matplotlib.pyplot as plt import pandas as pd
現(xiàn)在,可以通過(guò)輸入如下語(yǔ)句讀入數(shù)據(jù)集:
dataset = pd.read_csv('my_data.csv')
這個(gè)語(yǔ)句告訴 Pandas(pd) 來(lái)讀入數(shù)據(jù)集。在本文中,我也附上數(shù)據(jù)集的前幾行數(shù)據(jù)。
我們有了數(shù)據(jù)集,但需要?jiǎng)?chuàng)建一個(gè)矩陣來(lái)保存自變量,以及一個(gè)向量來(lái)保存因變量。為了創(chuàng)建保存自變量的矩陣,輸入語(yǔ)句:
X = dataset.iloc[:, :-1].values
第一個(gè)冒號(hào)表示提取數(shù)據(jù)集的全部行,「:-1」則表示提取除最后一列以外的所有列。最后的「.values」表示希望提取所有的值。接下來(lái),我們希望創(chuàng)建保存因變量的向量,取數(shù)據(jù)的最后一列。輸入語(yǔ)句:
y = dataset.iloc[:, 3].values
記住,在查看數(shù)據(jù)集的時(shí)候,索引(index)是從 0 開(kāi)始的。所以,如果希望統(tǒng)計(jì)列數(shù),從 0 開(kāi)始計(jì)數(shù)而不是 1?!竅:, :3]」會(huì)返回 animal、age 和 worth 三列。其中 0 表示 animal,1 表示 age,2 表示 worth。對(duì)于這種計(jì)數(shù)方法,即使你沒(méi)見(jiàn)過(guò),也會(huì)在很短的時(shí)間內(nèi)適應(yīng)。
如果有缺失數(shù)據(jù)會(huì)怎么樣
事實(shí)上,我們總會(huì)遇到數(shù)據(jù)缺失。對(duì)此,我們可以將存在缺失的行直接刪除,但這不是一個(gè)好辦法,還很容易引發(fā)問(wèn)題。因此需要一個(gè)更好的解決方案。最常用的方法是,用其所在列的均值來(lái)填充缺失。為此,你可以利用 scikit-learn 預(yù)處理模型中的 inputer 類來(lái)很輕松地實(shí)現(xiàn)。(如果你還不知道,那么我強(qiáng)烈建議你搞明白它:scikit-learn 包含非常棒的機(jī)器學(xué)習(xí)模型)。在機(jī)器學(xué)習(xí)中,你可能并不適應(yīng)諸如方法、類和對(duì)象這些術(shù)語(yǔ)。這不是什么大問(wèn)題!
- 類就是我們希望為某目的所建立的模型。如果我們希望搭建一個(gè)棚子,那么搭建規(guī)劃就是一個(gè)類。
- 對(duì)象是類的一個(gè)實(shí)例。在這個(gè)例子中,根據(jù)規(guī)劃所搭建出來(lái)的一個(gè)棚子就是一個(gè)對(duì)象。同一個(gè)類可以有很多對(duì)象,就像可以根據(jù)規(guī)劃搭建出很多個(gè)棚子一樣。
- 方法是我們可以在對(duì)象上使用的工具,或在對(duì)象上實(shí)現(xiàn)的函數(shù):傳遞給它某些輸入,它返回一個(gè)輸出。這就像,當(dāng)我們的棚子變得有點(diǎn)不通氣的時(shí)候,可以使用「打開(kāi)窗戶」這個(gè)方法。
為了使用 imputer,輸入類似如下語(yǔ)句。
from sklearn.preprocessing import Imputer imputer = Imputer(missing_values = np.nan, strategy = ‘mean', axis = 0)
均值填充是默認(rèn)的填充策略,所以其實(shí)不需要指定,加在此處是為了方便了解可以包含什么信息。missing_values 的默認(rèn)值是 nan。如果你的數(shù)據(jù)集中存在「NaN」形式的缺失值,那么你應(yīng)該關(guān)注 np.nan,可以在此查看官方文檔:
https://scikit-learn.org/stable/modules/generated/sklearn.impute.SimpleImputer.html
為了擬合這個(gè) imputer,輸入:
imputer = imputer.fit(X[:, 1:3])
我們只希望在數(shù)據(jù)存在缺失的列上擬合 imputer。這里的第一個(gè)冒號(hào)表示包含所有行,而「1:3」則表示我們?nèi)∷饕秊?1 和 2 的列。不要擔(dān)心,你很快就會(huì)習(xí)慣 Python 的計(jì)數(shù)方法的。
現(xiàn)在,我們希望調(diào)用實(shí)際上可以替換填充缺失數(shù)據(jù)的方法。通過(guò)輸入以下語(yǔ)句完成:
X[:, 1:3] = imputer.transform(X[:, 1:3])
多嘗試一些不同的填充策略。也許在某些項(xiàng)目中,你會(huì)發(fā)現(xiàn),使用缺失值所在列的中位數(shù)或眾數(shù)來(lái)填充缺失值會(huì)更加合理。填充策略之類的決策看似細(xì)微,但其實(shí)意義重大。因?yàn)榱餍型ㄓ玫姆椒ú⒉灰欢ň褪钦_的選擇,對(duì)于模型而言,均值也不一定是最優(yōu)的缺失填充選擇。
畢竟,幾乎所有正閱讀本文的人,都有高于平均水平的手臂數(shù)。
如果包含屬性數(shù)據(jù),會(huì)怎么樣呢
這是一個(gè)好問(wèn)題。沒(méi)有辦法明確地計(jì)算諸如貓、狗、麋鹿的均值。那么可以怎么做呢?可以將屬性數(shù)據(jù)編碼為數(shù)值!你可能希望使用 sklearn.preprocessing 所提供的 LabelEncoder 類。從你希望進(jìn)行編碼的某列數(shù)據(jù)入手,調(diào)用 label encoder 并擬合在你的數(shù)據(jù)上。
from sklearn.preprocessing import LabelEncoder labelencoder_X = LabelEncoder() X[:, 0] = labelencoder_X.fit_transform(X[:, 0])
(還記得括號(hào)里的數(shù)字所表示的含義嗎?「:」表示希望提取所有行的數(shù)據(jù),0 表示希望提取第一列)
這就是將第一列中的屬性變量替換為數(shù)值所需的全部工作了。例如,麋鹿將用 0 表示,狗將用 2 表示,貓將用 3 表示。
你發(fā)現(xiàn)什么潛在問(wèn)題了嗎
標(biāo)注體系暗含以下信息:所使用的數(shù)值層級(jí)關(guān)系可能會(huì)影響模型結(jié)果:3 比 0 的數(shù)值大,但貓并不一定比麋鹿大。
我們需要?jiǎng)?chuàng)建啞變量。
我們可以為貓創(chuàng)建一列數(shù)據(jù),為麋鹿創(chuàng)建一列數(shù)據(jù),……以此類推。然后,將每一列分別以 0/1 填充(認(rèn)為 1=Yes,0 = No)。這表明,如果原始列的值為貓,那么就會(huì)在麋鹿一列得到 0,狗一列得到 0,貓一列得到 1。
看上去非常復(fù)雜。輸入 OneHotEncoder 吧!
導(dǎo)入編碼器,并制定對(duì)應(yīng)列的索引。
from sklearn.preprocessing import OneHotEncoder onehotencoder = OneHotEncoder(categorical_features = [0])
接著是一點(diǎn)擬合和轉(zhuǎn)換。
X = onehotencoder.fit_transform(X).toarray()
現(xiàn)在,你的那一列數(shù)據(jù)已經(jīng)被替換為了這種形式:數(shù)據(jù)組中的每一個(gè)屬性數(shù)據(jù)對(duì)應(yīng)一列,并以 1 和 0 取代屬性變量。非常貼心,對(duì)吧?如果我們的 Y 列也是如「Y」和「N」的屬性變量,那么我們也可以在其上使用這個(gè)編碼器。
labelencoder_y = LabelEncoder() y = labelencoder_y.fit_transform(y)
這會(huì)直接擬合并將 y 表示為編碼變量:1 表示「Y」,0 表示「N」。
訓(xùn)練集與測(cè)試集的劃分
現(xiàn)在,你可以開(kāi)始將數(shù)據(jù)集劃分為訓(xùn)練集和測(cè)試集了。這已經(jīng)在之前的圖像分類教程一文中論述過(guò)了。不過(guò)記得,一定要將你的數(shù)據(jù)分為訓(xùn)練集和測(cè)試集,永遠(yuǎn)不要用測(cè)試集來(lái)訓(xùn)練!需要避免過(guò)擬合。(可以認(rèn)為,過(guò)擬合就像在一次測(cè)驗(yàn)前,記憶了許多細(xì)節(jié),但沒(méi)有理解其中的信息。如果只是記憶細(xì)節(jié),那么當(dāng)你自己在家復(fù)習(xí)知識(shí)卡片時(shí),效果會(huì)很好,但在所有會(huì)考察新信息的真實(shí)測(cè)驗(yàn)中,都會(huì)不及格。)
現(xiàn)在,我們有了需要學(xué)習(xí)的模型。模型需要在數(shù)據(jù)上訓(xùn)練,并在另外的數(shù)據(jù)上完成測(cè)試。對(duì)訓(xùn)練集的記憶并不等于學(xué)習(xí)。模型在訓(xùn)練集上學(xué)習(xí)得越好,就應(yīng)該在測(cè)試集給出更好的預(yù)測(cè)結(jié)果。過(guò)擬合永遠(yuǎn)都不是你想要的結(jié)果,學(xué)習(xí)才是!
首先,導(dǎo)入:
from sklearn.model_selection import train_test_split
現(xiàn)在,可以創(chuàng)建 X_train、X_test、y_train 和 y_test 集合了。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)
一種常見(jiàn)的方法是將數(shù)據(jù)集按 80/20 進(jìn)行劃分,其中 80% 的數(shù)據(jù)用作訓(xùn)練,20% 的數(shù)據(jù)用作測(cè)試。這也是為何指定 test_size 為 0.2 的原因。你也可以根據(jù)自己的需求來(lái)任意劃分。你并不需要設(shè)置 random_state,這里設(shè)置的原因是為了可以完全復(fù)現(xiàn)結(jié)果。
特征縮放
什么是特征縮放?為什么需要特征縮放?
看看我們的數(shù)據(jù)。我們有一列動(dòng)物年齡,范圍是 417,還有一列動(dòng)物價(jià)值,范圍是48,00083,000。價(jià)值一欄的數(shù)值不僅遠(yuǎn)大于年齡一欄,而且它還包含更加廣闊的數(shù)據(jù)范圍。這表明,歐式距離將完全由價(jià)值這一特征所主導(dǎo),而忽視年齡數(shù)據(jù)的主導(dǎo)效果。如果歐式距離在特定機(jī)器學(xué)習(xí)模型中并沒(méi)有具體作用會(huì)怎么樣?縮放特征將仍能夠加速模型,因此,你可以在數(shù)據(jù)預(yù)處理中,加入特征縮放這一步。
特征縮放的方法有很多。但它們都意味著我們將所有的特征放在同一量綱上,進(jìn)而沒(méi)有一個(gè)會(huì)被另一個(gè)所主導(dǎo)。
導(dǎo)入相關(guān)庫(kù)開(kāi)始:
from sklearn.preprocessing import StandardScaler
創(chuàng)建一個(gè)需要縮放對(duì)象并調(diào)用 Standard Scaler 。
sc_X = StandardScaler()
直接在數(shù)據(jù)集上進(jìn)行擬合以及變換。獲取對(duì)象并應(yīng)用方法。
X_train = sc_X.fit_transform(X_train) X_test = sc_X.transform(X_test)
不需要在測(cè)試集上進(jìn)行擬合,只進(jìn)行變換。
sc_y = StandardScaler() y_train = sc_y.fit_transform(y_train)
對(duì)于啞變量而言是否需要進(jìn)行縮放
對(duì)于這個(gè)問(wèn)題,有些人認(rèn)為需要,有些則認(rèn)為不需要。這取決于你對(duì)模型可解釋性的看重誠(chéng)度。將所有數(shù)據(jù)縮放至同一量綱固然有好處,但缺點(diǎn)是,這丟失了解釋每個(gè)觀測(cè)樣本歸屬于哪個(gè)變量的便捷性。
對(duì)于 Y 呢?如果因變量是 0 和 1,那么并不需要進(jìn)行特征縮放。這是一個(gè)具有明確相關(guān)值的分類問(wèn)題。但如果其取值范圍非常大,那么答案是你需要做縮放。
恭喜你,你已經(jīng)完成了數(shù)據(jù)預(yù)處理的工作!
通過(guò)少量的幾行代碼,你已經(jīng)領(lǐng)略了數(shù)據(jù)清洗和預(yù)處理的基礎(chǔ)。毫無(wú)疑問(wèn),在數(shù)據(jù)預(yù)處理這一步中,你可以加入很多自己的想法:你可能會(huì)想如何填充缺失值。思考是否縮放特征以及如何縮放特征?是否引入啞變量?是否要對(duì)數(shù)據(jù)做編碼?是否編碼啞變量……有非常多需要考慮的細(xì)節(jié)?,F(xiàn)在,你已經(jīng)完全了解了這些,可以親自動(dòng)手試試了,準(zhǔn)備數(shù)據(jù)吧!
到此這篇關(guān)于Python數(shù)據(jù)清洗&預(yù)處理入門教程的文章就介紹到這了,更多相關(guān)Python數(shù)據(jù)清洗 預(yù)處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用Python進(jìn)行數(shù)據(jù)清洗與存儲(chǔ)的基本方法
- 如何使用Python數(shù)據(jù)清洗庫(kù)
- 使用python數(shù)據(jù)清洗代碼實(shí)例
- 用Python進(jìn)行數(shù)據(jù)清洗以及值處理
- Python常用的數(shù)據(jù)清洗方法詳解
- 一文帶你深入了解Python中的數(shù)據(jù)清洗
- 三個(gè)Python常用的數(shù)據(jù)清洗處理方式總結(jié)
- python?文件讀寫和數(shù)據(jù)清洗
- Python實(shí)現(xiàn)數(shù)據(jù)清洗的示例詳解
- python數(shù)據(jù)清洗中的時(shí)間格式化實(shí)現(xiàn)
- Python實(shí)現(xiàn)數(shù)據(jù)清洗的18種方法
相關(guān)文章
python 利用panda 實(shí)現(xiàn)列聯(lián)表(交叉表)
這篇文章主要介紹了python 利用panda 實(shí)現(xiàn)列聯(lián)表(交叉表),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02基于Python實(shí)現(xiàn)2種反轉(zhuǎn)鏈表方法代碼實(shí)例
這篇文章主要介紹了基于Python實(shí)現(xiàn)2種反轉(zhuǎn)鏈表方法代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Python+tkinter模擬“記住我”自動(dòng)登錄實(shí)例代碼
這篇文章主要介紹了Python+tkinter模擬“記住我”自動(dòng)登錄實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01請(qǐng)不要重復(fù)犯我在學(xué)習(xí)Python和Linux系統(tǒng)上的錯(cuò)誤
本人已經(jīng)在運(yùn)維行業(yè)工作了將近十年,我最早接觸Linux是在大二的樣子,那時(shí)候只追求易懂,所以就選擇了Ubuntu作為學(xué)習(xí)、使用的對(duì)象,它簡(jiǎn)單、易用、好操作、界面絢麗,對(duì)于想接觸Linux的新手來(lái)說(shuō)是非常不錯(cuò)的2016-12-12利用Python寫個(gè)簡(jiǎn)易版星空大戰(zhàn)游戲
通過(guò)小編觀察,大家好像對(duì)劃水摸魚是情有獨(dú)鐘啊。所以本文給大家?guī)?lái)了一個(gè)用Python編寫的簡(jiǎn)單版的星空大戰(zhàn)小游戲,感興趣的小伙伴可以動(dòng)手試一試2022-03-03Python+PIL實(shí)現(xiàn)支付寶AR紅包
這篇文章主要為大家詳細(xì)介紹了Python+PIL實(shí)現(xiàn)支付寶AR紅包,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02