了解Data Pre-processing的概念後,接著就是要實作了
資料下載的部分,連結雖然是公開的,但畢竟是課程資源的一部分,在此只顯示部分截圖。
課程提供google colab的連結,連結中包含很多python檔,但是只能閱覽不能編輯,要自己手動做做看的話,要將這些檔案複製到個人的colab中,要執行作業前必須要上傳範例檔案。Google Colab介面非常簡潔易懂,可以放text跟code,左側還可以依據text顯示coding的段落。檔案也可於左側的操作版中上傳。
Data Preprocessing的步驟有那些呢? 昨日提到的觀念:
Data pre-processing
這部分包含資料匯入、去除雜值(讓資料比較標準化、或把空值補齊),以及將資料分為訓練組 (training set)及驗證組(test set),最後簡單介紹了資料標準化的做法(feature scaling)
範例資料筆數很少,欄位則延續課堂提到的範例,有國籍、年紀、薪水、是否購買(Country,Age,Salary,Purchased)
接著就是第一步了,匯入資料,喔不,第一步其實是要匯入library
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
這三個library是非常常使用的,不過其實在這個章節應該是沒有用到matplotlib,後續做一些比較複雜得模型時應該都會用到,看起來做ML時這三個匯入就穩了(若不夠的compilier也會提示拉XD)
匯入資料
使用pd.read_csv 讀檔,並且用iloc 把資料分成X(自變數)跟Y(依變數)
dataset = pd.read_csv('Data.csv')
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, -1].values
X擷取國籍、年紀、薪水三欄資料,用Iloc擷取除了最後一行以外的所有資料,而Y則是是否購買資料,用iloc萃取最後一行的資料。
接著是去除雜值(讓資料比較標準化、或把空值補齊)
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
imputer.fit(X[:, 1:3])
X[:, 1:3] = imputer.transform(X[:, 1:3])
這兒使用sklearn這個library,也是後頭會一直使用到的library。至於為何沒有一開始就匯入我也不知道XD 使用sklearn裡的simpleimputer後,可以將空值用平均值補齊,你也可以選擇不同的方式補nan資料,例如用中位數。
接著,因為資料中含有類別資料(國籍),所以要編譯類別資料(encoding)
根據資料不同,有兩種做法,假設是多種類別資料,我認為要直接使用OneHotEncoder(),將其轉為二位元的資料,後續將資料呈現如下:
| 國家 | encoding1 | encoding2 | encoding3 |
|---|---|---|---|
| France | 1.0 | 0.0 | 1.0 |
| Spain | 0.0 | 1.0 | 0.0 |
| Germany | 0.0 | 1.0 | 0.0 |
會使用到的函數為 ColumnTransformer,轉換方式則為前述的OneHotEncoder
ColumnTransformer 可以設定多個參數,可參考官方文件
在這課程中,基本上只有使用到transfromers跟reminder。Transformers必須要放轉換的名稱、轉換涵式跟要轉換的欄位,而remainder則是決定,其他陣列的值要怎麼處理,可以passthrough(全留)、drop(全丟,此為預設)。
大家應該有注意到transformers是個陣列、所以基本上你可以一次丟好幾欄處理,例如以下為將id丟掉、將第一欄類別資料轉成二元資料:
ColumnTransformer(transformers=[('encoder', OneHotEncoder(), [1]),('id', drop, [0])]
因此使用前要將這幾個工具先匯入
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(), [0])], remainder='passthrough')
# 接著使用資料,並使用fit_transform方法,就可以得到轉換的資料拉~
ct.fit_transform(X)
另一種是直接使用LabelEncoder(),假設類別資料只有兩種(Yes/No, A/B)就可以直接拿LabelEncoder做轉換。
如果把國籍資料拿來轉換的話,會得到以下資料,雖然0,2,1是數值可以拿來做運算,但這個運算本身是沒有意義的。
| 國家 | encoding1 |
|---|---|
| France | 0 |
| Spain | 2 |
| Germany | 1 |
所以複雜的類別資料要使用OneHotEncoder()處理。而剛好資料的predictor(變數y,紀錄是否買車)就是yes and no兩種資料,所以用labelencoder處理比較快。方法如下
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y = le.fit_transform(y)
將資料處理完成後,就要把資料分組了,分為train set跟test set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 1)
# 使用的是model_selection中的train_test_split
# train_test_split需要放入四個參數(自變數X、依變數Y,test_size(拿多少比例的資料作驗證,0.2表示20%的資料),random_state = 1 ),輸入後,會回傳四個參數,分別為X_train,X_test,y_train, y_test。
train_test_split 參數細部設定可操考官方說明
sklearn.model_selection.train_test_split(*arrays, test_size=None, train_size=None, random_state=None, shuffle=True, stratify=None)
# array看起來可以放很多個。
# test_size, train_size預設是none,可放0-1之間的數值,兩個取一個用就好了。
"""random_state 這個預設是none,random_state跟shuffle是一起作用的,shuffle很好理解,就是洗牌,打亂數據重新排序,用這種方式去分train set跟test set也比較有公信力(就像魔術師請觀眾洗牌),而random_state則是可以理解為shuffle的方式(例如每次都是一次抽10張往最上頭,然後執行此動作5次)。官方文件寫random_state值常用0跟42,但講者使用1,也因此我認為什麼數字是開心就好。"""
# stratify 我就沒查了,反正看起來不是很常需要用的涵式XD 用預設就好
最後終於把資料分好了、可以來做 feature scaling 惹
經過前面的訓練,我們可以知道要將資料處理其實第一步驟就是找到適合的sklearn涵式,import後,建立對應的涵式變數,再用fit_transform得到我們想要的結果。featrue scaling也是囉
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
#Standardscaler是用standardidation處理資料,若想要使用normalization,可以用Normalizer()
x_train = sc.fit_transform(x_train)
x_test = sc.fit_transform(x_test)
好了、終於處理完資料,有點囫圇吞棗的學了一堆涵式,所以最後來總結一下,本次資料前處理學到的是
匯入資料 > 補空值> 轉換類別資料 > 資料分組為訓練組/驗證組 > featurescaling
其中,我們用到的涵式庫有 numpy,pandas,sklearn
sklearn.impute是處理資料空值的好朋友,
sklearn.preprocessing是資料轉換、前處理的好朋友,我們用了其中的StandardScaler,OneHotEncoder,LabelEncoder
sklearn.model_selection
是拿來做資料分組的工具,很多model驗證的工具也放在這區,後續章節可能會用到。
最後是我們偶爾會需要多種preprocessing的工具一起使用,這時候要使用
sklearn.compose像是工具箱管理員,可以把多種preprocessing的方法綜合使用來轉換資料,例如本章用到的ColumnTransformer,裏頭就用了OneHotEncoder處理國籍。不過假設你有國籍、城市、性別、...資料,其實可以把涵式寫得很複雜,例如:
ColumnTransformer(transformers=[('id', drop, [0]),('encoder', OneHotEncoder(), [1]),('encoder', LabelEncoder(), [2]),('encoder', LabelEncoder(), [3]) ]
一次也能處理多個欄位。
ok,以上就是本日的學習。