En esta, la tercera entrada de la serie de “AI y Donaciones” vamos a ponernos prácticos. La idea será generar un entorno en el cual nuestro equipo de fundraising pueda aprovechar el modelo que ya entrenamos, para evaluar una serie de casos individuales (tanto para scoring cómo para remarketing) sin tener que escribir una sola línea de código.
NOTA IMPORTANTE: esta es otra guía paso a paso, con lo cual no requiere conocimientos especiales.
Un poco de contexto
En este posteo vamos a usar los mismos datos que usamos en la entrada anterior:
Pero esta vez vamos a crear un pipeline (vamos a empaquetar todo el modelo) y le vamos a dar al usuario de la aplicación la posibilidad de ingresar nuevos datos de uno en uno y recibir un predicción que lo ayudará a tomar decisiones sobre como procesar ese posible donante.
Creando la “tubería”
En el contexto de Machine Learning, un pipeline se refiere a una serie de pasos o etapas ordenadas que se siguen para realizar una tarea específica. Es como una línea de ensamblaje donde cada paso realiza una función particular y el resultado se pasa al siguiente paso.
Estos son los pasos que suele incluir:
- Adquisición de datos: Obtención de datos relevantes para el problema que estás abordando.
- Preprocesamiento de datos: Limpieza y organización de los datos para que sean adecuados para el modelo.
- Selección de características: Si es necesario, elegir las características más relevantes o importantes para el modelo.
- Entrenamiento del modelo: Usar los datos para enseñar al modelo a realizar la tarea específica.
- Evaluación del modelo: Comprobar qué tan bien el modelo realiza la tarea utilizando datos que no ha visto antes.
- Predicciones: Utilizar el modelo entrenado para realizar predicciones o tomar decisiones en nuevos datos.
Esta vez vamos a trabajar con una parte del set de datos con los columnas que ya sabemos son relevantes para que nuestro modelo pueda realizar predicciones (descargarlo aquí). Este dataset tendra unos 10.000 registros y poseera nuestra columna target (si fue donante o no). El resto de los datos los guardaremos para hacer las pruebas individuales.
Partiendo como base el código de nuestro modelo entrenado (recordemos que aquí estamos trabajando en un notebook de Jupiter), el código necesario para construir el pipeline, evaluar el modelo y descargarlo es:
import pandas as pd
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from imblearn.pipeline import Pipeline
import joblib
# Carga tu conjunto de datos
data = pd.read_csv("datos_limpios-preprocesados-set-fundrasing-prueba-pipe.csv")
# Preprocesamiento de Datos
X = data.drop('DONOR_IND', axis=1)
y = data['DONOR_IND']
# Codifica 'DONOR_IND' como 0 y 1
y = y.map({'N': 0, 'Y': 1})
# Aplica codificación one-hot a las variables categóricas usando get_dummies
X = pd.get_dummies(X, columns=['GENDER', 'DEGREE_LEVEL', 'EMAIL_PRESENT_IND'], drop_first=True)
# Divide los datos en conjuntos de entrenamiento y prueba antes de aplicar SMOTE
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Construye el pipeline con RandomForest y SMOTE
pipeline = Pipeline([
('smote', SMOTE()),
('random_forest', RandomForestClassifier(
n_estimators=800,
min_samples_split=10,
min_samples_leaf=4,
max_depth=30,
random_state=42
))
])
# Entrenamiento del modelo usando el pipeline
pipeline.fit(X_train, y_train)
# Predicciones en el conjunto de prueba
y_pred = pipeline.predict(X_test)
# Evaluación del modelo
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
class_report = classification_report(y_test, y_pred)
print(f'Accuracy: {accuracy}')
print(f'Confusion Matrix:\n{conf_matrix}')
print(f'Classification Report:\n{class_report}')
# Ruta donde deseas guardar el archivo del pipeline
pipeline_filename = 'random_forest_pipeline.joblib'
# Guarda el pipeline usando joblib
joblib.dump(pipeline, pipeline_filename)
Ahora que ya tenemos nuestro modelo empaquetado, podemos llamarlo para hacer las pruebas con otros datos.
Una “App” para predecir donaciones
Lo que vamos a hacer ahora es generar un programa con Python, con una función para que un usuario pueda interactuar con nuestro modelo cargando los datos de los casos individuales, tal cual los puede tener en un CRM o planilla.
Recordemos que los valores que tomamos para evaluar cada caso son: ZIPCODE, AGE, GENDER, DEGREE_LEVEL, EMAIL_PRESENT_IND. Por lo cual nuestro set de datos no visto va tener solo esos valores (lo pueden descargar aquí).
El código:
import pandas as pd
from imblearn.pipeline import Pipeline
import joblib
# Carga el pipeline guardado
pipeline_filename = 'random_forest_pipeline.joblib'
loaded_pipeline = joblib.load(pipeline_filename)
# Función para obtener la entrada del usuario y realizar predicciones
def predecir_usuario():
while True: # Bucle infinito hasta que el usuario decida detenerse
# Define los nombres de las columnas
columnas = ['ZIPCODE', 'AGE', 'GENDER', 'DEGREE_LEVEL', 'EMAIL_PRESENT_IND']
# Crea un diccionario vacío para almacenar los datos del usuario
datos_usuario = {}
# Pide al usuario que ingrese los datos uno a uno
for columna in columnas:
print(f"Por favor, ingrese su {columna}:")
dato = input()
datos_usuario[columna] = dato
# Convierte el diccionario en un DataFrame de pandas
df = pd.DataFrame([datos_usuario])
# Define las columnas categóricas
columnas_categoricas = ['GENDER', 'DEGREE_LEVEL', 'EMAIL_PRESENT_IND']
# Usa get_dummies para codificar solo las columnas categóricas
for columna in columnas_categoricas:
df = pd.concat([df.drop(columna, axis=1), pd.get_dummies(df[columna], prefix=columna)], axis=1)
# Reorganizar las columnas para que coincidan con el orden durante el entrenamiento
feature_names = loaded_pipeline.named_steps['random_forest'].feature_names_in_
df = df.reindex(columns=feature_names, fill_value=0)
# Realizar la predicción
prediccion = loaded_pipeline.predict(df)
# Mostrar la predicción al usuario
print(f"La predicción es: {prediccion[0]}")
# Preguntar al usuario si desea continuar
continuar = input("¿Desea ingresar nuevos datos? (s/n): ")
if continuar.lower() != 's':
break # Salir del bucle si el usuario no desea continuar
# Llamar a la función para probar
predecir_usuario()
Lo que estamos haciendo es:
- Cargar el pipeline que contiene nuestro modelo probado,
- Pedirle al usuario que ingrese los datos de un caso no visto,
- Procesar las variables categóricas para transformarlas en números de tal manera que el modelo los pueda procesar,
- Hacer la predicción del caso,
- Preguntarle al usuario si quiere ingresar más datos, o no.
Si todo sale bien, después de correr el modelo, tenemos que encontrarnos con el siguiente pedido:
Una vez que cargamos el dato y damos enter, el sistema nos pedirá el resto de los datos, hasta que lleguemos a la predicción:
En el ejemplo cargamos dos casos de nuestro archivo, uno con resultado negativo (0) y uno con resultado positivo (1). Siguiendo el ejemplo, podríamos poner el lista prioritaria de seguimiento el segundo caso (llamados/whatsapp) mientras que el primer caso quedaría en una lista “normal” de seguimiento (email).
Lo mismo, pero en COLAB
Como en las entradas anteriores, si no queremos preocuparnos de las instalaciones y las librerías, cualquier usuario de Google puede usar Colab como entorno de Python y Machine Learning.
Y es la manera más fácil de hacer correr nuestra aplicación y que la pueda usar el equipo de recaudación de fondos de nuestra organización.
Acá pueden encontrar el entorno para generar el pipeline.
Aquí pueden encontrar el entorno de la App en cuestión. Solo deben copiarlo y ¡usarlo! Recuerden ajustar la ruta según sus carpetas de drive.
Conclusión
En este recorrido desde ‘De Datos a Donaciones’, hemos explorado un nuevo terreno donde los algoritmos y la filantropía convergen. La implementación de una aplicación en python, respaldada por un modelo predictivo, ofrece a tu equipo de recaudación de fondos una herramienta valiosa.
Este proceso, basado en datos de donaciones pasadas, no solo es una herramienta práctica, sino también un reflejo del compromiso continuo con la innovación y la mejora en la estrategias de fundraising.