前面一節咱們已經介紹了決策樹的原理已經在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應用中的小知識點。