Регрессия в Керасе имеет низкую MSE, но результаты еще далеко - PullRequest
0 голосов
/ 01 апреля 2020

[ ОБНОВЛЕНИЕ : Ответ от desertaut ниже обнаружил ошибку кодирования (вдвойне масштабируя мои прогнозы, приведя их к ~ E+22), но даже после исправления этого моя проблема остается.]


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

Я беру 3 финансовые переменные, используя 2 из них, чтобы вычислить новый столбец, а затем попытаться выяснить, может ли моя модель предсказать столбец, который я создал. Я думал, что это будет легко, потому что я беру 2 переменные и вычитаю их. У меня был низкий балл по MSE, который казался многообещающим, но когда я смотрю на свои реальные результаты, они далеко.

Вот мои результаты (обратите внимание, что я рассчитываю grossProfit1 из totalRevenue-costOfRevenue. Столбец прогноза - это мой прогноз, который, как вы можете видеть, далек):

     grossProfit1  totalRevenue Exchange  costOfRevenue    prediction
0    9.839200e+10  2.601740e+11   NASDAQ   1.617820e+11  1.115318e+11
1    9.839200e+10  2.601740e+11   NASDAQ   1.617820e+11  1.115318e+11
2    1.018390e+11  2.655950e+11   NASDAQ   1.637560e+11  1.137465e+11
3    1.018390e+11  2.655950e+11   NASDAQ   1.637560e+11  1.137465e+11
4    8.818600e+10  2.292340e+11   NASDAQ   1.410480e+11  9.953879e+10
..            ...           ...      ...            ...           ...
186  4.224500e+10  9.113400e+10     NYSE   4.888900e+10  4.286892e+10
187  4.078900e+10  9.629300e+10     NYSE   5.550400e+10  4.505001e+10
188  3.748200e+10  8.913100e+10     NYSE   5.164900e+10  4.277003e+10
189  3.397500e+10  8.118600e+10     NYSE   4.721100e+10  4.012077e+10
190  3.597700e+10  8.586600e+10     NYSE   4.988900e+10  4.168953e+10

Вот мой упрощенный код (убрал имена переменных, прокомментировал их и т. д. c), обновлен на основе двойного обратного масштабирования в соответствии с ответом @desertnaut ниже:

#data
#create grossProfit column, to predict
df['grossProfit1'] = df['totalRevenue'] - df['costOfRevenue'] 
variableToPredict = ['grossProfit1']
#all columns we are using - grossProfit1 is what we will predict, and it's created simply from substracting totalRevenue from costOfRevenue. Exchange is just there for see if neural can ignore it.
df2=df[['grossProfit1','totalRevenue','Exchange', 'costOfRevenue']]
#I process this data frame, remove duplicates, drop variable to predict,etc.

#create the dataset for prediction
X_train=df2
X_train = X_train.drop(columns=variableToPredict) 
#add data for features 
y_train=df2[variableToPredict]

#check to see if there is any catergories
catergoryEncoder = OrdinalEncoder()
columnsObjects = list(cleanData.select_dtypes(include=['object']).columns) 
if len(columnsObjects) != 0:
    X_train[columnsObjects] = catergoryEncoder.fit_transform(X_train[columnsObjects])

#scale the data
scaler_X = MinMaxScaler()
scaler_Y = MinMaxScaler()
Xscaled = scaler_X.fit_transform(X_train)
unscaled = scaler_X.inverse_transform(Xscaled)
Yscaled = scaler_Y.fit_transform(y_train)

#run simple model for prediction:
model = tf.keras.Sequential() #using tensorflow keras
model.add(layers.Dense(64, activation='relu', input_shape=(numInputColumns,)))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['MSE'])
model.fit(Xscaled,Yscaled,epochs=10,validation_split=0.2)

# this is the result - seems good with low MSE.
# Epoch 10/10
# 152/152 [==============================] - 0s 174us/sample - loss: 0.0075 - MSE: 0.0075 - val_loss: 0.0076 - val_MSE: 0.0076

#do the predictions on previous data
prediction = model.predict(Xscaled)
# prediction = scaler.inverse_transform(prediction)  # REMOVED after desertnaut's answer below

#join all the data together
new_data_frame=pd.DataFrame(df2) 
new_data_frame['prediction'] = (scaler_Y.inverse_transform(np.asarray(prediction)))
print(new_data_frame)

Что я делаю не так с этой регрессией? С другими учебными пособиями это работает хорошо (цены на жилье в Бостоне, учебные пособия по регрессии миль за галлон). Меня посоветовали для проблем регрессии, MSE - лучший показатель, чем точность (лучше для задач классификации), и MSE выглядит хорошо, но я не уверен, почему мои результаты так далеки. Любая помощь или совет будут великолепны.

1 Ответ

1 голос
/ 01 апреля 2020

У вас есть проблема с пересчетом ваших прогнозов; сначала вы делаете это здесь:

#do the predictions on previous data
prediction = model.predict(Xscaled)
prediction = scaler.inverse_transform(prediction) 

, а затем делаете это снова при построении вашего фрейма данных:

new_data_frame=pd.DataFrame(df2) 
new_data_frame['prediction'] = (scaler.inverse_transform(np.asarray(prediction)))

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

In В общем, вы должны использовать два отдельных инструмента масштабирования для своих функций и меток:

#scale the data
scaler_X = MinMaxScaler()
Xscaled = scaler_X.fit_transform(X_train)
scaler_Y = MinMaxScaler()
Yscaled = scaler_Y.fit_transform(y_train)

Кажется, здесь нет проблем, но это кажется случайным из-за порядка, в котором вы используете соответствующие команды; это требует внимания.

Также следует иметь в виду, что MSE, возвращаемое Keras в подобных случаях, на самом деле является MSE масштаба. Чтобы получить «истинную» MSE для своих прогнозов, вы должны сделать

y_pred_scaled = model.predict(Xscaled)
from sklearn.metrics import mean_squared_error
MSE_true = mean_squared_error(Y, scaler_Y.inverse_transform(y_pred_scaled)) 

при условии, что Y - это ваши исходные немасштабированные цели.

См. Собственный ответ в Как интерпретировать MSE в Keras Regressor для более.

...