Aplicar TODO lo aprendido en un proyecto integrador realista: desde la carga de datos crudos hasta un modelo evaluado con métricas de negocio, incluyendo preprocesamiento, codificación, escalado, selección de características y validación robusta.
transacciones_fraude.csvCaracterísticas simuladas:
monto_transaccion (float)edad_cliente (int)tipo_tarjeta (categórica: "Visa", "Mastercard", "Amex")pais_origen (categórica)hora_del_dia (int 0-23)dias_desde_ultima_transaccion (int)es_fraude (bool: 0 o 1) → ¡solo 1.5% de fraude!# Cargar y explorar
df = pd.read_csv("transacciones_fraude.csv")
print(df.info())
print(df.isnull().sum())
# Imputar edad con mediana, tipo de tarjeta con moda
df['edad_cliente'].fillna(df['edad_cliente'].median(), inplace=True)
df['tipo_tarjeta'].fillna(df['tipo_tarjeta'].mode()[0], inplace=True)
# Limitar monto de transacción usando IQR
Q1 = df['monto_transaccion'].quantile(0.25)
Q3 = df['monto_transaccion'].quantile(0.75)
IQR = Q3 - Q1
lim_inf, lim_sup = Q1 - 1.5*IQR, Q3 + 1.5*IQR
df['monto_transaccion'] = df['monto_transaccion'].clip(lim_inf, lim_sup)
# Codificación
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.compose import ColumnTransformer
# Codificación de Etiquetas para variables ordinales (ninguna aquí, pero por si acaso)
# One-Hot para variables categóricas nominales
categorical_features = ['tipo_tarjeta', 'pais_origen']
numeric_features = ['monto_transaccion', 'edad_cliente', 'hora_del_dia', 'dias_desde_ultima_transaccion']
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(drop='first', handle_unknown='ignore'), categorical_features)
])
X = df.drop('es_fraude', axis=1)
y = df['es_fraude']
X_processed = preprocessor.fit_transform(X)
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.model_selection import train_test_split, StratifiedKFold
from sklearn.linear_model import LogisticRegression
# Dividir datos
X_train, X_test, y_train, y_test = train_test_split(X_processed, y, test_size=0.2, stratify=y, random_state=42)
# Selección de características
selector = SelectKBest(score_func=f_classif, k=10)
X_train_selected = selector.fit_transform(X_train, y_train)
X_test_selected = selector.transform(X_test)
# Entrenar modelo
modelo = LogisticRegression(penalty='l2', C=1.0, random_state=42)
modelo.fit(X_train_selected, y_train)
from sklearn.metrics import classification_report, roc_auc_score, confusion_matrix
import seaborn as sns
y_pred = modelo.predict(X_test_selected)
y_proba = modelo.predict_proba(X_test_selected)[:,1]
print("=== REPORTE DE CLASIFICACIÓN ===")
print(classification_report(y_test, y_pred, target_names=['Legítimo', 'Fraude']))
print(f"\nAUC-ROC: {roc_auc_score(y_test, y_proba):.4f}")
# Matriz de confusión
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['Legítimo', 'Fraude'],
yticklabels=['Legítimo', 'Fraude'])
plt.title("Matriz de Confusión - Detección de Fraude")
plt.ylabel("Real")
plt.xlabel("Predicho")
plt.show()
# Validación cruzada para confianza
cv_scores = cross_val_score(modelo, X_train_selected, y_train, cv=StratifiedKFold(5), scoring='roc_auc')
print(f"\nValidación Cruzada AUC-ROC: {cv_scores.mean():.4f} (+/- {cv_scores.std()*2:.4f})")
from sklearn.metrics import precision_recall_curve
# Encontrar umbral que maximice F1 o exhaustividad
precision, recall, thresholds = precision_recall_curve(y_test, y_proba)
# Calcular F1 para cada umbral
f1_scores = 2 * (precision * recall) / (precision + recall)
best_threshold = thresholds[np.argmax(f1_scores)]
print(f"Mejor umbral para F1: {best_threshold:.3f}")
# Predecir con nuevo umbral
y_pred_new = (y_proba >= best_threshold).astype(int)
print("\n=== CON UMBRAL AJUSTADO ===")
print(classification_report(y_test, y_pred_new, target_names=['Legítimo', 'Fraude']))
✅ El preprocesamiento no es un mal necesario—es tu superpoder.
✅ Nunca confíes en la precisión en problemas desbalanceados. Usa AUC-ROC, Exhaustividad, F1.
✅ La validación cruzada estratificada es tu aliada para construir modelos robustos.
✅ Documenta cada paso. Tu yo futuro (y tu equipo) te lo agradecerán.
✅ En producción, monitorea no solo la precisión, sino la distribución de tus datos. ¡Puede cambiar con el tiempo!