我无法使用此回归神经网络将预测中的误差降低至 0.8/0.9。我该如何解决这个问题? 我想预测一个从 1 到 7(整数)的数字,其中每个输入变量(8 是 41)的值从 1 到 7(也是整数)
import pandas as pd
import numpy as np
import tensorflow as tf
import keras_tuner
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import Adam, RMSprop
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
df = pd.read_excel('dataset_completo.xlsx')
X = df.iloc[:, 3:] # Características (variables de entrada)
y = df['OSAT'] # Variable de salida
# Estandarización de datos
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# División del conjunto train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Semilla generador aleatorio
tf.random.set_seed(123)
def crear_modelo(hp):
# Contenedor vacío
model = tf.keras.Sequential()
# Capa de entrada: cada dato tendrá 40 elementos
model.add(tf.keras.layers.Input(shape=(X_train.shape[1],))) # Forma de entrada
# Hiperparámetro número de capas ocultas
for i in range(hp.Int("num_layers", min_value=1, max_value=6, step=1)):
# Hiperparámetro número de neuronas por capa
model.add(tf.keras.layers.Dense(
units=hp.Int(f"units_{i}", min_value=8, max_value=256, step=8),
activation="relu")
)
model.add(Dropout(rate=hp.Float(f"dropout_{i}", min_value=0.0, max_value=0.5, step=0.1)))
# Capa de salida
model.add(tf.keras.layers.Dense(units=1, activation="linear"))
# Hiperparámetro tasa de aprendizaje del optimizador
hp_lr = hp.Choice("learning_rate", values=[0.1, 0.01, 0.001])
# Compilar (optimizador, pérdida, métrica de desempeño)
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=hp_lr),
loss=tf.keras.losses.MeanSquaredError(),
metrics=["mse", "mae"]
)
return model
# Crear modelo
crear_modelo(keras_tuner.HyperParameters())
# Configuración del tuner
tuner = keras_tuner.RandomSearch(
hypermodel=crear_modelo,
objective="val_mse",
max_trials=10,
directory="afinacion_red",
project_name="trials",
overwrite=True,
)
# Imprimir en pantalla el espacio de búsqueda
tuner.search_space_summary()
# Callbacks
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
# Búsqueda de hiperparámetros
tuner.search(X_train, y_train, epochs=100, validation_data=(X_test, y_test), callbacks=[early_stopping])
# Imprimir resumen de la afinación
tuner.results_summary()
# Extraer el mejor modelo
mejor_modelo = tuner.get_best_models(num_models=1)[0]
mejor_modelo.summary()
# Predicciones sobre el set de prueba
preds = mejor_modelo.predict(X_test)
# Imprimir las predicciones
print(preds)
# Evaluación del modelo
mse = mean_squared_error(y_test, preds)
mae = mean_absolute_error(y_test, preds)
r2 = r2_score(y_test, preds)
print(f"MSE: {mse}, MAE: {mae}, R2: {r2}")
我尝试更改层数、神经元、dropout 和学习率。、epochs 和 bach
我还尝试了下一个代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import Adam, RMSprop
from tensorflow.keras import regularizers
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
df = pd.read_excel('dataset_completo.xlsx')
# Preprocesamiento de datos
"""column_means = df.iloc[:, 3:].mean().round().astype(int)
df.iloc[:, 3:] = df.iloc[:, 3:].fillna(column_means)"""
# Separar datos en características y variable objetivo
X = df.iloc[:, 3:] # Características
y = df['OSAT'] # Variable de salida
# Estandarización de datos
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# División en conjunto de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# Definición del modelo con regularización L2 y Dropout
model = Sequential([
Dense(256, activation='relu', input_dim=X_train.shape[1]),
Dropout(0.6),
Dense(128, activation='relu'),
Dropout(0.6),
Dense(128, activation='relu'),
Dropout(0.6),
Dense(64, activation='relu'),
Dense(32, activation='relu'),
Dropout(0.6),
Dense(16, activation='relu'),
Dropout(0.6),
Dense(8, activation='relu'),
Dropout(0.6),
Dense(1, activation='linear') # Capa de salida para regresión lineal
])
# Compilación del modelo con optimizador Adam
optimizer = Adam(learning_rate=0.001)
model.compile(optimizer=optimizer, loss='mse', metrics=['mae', 'mse'])
# Early stopping para evitar sobreajuste
early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
#train
history = model.fit(X_train, y_train, epochs=250, batch_size=64, validation_data=(X_test, y_test))
#predict
predictions = model.predict(X_test)
#métricas
mae = mean_absolute_error(y_test, predictions)
mse = mean_squared_error(y_test, predictions)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, predictions)
print('Mean Absolute Error (MAE): ', mae)
print('Mean Squared Error (MSE): ', mse)
print('Root Mean Squared Error (RMSE): ', rmse)
print('R^2 Score: ', r2)
# Gráficos de métricas por épocas
epochs = range(1, len(history.history['loss']) + 1)
plt.figure(figsize=(14, 8))
# MAE
plt.subplot(2, 2, 1)
plt.plot(epochs, history.history['mae'], label='MAE en entrenamiento')
plt.plot(epochs, history.history['val_mae'], label='MAE en validación')
plt.xlabel('Épocas')
plt.ylabel('MAE')
plt.legend()
plt.title('MAE por Época')
# MSE
plt.subplot(2, 2, 2)
plt.plot(epochs, history.history['mse'], label='MSE en entrenamiento')
plt.plot(epochs, history.history['val_mse'], label='MSE en validación')
plt.xlabel('Épocas')
plt.ylabel('MSE')
plt.legend()
plt.title('MSE por Época')
# RMSE
plt.subplot(2, 2, 3)
plt.plot(epochs, np.sqrt(history.history['mse']), label='RMSE en entrenamiento')
plt.plot(epochs, np.sqrt(history.history['val_mse']), label='RMSE en validación')
plt.xlabel('Épocas')
plt.ylabel('RMSE')
plt.legend()
plt.title('RMSE por Época')
# R² Score (usando las predicciones para cada época)
# Para el R² Score, necesitamos calcularlo manualmente por época
r2_scores = []
for epoch in epochs:
pred_epoch = model.predict(X_train[:epoch])
r2_scores.append(r2_score(y_train[:epoch], pred_epoch))
plt.subplot(2, 2, 4)
plt.plot(epochs, r2_scores, label='R² Score en entrenamiento')
plt.xlabel('Épocas')
plt.ylabel('R² Score')
plt.legend()
plt.title('R² Score por Época')
plt.tight_layout()
plt.show()
# Pérdida durante el entrenamiento
plt.figure(figsize=(10, 6))
plt.plot(epochs, history.history['loss'], label='Pérdida en entrenamiento')
plt.plot(epochs, history.history['val_loss'], label='Pérdida en validación')
plt.xlabel('Épocas')
plt.ylabel('Pérdida')
plt.legend()
plt.title('Pérdida de Entrenamiento por Época')
plt.show()
# Predicción para nuevas características
new_osat_features = df.drop('OSAT', axis=1).iloc[0].values.reshape(1, -1) # Características de nueva predicción
new_osat_features_scaled = scaler.transform(new_osat_features)
new_osat_prediction = model.predict(new_osat_features_scaled) # Predecir OSAT escalado
print(f'Características de la nueva predicción de OSAT:\n{new_osat_features}')
print(f'Predicción de OSAT: {np.round(new_osat_prediction[0][0])}')
# OSAT original
print('\nOSAT original:', df.iloc[0]['OSAT'])