Различные RMSE при обучении/тестировании моей полиномиальной регрессии до/после стандартизации

Я нахожусь в процессе создания регрессионной модели, которая в конечном итоге будет использоваться другими пользователями. Эта модель служит для прогнозирования температуры цветов с использованием нескольких атмосферных переменных, таких как температура воздуха, влажность, солнечная радиация, ветер и т. д.

После долгих размышлений я пришел к выводу, что полиномиальная регрессия 2-й степени с помощью SKlearn дает хороший RMSE как для моих обучающих, так и для тестовых данных. Однако, поскольку существует более 36 коэффициентов, возникает коллинеарность, и, согласно комментарию к этому сообщению: you-center-your-predictor-varia">https://stats.stackexchange.com/questions/29781/when-conducting-multiple-regression-when-should-you-center-your-predictor-varia , коллинеарность нарушила бы бета-версию, и поэтому RMSE, который я получаю, был бы неправильным.

Я слышал, что, возможно, мне следует стандартизировать, чтобы удалить коллинеарность или использовать ортогональное разложение, но я не знаю, что было бы лучше. В любом случае, я пытался стандартизировать свои переменные x, и когда я вычисляю RMSE для своих данных обучения и тестирования, я получаю одно и то же RMSE для данных обучения, но другое RMSE для данных тестирования.

Вот код:

import pandas as pd
import numpy as np 
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn import metrics

def OpenFile(ThePath):
    path = Location + ThePath
    Prepared_df = pd.read_csv(path, sep=',', encoding='utf-8')
    Prepared_df = Prepared_df.loc[:, ~Prepared_df.columns.str.contains('^Unnamed')]
    return(Prepared_df)

def EvaluateRegression(Test_data,Predict_data):
    MAE = np.round(metrics.mean_absolute_error(Test_data, Predict_data),3)
    MSE = np.round(metrics.mean_squared_error(Test_data, Predict_data),3)
    RMSE = np.round(np.sqrt(metrics.mean_squared_error(Test_data, Predict_data)),3)
    print('Mean absolute error :',MAE)
    print('Mean square error :',MSE)
    print('RMSE :',RMSE)
    return MAE,MSE,RMSE

#Read files ------------------------------------------------------------------------------------------------------------
Location = 'C:\\Users\...'

#Training data
File_Station_day = 'Flower_Station_data_day.csv' #X training data
File_TD = 'Flower_Y_data_day.csv' #Y training data
Chosen_Air = OpenFile(File_Station_day)
Day_TC = OpenFile(File_TD)

#Testing data 
File_Fluke_Station= 'Fluke_Station_data.csv' #X testing data
File_Fluke = 'Flower_Fluke_data.csv' #Y testing data
Chosen_Air_Fluke = OpenFile(File_Fluke)
Fluke_Station = OpenFile(File_Fluke_Station)     

#Prepare data --------------------------------------------------------------------------------------------------------
y_train = Day_TC
y_test = Fluke_data
#Get the desired atmospheric variables
Air_cols = ['MAXTemp_data', 'MINTemp_data', 'Humidity', 'Precipitation', 'Pression', 'Arti_InSW', 'sin_time'] #Specify the desired atmospheriv variables
X_train = Chosen_Air[Air_cols]  
X_test = Chosen_Air_Fluke[Air_cols]

#If not standardizing
poly = PolynomialFeatures(degree=2)
linear_poly = LinearRegression()
X_train_rdy = poly.fit_transform(X_train)
linear_poly.fit(X_train_rdy,y_train)
X_test_rdy = poly.fit_transform(X_test)

Input_model= linear_poly
print('Regression: For train')
MAE, MSE, RMSE = EvaluateRegression(y_train, Input_model.predict(X_train_rdy))
#For testing data
print('Regression: For test')
MAE, MSE, RMSE = EvaluateRegression(y_test,  Input_model.predict(X_test_rdy))

#Output:
Regression: For train
Mean absolute error : 0.391
Mean square error : 0.256
RMSE : 0.506
Regression: For test
Mean absolute error : 0.652
Mean square error : 0.569
RMSE : 0.754

#If standardizing
std = StandardScaler()
X_train_std = pd.DataFrame(std.fit_transform(X_train),columns = Air_cols)
X_test_std = pd.DataFrame(std.fit_transform(X_test),columns = Air_cols)
poly = PolynomialFeatures(degree=2)
linear_poly_std = LinearRegression()
X_train_std_rdy = poly.fit_transform(X_train_std)
linear_poly_std.fit(X_train_std_rdy,y_train)
X_test_std_rdy = poly.fit_transform(X_test_std)

Input_model= linear_poly_std
print('Regression: For train')
MAE, MSE, RMSE = EvaluateRegression(y_train, Input_model.predict(X_train_std_rdy))
#For testing data
print('Regression: For test')
MAE, MSE, RMSE = EvaluateRegression(y_test,  Input_model.predict(X_test_std_rdy))

#Output:
Regression: For train
Mean absolute error : 0.391
Mean square error : 0.256
RMSE : 0.506
Regression: For test
Mean absolute error : 10.901
Mean square error : 304.53
RMSE : 17.451

Почему RMSE, который я получаю для данных стандартизированного тестирования, так отличается от нестандартизированного? Может быть, то, как я это делаю, совсем не годится? Подскажите, пожалуйста, нужно ли прикреплять файлы к сообщению.

Спасибо за ваше время!


person MorningGlory    schedule 27.01.2019    source источник


Ответы (1)


IIRC, по крайней мере, вам не следует вызывать poly.fit_transform дважды — вы делаете это так же, как и с регрессионной моделью — один раз подходите к данным поезда, а затем преобразуете с помощью теста. Теперь вы переобучаете скейлер (который, вероятно, дает вам другое среднее/стандартное значение), но применяете ту же модель регрессии.

Примечание: ваш код довольно сложно читать/отлаживать, и это легко приводит к простым опечаткам/ошибкам. Я предлагаю вам обернуть логику обучения внутри одной функции и, при желании, использовать sklearn трубопроводы. Это сделает масштабирование тестирования буквально [не]комментирующим одну строку.

person Slam    schedule 27.01.2019
comment
Спасибо за совет по использованию Pipeline. С его помощью я смог сделать следующее: pipe_model = Pipeline([('ssc', StandardScaler()),('pf', PolynomialFeatures(2)),('clf',LinearRegression())]) pipe_model.fit(X_train,y_train) И получить идентичную среднеквадратичную ошибку как для обучающих, так и для тестовых данных. Далее, интерпретация коэффициентов - person MorningGlory; 28.01.2019