MLP with Scikitlearn:用于预测的人工神经网络应用

MLP with Scikitlearn: Artificial Neural Network application for forecast

我有交通数据,我想通过向模型显示这些输入来预测下一小时的车辆数量:这一小时的车辆数量和这一小时的平均速度值。 这是我的代码:

dataset=pd.read_csv('/content/final - Sayfa5.csv',delimiter=',') 
dataset=dataset[[ 'MINIMUM_SPEED', 'MAXIMUM_SPEED', 'AVERAGE_SPEED','NUMBER_OF_VEHICLES','1_LAG_NO_VEHICLES']]
X = np.array(dataset.iloc[:,1:4])
L = len(dataset)
Y = np.array([dataset.iloc[:,4]])
Y= Y[:,0:L]
Y = np.transpose(Y)

#scaling with MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X)
X = scaler.transform(X)
 
scaler.fit(Y)
Y = scaler.transform(Y)
print(X,Y)

X_train , X_test, Y_train, Y_test = train_test_split(X,Y,test_size=0.3)
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import mean_squared_error 
mlp = MLPRegressor(activation='logistic')
mlp.fit(X_train,Y_train)
predictions = mlp.predict(X_test)
predictions1=mlp.predict(X_train)
print("mse_test :" ,mean_squared_error(Y_test,predictions), "mse_train :",mean_squared_error(Y_train,predictions1))


我得到了很好的 mse 值,例如 mse_test:0.005467816018933008 mse_train:0.005072774796622158

但我有两点很困惑:

  1. 我应该缩放y值吗,我看了很多博客写的不应该缩放Ys,只缩放X_train和X_test。但是我的mse成绩很差,比如49,50,100甚至更多。

  2. 我怎样才能得到对未来的预测而不是缩放值。 例如我写道:

    Xnew=[[ 80 , 40 , 47],
    [ 80 , 30,  81],
    [ 80 , 33, 115]]
    Xnew = scaler.transform(Xnew)
    print("prediction for that input is" , mlp.predict(Xnew))

但我得到了缩放值,例如:该输入的预测是 [0.08533431 0.1402755 0.19497315]

本来应该是这样的[81,115,102]

  1. 您无法比较这两个模型之间的 MSE,因为它取决于规模。很明显,当您缩放 y 时,您的 MSE 更小,因为 y(在您的情况下)通过应用 MinMaxScaler 变得更小。当您“取消缩放”您的预测和实际 y 值并再次计算 MSE 时,它应该与具有原始 y 值的模型相同(虽然不是 100% 确定)。

要点:不要仅在一个模型内比较模型之间的 MSE。 MSE的绝对值很难解释。

  1. 我不确定我是否理解你的问题。我想你是在问那些你用缩放的 y 值训练你的模型的人,你怎么能在缩放是车辆数量的意义上做出 y 的预测。如果这是问题,那么这正是您不应该缩放 y 的原因。

MinMaxScaler 所做的是计算以下内容:

X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std * (max - min) + min

另见 MinMaxScaler docu。之后您可以尝试反向计算预测,但我认为这没有意义

  1. 由于这是一个回归问题,在这种情况下您可能不想缩放 target/response 变量。您将希望缩放某些特征,尤其是考虑与其他特征(例如二进制)配对的大数量级数字。但是在没有看到完整数据集的情况下,我无法确认这是否是前往此处的方式。此外,您应该将其与基线模型进行比较。 45,000 的 MSE 可能看起来很糟糕,但如果基线的 MSE 是它的 10 倍,那么你的模型就在基线 MSE 的基础上提高了 1000%。

TL;DR 仅在要素大小不同或存在差异时才尝试缩放 是给定特征中的大异常值。 在此处输入代码

  1. 如果您不缩放目标变量,则无需尝试 'rescale it'。但是,如果您 need/want 可以考虑使用 TransformedTargetRegressor here

祝贺您使用 [sklearn's MLPRegressor][1],介绍神经网络总是一件好事。

缩放输入数据对于神经网络至关重要。考虑查看 Chapter 11 of Etham Alpaydin's Introduction to Machine Learning. This is also put into great detail in the Efficient BackProp paper。简而言之,缩放 输入数据 至关重要,这样您的模型才能学习如何 以输出为目标。

在英语中,scaling 在这种情况下表示将您的数据转换为介于 0 and 1(含)之间的值。不错Stats Exchange post on this describes the differences in scaling. For MinMax scaling, you are keeping the same distribution of your data, including being sensitive to outliers. More robust methods (described in that post) do exist in sklearn, such as RobustScaler.

因此,以这样一个非常基本的数据集为例:

| Feature 1 | Feature 2 | Feature 3 | Feature 4 | Feature 5 | Target |
|:---------:|:---------:|:---------:|:---------:|:---------:|:------:|
|     1     |     17    |     22    |     3     |     3     |   53   |
|     2     |     18    |     24    |     5     |     4     |   54   |
|     1     |     11    |     22    |     2     |     5     |   96   |
|     5     |     20    |     22    |     7     |     5     |   59   |
|     3     |     10    |     26    |     4     |     5     |   66   |
|     5     |     14    |     30    |     1     |     4     |   63   |
|     2     |     17    |     30    |     9     |     5     |   93   |
|     4     |     5     |     27    |     1     |     5     |   91   |
|     3     |     20    |     25    |     7     |     4     |   70   |
|     4     |     19    |     23    |     10    |     4     |   81   |
|     3     |     13    |     8     |     19    |     5     |   14   |
|     9     |     18    |     3     |     67    |     5     |   35   |
|     8     |     12    |     3     |     34    |     7     |   25   |
|     5     |     15    |     6     |     12    |     6     |   33   |
|     2     |     13    |     2     |     4     |     8     |   21   |
|     4     |     13    |     6     |     28    |     5     |   46   |
|     7     |     17    |     7     |     89    |     6     |   21   |
|     4     |     18    |     4     |     11    |     8     |    5   |
|     9     |     19    |     7     |     21    |     5     |   30   |
|     6     |     14    |     6     |     17    |     7     |   73   |

我可以稍微修改一下你的代码来玩这个:

import pandas as pd, numpy as np
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import RobustScaler
from sklearn.metrics import mean_squared_error 

df = pd.read_clipboard()

# Build data
y = df['Target'].to_numpy()
scaled_y = df['Target'].values.reshape(-1, 1) #returns a numpy array
df.drop('Target', inplace=True, axis=1)
X = df.to_numpy()

#scaling with RobustScaler
scaler = RobustScaler()
X = scaler.fit_transform(X)

# Scaling y just to show you the difference
scaled_y = scaler.fit_transform(scaled_y)

# Set random_state so we can replicate results
X_train , X_test, y_train, y_test = train_test_split(X,y,test_size=0.2, random_state=8)
scaled_X_train , scaled_X_test, scaled_y_train, scaled_y_test = train_test_split(X,scaled_y,test_size=0.2, random_state=8)

mlp = MLPRegressor(activation='logistic')
scaled_mlp = MLPRegressor(activation='logistic')

mlp.fit(X_train, y_train)
scaled_mlp.fit(scaled_X_train, scaled_y_train)

preds = mlp.predict(X_test)
scaled_preds = mlp.predict(scaled_X_test)

for pred, scaled_pred, tar, scaled_tar in zip(preds, scaled_preds, y_test, scaled_y_test):
    print("Regular MLP:")
    print("Prediction: {} | Actual: {} | Error: {}".format(pred, tar, tar-pred))
    
    print()
    print("MLP that was shown scaled labels: ")
    print("Prediction: {} | Actual: {} | Error: {}".format(scaled_pred, scaled_tar, scaled_tar-scaled_pred))

简而言之,缩小你的目标自然会缩小你的错误,因为你的模型不是在学习实际值,而是在 0 和 1 之间的值。

这就是我们不缩放目标变量的原因,因为我们将值强制为 0...1 space.

,因此误差自然会更小