# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + id="OYbyBXjz3eZY"
# Se importan las librerías que corresponden
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OrdinalEncoder, StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from matplotlib import pyplot as plt
import seaborn as sns
from pandas.plotting import scatter_matrix

import warnings
warnings.filterwarnings("ignore")

# + colab={"base_uri": "https://localhost:8080/", "height": 204} id="D0Cp9rS76hD0" outputId="e59ba744-9bd8-47b1-f3f9-abcd580d5cd7"
# Se leen los datos
df_heart = pd.read_csv('https://raw.githubusercontent.com/JhonBS17/machineLearningFiles/main/heart.csv')
df_heart.head()

# + [markdown] id="ddUV3zWP7nB6"
# A continuación, se presenta el significado de cada columna del dataset:
# * age
# * sex
# * cp - Tipo de dolor de pecho (4 valores desde 0 hasta 3)
# * trestbps - Presión arterial en reposo
# * chol - Colesterol sérico en mg/dl
# * fbs - Azucar en la sangre en ayunas > 120 mg/dl
# * restecg - Resultados electrocardiográficos en reposo (valores de 0,1,2)
# * thalach - Frecuencia cardíaca máxima alcanzada
# * exang - Angina inducida por ejercicio
# * oldpeak - Depresión inducida por el ejercicio en relación con el reposo
# * slope - 
# * ca - Número de vasos principales (0-3) coloreados por la floración
# * thal - 0 = normal; 1 = defecto fijo; 2 = defecto reversible
# * target - Infarto: sí = 1; no = 0
#
#

# + [markdown] id="17WCLbCrEfbR"
# #**1. Exploración Inicial**

# + colab={"base_uri": "https://localhost:8080/"} id="ylCy6b-9GiNq" outputId="a4f13a73-34f9-4f8e-8e8d-531d29db7eec"
# Obtener el número de registros y features del dataset
df_heart.shape

# + colab={"base_uri": "https://localhost:8080/"} id="ZgJcxZ_Z6yWE" outputId="c23d0dc7-f812-4225-cc81-b9354b2196ba"
# Obtener información acerca del dataset
df_heart.info()

# + colab={"base_uri": "https://localhost:8080/", "height": 483} id="JTANI9BcE8VL" outputId="9cd1e222-63f4-4e5a-82b1-6e6589fd78fe"
# Generar estadísticas del dataset
df_heart.describe().T

# + colab={"base_uri": "https://localhost:8080/", "height": 595} id="7dErCGoyHLVf" outputId="be3a8bf0-63b2-49f1-a41a-3e75fcf8e4ed"
# Obtener la correlación entre las variables del dataset
plt.figure(figsize=(13,10))
sns.heatmap(df_heart.corr(), annot=True, cmap='inferno')
plt.show()

# + [markdown] id="8B91vUef8qxd"
# #**2. Separación en entrenamiento y test**

# + id="FOT-_q1kbFwC"
# Se escogen las variables con las que se van a trabajar, teniendo en cuenta las correlaciones halladas anteriormente
columns_df = ['cp', 'thalach', 'exang', 'oldpeak', 'slope', 'ca', 'target']
df_heart_final = df_heart[columns_df]

# + id="novZ-PYz8Ukh"
# Se divide el dataset en training y test
training, test = train_test_split(df_heart_final, test_size=0.3)

# + [markdown] id="vhvKj8gq8yfx"
# #**3.Preprocesamiento**

# + id="n78kD8wD8huz"
# Usar un pipeline para generar el modelo que se desea
pipe = Pipeline([('clean', SimpleImputer(strategy='most_frequent')), ('scaler', StandardScaler())])

# + id="Iz_lSLGf0Okj"
# Agrupar todos los datos al aplicar el pipeline en el DataFrame de training, a excepción de la variable 'target'
ct = ColumnTransformer([('pipe', pipe, [0, 1, 2, 3, 4, 5])], remainder='passthrough')
training_data = ct.fit_transform(training)

# + colab={"base_uri": "https://localhost:8080/", "height": 204} id="3mVEQwqdE2Jv" outputId="541ba517-4fcc-4821-c2ea-67fbdb0eb3e2"
# Se crea el nuevo dataframe de training con los datos procesados
new_training = pd.DataFrame(training_data, columns=columns_df)
new_training.head()

# + id="sUyJ49SDL7yK"
# Se dividen estos datos de entrenamiento en trainig y validation
X = new_training[columns_df[:6]]
y = new_training['target']

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.3)

# + [markdown] id="LuSw6f5j-2PQ"
# # **4. Selección y extracción de características**

# + colab={"base_uri": "https://localhost:8080/", "height": 499} id="JARoqAUzAEA8" outputId="c1937e26-2f8b-4404-aace-e1f0afe57ff1"
# Verificar la distribución de los datos mediante histogramas
X.hist(figsize=(10,8))
plt.show()

# + [markdown] id="_y1zLmPNf7PN"
# Inicialmente, se realizan histogramas para poder obsevar de mejor forma la distribucion de los datos en las variables escogidas. En algunas variables como 'exang' y 'ca' se puede ver una tendencia hacia cierto valores.

# + colab={"base_uri": "https://localhost:8080/", "height": 714} id="4Njrl20_MvDa" outputId="1005ba0b-c07a-42a8-c87e-7256ee3f9f87"
# Obtener los principales datos estadísiticos de cada variable mediante el diagrama boxplot
plt.figure(figsize=(13,12))
plt.subplot(3,2,1)
sns.boxplot(x=X['cp'])
plt.subplot(3,2,2)
sns.boxplot(x=X['thalach'], color='red')
plt.subplot(3,2,3)
sns.boxplot(x=X['exang'], color='green')
plt.subplot(3,2,4)
sns.boxplot(x=X['oldpeak'], color='yellow')
plt.subplot(3,2,5)
sns.boxplot(x=X['slope'], color='orange')
plt.subplot(3,2,6)
sns.boxplot(x=X['ca'], color='grey')
plt.show()

# + [markdown] id="0k9a2eSvhOTj"
# El diagrama de cajas y bigotes nos muestra algunos datos estadísticos relevantes, en donde se puede resaltar la escasez de datos extraordinarios o alejados del promedio en casi todas las variables, lo cual es un aspecto positivo al momento de elegir dichas variables.

# + colab={"base_uri": "https://localhost:8080/", "height": 269} id="WKVg3E0TSf03" outputId="48bef1f9-a387-4cab-857b-967daa6ded2a"
# Obtener la correlación entre las variables del dataset de training
sns.heatmap(X.corr(), annot=True)
plt.show()

# + [markdown] id="-JcpXcsoiE-v"
# Por último se puede apreciar una correlación entre variables como se había presentado anteriormente con todo el dataset. Esta gráfica comprueba que las variables escogidas representan las correlaciones más altas encontradas y que pueden aportar al rendimiento de los modelos a realizar.

# + [markdown] id="7O-FmnOBcvOb"
# #**5. Evaluación de modelos**

# + [markdown] id="TRyYTdsEeTfq"
# **Decision Tree**

# + id="9iWhbokRZI_5"
clf_DT = DecisionTreeClassifier()

# + colab={"base_uri": "https://localhost:8080/"} id="qPX86IRQemO8" outputId="422be3e1-9bd2-4787-bc10-319c72bf2e73"
# Se utilizan algunas métricas para evaluar el modelo)
accuracy = np.around(cross_val_score(clf_DT, X, y, cv=5), decimals=3)
recall = np.around(cross_val_score(clf_DT, X, y, cv=5, scoring='recall'), decimals=3)
f1 = np.around(cross_val_score(clf_DT, X, y, cv=5, scoring='f1'), decimals=3)

print(f'''Decision Tree Metrics\n
Accuracy:
array: {accuracy.tolist()}
mean: {round(np.mean(accuracy), 3)}
std: {round(np.std(accuracy), 3)}\n
Recall:
array: {recall.tolist()}
mean: {round(np.mean(recall), 3)}
std: {round(np.std(recall), 3)}\n
f1-score:
array: {f1.tolist()}
mean: {round(np.mean(f1), 3)}
std: {round(np.std(f1), 3)}''')

# + colab={"base_uri": "https://localhost:8080/"} id="EhZEFpyCp6tV" outputId="343e4fa7-3421-4d59-fb10-9864e8deda25"
# Se entrena el clasificador
clf_DT.fit(X_train, y_train)

# + id="pE8S2dErqlFz" colab={"base_uri": "https://localhost:8080/"} outputId="3feeebd7-c875-4fc6-cb8d-01c8582ab738"
# Se realiza la prediccion de validación
y_predict = clf_DT.predict(X_val)
recall_score(y_val, y_predict)

# + colab={"base_uri": "https://localhost:8080/", "height": 297} id="Xyxf1SaPs8Z-" outputId="051f9989-346d-4257-d887-25ae6d631bde"
# Se comparan los valores de y_val y y_predict
values = pd.DataFrame({'Actual': y_val, 'Predicted': y_predict})
values.head(8)

# + colab={"base_uri": "https://localhost:8080/", "height": 267} id="e8TQb1gt6vrg" outputId="8d30a012-e6c1-41bd-e248-87c36ef45418"
# Se implementa la matriz de confusión
cf_matrix = confusion_matrix(y_val, y_predict)
group_names = ['True Neg', 'False Pos', 'False Neg', 'True Pos']
group_counts = ['{0:0.0f}'.format(value) for value in cf_matrix.flatten()]
group_percentages = ['{0:.2%}'.format(value) for value in cf_matrix.flatten()/np.sum(cf_matrix)]
labels = [f'{v1}\n{v2}\n{v3}' for v1, v2, v3 in zip(group_names,group_counts,group_percentages)]
labels = np.asarray(labels).reshape(2,2)

sns.heatmap(cf_matrix, annot=labels, fmt='', cmap='Greens')
plt.show()

# + [markdown] id="Xg99Q-VBlJEB"
# **K-Nearest Neighbors**

# + id="Pvj3bSuwx1ce"
param_grid = [{'n_neighbors': [1, 5, 10, 20]}]

# + id="72VowfIhyDIw"
# Se realiza el ajuste de hiperparámetros
clf_KNN = KNeighborsClassifier()
gs = GridSearchCV(clf_KNN, param_grid)

# + colab={"base_uri": "https://localhost:8080/"} id="63vAiY7iyLnP" outputId="519936b4-4850-4178-b076-a95018271ab2"
gs.fit(X, y)

# + colab={"base_uri": "https://localhost:8080/"} id="RQFl6LuFyO6f" outputId="b8111ee0-78c3-49da-a97b-84370a16b578"
# Se consulta el mejor valor para el parámetro 'n_neighbors'
gs.best_params_

# + id="68UOvMHulJEJ"
clf_KNN = KNeighborsClassifier(n_neighbors=1)

# + colab={"base_uri": "https://localhost:8080/"} id="6K_LGrKElJEK" outputId="750252e4-5163-4d66-9fd9-c919b2342313"
# Se utilizan algunas métricas para evaluar el modelo)
accuracy = np.around(cross_val_score(clf_KNN, X, y, cv=5), decimals=3)
recall = np.around(cross_val_score(clf_KNN, X, y, cv=5, scoring='recall'), decimals=3)
f1 = np.around(cross_val_score(clf_KNN, X, y, cv=5, scoring='f1'), decimals=3)

print(f'''K-Neirest Neighbors Metrics\n
Accuracy:
array: {accuracy.tolist()}
mean: {round(np.mean(accuracy), 3)}
std: {round(np.std(accuracy), 3)}\n
Recall:
array: {recall.tolist()}
mean: {round(np.mean(recall), 3)}
std: {round(np.std(recall), 3)}\n
f1-score:
array: {f1.tolist()}
mean: {round(np.mean(f1), 3)}
std: {round(np.std(f1), 3)}''')

# + colab={"base_uri": "https://localhost:8080/"} id="2O17ujJGlJEK" outputId="61780b4d-8ef2-4b63-e693-c973a1fbe944"
# Se entrena el clasificador
clf_KNN.fit(X_train, y_train)

# + colab={"base_uri": "https://localhost:8080/"} id="XZkjiDaylJEL" outputId="aceae928-ac72-4420-b18b-d9dad5446d5d"
# Se realiza la prediccion de validación
y_predict = clf_KNN.predict(X_val)
recall_score(y_val, y_predict)

# + colab={"base_uri": "https://localhost:8080/", "height": 297} id="8KAoxLrulJEL" outputId="ad4b3c87-88d0-4ab0-e76b-fae799982ab9"
# Se comparan los valores de y_val y y_predict
values = pd.DataFrame({'Actual': y_val, 'Predicted': y_predict})
values.head(8)

# + colab={"base_uri": "https://localhost:8080/", "height": 267} id="UsWVWOgm6-8F" outputId="f416886d-6a3a-4d53-a73f-747265754e02"
# Se implementa la matriz de confusión
cf_matrix = confusion_matrix(y_val, y_predict)
group_names = ['True Neg', 'False Pos', 'False Neg', 'True Pos']
group_counts = ['{0:0.0f}'.format(value) for value in cf_matrix.flatten()]
group_percentages = ['{0:.2%}'.format(value) for value in cf_matrix.flatten()/np.sum(cf_matrix)]
labels = [f'{v1}\n{v2}\n{v3}' for v1, v2, v3 in zip(group_names,group_counts,group_percentages)]
labels = np.asarray(labels).reshape(2,2)

sns.heatmap(cf_matrix, annot=labels, fmt='', cmap='Greens')
plt.show()

# + [markdown] id="rNbnykxMkhPk"
# **Logistic Regression**

# + id="Fvb-eQ-2kefg"
clf_LR = LogisticRegression()

# + colab={"base_uri": "https://localhost:8080/"} id="pP8NFU3_kefo" outputId="ee19aa44-aef1-4d8e-8959-8958a3cd5f16"
# Se utilizan algunas métricas para evaluar el modelo)
accuracy = np.around(cross_val_score(clf_LR, X, y, cv=5), decimals=3)
recall = np.around(cross_val_score(clf_LR, X, y, cv=5, scoring='recall'), decimals=3)
f1 = np.around(cross_val_score(clf_LR, X, y, cv=5, scoring='f1'), decimals=3)

print(f'''Logistic Regression Metrics\n
Accuracy:
array: {accuracy.tolist()}
mean: {round(np.mean(accuracy), 3)}
std: {round(np.std(accuracy), 3)}\n
Recall:
array: {recall.tolist()}
mean: {round(np.mean(recall), 3)}
std: {round(np.std(recall), 3)}\n
f1-score:
array: {f1.tolist()}
mean: {round(np.mean(f1), 3)}
std: {round(np.std(f1), 3)}''')

# + colab={"base_uri": "https://localhost:8080/"} id="HcsLhQeFkefp" outputId="147ee5bc-dcee-4bd2-905f-d485f7d14c7f"
# Se entrena el clasificador
clf_LR.fit(X_train, y_train)

# + colab={"base_uri": "https://localhost:8080/"} id="dN1s5CFbkefq" outputId="eea9ac61-0b01-49ff-9fd2-29831feb9213"
# Se realiza la prediccion de validación
y_predict = clf_LR.predict(X_val)
recall_score(y_val, y_predict)

# + colab={"base_uri": "https://localhost:8080/", "height": 297} id="5J0kJ-Ngkefq" outputId="ea2c7058-4bde-4e42-b029-fe96755e814e"
# Se comparan los valores de y_val y y_predict
values = pd.DataFrame({'Actual': y_val, 'Predicted': y_predict})
values.head(8)

# + colab={"base_uri": "https://localhost:8080/", "height": 265} id="IVRDPwZB7A7C" outputId="c2c475bb-9b5b-4ddf-aa33-865d821d6ce0"
# Se implementa la matriz de confusión
cf_matrix = confusion_matrix(y_val, y_predict)
group_names = ['True Neg', 'False Pos', 'False Neg', 'True Pos']
group_counts = ['{0:0.0f}'.format(value) for value in cf_matrix.flatten()]
group_percentages = ['{0:.2%}'.format(value) for value in cf_matrix.flatten()/np.sum(cf_matrix)]
labels = [f'{v1}\n{v2}\n{v3}' for v1, v2, v3 in zip(group_names,group_counts,group_percentages)]
labels = np.asarray(labels).reshape(2,2)

sns.heatmap(cf_matrix, annot=labels, fmt='', cmap='Greens')
plt.show()

# + [markdown] id="Cg0oUODVmGCN"
# #**6. Evaluación final sobre dataset de test**

# + id="7l_MNW_dtMvu"
# Usar un pipeline para estandarizar el dataframe de test
pipe = Pipeline([('scaler', StandardScaler())])

# + id="8l18c5iytMvv"
# Agrupar todos los datos al aplicar el pipeline en el DataFrame de test, a excepción de la variable 'target'
ct = ColumnTransformer([('pipe', pipe, [0, 1, 2, 3, 4, 5])], remainder='passthrough')
test_data = ct.fit_transform(test)

# + colab={"base_uri": "https://localhost:8080/", "height": 204} id="pj-GLjmYtMvx" outputId="7b6fce5f-33e1-4ac1-d00b-0859e9105ee4"
# Se crea el nuevo dataframe de test con los datos procesados
new_test = pd.DataFrame(test_data, columns=columns_df)
new_test.head()

# + id="zhGV27ugrYJC"
# Se divide el dataset de test en X_test y y_test
X_test = new_test[columns_df[:6]]
y_test = new_test['target']


# + id="0zDKFDVNmMJU"
def clasificar(clf, X, umbral):
  
  """Función que determina si para un conjunto de muestras,
      cada muestra pertenece o no a la clase

  Args:
      clf: clasificador entrenado
      X: matriz de variables de entrada
      umbral: valor a tener en cuenta para determinar si una muestra es 
      de la clase 1 o no
      basado en las probabilidades retornadas por el clasificador.
  Returns:
      y: Devuelve un arreglo correspondiente a las clases encontradas para cada 
      una de las muestras

  """
  y_pred_proba = clf.predict_proba(X)
  return [0 if x[0] > umbral else 1 for x in y_pred_proba]



# + [markdown] id="bZXVLcTRrRJQ"
# **Decision Tree**

# + colab={"base_uri": "https://localhost:8080/"} id="TmrRSEOH4gV4" outputId="80d7de4c-f221-4b9e-dca7-9b2f182dddeb"
# Se realiza la predicción de y_test para evaluar el modelo mediant las métricas correspondientes
y_pred = clf_DT.predict(X_test)
print(f'''Accuracy: {accuracy_score(y_test, y_pred)}
Recall: {recall_score(y_test, y_pred)}
f1-score: {f1_score(y_test, y_pred)}''')

# + colab={"base_uri": "https://localhost:8080/", "height": 295} id="EmzWQtx8rBnd" outputId="e676b9e4-6315-4338-fe0c-22f636830e10"
# Se crea la curva Precision vs Recall
i = []; j = []

for k in range(1, 11):
  clasif = clasificar(clf_DT, X_test, k*0.1)
  i.append(recall_score(y_test, clasif))
  j.append(precision_score(y_test, clasif))

plt.plot(i, j)
plt.title('Precision vs Recall')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.show()

# + colab={"base_uri": "https://localhost:8080/", "height": 295} id="AyY5MOTlr3-9" outputId="6436fe68-6809-4aff-ed68-b8dd149f942c"
# Se crea la curva ROC (TPR vs FPR)
TPR = []
FPR = []

for k in range(0, 10):
  clasif = clasificar(clf_LR, X_test, k*0.1)
  TPR.append(recall_score(y_test, clasif))
  FPR.append(1 - recall_score(np.logical_not(y_test), np.logical_not(clasif)))

plt.plot(FPR, TPR)
plt.title('TPR vs FPR')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

# + [markdown] id="7tih56Yn2cyf"
# **K-Nearest Neighbors**

# + colab={"base_uri": "https://localhost:8080/"} id="zQ726fEU5tPY" outputId="6f68c308-60b6-4c12-80a2-c641a2540890"
# Se realiza la predicción de y_test para evaluar el modelo mediant las métricas correspondientes
y_pred = clf_KNN.predict(X_test)
print(f'''Accuracy: {accuracy_score(y_test, y_pred)}
Recall: {recall_score(y_test, y_pred)}
f1-score: {f1_score(y_test, y_pred)}''')

# + colab={"base_uri": "https://localhost:8080/", "height": 295} id="RjjupzdT2cyy" outputId="1be59f76-0593-43ef-b78f-b1dd6ecbb7bf"
# Se crea la curva Precision vs Recall
i = []; j = []

for k in range(1, 11):
  clasif = clasificar(clf_KNN, X_test, k*0.1)
  i.append(recall_score(y_test, clasif))
  j.append(precision_score(y_test, clasif))

plt.plot(i, j)
plt.title('Precision vs Recall')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.show()

# + colab={"base_uri": "https://localhost:8080/", "height": 295} id="tEFS2Pi72cyz" outputId="3022054c-73fc-441c-efc7-ba41b88ecb64"
# Se crea la curva ROC (TPR vs FPR)
TPR = []
FPR = []

for k in range(0, 10):
  clasif = clasificar(clf_KNN, X_test, k*0.1)
  TPR.append(recall_score(y_test, clasif))
  FPR.append(1 - recall_score(np.logical_not(y_test), np.logical_not(clasif)))

plt.plot(FPR, TPR)
plt.title('TPR vs FPR')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

# + [markdown] id="NsKwpXAO3khe"
# **Logistic Regression**

# + colab={"base_uri": "https://localhost:8080/"} id="t2dPgQ7u5yHm" outputId="0df9fd08-2125-49da-bec6-9b4c147ab2c3"
# Se realiza la predicción de y_test para evaluar el modelo mediant las métricas correspondientes
y_pred = clf_LR.predict(X_test)
print(f'''Accuracy: {accuracy_score(y_test, y_pred)}
Recall: {recall_score(y_test, y_pred)}
f1-score: {f1_score(y_test, y_pred)}''')

# + colab={"base_uri": "https://localhost:8080/", "height": 295} id="TFPfnkP73khg" outputId="623cbdc6-f339-4f49-a926-f4b0a19fa9ee"
# Se crea la curva Precision vs Recall
i = []; j = []

for k in range(1, 11):
  clasif = clasificar(clf_LR, X_test, k*0.1)
  i.append(recall_score(y_test, clasif))
  j.append(precision_score(y_test, clasif))

plt.plot(i, j)
plt.title('Precision vs Recall')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.show()

# + colab={"base_uri": "https://localhost:8080/", "height": 295} id="8gaYbs4o3khh" outputId="9d14ba6f-e847-496a-fe85-71457994bbee"
# Se crea la curva ROC (TPR vs FPR)
TPR = []
FPR = []

for k in range(0, 10):
  clasif = clasificar(clf_LR, X_test, k*0.1)
  TPR.append(recall_score(y_test, clasif))
  FPR.append(1 - recall_score(np.logical_not(y_test), np.logical_not(clasif)))

plt.plot(FPR, TPR)
plt.title('TPR vs FPR')
plt.xlabel('FPR')
plt.ylabel('TPR')
plt.show()

# + [markdown] id="-B2jDPbhiw84"
# ##**Análisis Final**
#
# * Teniendo en cuenta los algoritmos implementados, se puede concluir que al utilizar **Decision Tree** hubo un mayor rendimiento o resultados al realizar el entrenamiento del modelo, aunque es muy cercano al de **KNN**. Por otro lado, con la implementación del algoritmo **KNN** se logró un rendimiento más alto en la etapa de test con respecto a los demás algoritmos.
#
# * Al usar el algoritmo **Logistic Regression** se obtuvieron los datos más bajos, sin embargo superan el 80% por lo que se puede considerar como un buen modelo.
#
# * Con las variables escogidas se obtuvo el mayor rendimiento posible, esto debido a los valores de correlación que, aunque no sean tan altos en general, son los más altos en este dataset.
#
# * Al realizar la evaluación final sobre el dataset de test, las gráficas de curvas **ROC** y **Precision vs Recall** halladas para cada algoritmo presentan una tendencia ideal con respecto a los valores esperados, esto debido a los altos rendimientos en cada modelo como ya se ha mencionado anteriormente.

# + id="dpoDKnYs3MPS"


StarcoderdataJupyterScriptsDedupFiltered