Fernando Chavez Caracas
Ricardo Alanis
Felipe Sebastián Zepeda González
Ricardo Alanis
Julián Cárdenas
Angelo Augusto Gallici Aquino
Angelo Augusto Gallici Aquino
Antonio Demarco Bonino
Rodrigo Martinez
Diego Alexander Chero Olazabal
Lo mejor que pude optimizar el modelo fue con los siguientes parametros:
logreg_model = LogisticRegression(penalty='l1', solver='liblinear', random_state=42, C=0.01)
Me dio las siguientes métricas:
Accuracy: 0.8105 Precision: 0.7692307692307693 Recall: 0.05089058524173028 ROC AUC: 0.5235784600135223
Yo creo que la regresión logística no es el modelo más eficiente en este caso en específico.
Gracias por compartir!
Recomiendo hacer un OneHot Encoding y un MinMax Scaling.
# Importamos las librerías necesarias from sklearn.preprocessing import OneHotEncoder from sklearn.compose import make_column_transformer from sklearn.preprocessing import MinMaxScaler # Copiamos el dataset original data_df=data.copy() # Separamos la variable de respuesta de los datos que tenemos disponibles y = data_df.pop(data_df.columns[-1]) # Realizamos edl OneHotEncoder sobre las variables categóricas categorical_columns = data_df.select_dtypes(object).columns categorical_transformer = make_column_transformer( (OneHotEncoder(), categorical_columns), remainder="passthrough" ) transformed_df = ( pd.DataFrame( categorical_transformer.fit_transform(data_df), columns = categorical_transformer.get_feature_names_out(), index = data_df.index ) .rename_columns( function = lambda x: x.removeprefix("ordinalencoder__") ) .rename_columns( function = lambda x: x.removeprefix("onehotencoder__") ) .rename_columns( function = lambda x: x.removeprefix("remainder__") ) ) # Realizamos el MinMaxScaler para normalizar los datos scaler=MinMaxScaler() df_scaled=scaler.fit_transform(transformed_df) df_scaled=pd.DataFrame(df_scaled,columns=transformed_df.columns) df_scaled.head()
Una vez resuelto aquello, implementé una red neuronal sobre el modelo original. Usé esta arquitectura:
Y los resultados fueron los siguientes: 'accuracy': 0.858, 'precision': 0.6981818181818182, 'recall': 0.48854961832061067, 'f1score': 0.5748502994011976.
Creo que podría encontrarse una mejor arquitectura y/o enriquecer más los datos. Cualquier comentario se agradece.
Gracias por compartir!
Wow que bueen aporte!
Bueno el primer cambio que implemente es crear una nueva columna de tipo binaria con 1 o 0 para saber si una persona tenia balance cero o no, esto debido que al graficar dichos datos previamente, habia una gran cantidad de personas con balance cero.# Eliminar las filas que contienen valores nulosdata_cleaned = data.dropna()# Aplicar One Hot Encodingdata_encoded = pd.get_dummies(data, drop_first=True)# Vamos a crear un modelo de regresion logisticafrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import LogisticRegression # Convertir las columnas booleanas a 1 y 0data_encoded = data_encoded.astype(int) # Verificar cuántas filas y columnas quedan después de la limpiezaprint(data_cleaned.shape)
# Crear una nueva columna que indica si el cliente tiene saldo o no data['HasBalance'] = (data['Balance'] > 0).astype(int) # Mostrar la nueva columna para verificar print(data[['Balance', 'HasBalance']].head()) ```Luego elimine filas con valores nulos ```js # Eliminar las filas que contienen valores nulos data_cleaned = data.dropna() # Verificar cuántas filas y columnas quedan después de la limpieza print(data_cleaned.shape)
Siguiente a esto hice un One hot encoding
# Aplicar One Hot Encoding data_encoded = pd.get_dummies(data, drop_first=True) # Convertir las columnas booleanas a 1 y 0 data_encoded = data_encoded.astype(int) ```Viene la parte de crear el modelo y aca utilize XgeBoost como variante de arboles de decision ```js # Vamos a crear un modelo de regresion logistica from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression # Generar los datos para poder separar la variable de respuesta de los datos que tenemos disponibles X = data_encoded.copy() # Usamos los datos procesados (con One Hot Encoding) y = X.pop('Exited') # Extraemos la columna 'Exited' como variable objetivo # Separar los datos en datos de entrenamiento y testing X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.33, random_state=42) import xgboost as xgb from sklearn.metrics import confusion_matrix, classification_report # Crear el modelo de XGBoost clf_xgb = xgb.XGBClassifier(random_state=0, n_estimators=100, learning_rate=0.05, scale_pos_weight=2) # Entrenar el modelo clf_xgb.fit(X_train, y_train) # Predecir y_pred = clf_xgb.predict(X_test) # Evaluar print(confusion_matrix(y_test, y_pred)) print(classification_report(y_test, y_pred)) ```El resultado obtenido es el siguiente 
[[2436 221] [ 248 395]] precision recall f1-score support
0 0.91 0.92 0.91 2657 1 0.64 0.61 0.63 643
accuracy 0.86 3300 macro avg 0.77 0.77 0.77 3300 weighted avg 0.86 0.86 0.86 3300
Estos son mis números del modelo:
Hice un poco de trampa y ocupe autosklearn para tener un clasificador base y poder seguir mejorandolo o con mas datos porque estan desbalanceados o cambiarlo por una arquitectura de red neuronal. Ahora obtuve los siguientes metricas con mi ensamble de metodos:
Teniendo en cuenta que la variable target se encuentra desbalanceada, procedi a una SMOTEEN de imblearm para balancear los datos submuestreando la clase dominante y sobremuestreando la clase minoritaria. Luego procedi a realizar una validacion de estos nuevos datos para verificar que los datos sobremuestreados sean representativos de mi data original. Para ello use graficas de distribucion en todas mis variables. Una veza comprobado esto procedi a probar con algunos modelos como RandomForestClassifeer, XGBoost y ExtreTree. Realice varios entrenamientos usando la data original y la data balanceada para los modelos que usea, y ya que no se pueden contrastar usando la metrica de acuracy como referencia pues algunos modelos presentan una cantidad de datos de testeo diferentes por el sobremuestreo, opte por una la metria de AUC_ROC y AUC_PR para medir la adpatbilidad de mis modelos a nuevos datos. Teniendo los siguientes resultados: