Saltar navegación

Actividade 4: Proba de modelos e adestramento

📌 Obxectivo

Copilot (CC BY-SA)

  

Chegou o momento decisivo! Xa explorastes os datos, limpástelos e analizastes patróns importantes. Agora é hora de construír un modelo de Intelixencia Artificial capaz de predicir a supervivencia no Titanic. Terás que escoller un modelo axeitado, adestralo con datos reais probalo e avaliar o seu rendemento para ver se realmente aprende ben.

A adestrar modelos!

✂️ Paso 1: División de datos para adestramento e test

Antes de nada, debemos dividir os datos que xa temos procesados e escalados (csv - 95303 B) en conxunto de adestramento(train) e conxunto de test. Isto permítenos ensinar ao modelo con unha parte dos datos e despois probar se realmente aprendeu ben con datos novos. Podes facelo con con train_test_split() de Scikit-learn:

Código Python: División dos datos en trainset e dataset

from sklearn.model_selection import train_test_split

X = df.drop(columns=['Survived'])  # Variables independentes
y = df['Survived']  # Variable obxectivo

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)    
Variables independentes (X): Son as características ou factores que usamos para facer predicións. No teu caso, estas variables poderían ser a idade, o sexo ou a clase do pasaxeiro no Titanic. Non dependen do resultado final, só serven como entradas para o modelo
Variable obxectivo (y): É o que queremos predicir, a saída do modelo. Neste código, Survived indica se a persoa sobreviviu ou non ao afundimento do Titanic. O modelo aprende a relacionar as variables independentes co resultado final para facer predicións en novos datos.
 X_train e y_train serán os datos para adestrar ao modelo. 
X_test e y_test serán os datos para avaliar se realmente funciona.
test_size=0.2 significa que usamos o 20% dos datos para test.
random_state=42 (podes usar outro nº) úsase para fixar a semente do xerador aleatorio no proceso de división do conxunto de datos en adestramento e proba. Isto significa que, cada vez que executes o código, obterás exactamente a mesma separación entre datos de adestramento e proba, o que fai que todas as probas que executes sexan reproducibles e comparables.
💡 Preguntas para reflexionar:
  • Por que é importante ter un conxunto de test separado?
  • Que pasa se usamos poucos datos para adestramento?
  • Podes visualizar os datos resultantes con X_train.head(5) etc. para comprender ben o proceso

❓ Paso 2: Proba con modelos clásicos

Primeiro probarás modelos clásicos de machine learning como Regresión Loxística, Random Forest e Support Vector Machine (SVM). Estes modelos son rápidos e sinxelos de interpretar.

  1. 👉 Regresión Loxística: Modelo moi útil para clasificación binaria (sobrevive ou non).

    Código Python: Creación e adestramento do modelo de regresión

    #Isto carga LogisticRegression desde scikit-learn, que usaremos para crear o noso modelo de clasificación.
    from sklearn.linear_model import LogisticRegression
    
    #Este paso elimina todas as columnas con datos en formato texto, xa que LogisticRegression só funciona con números. 
    #Se hai nomes ou categorías en texto, estas deben ser convertidas antes de poder adestrar o modelo.
    #Todavía quedan os nomes das personas e os tickets como texto 'objet' e non as precisamos
    X_train = X_train.select_dtypes(exclude=['object'])
    X_test = X_test.select_dtypes(exclude=['object'])
    
    #Aquí creamos un modelo de regresión loxística e fixamos max_iter=500, o que significa que permitiremos ata 500 iteracións 
    #para que o modelo mellore a súa precisión antes de deter o proceso de adestramento.
    model_lr = LogisticRegression(max_iter=500)
    
    #Nesta liña, o modelo aprende a relacionar as variables independentes (X_train) coa variable obxectivo (y_train). 
    #Está "estudando" os datos para poder facer predicións.
    model_lr.fit(X_train, y_train)  # Adestramento
    
    #Unha vez adestrado, o modelo usa os datos de X_test (que nunca viu antes) para facer predicións sobre y_test. 
    #O resultado y_pred_lr conterá os valores que o modelo cre que son correctos.
    y_pred_lr = model_lr.predict(X_test)  # Predición
        

    O resultado y_pred_lr contén os valores que o modelo cre que son correctos. Agora podes comprobar os resultados e avaliar que tal funciona o modelo. O máis sinxelo e visual é usar a matriz de confusión ou heatmap e a tasa de acertos ou precisión do modelo.

    Código Python: Matriz de confusión e precisión do modelo

    # Importamos as ferramentas necesarias para avaliar o modelo e visualizar a matriz de confusión e a precisión do modelo
    from sklearn.metrics import confusion_matrix  # Para calcular a matriz de confusión
    from sklearn.metrics import accuracy_score  # Para calcular a porcentaxe de acertos do modelo
    import seaborn as sns  # Para xerar gráficos bonitos
    
    # Creamos a matriz de confusión, comparando os valores reais (y_test) coas predicións do modelo (y_pred_lr)
    cm = confusion_matrix(y_test, y_pred_lr)
    
    # Debuxamos a matriz de confusión cun mapa de calor usando Seaborn
    sns.heatmap(cm, annot=True, fmt="d", cmap="Oranges")  # Mostramos os valores no gráfico e escollemos a cor "Oranges"
    
    # Engadimos etiquetas aos eixes para que se entenda ben a visualización
    plt.xlabel("Predición")  # Eixo X = Valores predicidos polo modelo
    plt.ylabel("Real")  # Eixo Y = Valores reais no conxunto de test
    plt.title("Matriz de confusión")  # Título do gráfico
    
    # Mostramos o gráfico na pantalla
    plt.show()
    
    # Comparación entre as predicións feitas polo modelo e os valores reais dos datos de test
    precision = accuracy_score(y_test, y_pred_lr)  # Calcula a precisión do modelo
    
    # Mostramos a precisión obtida, redondeada a dous decimais para mellor visualización
    print(f"Precisión do modelo: {precision:.2f}")  # Exemplo: se a precisión é 0.75, significa que o modelo acerta no 75% dos casos    
  2. 👉 Random Forest: Modelo baseado en múltiples árbores de decisión que combina predicións.

    Código Python:Creamos e adestramos o modelo de árbore de decisión

    # Importamos a clase RandomForestClassifier desde sklearn, que permite crear un modelo de bosques aleatorios
    from sklearn.ensemble import RandomForestClassifier  
    
    # Creamos o modelo de Random Forest con 100 árbores de decisión e unha semilla fixa para reproducibilidade
    model_rf = RandomForestClassifier(n_estimators=100, random_state=42)  
    # "n_estimators=100" significa que o modelo terá 100 árbores para tomar decisións en conxunto
    #"random_state=42" garante que a execución sexa reproducible e sempre obtemos os mesmos resultados
    
    # Adestramos o modelo cos datos de entrenamiento (X_train) e a variable obxectivo (y_train)
    model_rf.fit(X_train, y_train)  
    #O modelo aprende a relación entre as características (X_train) e os resultados reais (y_train)
    
    # Facemos predicións cos datos de test (X_test), que nunca antes foron vistos polo modelo
    y_pred_rf = model_rf.predict(X_test)  
    #O modelo usa as regras que aprendeu para prever os valores de y_test
        

    O resultado y_pred_rf contén os valores que o modelo cre que son correctos. Agora podes comprobar os resultados e avaliar que tal funciona o modelo. Volvemos usar a matriz de confusión ou heatmap e a tasa de acertos ou precisión do modelo.

    Código Python: Visualizamos o heatmap do modelo e a súa precisión

    # Creamos a matriz de confusión, comparando os valores reais (y_test) coas predicións do modelo (y_pred_rf)
    cm = confusion_matrix(y_test, y_pred_rf)
    
    # Debuxamos a matriz de confusión cun mapa de calor usando Seaborn
    sns.heatmap(cm, annot=True, fmt="d", cmap="Blues")  # Mostramos os valores no gráfico e escollemos a cor "Blues"
    
    # Engadimos etiquetas aos eixes para que se entenda ben a visualización
    plt.xlabel("Predición")  # Eixo X = Valores predicidos polo modelo
    plt.ylabel("Real")  # Eixo Y = Valores reais no conxunto de test
    plt.title("Matriz de confusión")  # Título do gráfico
    
    # Mostramos o gráfico na pantalla
    plt.show()
    
    # Comparación entre as predicións feitas polo modelo e os valores reais dos datos de test
    precision = accuracy_score(y_test, y_pred_rf)  # Calcula a precisión do modelo
    
    # Mostramos a precisión obtida, redondeada a dous decimais para mellor visualización
    print(f"Precisión do modelo: {precision:.2f}")  # Exemplo: se a precisión é 0.75, significa que o modelo acerta no 75% dos casos    
  3. 👉 Support Vector Machine (SVM): Modelo que busca separadores óptimos entre clases. Este modelo é útil para problemas de clasificación binaria ou multi-clase, especialmente cando os datos non son linealmente separables.

    Código Python: Creamos e adestramos o modelo de SVM

    # Importamos a clase SVC (Support Vector Classifier) desde a biblioteca scikit-learn
    from sklearn.svm import SVC  
    
    # Creamos o modelo de SVM (Máquinas de Soporte Vectorial) sen parámetros específicos
    #Probei a introducir axustes nos parámetros model_svm = SVC(C=0.1, class_weight='balanced'), pero non mellora significativamente
    
    model_svm = SVC()
    
     
    #SVM é un algoritmo de clasificación que busca a mellor liña (ou hiperplano) para separar as clases dos datos
    
    # Adestramos o modelo usando os datos de entrenamiento (X_train) e a variable obxectivo (y_train)
    model_svm.fit(X_train, y_train)  
    #O modelo aprende a relación entre as características (X_train) e os resultados reais (y_train)
    #Durante o adestramento, SVM intenta atopar o hiperplano óptimo que mellor separa as clases
    
    # Realizamos predicións sobre os datos de test (X_test), que o modelo nunca viu antes
    y_pred_svm = model_svm.predict(X_test)  
    #O modelo aplica o hiperplano aprendido para predicir se os novos exemplos pertencen á clase 0 ou 1    

    O resultado y_pred_svm contén os valores que o modelo cre que son correctos. Agora podes comprobar os resultados e avaliar que tal funciona o modelo. Volvemos usar a matriz de confusión ou heatmap e a tasa de acertos ou precisión do modelo.

    Código Python: Visualizamos o heatmap do modelo e a súa precisión

    # Creamos a matriz de confusión, comparando os valores reais (y_test) coas predicións do modelo (y_pred_svm)
    cm = confusion_matrix(y_test, y_pred_svm)
    
    # Debuxamos a matriz de confusión cun mapa de calor usando Seaborn
    sns.heatmap(cm, annot=True, fmt="d", cmap="Greens")  # Mostramos os valores no gráfico e escollemos a cor "Greens"
    
    # Engadimos etiquetas aos eixes para que se entenda ben a visualización
    plt.xlabel("Predición")  # Eixo X = Valores predicidos polo modelo
    plt.ylabel("Real")  # Eixo Y = Valores reais no conxunto de test
    plt.title("Matriz de confusión")  # Título do gráfico
    
    # Mostramos o gráfico na pantalla
    plt.show()
    
    # Comparación entre as predicións feitas polo modelo e os valores reais dos datos de test
    precision = accuracy_score(y_test, y_pred_svm)  # Calcula a precisión do modelo
    
    # Mostramos a precisión obtida, redondeada a dous decimais para mellor visualización
    print(f"Precisión do modelo: {precision:.2f}")  # Exemplo: se a precisión é 0.70, significa que o modelo acerta no 70% dos casos    

💡 Preguntas para reflexionar:

  • Cales son as vantaxes e desvantaxes de cada modelo?
  • Cal é o mellor?

🧠Paso 3: Proba dun modelo de Deep Learning

Probaremos agora unha Rede Neuronal Simple coas librarías TensorFlow/Keras.

Esta librería traballa con todas as columnas de datos á vez , e non acepta datos tipo object. Tes dúas posibilidades:

  1. eliminar as columnas Name e Ticket do dataframe, que son as que quedan con formato object, antes de realizar de novo a División dos datos en trainset e dataset 
  2. reconvertir os datos de adestramento e test noutros que non teñan xa datos tipo object.
Creamos e adestramos un modelo con Tensorflow e Keras:

Código Python: Modelo de rede neuronal con Tensorflow e keras

#Instalamos TensorFlow de xeito "silencioso"
!pip install -q tensorflow

# Importamos TensorFlow e Keras para traballar con redes neuronais
import tensorflow as tf
from tensorflow import keras
from keras import layers

# Convertimos os datos a tensores para que tensorflow os comprenda.
# Creo datos novos, para non perder os iniciais.
X_testT = tf.convert_to_tensor(X_test, dtype=tf.float32)
y_testT = tf.convert_to_tensor(y_test, dtype=tf.float32)
X_trainT = tf.convert_to_tensor(X_train, dtype=tf.float32)
y_trainT = tf.convert_to_tensor(y_train, dtype=tf.float32)


#Creamos un modelo de rede neuronal profunda usando o tipo Sequential
model_dl = keras.Sequential([
    # Primeira capa oculta → 16 neuronas, activación ReLU, entrada co número de características
   layers.Dense(16, activation='relu'),

    # Segunda capa oculta → 8 neuronas, activación ReLU, útil para captar patróns máis complexos
    layers.Dense(8, activation='relu'),

    # Capa de saída → 1 neurona, activación Sigmoid para clasificación binaria
    layers.Dense(1, activation='sigmoid')
])

# Compilamos o modelo, definindo como vai aprender
model_dl.compile(
    optimizer='adam',  #  Optimización con Adam, que axusta os pesos eficientemente
    loss='binary_crossentropy',  #  Perda para clasificación binaria
    metrics=['accuracy']  #  Métrica para medir acertos
)

# Adestramos a rede neuronal cos datos de entrenamento e gardamos a historia de perda e precisión
history=model_dl.fit(
    X_trainT, y_trainT,  # Datos de entrada e etiquetas reais
    epochs=30,  #  Número de veces que o modelo aprende cos datos
    batch_size=16,  #  Procesa os datos en grupos de 16 exemplos para máis eficiencia
    validation_data=(X_testT, y_testT)  #  Usa datos de validación para comprobar o rendemento
)
print("Rematou o adestramento do modelo")
y_pred = model_dl.predict(X_testT)  # Executa a predición unha única vez
y_pred_rede = tf.cast((y_pred > 0.5), tf.int32)

Este código:

  • Instala TensorFlow de xeito "silencioso", sen mostrar demasiada información na consola con !pip install -q tensorflow
  • Transforma os datos de entrada (X_train, X_test) e as etiquetas (y_train, y_test) en tensores para que TensorFlow os procese mellor.
    • X_testT = tf.convert_to_tensor(X_test, dtype=tf.float32)
    • y_testT = tf.convert_to_tensor(y_test, dtype=tf.float32)
    • X_trainT = tf.convert_to_tensor(X_train, dtype=tf.float32)
    • y_trainT = tf.convert_to_tensor(y_train, dtype=tf.float32)
  • Crea unha rede neuronal profunda con TensorFlow e Keras tipo Sequential, que organiza as capas en orde:
    • model_dl = keras.Sequential([

layers.Dense(16, activation='relu'),⇒Primeira capa oculta: 16 neuronas(sempre>=características dos datos) con ReLU para extraer patróns básicos.
layers.Dense(8, activation='relu'),⇒Segunda capa oculta: 8 neuronas con ReLU, útil para capturar patróns máis complexos.
layers.Dense(1, activation='sigmoid')⇒Capa de saída: 1 neurona con Sigmoid, que decide entre dúas opcións posibles sobrevive ou non sobrevive.
])

  • Compilación do modelo. Aquí definimos como vai aprender o modelo
    • model_dl.compile(
      optimizer='adam', ⇒adam: Axusta os pesos automaticamente en cada época, según loss
      loss='binary_crossentropy',⇒Indicalle ó modelo canto erro está cometendo a rede neuronal nas súas predicións, para que se axuste
      metrics=['accuracy']⇒Só mide a precisión do modelo, pero non modifica os pesos.
      )
  • Adestramento do modelo
    • history = model_dl.fit(
      X_trainT, y_trainT,
      epochs=30,⇒O modelo aprende cos datos 30 veces.
      batch_size=16,⇒Usa bloques de 16 exemplos de datos para máis eficiencia.
      validation_data=(X_testT, y_testT)⇒Usa datos que non foron vistos para comprobar a precisión.
      )
  • Realización de predicións: Compara os valores preditos con 0.5 (se é maior, asúmese como "1", se é menor, como "0").
    • y_pred = model_dl.predict(X_testT)⇒Aquí usamos o modelo adestrado para prever resultados sobre os datos de proba (X_testT). A saída será un número entre 0 e 1.
    • y_pred_rede = tf.cast((y_pred > 0.5), tf.int32)⇒Tranforma isto nunha decisión binaria (0 ou 1)

O resultado y_pred_rede contén os valores que o modelo cre que son correctos. Agora podes comprobar os resultados e avaliar que tal funciona o modelo. Volvemos usar a matriz de confusión ou heatmap e a tasa de acertos ou precisión do modelo.

Código Python: Visualizamos o heatmap do modelo e a súa precisión

# Importamos as ferramentas necesarias para avaliar o modelo e visualizar a matriz de confusión e a precisión do modelo
from sklearn.metrics import confusion_matrix # Para calcular a matriz de confusión
from sklearn.metrics import accuracy_score # Para calcular a porcentaxe de acertos do modelo import seaborn as sns

# Creamos a matriz de confusión, comparando os valores reais (y_testT) coas predicións do modelo (y_pred_rede)
cm = confusion_matrix(y_testT, y_pred_rede)

# Debuxamos a matriz de confusión cun mapa de calor usando Seaborn
sns.heatmap(cm, annot=True, fmt="d", cmap="Greys") # Mostramos os valores no gráfico e escollemos a cor "Greys"

# Engadimos etiquetas aos eixes para que se entenda ben a visualización
plt.xlabel("Predición") # Eixo X = Valores predicidos polo modelo
plt.ylabel("Real") # Eixo Y = Valores reais no conxunto de test
plt.title("Matriz de confusión") # Título do gráfico

# Mostramos o gráfico na pantalla
plt.show()

# Comparación entre as predicións feitas polo modelo e os valores reais dos datos de test
precision = accuracy_score(y_testT, y_pred_rede) # Calcula a precisión do modelo

# Mostramos a precisión obtida, redondeada a dous decimais para mellor visualización
print(f"Precisión do modelo: {precision:.2f}") # Exemplo: se a precisión é 0.5, significa que o modelo acerta no 50% dos casos    

💡 Preguntas para reflexionar:

  • Como se diferencia unha rede neuronal doutros modelos?
  • Cres que Deep Learning é necesario para este problema ou un modelo clásico pode funcionar ben?

✅ Feito

Agora temos varios modelos de IA adestrados e funcionando! Probastes diferentes técnicas de Machine Learning e incluso unha Rede Neuronal. Calculáchedes o rendemento e precisión de cada unha. Comparáchedes os resultados para poder escoller o mellor modelo.

🚢Xa están listos para predicir a supervivencia no Titanic!

Existe en kaggle un conxunto de datos do Titanic testset que podes usar, neste ODE usarémolo para datos de proba no modelo. Podes se queres, introducir parte no dataset e deixar uns cantos para avaliar o modelo.

Cando os datos non son linealmente separables, significa que non podemos debuxar unha liña recta para dividir perfectamente as diferentes categorías. 

Que significa isto de forma simple? Imaxina que tes unha mesa chea de puntos vermellos e azuis, e queres separar os dous grupos usando unha regra (unha liña). Se podes debuxar unha liña recta que divida completamente as dúas cores, os datos son linealmente separables. Pero se os puntos están mesturados ou forman unha curva, non podemos usar unha liña recta para separalos correctamente ⇒ Nestes casos, os datos son non linealmente separables e precisamos modelos máis avanzados, como SVM con kernels, árbores de decisión ou redes neuronais. 

Exemplo

Se tes isto:🔴🔴🔴 | 🔵🔵🔵⇒ Datos linealmente separables, porque podemos debuxar unha liña recta no medio.

Pero se tes isto: 🔴🔵🔴 🔵🔴🔵 🔴🔵🔴 ⇒ Datos non linealmente separables, porque unha liña recta non pode dividir os dous grupos claramente. 

Cando os datos non son linealmente separables, necesitamos técnicas máis sofisticadas para encontrar fronteiras de decisión máis complexas

Os datos dos superviventes do Titanic non son perfectamente separables linealmente, porque non existe unha única liña recta que divida claramente os que sobreviviron dos que non.

Por que non son linealmente separables? As variables que afectan a supervivencia ( sexo, clase no barco,  etc.) non teñen unha relación simple que se poida dividir cunha liña recta. Por exemplo: O feito de ser home ou muller afectaba a probabilidade de supervivencia. A clase do pasaxeiro influía moito (1ª clase tiña máis posibilidades de sobrevivir). Algúns nenos e mulleres faleceron, mentres que algúns homes sobreviviron.

Que modelo usar neste caso? Dado que os datos non son linealmente separables, modelos como Regresión Loxística ou SVM sen kernel poden ter dificultades para atopar unha fronteira clara. En cambio, modelos como Árbores de Decisión, Random Forest ou Redes Neuronais poden capturar mellor as interaccións complexas entre variables.

Para clasificar superviventes do Titanic de forma precisa, necesitamos modelos que poidan capturar relacións non lineais e considerar múltiples factores ao mesmo tempo.

A diferenza principal entre Machine Learning e Deep Learning é a complexidade dos algoritmos que usan para aprender dos datos: 

Machine Learning (ML) ⇒ Usa algoritmos máis sinxelos, como regresión, árbores de decisión ou Random Forest.  Require que os humanos escollan as características importantes dos datos antes de que o modelo aprenda.

Deep Learning (DL) ⇒ Usa redes neuronais artificiais, inspiradas no funcionamento do cerebro. Aprende directamente dos datos sen necesidade de selección manual de características.

Deep Learning é un tipo avanzado de Machine Learning que emprega redes neuronais profundas para aprender de grandes cantidades de datos con menos intervención humana. 

Opción 2: Antes de usar os datos X_train e y_train extraemos un novo set de datos con todo, salvo as columnas object 

X_train = X_train.select_dtypes(exclude=['object'])

X_test = X_test.select_dtypes(exclude=['object'])

Opción 1:Eliminamos as columnas categóricas que quedan e creamos un novo arquivo de datos, só numérico, conservando o anterior, temos que executar de novo a división dos datos en train e test.

import pandas as pd # Incluímos pandas para traballar con datos

import numpy as np #numpy para facer contas import

matplotlib.pyplot as plt import seaborn as sns #E matplotlib e seaborn para gráficos

# Ruta do ficheiro en Colab, tes que telo subido en arquivos, e cambia o nome se lle tes un distinto

df = pd.read_csv("/content/datasetTitanicProcesado.csv")

# Eliminar a columna Nome e Ticket porque ten valores object que non nos interesan para o proxecto, podemos sempre localizar á persona co seu PassengerId df = df.drop(columns=['Name','Ticket'])

# Gardar o DataFrame simplificado como CSV

df.to_csv("datasetTitanicNumeros.csv", index=False)

# Descargar o arquivo en Colab from google.colab import files

files.download("datasetTitanicNumeros.csv")

df.head(5) # Mostra as 5 primeiras filas do DataFrame agora sen Name nin Ticket

Dense é unha capa onde cada neurona está conectada a todas as anteriores, permitindo que a rede neuronal aprenda mellor os datos.

Autoavaliación

Lista de cotexo

🧠 Actividade 4: Proba de modelos e adestramento

Esta lista axúdache a organizar e verificar o teu progreso na análise de modelos de IA.