MLP con Scikitlearn: Red Neural Artificial aplicación para pronóstico

Tengo datos de tráfico y quiero predecir el número de vehículos para la próxima hora mostrando el modelo de estas entradas: el número de vehículos de esta hora y el valor medio de velocidad de esta hora. Aquí está mi código:

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))


Tengo buenos valores de mse como mse_test : 0.005467816018933008 mse_train : 0.005072774796622158

Pero estoy confundido en dos puntos:

  1. En caso de escalar y valores, leí tantos blogs escritos que uno no debe escalar Ys, sólo escala el X_train y X_test. Pero tengo tan malas puntuaciones de mse como 49,50,100 o incluso más.

  2. ¿Cómo puedo obtener predicciones para el futuro pero no valores escalados. Por ejemplo, escribí:

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

Pero tengo valores escalados tales como: predicción para esa entrada es [0.08533431 0.1402755 0.19497315]

Debería haber sido así. [81,115,102].

Pregunta hecha hace 3 años, 4 meses, 28 días - Por quantumcoder403a


5 Respuestas:

  • Felicitaciones por usar [sklearn's MLPRegressor][1], una introducción a Redes Neurales es siempre una buena cosa.

    Escalar sus datos de entrada es crítico para las redes neuronales. Considerar la posibilidad de revisar Capítulo 11 de la introducción de Etham Alpaydin al aprendizaje automático. Esto también se pone en gran detalle en el Papel de BackProp eficiente. Para decirlo claramente, es crítico escalar el Datos de entrada para que tu modelo aprenda cómo apuntar una salida.

    En inglés, scaling en este caso significa convertir sus datos en valores entre 0 and 1 (inclusive). Una buena Stats Exchange post en esto describe las diferencias en el escalado. Para escalar MinMax, usted mantiene la misma distribución de sus datos, incluyendo ser sensible a los outliers. Existen métodos más robustos (descritos en ese puesto) sklearn, como RobustScaler.

    Así que tome por ejemplo un conjunto de datos muy básico como este:

    | 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   |
    

    Puedo modificar ligeramente su código para jugar con esto:

    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))
    

    En resumen, La reducción de su objetivo reducirá naturalmente su error, ya que su modelo no está aprendiendo el valor real, sino el valor entre 0 y 1.

    Es por eso que no escalamos nuestra variable objetivo, ya que el error es naturalmente menor ya que estamos forzando los valores en un 0...1 espacio.

    Respondida el Dec 18, 2020 a las 15:20 - por syntaxsensei

    Votos positivos: 0 | Votos negativos: 0

    1. no puedes comparar el MSE entre esos dos modelos, ya que depende de la escala. Está claro que su MSE es más pequeño cuando usted escala su y, como y (en su caso) se vuelve más pequeño aplicando el MinMaxScaler. Cuando usted "inescala" sus valores predichos y reales y que calcula el MSE de nuevo debe ser el mismo que para el modelo con los valores crudos y (no 100% seguro).

    Main takeaway: do not compare MSE between models only within a model. El valor absoluto del MSE es difícil de interpretar.

    1. No estoy seguro de que consiga su pregunta. Supongo que estás preguntando a los que entrenaste tu modelo con valores escalados y cómo puedes hacer predicciones de y en un sentido que la escala es No. de los vehículos. Si esa es la pregunta de que esto es exactamente por qué no debe escalar y.

    Lo que hace MinMaxScaler es calcular lo siguiente:

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

    ver también el MinMaxScaler docu. Podrías intentar volver a calcular las predicciones después pero no creo que esto tenga sentido.

    Respondida el Dec 18, 2020 a las 15:25 - por gitguru

    Votos positivos: 0 | Votos negativos: 0

    1. Dado que este es un problema de regresión, es probable que no desee escalar la variable de destino/respuesta en este caso. Usted querrá escalar ciertas características especialmente considerando grandes números de magnitud que se combinan con otras características que pueden ser, por ejemplo, binarias. Pero sin ver el conjunto completo de datos no puedo confirmar si esta sería la forma de ir aquí. Además, debe comparar esto con un modelo de referencia. Un MSE de 45.000 puede parecer malo, pero si el MSE de la base es 10X que entonces su modelo acaba de mejorar en el MSE de referencia en un 1000%.

    TL;DR Sólo intento de escalar si las características difieren en magnitud o allí son grandes outliers en una característica dada. Introduzca el código aquí

    1. Si no escalas tu variable objetivo, no deberías intentar "reescalarla". Sin embargo, si usted necesita / desea que usted puede buscar en el uso TransformedTargetRegressor Aquí.

    Respondida el Dec 18, 2020 a las 15:30 - por scriptsculptor52b5

    Votos positivos: 0 | Votos negativos: 0

  • Veamos tus dos puntos de confusión:

    • Escalado de Y:
    - La razón por la que se recomienda escalar solo las características (X) y no la variable a predecir (Y) es que, en general, las redes neuronales pueden tener dificultades para aprender cuando se escalan las variables dependientes. Al escalar Y, estarías cambiando la escala de los valores que estás intentando predecir, lo que puede llevar a resultados incorrectos.
    • Si al no escalar Y obtienes malas puntuaciones de error cuadrático medio (MSE), es probable que haya otros problemas en tu modelo. Podrías intentar afinar los hiperparámetros de la red neuronal, ajustar la arquitectura de la red o explorar otras técnicas de preprocesamiento de datos.

    • Obtener predicciones en la escala original:
    - Para obtener predicciones en la escala original después de escalar tus características de entrada, necesitas invertir la transformación que has aplicado a tus datos de entrada. Puedes hacerlo utilizando la función inverse_transform del scaler. -

    Respondida el Dec 19, 2020 a las 15:18 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Punto 1: Escalado de valores

    Sí, es correcto que normalmente no se escala el valor objetivo (Y) en los problemas de regresión. El escalado de Y puede distorsionar la distribución de los valores objetivo y afectar el rendimiento del modelo.

    Sin embargo, en tu caso, el escalado de Y puede estar mejorando el rendimiento porque la salida de tu modelo es una probabilidad (activación logística). El escalado de Y hace que los valores objetivo estén más centrados alrededor del 0, lo que puede ayudar al modelo a aprender y predecir mejor las probabilidades.

    Punto 2: Obtener predicciones sin escalar

    Para obtener predicciones sin escalar, debes invertir el escalado aplicado a los datos de entrada (X) y luego aplicar el modelo a los datos sin escalar.

    Aquí tienes un código modificado que realiza esta operación:

    python
    

    Escalar los datos de entrada (X)

    scaler = MinMaxScaler() scaler.fit(X_train) X_train_scaled = scaler.transform(X_train) X_test_scaled = scaler.transform(X_test)

    Entrenar el modelo

    mlp = MLPRegressor(activation='logistic') mlp.fit(X_train_scaled, Y_train)

    Obtener predicciones para datos nuevos sin escalar

    X_new = [[80, 40, 47], [80, 30, 81], [80, 33, 115]] X_new_scaled = scaler.transform(X_new) predictions = mlp.predict(X_new_scaled)

    Invertir el escalado de las predicciones

    predictions_unscaled = scaler.inverse_transform(predictions) print("Predicciones sin escalar:", predictions_unscaled)

    Este código debería proporcionarte predicciones sin escalar para los datos de entrada nuevos.

    Respondida el Dec 19, 2020 a las 15:25 - por Gemini

    Votos positivos: 0 | Votos negativos: 0