In [ ]:
# Importar librerías necesarias para la red neuronal y procesamiento
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import layers, models
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
In [ ]:
# Cargar datos (ya cargado en df) y preparar características
# Vamos a usar las siguientes columnas: latitude, longitude, depth, mag, nst, gap, dmin, rms, horizontalError, depthError, magError, magNst
# Usaremos 'mag' como una de las features, pero la usaremos como target para predecir el valor de magnitud de un terremoto,
# dada la hipótesis de que podríamos predecir magnitud a partir de otras características.
# Esto es un ejemplo demostrativo: en la realidad, predecir terremotos es muy complejo y requiere muchos factores adicionales.

# Seleccionar columnas relevantes
cols_features = ['latitude', 'longitude', 'depth', 'nst', 'gap', 'dmin', 'rms', 'horizontalError', 'depthError', 'magError', 'magNst']
# Como target usaremos 'mag'

# Limpiar datos: eliminar filas con valores nulos en las columnas que usaremos
data = df.dropna(subset=cols_features + ['mag']).copy()

# Convertir a valores numéricos si es necesario
for col in cols_features + ['mag']:
    data[col] = pd.to_numeric(data[col], errors='coerce')

# Eliminar posibles rows con NaNs resultantes de la conversión
data = data.dropna(subset=cols_features + ['mag'])

# Separamos características (X) y target (y)
X = data[cols_features].values
y = data['mag'].values

# Dividir en train y test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Escalar las características
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Crear la red neuronal
model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(X_train_scaled.shape[1],)))
model.add(layers.Dense(32, activation='relu'))
model.add(layers.Dense(16, activation='relu'))
# Salida única para predecir la magnitud
model.add(layers.Dense(1))

# Compilar el modelo
model.compile(optimizer='adam', loss='mse', metrics=['mae'])

# Documentación de la arquitectura
print('Arquitectura del modelo:')
model.summary()

# Entrenamiento del modelo con validación
history = model.fit(X_train_scaled, y_train, validation_split=0.2, epochs=50, batch_size=32, verbose=1)

# Graficar la evolución del entrenamiento
plt.figure(figsize=(12,5))

# Loss
plt.subplot(1,2,1)
plt.plot(history.history['loss'], label='Entrenamiento')
plt.plot(history.history['val_loss'], label='Validación')
plt.title('Pérdida del modelo')
plt.xlabel('Época')
plt.ylabel('Pérdida (MSE)')
plt.legend()

# MAE
plt.subplot(1,2,2)
plt.plot(history.history['mae'], label='Entrenamiento')
plt.plot(history.history['val_mae'], label='Validación')
plt.title('Error Absoluto Medio (MAE)')
plt.xlabel('Época')
plt.ylabel('MAE')
plt.legend()

plt.tight_layout()
plt.show()

# Evaluar el modelo en el conjunto de test
test_loss, test_mae = model.evaluate(X_test_scaled, y_test, verbose=0)
print('\
Evaluación en conjunto de prueba:')
print('Pérdida (MSE):', test_loss)
print('MAE:', test_mae)

# Guardar modelo y documentación
model.save('earthquake_prediction_model.h5')
print('\
El modelo ha sido guardado como earthquake_prediction_model.h5')

# Breve documentación del proceso:
# 1. Se utilizó el dataset provisto (query.csv) y se prepararon las variables numéricas referentes a la geolocalización 'latitude', 'longitude' y otras características del terremoto.
# 2. Se definió la variable objetivo (target) como la magnitud 'mag'.
# 3. Se preprocesaron los datos: eliminación de missing values, conversión a numéricos y escalado.
# 4. Se definió una red neuronal simple de tres capas densas con activaciones ReLU y una capa de salida para regresión.
# 5. Se entrenó el modelo y se evaluó su desempeño en un conjunto de validación y test, mostrando gráficas de la pérdida y del MAE.
# Nota: En un escenario real, se podrían agregar datos de fuentes en línea (por ejemplo, series de tiempo de actividad sísmica global, información geológica adicional, variables meteorológicas, etc.) utilizando APIs como la USGS, y se realizarían procesos de ingeniería de características más complejos.

print('Proceso completado.')