Descubriendo el Poder de los Modelos de Clasificación en Machine Learning: Predicciones Precisas y Clasificaciones Sorprendentes
El problema de clasificación en Machine Learning permite predecir categorías a partir de datos, como identificar el tipo de materia prima (CD, DB, SBT, R) según características como porcentajes de Grado A, B, C y el peso total del lote. En este artículo, exploramos algoritmos clave como Regresión Logística, Máquina de soporte vectorial (SVM), Árboles de Decisión, Random Forest, Extreme gradient descent (XGBoost) y K-nearest neighborhood (KNN), con implementaciones en Python, manejo de datos desbalanceados y evaluación de métricas. ¡Acompáñanos en este viaje técnico! 🚀
Ilustración de clasificación de datos con Machine Learning, representando la asignación de categorías (Fuente: Propia).
El Problema de Clasificación de Materias Primas
El objetivo es clasificar lotes de materias primas en categorías (CD, DB, SBT, R) según características como:
- Porcentaje de libras en Grado A, B y C (calidad del material).
- Peso total del lote (en libras).
Este problema es común en industrias como la agricultura o la manufactura, donde identificar el tipo de materia prima optimiza procesos. Sin embargo, los datos suelen estar desbalanceados (e.g., más muestras de una categoría que de otras), lo que requiere técnicas específicas.
stratify=y en la división de datos para mantener proporciones.
Exploración de los Datos
Cargamos el dataset desde un archivo Excel ("PT.xlsx") y exploramos su estructura:
import pandas as pd
# Cargar los datos
dt = pd.read_excel("PT.xlsx")
# Mostrar las primeras filas
dt.head()
Vista previa del dataset con columnas de características y la variable objetivo 'MP' (Fuente: Propia).
Verificamos el desbalanceo de clases:
# Conteo de clases en la columna 'MP'
dt["MP"].value_counts()
Distribución de clases (CD, DB, SBT, R) mostrando desbalanceo (Fuente: Propia).
Preparación de los Datos
Codificación de la Variable Objetivo
La columna 'MP' (categorías CD, DB, SBT, R) se codifica numéricamente con LabelEncoder:
from sklearn.preprocessing import LabelEncoder
# Codificar la variable objetivo
label_encoder = LabelEncoder()
dt['MP_encoded'] = label_encoder.fit_transform(dt['MP'])
dt.drop(columns=['MP'], inplace=True)
print(dt)
División y Escalado de Datos
Dividimos los datos en entrenamiento (70%) y prueba (30%), usando stratify=y para mantener el balance de clases, y escalamos las características con StandardScaler:
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# Separar características (X) y variable objetivo (y)
X = dt.drop(['MP_encoded'], axis=1)
y = dt['MP_encoded']
# Dividir datos
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42)
# Escalar características
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
Algoritmos de Clasificación
Probamos cinco algoritmos: Regresión Logística, Máquina de Soporte Vectorial (SVM), Árboles de Decisión, Random Forest, XGBoost, y KNN. A continuación, una breve descripción y su implementación:
1. Regresión Logística
Es un tipo de análisis de clasificación utilizado para predecir el resultado de una variable categórica (una variable que puede adoptar un número limitado de categorías) en función de las variables independientes o predictoras. Es útil para modelar la probabilidad de un evento ocurriendo en función de otros factores. Bueno para problemas multiclase con datos balanceados.
Regresión Logística, mostrando predicciones por clase (Fuente: Propia).
2. Máquina de Soporte Vectorial (SVM)
Busca un hiperplano que maximiza el margen entre clases. Usa kernels (lineal, RBF) para datos no lineales.
SVM separando clases con un hiperplano óptimo (Fuente: Propia).
3. Árboles de Decisión
Divide los datos en ramas basadas en reglas aprendidas, ideal para interpretabilidad.
Estructura de un Árbol de Decisión, mostrando nodos y ramas (Fuente: Propia).
4. Random Forest
Combina múltiples árboles de decisión para mejorar robustez y precisión.
Random Forest combinando múltiples árboles para clasificación (Fuente: Analytics Vidhya).
5. XGBoost
Algoritmo de boosting que construye árboles secuencialmente, optimizando errores previos.
XGBoost mejorando predicciones con boosting secuencial (Fuente: GeeksforGeeks).
6. K-Nearest Neighbors (KNN)
Clasifica basándose en los k vecinos más cercanos según una métrica de distancia.
KNN clasificando un punto según sus vecinos más cercanos (Fuente: Propia).
Entrenamiento y Evaluación de Modelos
Definición de Modelos y Hiperparámetros
Entrenamos los modelos con GridSearchCV para optimizar hiperparámetros y usamos validación cruzada (5 folds):
from sklearn.linear_model import LogisticRegression
from sklearn import svm
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
import xgboost as xgb
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
# Lista de modelos
model_list = [
LogisticRegression(max_iter=1000),
svm.SVC(),
DecisionTreeClassifier(),
RandomForestClassifier(n_estimators=300),
xgb.XGBClassifier(),
KNeighborsClassifier()
]
# Diccionario de hiperparámetros
param_list = {
"Logreg": {'C': [0.001, 0.01, 0.1, 1, 10]},
"svm": {'kernel': ('linear', 'rbf'), 'C': [0.001, 0.01, 0.1, 1, 10]},
"Tree": {
'criterion': ['gini', 'entropy'],
'max_depth': [None, 5, 10, 15],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
},
"Forest": {
'n_estimators': [100, 200, 300],
'max_depth': [None, 5, 10],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 4]
},
"xgb": {
'learning_rate': [0.1, 0.01],
'max_depth': [3, 5, 7],
'n_estimators': [100, 200, 300]
},
"knn": {
'n_neighbors': [2, 3, 4, 5, 6, 7],
'weights': ['uniform', 'distance'],
'p': [1, 2]
}
}
Funciones de Evaluación
Definimos funciones para calcular métricas y graficar matrices de confusión:
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns
# Función para métricas
def metricas(y_test, y_pred):
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred, average='macro', zero_division=1)
recall = recall_score(y_test, y_pred, average='macro')
f1 = f1_score(y_test, y_pred, average='macro')
return accuracy, precision, recall, f1
# Función para validación cruzada
def val_cruz(model, param_grid, X_train, y_train, X_test):
grid_search = GridSearchCV(model, param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
pred = grid_search.predict(X_test)
best_params = grid_search.best_params_
return best_params, pred
# Función para evaluar todos los modelos
def eval_model(model_list, param_list, X_train, y_train, X_test, y_test):
model_results = []
for name, model, params in zip(param_list.keys(), model_list, param_list.values()):
best_params, pred = val_cruz(model, params, X_train, y_train, X_test)
acc, pre, re, f1 = metricas(y_test, pred)
model_results.append(pd.DataFrame({
"Name": [name],
"best_params": [best_params],
"predictions": [pred],
"accuracy": [acc],
"precision": [pre],
"recall": [re],
"f1_score": [f1]
}))
results = pd.concat(model_results, ignore_index=True)
return results
# Ejecutar evaluación
results = eval_model(model_list, param_list, X_train, y_train, X_test, y_test)
Métricas de Evaluación
Evaluamos los modelos con métricas clave:
- Precisión: Proporción de predicciones positivas correctas. Precision = TP / (TP + FP)
- Recall: Proporción de positivos reales detectados. Recall = TP / (TP + FN)
- F1-Score: Media armónica de precisión y recall. F1 = 2 * (Precision * Recall) / (Precision + Recall)
- Exactitud: Proporción de predicciones correctas. Accuracy = (TP + TN) / (TP + TN + FP + FN)
Donde TP = Verdaderos Positivos, TN = Verdaderos Negativos, FP = Falsos Positivos, FN = Falsos Negativos.
Resultados y Comparación
Ordenamos los modelos por su F1-Score:
# Ordenar resultados por F1-Score
r_sorted = results.sort_values("f1_score", ascending=False)
print(r_sorted[["Name", "accuracy", "precision", "recall", "f1_score"]])
Resultados de los algoritmos ordenados por F1-Score (Fuente: Propia).
Ejemplo de matriz de confusión para Regresión Logística:
# Graficar matriz de confusión
def grafica_cm(y_test, y_pred):
cm = confusion_matrix(y_test, y_pred)
fig, ax = plt.subplots()
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', ax=ax)
ax.set_xlabel('Etiqueta Predicha')
ax.set_ylabel('Etiqueta Real')
ax.set_title('Matriz de Confusión')
plt.show()
return cm
grafica_cm(y_test, results.loc[0, 'predictions'])
Resultado: KNN obtuvo el mejor F1-Score, destacándose en precisión y recall. Sin embargo, todos los algoritmos tienen fortalezas según el contexto.
results.to_excel("ML_results.xlsx").
Conclusión
La clasificación de materias primas con Machine Learning es un problema práctico con aplicaciones industriales. Algoritmos como KNN, Random Forest y XGBoost destacan por su rendimiento, pero la elección depende del dataset y los objetivos. Este artículo mostró cómo preparar datos, entrenar modelos y evaluar métricas en Python. ¡Prueba el código y optimiza tus propios problemas de clasificación! 🔍
¿Tienes un caso de uso para Machine Learning? ¡Déjanos un comentario y comparte tus resultados! 👇
Explora más sobre Machine Learning con estos libros recomendados en Amazon.
¡Únete a la Comunidad!
🔔 Suscríbete para más contenido sobre Machine Learning y Python.
📢 Comparte este artículo en LinkedIn.