Logo

Optimización de la Retención de Clientes en Entidades Financieras con Análisis Predictivo y Machine Learning

Este proyecto desarrolla una solución basada en machine learning para predecir el abandono de clientes (churn) en una entidad bancaria, proporcionando a la compañía una herramienta clave para la toma de decisiones estratégicas basadas en datos.

El análisis comienza con la evaluación de diferentes modelos supervisados en R (regresión logística, árbol de decisión y random forest), seleccionando la alternativa más precisa para identificar clientes en riesgo de abandono. Los resultados se integran en Power BI para facilitar su visualización y monitorización por parte de los equipos directivos.

Además, el uso de técnicas de interpretabilidad avanzada en Python mediante valores SHAP permite comprender el peso de cada variable en la predicción individual, aportando información valiosa para diseñar campañas de retención personalizadas y estrategias de marketing segmentado. Este enfoque integral mejora la capacidad de la organización para anticipar comportamientos críticos de sus clientes y optimizar sus acciones de fidelización.

Descarga y vista del Dashboard en Power BI

Captura Dashboard Power BI
Captura del dashboard final realizado en Power BI
Descargar archivo Power BI (.pbix)

Código en R: Comparación de Modelos de Aprendizaje Supervisados

Se comparan distintos modelos de aprendizaje supervisado utilizadondo R. Se probaron tres modelos: Regresión Logística, Árbol de Decisión y Random Forest, evaluando su precisión y capacidad predictiva. El modelo elegido finalmente fue Random Forest, que ofreció mejores resultados. El resultado de este modelo se exportó a un CSV (predicciones_rf.csv) para su análisis posterior en Power BI.

library(readr)
churn <- read_csv("churn.csv")
View(churn)

datos <- churn

# Análisis descriptivo de los datos
summary(datos)
str(datos)

# Cuántos y qué % de clientes se van del banco
table(datos$Exited)
prop.table(table(datos$Exited))

# Categóricas
datos$Gender <- as.factor(datos$Gender)
datos$Geography <- as.factor(datos$Geography)
datos$Exited <- as.factor(datos$Exited)

# Split 80/20
library("caTools")
division <- sample.split(datos$Exited, SplitRatio = 0.8)
entrenamiento <- subset(datos, division==TRUE)
test <- subset(datos, division==FALSE)

prop.table(table(datos$Exited))
prop.table(table(entrenamiento$Exited))
prop.table(table(test$Exited))

# Regresión Logística
reg_logistica <- glm(Exited ~ Age + Gender + Geography + CreditScore + Balance + NumOfProducts + IsActiveMember,
                     data = entrenamiento, family = "binomial")
summary(reg_logistica)
prediccionmodelo <- predict(reg_logistica, newdata = test, type = "response")
prediccionmodelocod <- ifelse(prediccionmodelo > 0.5, 1, 0)
library(caret)
confusionMatrix(as.factor(prediccionmodelocod), as.factor(test$Exited))

# Árbol de decisión
library(rpart)
library(rpart.plot)
modelo_arbol <- rpart(Exited ~ Age + Gender + Geography + CreditScore + Balance + NumOfProducts + IsActiveMember,
                     data = entrenamiento, method = "class")
summary(modelo_arbol)
rpart.plot(modelo_arbol)
prediccionarbol <- predict(modelo_arbol, newdata = test, type = "class")
confusionMatrix(as.factor(test$Exited), as.factor(prediccionarbol))

# Random Forest
library(randomForest)
set.seed(123)
modelo_rf <- randomForest(Exited ~ Age + Gender + Geography + CreditScore + Balance + NumOfProducts + IsActiveMember,
                          data = entrenamiento, ntree = 500, mtry = 3, importance = TRUE)
print(modelo_rf)
prediccion_rf <- predict(modelo_rf, newdata = test)
confusionMatrix(as.factor(prediccion_rf), as.factor(test$Exited))
varImpPlot(modelo_rf)

# Exportar resultados para Power BI
datos$Predicted_Exited <- predict(modelo_rf, newdata = datos)
write.csv(datos, "predicciones_rf.csv", row.names = FALSE)

Código en Python: SHAP Values individualizados

En este bloque se muestra el código principal en Python utilizado para entrenar el modelo de Random Forest, analizar la importancia de las variables y aplicar técnicas de interpretabilidad mediante SHAP values. Este análisis permite comprender tanto el funcionamiento interno del modelo como el impacto de cada variable en la predicción individual de cada cliente.

# Instalación de librerías (en Google Colab)
!pip install shap

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
import shap

# Cargar los datos
data = pd.read_csv("churn.csv")
train, test = train_test_split(data, test_size=0.3, random_state=0, stratify=data['Exited'])

# Eliminación de columnas innecesarias
train = train.drop(['RowNumber', 'Surname', 'CustomerId'], axis=1)
test = test.drop(['RowNumber', 'Surname', 'CustomerId'], axis=1)

# Conversión de variables categóricas
train_processed = pd.get_dummies(train)
test_processed = pd.get_dummies(test)

# Rellenar valores nulos
train_processed = train_processed.fillna(train_processed.mean(numeric_only=True))
test_processed = test_processed.fillna(test_processed.mean(numeric_only=True))
test_processed = test_processed[train_processed.columns]

# Crear matrices de entrenamiento y test
X_train = train_processed.drop(['Exited'], axis=1)
Y_train = train_processed['Exited']
X_test = test_processed.drop(['Exited'], axis=1)
Y_test = test_processed['Exited']

# Entrenar modelo Random Forest
random_forest = RandomForestClassifier(n_estimators=100)
random_forest.fit(X_train, Y_train)
random_forest_preds = random_forest.predict(X_test)
print('The accuracy of the Random Forests model is :', metrics.accuracy_score(random_forest_preds, Y_test))

# Interpretabilidad con SHAP
explainer = shap.TreeExplainer(random_forest)

# Ejemplo de predicción e interpretación
choosen_instance = X_test.loc[2739]
shap_values = explainer.shap_values(choosen_instance)

shap.initjs()
shap.force_plot(explainer.expected_value[1], shap_values[1], choosen_instance)
    

Visualizaciones SHAP Values Individuales

SHAP Force Plot Cliente 1
Contribución de variables al resultado para el Cliente 230.
Se observa cómo cada característica influye en la predicción individual de churn.
SHAP Force Plot Cliente 2
Interpretación de la predicción del modelo para el Cliente 22.
Las variables en rojo contribuyen a aumentar la probabilidad de churn, y las azules a disminuirla.
SHAP Force Plot Cliente 3
Análisis individualizado de la decisión del modelo para el Cliente 7156.
Permite identificar los factores más determinantes en el resultado.
SHAP Force Plot Cliente 4
Visualización SHAP para el Cliente 1302.
Se aprecian las principales variables responsables de la clasificación del cliente.
SHAP Force Plot Cliente 5
Predicción explicada para el Cliente 2739.
El gráfico muestra el impacto de cada feature en la decisión final del modelo.
← Volver al inicio