1. 程式人生 > >標準化和歸一化對機器學習經典模型的影響

標準化和歸一化對機器學習經典模型的影響

歸一化

歸一化也稱標準化,是處理資料探勘的一項基礎工作,使用歸一化的原因大體如下:

資料存在不同的評價指標,其量綱或量綱單位不同,處於不同的數量級。解決特徵指標之間的可比性,經過歸一化處理後,各指標處於同一數量級,便於綜合對比。求最優解的過程會變得平緩,更容易正確收斂。即能提高梯度下降求最優解時的速度。提高計算精度。適合進行綜合對比評價。

MinMaxScaler

線性歸一化,也稱為離差標準化,是對原始資料的線性變換,MinMax標準化方法的缺陷在當有新資料加入時,可能會導致X.max和X.min的值發生變化,需要重新計算。其轉換函式如下:

StandardScaler

標準差歸一化

,也叫Z-score標準化,這種方法給予原始資料的均值(mean,μ)和標準差(standard deviation,σ)進行資料的標準化。經過處理後的資料符合標準正態分佈,即均值為0,標準差為1,轉化函式為:

MaxAbsScaler

原理與MinMaxScaler很像,只是資料會被規模化到[-1,1]之間。也就是特徵中,所有資料都會除以最大值。這個方法對那些已經中心化均值維0或者稀疏的資料有意義。

模型

本次實驗使用了5個模型,分別為Lasso、Redige、SVR、RandomForest、XGBoost。

方法:

  • 以不同方式劃分資料集和測試集
  • 使用不同的歸一化(標準化)方式
  • 使用不同的模型
  • 通過比較MSE(均方誤差,mean-square error)的大小來得出結論

部分程式碼及結果

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#data = pd.read_csv('路徑')

data = data.sort_values(by='time',ascending=True)
data.reset_index(inplace=True,drop=True)

target = data['T1AOMW_AV']
del data['T1AOMW_AV']
  

資料處理

   去除缺失值

# 沒有缺失值
All_NaN = pd.DataFrame(data.isnull().sum()).reset_index()
All_NaN.columns = ['name','times']
All_NaN.describe()

  

 

所有資料中,幹掉 方差小於1的屬性

feature_describe_T = data.describe().T
std_feature = feature_describe_T[feature_describe_T['std']<1].index
feature = [column for column in data.columns if column not in std_feature]  # 篩選方差大於1的屬性 
data = data[feature]

del data['time']

  

test_data = data[:5000]

data1 = data[5000:16060]
target1 = target[5000:16060]
data2 = data[16060:]
target2 = target[16060:]

import scipy.stats as stats
dict_corr = {
    'spearman' : [],
    'pearson' : [],
    'kendall' : [],
    'columns' : []
}

for i in data.columns:
    corr_pear,pval = stats.pearsonr(data[i],target)
    corr_spear,pval = stats.spearmanr(data[i],target)
    corr_kendall,pval = stats.kendalltau(data[i],target)
    
    dict_corr['pearson'].append(abs(corr_pear))
    dict_corr['spearman'].append(abs(corr_spear))
    dict_corr['kendall'].append(abs(corr_kendall))
    
    dict_corr['columns'].append(i)
    
# 篩選新屬性  
dict_corr =pd.DataFrame(dict_corr)
new_fea = list(dict_corr[(dict_corr['pearson']>0.32) & (dict_corr['spearman']>0.48) & (dict_corr['kendall']>0.44)]['columns'].values)
# 選取原則,選取25%分位數 以上的相關性係數
dict_corr.describe()
len(new_fea)

 

  

各種模型的測試:

from sklearn.linear_model import LinearRegression,Lasso,Ridge
from sklearn.preprocessing import MinMaxScaler,StandardScaler,MaxAbsScaler
from sklearn.metrics import mean_squared_error as mse
from sklearn.svm import SVR

mm = MinMaxScaler()
lr = Lasso(alpha=0.5)

lr.fit(mm.fit_transform(data1[new_fea]), target1)
lr_ans = lr.predict(mm.transform(data2[new_fea]))

print("LR : ", mse(lr_ans,target2) )##lr
ridge = Ridge(alpha=0.5)
ridge.fit(mm.fit_transform(data1[new_fea]),target1)
ridge_ans = ridge.predict(mm.transform(data2[new_fea]))

print("ridge : ",mse(ridge_ans,target2 ))#ridge
svr = SVR(kernel='rbf',C=100,epsilon=0.1).fit(mm.fit_transform(data1[new_fea]),target1)
svr_ans = svr.predict(mm.transform(data2[new_fea]))
print("svr : ",mse(svr_ans,target2) )#svr
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data[new_fea],target,test_size=0.25,random_state=12345)

ss = MaxAbsScaler()
ss_x_train = ss.fit_transform(X_train)
ss_x_test = ss.transform(X_test)

estimator_lr = Lasso(alpha=0.5).fit(ss_x_train,y_train)
predict_lr = estimator_lr.predict(ss_x_test)
print('Lssao:',mse(predict_lr,y_test))

estimator_rg = Ridge(alpha=0.5).fit(ss_x_train,y_train)
predict_rg = estimator_rg.predict(ss_x_test)
print('Ridge:',mse(predict_rg,y_test))

estimator_svr = SVR(kernel='rbf',C=100,epsilon=0.1).fit(ss_x_train,y_train)
predict_svr = estimator_svr.predict(ss_x_test)
print('SVR:',mse(predict_svr,y_test))

estimator_RF = RandomForestRegressor().fit(ss_x_train,y_train)
predict_RF = estimator_RF.predict(ss_x_test)
print('RF:',mse(predict_RF,y_test))

predict_XG  = xgb.XGBRegressor(learn_rate=0.1,n_estimators = 550,max_depth = 4,min_child_weight = 5,seed=0,subsample=0.7,gamma=0.1,reg_alpha=1,reg_lambda=1)
predict_XG.fit(ss_x_train,y_train)
predict_XG_ans=predict_XG.predict(ss_x_test)
print("predict_XG : ", mse(predict_XG_ans,y_test))

 結果:

 

 

 結論:

  • 對於Lasso模型,使用MaxAbsScaler方式時,mse增大十分明顯,且歸一化後結果高於不進行歸一化時;
  • 對於Redige模型,歸一化結果也明顯高於不歸一化時的結果;
  • 對於SVR模型,不進行歸一化時,其MSE會非常大;
  • 對於RandomForest和XGBoost來說,是否進行歸一化對結果影響不大;