Files
2026-06-24 20:02:13 -05:00

34 KiB

Clase 1

Aprendizaje Supervisado - Clasificación

In [ ]:
# Paso 1: Importar las bibliotecas necesarias
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# Paso 2: Cargar el dataset Iris
iris = load_iris()
X = iris.data   # Caracteristicas (largo y ancho de pétalos y sépalos)
y = iris.target # Rótulos (especies de flores)

# Paso 3: Dividir los datos para entrenamiento y para prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Paso 4: Entrenar el modelo
model = DecisionTreeClassifier()
model.fit(X_train, y_train)

# Paso 5: Realizar previsiones y evaluar el modelo
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Exactitud del modelo: {accuracy * 100:.2f}%")
In [ ]:
# Paso 1: Importar las bibliotecas necesarias
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
import pandas as pd

# Paso 2: Cargar y preparar el dataset Iris
dataset = load_iris()
df = pd.DataFrame(dataset.data, columns=dataset.feature_names)
df['species'] = dataset.target

# Paso 3: Normalizar los datos
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df.drop(columns=['species']))

# Paso 4: Dividir los datos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X_scaled, df['species'], test_size=0.3, random_state=42)

# Paso 5: Entrenar y evaluar el árbol de decisión
tree_model = DecisionTreeClassifier()
tree_model.fit(X_train, y_train)
tree_accuracy = accuracy_score(y_test, tree_model.predict(X_test))
print(f"Exactitud del modelo de Árbol de Decisión: {tree_accuracy * 100:.2f}%")

# Paso 6: Entrenar y evaluar el KNN
knn_model = KNeighborsClassifier()
knn_model.fit(X_train, y_train)
knn_accuracy = accuracy_score(y_test, knn_model.predict(X_test))
print(f"Exactitud del modelo KNN: {knn_accuracy * 100:.2f}%")

Aprendizaje Supervisado - Regresión

In [ ]:
# Importando bibliotecas
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

# Creando un conjunto de datos simulados
np.random.seed(42)
X = 2.5 * np.random.randn(100, 1) + 25  # Tamaño del inmueble (m2)
y = 500 + (X * 20) + np.random.randn(100, 1) * 10  # Precio del inmueble (miles de dólares)

# Definiendo features (independientes) y labels (dependientes)
features = X
labels = y

# Dividiendo los datos en entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42)

# Creando y entrenando el modelo
model = LinearRegression()
model.fit(X_train, y_train)

#Modelo de Regresión lineal
# Y = A X + B
# Y -> Variable de salida
# X -> Tamaño del inmueble
# A y B son los coeficientes

# Coeficientes de Regresión
print(f"Coeficiente angular (b1): {model.coef_[0][0]:.2f}")
print(f"Intercepto (b0): {model.intercept_[0]:.2f}")

# Predicciones con los datos de prueba
y_pred = model.predict(X_test)

# Indicadores de la Evaluación del modelo con los datos de prueba
#R² Ajuste de los datos al modelo
r2 = r2_score(y_test, y_pred)
#MAE (Error Medio Absoluto)
mae = mean_absolute_error(y_test, y_pred)
#RMSE (Raíz del error Cuadrático Medio)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))

print(f"\nMétricas de Evaluación:")
print(f"R² en datos de prueba: {r2:.2f}")
print(f"Erro Medio Absoluto (MAE): {mae:.2f}")
print(f"Raíz del Error Cuadrático Medio (RMSE): {rmse:.2f}")

# Evaluación cruzada
cv_scores = cross_val_score(model, features, labels, cv=5, scoring='r2')
print(f"\nPromedio de los puntajes de la validación cruzada: {cv_scores.mean():.2f}")

# Gráfico de la recta de Regresión
plt.figure(figsize=(8, 6))
plt.scatter(X_test, y_test, color='blue', label='Datos reales')
plt.plot(X_test, y_pred, color='red', linewidth=2, label='Regresión Lineal')
plt.xlabel("Tamaño del Inmueble")
plt.ylabel("Precio del Inmueble")
plt.title("Regresión Lineal: Precio x Tamaño del Inmueble")
plt.legend()
plt.show()

Actividad - Clase 1

In [ ]:
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# Cargar el dataset Iris de la biblioteca sklearn
dataset = datasets.load_iris()

# Convertir a DataFrame de Pandas para facilitar la manipulación de los datos
df = pd.DataFrame(data=dataset.data, columns=dataset.feature_names)
df['target'] = dataset.target  # Agregar la columna con las clases de las flores

# Separar los atributos (X) y las etiquetas (y)
X = df.iloc[:, :-1]  # Todas las columnas excepto la última
y = df['target']  # Última columna, que contiene las clases

# Dividir los datos en conjunto de entrenamiento y prueba (80% entrenamiento, 20% prueba)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Crear y entrenar un modelo de Árbol de Decisión
model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)

# Hacer predicciones en los datos de prueba
y_pred = model.predict(X_test)

# Evaluar el rendimiento del modelo
accuracy = accuracy_score(y_test, y_pred)
print(f'Precisión del modelo: {accuracy:.2f}')

# Aplicar validación cruzada para mejor evaluación del rendimiento
cross_val_scores = cross_val_score(model, X, y, cv=5)
print(f'Precisión media en la validación cruzada: {cross_val_scores.mean():.2f}')

# Probar con una nueva muestra
nueva_muestra = np.array([[5.1, 3.5, 1.4, 0.2]])  # Ejemplo de medidas de una flor
prediccion = model.predict(nueva_muestra)
print(f'Clase prevista para la nueva muestra: {dataset.target_names[prediccion[0]]}')

Clase 2

Ejemplos de Clasificación y Regresión

In [ ]:
from sklearn.datasets import fetch_california_housing

california = fetch_california_housing()
df = pd.DataFrame(california.data, columns=california.feature_names)
df['PRICE'] = california.target

# Ver las primeras 5 filas de los datos
df.head()
In [ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.datasets import fetch_california_housing

# Cargar el conjunto de datos
california = fetch_california_housing()
df = pd.DataFrame(california.data, columns=california.feature_names)
df['PRICE'] = california.target

# Dividir los datos en datos de entrenamiento y de prueba
X = df.drop('PRICE', axis=1)
y = df['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Entrenar el modelo
model = LinearRegression()
model.fit(X_train, y_train)

# Realizar la prevision
y_pred = model.predict(X_test)

# Evaluar el modelo
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

# Exhibir las métricas
print(f'Error Cuadrático Medio (MSE): {mse:.2f}')
print(f'Coeficiente de Determinación (R²): {r2:.2f}')

# Visualización de los resultados
plt.figure(figsize=(10, 6))
sns.scatterplot(x=y_test, y=y_pred, alpha=0.6)
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], '--r', linewidth=2) # Línea de referencia
plt.xlabel("Valores Reales")
plt.ylabel("Valores Previstos")
plt.title("Regresión Lineal: Valores Reales vs. Previstos")
plt.show()
In [ ]:
from sklearn.datasets import load_diabetes

# Cargar los datos
diabetes = load_diabetes()
df = pd.DataFrame(diabetes.data, columns=diabetes.feature_names)

# Ver las primeras 5 filas de los datos
df.head()
In [ ]:
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix, ConfusionMatrixDisplay
import matplotlib.pyplot as plt

# Cargar los datos
diabetes = load_diabetes()
df = pd.DataFrame(diabetes.data, columns=diabetes.feature_names)
df['OUTCOME'] = diabetes.target

# Transformar la variable target en binaria (clasificación)
df['OUTCOME'] = (df['OUTCOME'] > df['OUTCOME'].median()).astype(int) # 1 cuando es superior a la mediana, y 0 cuando es inferior

# Dividir los datos en datos de entrenamiento y datos de prueba
X = df.drop('OUTCOME', axis=1)
y = df['OUTCOME']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Entrenar el modelo
model = LogisticRegression(max_iter=1000) # Aumentando las iteraciones para evitar warnings
model.fit(X_train, y_train)

# Realizar la Previsión
y_pred = model.predict(X_test)

# Evaluar el modelo
accuracy = accuracy_score(y_test, y_pred)
print(f'Exactitud del Modelo: {accuracy * 100:.2f}%')

# Matriz de Confusión
cm = confusion_matrix(y_test, y_pred)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=['No Diabético', 'Diabético'])
disp.plot(cmap=plt.cm.Blues)
plt.title("Matriz de Confusión - Diagnóstico de Diabetes")
plt.show()
In [ ]:
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.tree import DecisionTreeRegressor

# Cargar dataset
X, y = fetch_california_housing(return_X_y=True)

# Dividir en datos de entrenamiento y datos de prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Definir los hiperparámetros para optimizarlos
param_grid = {
    'max_depth': [3, 5, 7, 10],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

# Aplicar GridSearchCV para encontrar los mejores hiperparámetros
grid_search = GridSearchCV(DecisionTreeRegressor(), param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)

# GridSearchCV -> Realiza la búsqueda de los mejores hiperparámetros combinando todos los valores de hiperparámetros
# Métrica de evaluación -> Error Cuadrático Medio Negativo
print(f'Mejores parámetros: {grid_search.best_params_}')
In [ ]:
# Importar bibliotecas
import pandas as pd
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
import matplotlib.pyplot as plt

# Cargar el dataset Diabetes
diabetes = load_diabetes()
X = diabetes.data # Variables independientes
y = diabetes.target # Variable dependiente

# Dividir los datos para entrenamiento y para prueba (70% treino, 30% teste)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Crear y entrenar el modelo RandomForestRegressor
model = RandomForestRegressor()
model.fit(X_train, y_train)

# Obtener la importancia de los atributos
importances = model.feature_importances_
feature_names = diabetes.feature_names

# Crear un gráfico de barras para visualizar la importancia de los atributos
plt.figure(figsize=(10, 6))
plt.barh(feature_names, importances)
plt.title("Importancia de los Atributos")
plt.xlabel("Importancia")
plt.ylabel("Atributo")
plt.show()
In [ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.datasets import fetch_california_housing

# Cargar el conjunto de datos
california = fetch_california_housing()
df = pd.DataFrame(california.data, columns=california.feature_names)
df['PRICE'] = california.target

# Dividir los datos en entrenamiento y prueba
X = df.drop('PRICE', axis=1)
y = df['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Crear y entrenar los modelos ensemble (Ensamblados)
rf_model = RandomForestRegressor(n_estimators=200, max_depth=10, random_state=42)
gb_model = GradientBoostingRegressor(n_estimators=200, learning_rate=0.05, max_depth=5, random_state=42)
rf_model.fit(X_train, y_train)
gb_model.fit(X_train, y_train)

# Realizar previsiones
y_pred_rf = rf_model.predict(X_test)
y_pred_gb = gb_model.predict(X_test)

# Evaluar los modelos
mse_rf = mean_squared_error(y_test, y_pred_rf)
r2_rf = r2_score(y_test, y_pred_rf)
mse_gb = mean_squared_error(y_test, y_pred_gb)
r2_gb = r2_score(y_test, y_pred_gb)

# Exhibir métricas
print(f"Random Forest - MSE: {mse_rf:.2f}, R²: {r2_rf:.2f}")
print(f"Gradient Boosting - MSE: {mse_gb:.2f}, R²: {r2_gb:.2f}")

# Visualizar los resultados
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
sns.scatterplot(x=y_test, y=y_pred_rf, alpha=0.6)
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], '--r', linewidth=2)
plt.xlabel("Valores Reales")
plt.ylabel("Valores Previstos")
plt.title("Random Forest")

plt.subplot(1, 2, 2)
sns.scatterplot(x=y_test, y=y_pred_gb, alpha=0.6, color='green')
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], '--r', linewidth=2)
plt.xlabel("Valores Reales")
plt.ylabel("Valores Previstos")
plt.title("Gradient Boosting")

plt.show()

Clase 3

Aprendizaje No Supervisado - Clustering

In [ ]:
from sklearn.datasets import load_iris
import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

# Cargar Dataset
iris = load_iris()
X = iris.data

# Aplicar K-Means
kmeans = KMeans(n_clusters=3, random_state=42)
clusters = kmeans.fit_predict(X)

# Visualizar los clusters
plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap='viridis')
plt.title("Agrupando con K-Means")
plt.xlabel("Caracteristica 1")
plt.ylabel("Caracteristica 2")
plt.show()
In [ ]:
from sklearn.datasets import load_iris
import scipy.cluster.hierarchy as sch
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler

# Cargar el dataset Iris
iris = load_iris()
X = iris.data

# Normalizar los datos para mejorar el desempeño del clustering
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Crear el dendrograma
plt.figure(figsize=(10, 5))
sch.dendrogram(sch.linkage(X_scaled, method='ward'))
plt.title("Dendrograma del Agrupamiento Jerárquico")
plt.xlabel("Muestras")
plt.ylabel("Distancia Eucliadiana")
plt.show()
In [ ]:
from sklearn.cluster import AgglomerativeClustering

# Aplicar Hierarchical Clustering definiendo 3 grupos
hc = AgglomerativeClustering(n_clusters=3, metric='euclidean', linkage='ward')
clusters = hc.fit_predict(X_scaled)

# Visualizar los clusters
plt.scatter(X[:, 0], X[:, 1], c=clusters, cmap='viridis')
plt.title("Agrupando con Hierarchical Clustering")
plt.xlabel("Caracteristica 1")
plt.ylabel("Caracteristica 2")
plt.show()

Aprendizaje No Supervisado - PCA

In [ ]:
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler

# Cargar el dataset Iris
iris = load_iris()
X = iris.data
y = iris.target # Etiquetas de las especies de flores

# Normalizar los datos para mejorar el desempeño
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Aplicar PCA para reducir de 4 a dos dimensiones
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# Visualizar los datos reducidos
plt.figure(figsize=(8, 6))
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis', alpha=0.7)
plt.xlabel("Componente Principal 1")
plt.ylabel("Componente Principal 2")
plt.title("Reducción de la Dimensionalidad con PCA")
plt.colorbar(label="Especies de Flores")
plt.show()
In [ ]:
print(pca.explained_variance_ratio_)
print(f"Varianza acumulada: {sum(pca.explained_variance_ratio_):.2f}")

Clase 4

Procesamiento de imágenes

In [ ]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files

# Realizar upload de la Imagen
uploaded = files.upload()
image_path = list(uploaded.keys())[0]

# Cargar la imagen en escala de grises
imagen = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

# Mostrar la imagen original y la matriz correspondiente
plt.figure(figsize=(15,8))

plt.subplot(1, 2, 1)
plt.imshow(imagen, cmap="gray")
plt.title("Imagen en tonos de gris")
plt.axis("off")

plt.subplot(1, 2, 2)
plt.imshow(imagen, cmap="gray")
plt.title("Matriz de Pixeles")
for i in range(0, imagen.shape[0], 30):
    for j in range(0, imagen.shape[1], 30):
        plt.text(j, i, str(imagen[i, j]), color="red", fontsize=6, ha='center', va='center')

plt.show()
In [ ]:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

# Crear un modelo CNN simple
modelo = Sequential([
    Conv2D(32, (3,3), activation='relu', input_shape=(64, 64, 3)), # Capa convolucional
    MaxPooling2D(pool_size=(2,2)), # Capa de pooling
    Flatten(), # Aplanando para la capa densa
    Dense(128, activation='relu'), # Capa totalmente conectada
    Dense(3, activation='softmax') # Salida para 3 clases
])

modelo.summary() # Exhibe la arquitectura de la red
In [ ]:
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input, decode_predictions
import numpy as np
import cv2
from google.colab import files
from PIL import Image

# Fazer upload de imagen
uploaded = files.upload()
imagen_path = list(uploaded.keys())[0] # Toma el nombre del archivo enviado

# Cargar la imagen usando OpenCV
imagen = cv2.imread(imagen_path)
imagen_rgb = cv2.cvtColor(imagen, cv2.COLOR_BGR2RGB)

# Cargar el modelo MobileNetV2 pre-entrenado
modelo = MobileNetV2(weights="imagenet")

# Pre-procesar la imagen para el formato esperado por el modelo
imagen_redimensionada = cv2.resize(imagen_rgb, (224, 224))
imagen_array = np.expand_dims(imagen_redimensionada, axis=0)
imagen_array = preprocess_input(imagen_array)

# Fazer a previsão
previsiones = modelo.predict(imagen_array)
label = decode_predictions(previsiones)
print("Objeto identificado:", label[0][0][1]) # Exhibe la clase identificada
In [ ]:
from sklearn.feature_extraction.text import CountVectorizer

# Conjunto de frases
frases = ["Yo amo viajar para Japón", "Viajar es increíble", "Quiero conocer Japón"]

# Creando el modelo BoW
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(frases)

# Exhibir matriz resultante
print(vectorizer.get_feature_names_out())
print(X.toarray())
In [ ]:
from transformers import pipeline

# Cargar un modelo de generación de texto
generador = pipeline("text-generation", model="gpt2")

# Definir el prompt
prompt = "Cuál es la mejor época para visitar Japón?"

# Generar una respuesta ajustando los parámetros para evitar repeticiones
respuesta = generador(
    prompt,
    max_length=50,      # Aumentar un poco la longitud
    temperature=0.1,    # Controla la aleatoriedad
    top_p=0.9,          # Realiza el muestreo con un núcleo (nucleus sampling)
    top_k=10,           # Restringe la elección al top 50 de palabras con mayor probabilidad
    repetition_penalty=1.2 # Penaliza repeticiones
)

# Exhibir la respuesta formateada
print(respuesta[0]['generated_text'])
In [ ]:
import numpy as np
import gymnasium as gym

# Inicializar el entorno FrozenLake
# El agente necesita cruzar un lago congelado sin caer en los agujeros
env = gym.make("FrozenLake-v1", is_slippery=True)

# Definir los hiperparámetros del Q-Learning
alpha = 0.8  # Tasa de aprendizaje: cuánto aprende el agente de nueva información
gamma = 0.95  # Factor de descuento: cuán importantes son las recompensas futuras en comparación con las inmediatas
epsilon = 1.0  # Probabilidad inicial de explorar acciones aleatorias
epsilon_decay = 0.999  # Reduce gradualmente la exploración a medida que el agente aprende
epsilon_min = 0.01  # Límite mínimo de exploración para garantizar que el agente aún explore un poco
num_episodes = 20000  # Número total de intentos de aprendizaje (episodios)

# Crear la tabla Q (Q-table) con ceros
# Las filas representan los estados y las columnas representan las acciones
q_table = np.zeros((env.observation_space.n, env.action_space.n))

# Iniciar el entrenamiento del agente
for episode in range(num_episodes):
    # Reiniciar el entorno en cada episodio
    state, _ = env.reset()
    done = False

    while not done:
        # Elegir una acción usando la estrategia epsilon-greedy
        # Con probabilidad 'epsilon', elegimos una acción aleatoria (exploración)
        # De lo contrario, elegimos la mejor acción conocida hasta el momento (explotación)
        if np.random.rand() < epsilon:
            action = env.action_space.sample()  # Explorar una acción aleatoria
        else:
            action = np.argmax(q_table[state])  # Explorar la acción con mayor valor en la Q-table

        # Ejecutar la acción elegida en el entorno
        next_state, reward, done, truncated, _ = env.step(action)

        # Actualizar la Q-table con la fórmula de aprendizaje por refuerzo
        # Q(s, a) = Q(s, a) + alpha * (recompensa + descuento * max(Q(s', a')) - Q(s, a))
        best_next_action = np.max(q_table[next_state])  # Mejor acción en el siguiente estado
        q_table[state, action] += alpha * (reward + gamma * best_next_action - q_table[state, action])

        # Avanzar al siguiente estado
        state = next_state

    # Reducir la tasa de exploración gradualmente, sin superar el mínimo definido
    if epsilon > epsilon_min:
        epsilon *= epsilon_decay

# Evaluar el rendimiento del agente entrenado
# Aquí, probamos 1000 episodios para verificar cuántas veces logra cruzar el lago con éxito
successes = 0
for episode in range(1000):
    state, _ = env.reset()
    done = False
    while not done:
        # El agente ahora solo elige la mejor acción aprendida (sin exploración aleatoria)
        action = np.argmax(q_table[state])
        state, reward, done, truncated, _ = env.step(action)
        if done and reward == 1.0:
            successes += 1  # Contabilizar los éxitos

# Mostrar el resultado final
print(f"El agente logró cruzar el lago con éxito en {successes} de 1000 episodios.")