1. 程式人生 > >機器學習- Sklearn (交叉驗證和Pipeline)

機器學習- Sklearn (交叉驗證和Pipeline)

前面一節咱們已經介紹了決策樹的原理已經在sklearn中的應用。那麼這裡還有兩個資料處理和sklearn應用中的小知識點咱們還沒有講,但是在實踐中卻會經常要用到的,那就是交叉驗證cross_validation和Pipeline。cross_validation是保證了咱們的模型不受資料分佈的影響,因為有些資料可能因為資料的分佈很不平均,導致咱們訓練的模型雖然在咱們的資料集裡面的表現很好,但是在實際中卻可能是不一樣的情況,cross validation的作用是model checking,而不是model building,無論用哪種方式validation,只是驗證根據這些資料訓練訓練出來的模型能不能用而已,可不可以用這些資料來訓練模型而已。而pipeline主要是為了能將模型的訓練更加格式化而已,也能規範程式碼的格式,以後所有的的模型從定義到驗證的過程都格式化了。接下來咱們細細的來看看他們具體是個什麼玩意兒。

  • Cross_validation

在解釋交叉驗證之前,我先上一個圖,如下所示

 

看上面的圖,咱們會將咱們的整個dataset分割五次,分別依次將其中的20%的部分作為validation dataset,80%的部分作為training dataset。咱們可以看出咱們會分別訓練五個模型,然後分別將各自的validation dataset拿去驗證,計算他們的score,然後將這5個score返回裝進list中,如果這些list中的元素都差不多的,並且大小都在合理範圍之內的話,那麼說明這個dataset是整個資料的分佈是合理的,並且 可以用這些資料來訓練的咱們的模型。記住前面的2個條件缺一不可,如果score的大小都差不多,但是score的數值都很大的話,則說明雖然這個dataset的分佈合理,但是這些features並不適合咱們模型,那麼咱們就得重新調整模型或者重新feature engineering。如果score的值都不大,在合理範圍之內,但是score之間的差值很大,那麼就說明咱們這個dataset的資料分佈很不合理,訓練的模型可能並不具備廣發應用的條件,這種情況下咱們得重新permutate咱們的dataset。最後,如果通過cross_validation之後滿足了所有的條件,那麼咱們最後的最後會用整個dataset來訓練咱們的最終模型。所以cross_validation的最終目的還是用來驗證咱們的資料和模型的,並不是用來訓練模型的。這一點對於剛剛接觸交叉驗證的同學經常容易混淆。上面像大家展示了什麼是cross_validation,那麼具體在sklearn中如何應用它呢?麻煩大家直接看下面的程式碼,一句話解決

from sklearn.model_selection import cross_val_score
scores = cross_val_score(estimator=my_pipeline, X=X, y=y, cv=5,scoring = "neg_mean_absolute_error")

這裡我來簡單解釋一下里面的引數,首先它也是來自於sklearn.model_selection這個模組的,estimator代表的是咱們定義的模型(未訓練過的),X,y分別代表著training dataset和labels, cv代表的是咱們將這個dataset分成幾個部分,最後的scoring是咱們選擇哪種計算方式。最後他會返回5個score,並且在scores這個list裡面。上面的部分就是cross_validation的解釋和具體應用過程。

  • Pipeline

 咱們前面花了很多的時間講了feature engineering, 模型訓練等等知識,咱們可以看見data preprocess的過程還是很複雜的,例如有missing value handling, categorical data encoding等等這些步驟,然而,每個專案中的資料都是不一樣的,這就讓咱們的資料進行preprocess的時候會非常複雜,沒換一個dataset,咱們就得重新來一遍,非常不方便,這時候聰明的人類就想到了,能不能通過定義一部分引數,來實現把這些繁雜的過程格式化呢???這時候pipeline就出來了。咱們現在先把程式碼貼出來,然後在一條一條的解釋一下pipeline的步驟

#Step1: data preparation
import pandas as pd
from sklearn.model_selection import train_test_split
melb_house_price = pd.read_csv("C:\\Users\\tangx\\OneDrive\\Desktop\\DATA\\melb_data.csv")
X = melb_house_price.drop(["Price"],axis = 1)
y = melb_house_price.Price
X_train_full, X_val_full,y_train,y_val = train_test_split(X,y,train_size=0.8,test_size=0.2,random_state=1)

numerical_cols = [col for col in X_train_full.columns if X_train_full[col].dtype in ['int64','float64']]
categorical_cols = [col for col in X_train_full.columns if X_train_full[col].dtype == 'object' and X_train_full[col].nunique()<10]
my_cols = numerical_cols+categorical_cols

X_train = X_train_full[my_cols].copy()
X_val = X_val_full[my_cols].copy()


#Step2: define preprocess steps
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.metrics import mean_absolute_error
#2.1 define transformer of numerical data
numerical_transformer = SimpleImputer(strategy="mean") #missing value handling
#2.2 define transformer of categorical data #(Firstly handle the missing value and then secondly encoding the )
categorical_transformer = Pipeline(steps=[
        ("Imputer",SimpleImputer(strategy="most_frequent")),
        ("Onehot",OneHotEncoder(handle_unknown='ignore'))]
    )
#2.3 data preprocessor
preprocessor = ColumnTransformer(
        transformers = [
                ("num", numerical_transformer, numerical_cols),
                ("cat",categorical_transformer,categorical_cols)]
        )
#step2.4: model selection and definition
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(n_estimators = 100, random_state = 0)
#step2.5: bundle preprocessor and model
my_pipeline = Pipeline(
        steps = [
                ('preprocessor', preprocessor),
                ('model',model)]
        )


#step3: fitting the model
my_pipeline.fit(X_train,y_train)

#step4: predicts
predictions = my_pipeline.predict(X_val)

#step5: evaluate the modle
print(mean_absolute_error(y_val,predictions))

根據上面的程式碼,咱們以後所有的程式碼幾乎都可以用上面的框架,第一步肯定就是將training dataset和validation dataset分離出來;第二步就是咱們pipeline,這裡也是咱們的重點,首先就是先定義咱們的transform,這裡就是宣告如何來處理missing value和categorical data,接下來就是宣告這些transforms分別用於那些features,並且返回preprocessor;然後定義模型;最後例項化一個pipeline物件,並且將前面定義的模型和preprocessor傳遞給這個pipeline。接下來的步驟就是fitting,predict,evaluate啦和其他的都一樣。所以咱們在這裡的重點其實就是第二步,故而以後所有tabular data都可以用上面的結構來進行資料的處理,非常方便簡單,不必一個個的單獨處理了,只需要定義transforms和preprocessor就可以了。

  • 總結

 上面已經展示的交叉驗證cross_validation和pipeline的兩個知識點的一些基本原理和應用。在這裡cross_validation的形式和原理是重點,已經cross_validation的作用和原因要理解,至於應用方面就很簡單了,重點關注一下里面的一些引數設定就行了。pipeline能夠大大的減少咱們資料處理方面的工作量,相當於把資料的preprocessor打包了,並且結構化,具有很高的複用性,這裡重點需要了解pipeline的應用的流程以及為什麼是這個流程,然後是每個流程的作用。上面就是這一節補充的2個sklearn應用中的小知識點。

&n