Menu
CoddyTech

Hoja de Trucos de scikit-learn (sklearn)

Última actualización

Cargar y dividir los datos

Aparta un conjunto de test antes que nada y no lo mires hasta el final.

TareaCódigo
Importar el divisorfrom sklearn.model_selection import train_test_split
Features y target desde un DataFrameX = df.drop(columns="target") y = df["target"]
Dataset integrado como pandasfrom sklearn.datasets import load_iris X, y = load_iris(return_X_y=True, as_frame=True)
Datos sintéticos para experimentarfrom sklearn.datasets import make_classification X, y = make_classification(n_samples=500, n_features=8, random_state=0)
División 80/20 en train y testX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Mantener la proporción de clases en ambas partestrain_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
Train, validación y test (60/20/20)X_tmp, X_test, y_tmp, y_test = train_test_split(X, y, test_size=0.2, random_state=0) X_train, X_val, y_train, y_val = train_test_split(X_tmp, y_tmp, test_size=0.25, random_state=0)

Preprocesar las features

Ajusta un transformador solo con los datos de entrenamiento y luego transforma ambos conjuntos. Ajustarlo con los datos de test filtra información.

TareaCódigo
Importsfrom sklearn.preprocessing import StandardScaler, MinMaxScaler, OneHotEncoder, OrdinalEncoder
Escalar a media 0 y desviación estándar 1scaler = StandardScaler() X_train_s = scaler.fit_transform(X_train[["age", "income"]]) X_test_s = scaler.transform(X_test[["age", "income"]])
Escalar al rango de 0 a 1MinMaxScaler().fit_transform(X_train[["age", "income"]])
One-hot encoding de categoríasenc = OneHotEncoder(handle_unknown="ignore", sparse_output=False) enc.fit_transform(X_train[["city"]])
Codificar categorías ordenadas como númerosOrdinalEncoder(categories=[["low", "mid", "high"]]).fit_transform([["mid"], ["high"]])
Rellenar valores faltantesfrom sklearn.impute import SimpleImputer SimpleImputer(strategy="median").fit_transform(X_train[["age", "income"]])
Features polinómicas y de interacciónfrom sklearn.preprocessing import PolynomialFeatures PolynomialFeatures(degree=2, include_bias=False).fit_transform(X_train[["age", "income"]])
Obtener DataFrames en vez de arraysscaler.set_output(transform="pandas")
Etiquetas de texto a enterosfrom sklearn.preprocessing import LabelEncoder LabelEncoder().fit_transform(["cat", "dog", "cat"])

Elegir un modelo

Empieza por lo simple y usa el modelo simple como la puntuación a superar.

ProblemaEmpieza conDespués prueba
Predecir un número (regresión)LinearRegression(), Ridge(alpha=1.0)RandomForestRegressor(), HistGradientBoostingRegressor()
Predecir una clase (clasificación)LogisticRegression(max_iter=1000)RandomForestClassifier(), HistGradientBoostingClassifier()
Pocos datos, puntos parecidos comparten etiquetaKNeighborsClassifier(n_neighbors=5)SVC(kernel="rbf")
Reglas que puedes leerDecisionTreeClassifier(max_depth=3)RandomForestClassifier()
Agrupar filas sin etiquetasKMeans(n_clusters=3)DBSCAN(eps=0.5)
Menos features para gráficos o velocidadPCA(n_components=2)TSNE(n_components=2)
Detectar filas inusualesIsolationForest(random_state=0)LocalOutlierFactor()

Entrenar un modelo

Todos los estimadores siguen el mismo patrón: créalo con su configuración y luego llama a fit.

TareaCódigo
El patrón para cualquier modelomodel = LogisticRegression(max_iter=1000) model.fit(X_train, y_train)
Regresión linealfrom sklearn.linear_model import LinearRegression LinearRegression()
Regresión lineal regularizadafrom sklearn.linear_model import Ridge, Lasso Ridge(alpha=1.0), Lasso(alpha=0.1)
Regresión logística (clasificación)from sklearn.linear_model import LogisticRegression LogisticRegression(C=1.0, max_iter=1000)
k vecinos más cercanosfrom sklearn.neighbors import KNeighborsClassifier KNeighborsClassifier(n_neighbors=5)
Árbol de decisiónfrom sklearn.tree import DecisionTreeClassifier DecisionTreeClassifier(max_depth=3, random_state=0)
Random forestfrom sklearn.ensemble import RandomForestClassifier RandomForestClassifier(n_estimators=200, random_state=0)
Gradient boosting, rápido con muchos datosfrom sklearn.ensemble import HistGradientBoostingClassifier HistGradientBoostingClassifier(random_state=0)
Máquina de vectores de soportefrom sklearn.svm import SVC SVC(kernel="rbf", C=1.0)
Naive Bayesfrom sklearn.naive_bayes import GaussianNB GaussianNB()
Baseline que siempre predice la clase mayoritariafrom sklearn.dummy import DummyClassifier DummyClassifier(strategy="most_frequent")

Predecir e inspeccionar

TareaCódigo
Predecir clases o valoresy_pred = model.predict(X_test)
Probabilidad de la clase positivamodel.predict_proba(X_test)[:, 1]
Puntuación rápida: accuracy o R²model.score(X_test, y_test)
Coeficientes de un modelo linealmodel.coef_, model.intercept_
Importancia de features de un modelo de árbolpd.Series(forest.feature_importances_, index=X_train.columns).sort_values()
Importancia barajando cada featurefrom sklearn.inspection import permutation_importance permutation_importance(model, X_test, y_test, random_state=0).importances_mean
Etiquetas de clase que conoce el modelomodel.classes_
Leer y cambiar la configuraciónmodel.get_params(), model.set_params(C=0.5)
Dibujar un árbol de decisiónfrom sklearn.tree import plot_tree plot_tree(tree, filled=True, feature_names=list(X_train.columns))

Métricas de clasificación

La accuracy por sí sola esconde los errores en una clase poco frecuente. Revisa también la precisión, el recall y la matriz de confusión.

TareaCódigo
Importsfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
Accuracyaccuracy_score(y_test, y_pred)
Precisión, recall y F1precision_score(y_test, y_pred), recall_score(y_test, y_pred), f1_score(y_test, y_pred)
F1 para varias clasesf1_score(y_test, y_pred, average="macro")
Todas las métricas por clasefrom sklearn.metrics import classification_report print(classification_report(y_test, y_pred))
Matriz de confusiónfrom sklearn.metrics import confusion_matrix confusion_matrix(y_test, y_pred)
Graficar la matriz de confusiónfrom sklearn.metrics import ConfusionMatrixDisplay ConfusionMatrixDisplay.from_estimator(model, X_test, y_test)
ROC AUC a partir de probabilidadesfrom sklearn.metrics import roc_auc_score roc_auc_score(y_test, model.predict_proba(X_test)[:, 1])
Graficar la curva ROCfrom sklearn.metrics import RocCurveDisplay RocCurveDisplay.from_estimator(model, X_test, y_test)
Accuracy para clases desbalanceadasfrom sklearn.metrics import balanced_accuracy_score balanced_accuracy_score(y_test, y_pred)
Tu propio umbral de decisióny_pred = (model.predict_proba(X_test)[:, 1] >= 0.3).astype(int)

Métricas de regresión

Las métricas de error están en las unidades del target (cuanto más bajas, mejor). R² es la proporción de varianza explicada (1 es perfecto).

TareaCódigo
Importsfrom sklearn.metrics import mean_absolute_error, mean_squared_error, root_mean_squared_error, r2_score
Error absoluto mediomean_absolute_error(y_test, y_pred)
Error cuadrático medio y su raízmean_squared_error(y_test, y_pred), root_mean_squared_error(y_test, y_pred)
Puntuación R²r2_score(y_test, y_pred)
Error porcentual absoluto mediofrom sklearn.metrics import mean_absolute_percentage_error mean_absolute_percentage_error(y_test, y_pred)
Graficar predicho frente a realfrom sklearn.metrics import PredictionErrorDisplay PredictionErrorDisplay.from_predictions(y_test, y_pred, kind="actual_vs_predicted")

Pipelines

Un pipeline encadena el preprocesado y un modelo en un solo estimador, así que la validación cruzada y el grid search ajustan cada paso solo con los folds de entrenamiento.

TareaCódigo
Importsfrom sklearn.pipeline import make_pipeline, Pipeline
Escalar y luego entrenar un modelopipe = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000)) pipe.fit(X_train, y_train)
Pasos con tus propios nombrespipe = Pipeline([("scale", StandardScaler()), ("model", LogisticRegression(max_iter=1000))])
Acceder a un paso internopipe.named_steps["model"], pipe[-1]
Pasos distintos para columnas distintasfrom sklearn.compose import ColumnTransformer pre = ColumnTransformer([ ("num", StandardScaler(), ["age", "income"]), ("cat", OneHotEncoder(handle_unknown="ignore"), ["city"]), ])
Preprocesado y modelo en un solo objetomodel = make_pipeline(pre, RandomForestClassifier(random_state=0)) model.fit(X_train, y_train) model.score(X_test, y_test)
Elegir columnas por tipofrom sklearn.compose import make_column_selector make_column_selector(dtype_include="number")(X_train)
Imputar y luego escalarmake_pipeline(SimpleImputer(strategy="median"), StandardScaler())
Nombres de las features de salidapre.get_feature_names_out()

Validación cruzada

La validación cruzada entrena y evalúa el modelo con varias divisiones, lo que da una estimación más estable que un solo conjunto de test.

TareaCódigo
Importsfrom sklearn.model_selection import cross_val_score, cross_validate, KFold, StratifiedKFold
Puntuar con 5 foldsscores = cross_val_score(pipe, X, y, cv=5) scores.mean(), scores.std()
Elegir la métricacross_val_score(pipe, X, y, cv=5, scoring="f1_macro")
Folds barajadoscv = KFold(n_splits=5, shuffle=True, random_state=0)
El mismo balance de clases en cada foldcv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
Varias métricas y puntuaciones de traincross_validate(pipe, X, y, cv=cv, scoring=["accuracy", "f1"], return_train_score=True)
Una predicción por fila, hecha fuera del foldfrom sklearn.model_selection import cross_val_predict cross_val_predict(pipe, X, y, cv=5)
Folds por grupo, folds en orden temporalfrom sklearn.model_selection import GroupKFold, TimeSeriesSplit GroupKFold(n_splits=5), TimeSeriesSplit(n_splits=5)
Todos los nombres de scoring válidosfrom sklearn.metrics import get_scorer_names get_scorer_names()

Grid search y ajuste de hiperparámetros

Una búsqueda entrena el modelo con cada configuración usando validación cruzada, se queda con la mejor y la vuelve a entrenar con todos los datos de entrenamiento.

TareaCódigo
Importsfrom sklearn.model_selection import GridSearchCV, RandomizedSearchCV
Probar todas las combinacionesgrid = GridSearchCV(RandomForestClassifier(random_state=0), {"n_estimators": [50, 100], "max_depth": [None, 5]}, cv=5) grid.fit(X_train, y_train)
Mejor configuración y su puntuacióngrid.best_params_, grid.best_score_
Usar el mejor modelogrid.best_estimator_.predict(X_test), grid.score(X_test, y_test)
Ajustar un paso dentro de un pipelineGridSearchCV(pipe, {"logisticregression__C": [0.1, 1, 10]}, cv=5).fit(X_train, y_train)
Configuraciones aleatorias desde distribucionesfrom scipy.stats import randint search = RandomizedSearchCV(RandomForestClassifier(random_state=0), {"n_estimators": randint(50, 150)}, n_iter=5, cv=3, random_state=0) search.fit(X_train, y_train)
Usar todos los núcleos de la CPUGridSearchCV(pipe, {"logisticregression__C": [0.1, 1]}, cv=5, n_jobs=-1)
Todos los resultados como tablapd.DataFrame(grid.cv_results_).sort_values("rank_test_score")

Clustering y reducción de dimensionalidad

Los modelos no supervisados aprenden solo de X. Escala antes las features, porque ambos usan distancias.

TareaCódigo
Clusters con k-meansfrom sklearn.cluster import KMeans km = KMeans(n_clusters=3, random_state=0) labels = km.fit_predict(X)
Centros de los clusters e inerciakm.cluster_centers_, km.inertia_
Qué tan separados están los clustersfrom sklearn.metrics import silhouette_score silhouette_score(X, labels)
Clusters por densidad, el ruido es -1from sklearn.cluster import DBSCAN DBSCAN(eps=0.5, min_samples=5).fit_predict(X)
Proyectar sobre 2 componentesfrom sklearn.decomposition import PCA pca = PCA(n_components=2) X_2d = pca.fit_transform(X)
Varianza que explica cada componentepca.explained_variance_ratio_
Conservar el 95% de la varianzaPCA(n_components=0.95).fit_transform(X)

scikit-learn 1.9: formas antiguas y qué escribir ahora

El código copiado de tutoriales antiguos puede fallar o lanzar avisos en scikit-learn 1.9. Usa en su lugar las formas de la columna scikit-learn 1.9.

Tareascikit-learn 1.9Forma antigua
Raíz del error cuadrático medioroot_mean_squared_error(y_test, y_pred)mean_squared_error(y_test, y_pred, squared=False)
Salida one-hot densaOneHotEncoder(sparse_output=False)OneHotEncoder(sparse=False)
Regresión logística L1 (lasso)LogisticRegression(l1_ratio=1, solver="liblinear")LogisticRegression(penalty="l1", solver="liblinear")
Regresión logística sin regularizaciónLogisticRegression(C=np.inf)LogisticRegression(penalty=None)

Guardar, cargar y reproducir

TareaCódigo
Guardar un modelo o pipeline entrenadoimport joblib joblib.dump(model, "model.joblib")
Volver a cargarlomodel = joblib.load("model.joblib")
El mismo resultado en cada ejecuciónrandom_state=0
Qué versión está instaladaimport sklearn sklearn.__version__

El código de scikit-learn detrás de un flujo de trabajo real de machine learning, en el orden en que lo escribes: cargar y dividir los datos, preprocesarlos, elegir un modelo, entrenar y predecir, medir el resultado, encadenar los pasos en un pipeline, hacer validación cruzada y ajustar con grid search. Cada fila es un fragmento corto que puedes pegar, con una línea que explica qué hace.

Todos los modelos de scikit-learn comparten la misma API: fit aprende de los datos de entrenamiento, y predict y transform aplican lo aprendido. Todo está escrito para scikit-learn 1.9, la versión que usa Coddy, con X para las features y y para el target. scikit-learn trabaja con arrays de NumPy y DataFrames de pandas, y la hoja de trucos de Matplotlib cubre los gráficos. ¿Empiezas con Python? Arranca por la hoja de trucos de Python.

Preguntas frecuentes sobre la hoja de trucos de scikit-learn

¿Esta hoja de trucos de scikit-learn es gratis?
Sí. Esta hoja de trucos de scikit-learn es totalmente gratis y no necesitas registrarte. Guárdala en marcadores o imprímela en PDF desde tu navegador, y vuelve cuando necesites la llamada exacta para un pipeline, una métrica o un grid search.
¿sklearn es lo mismo que scikit-learn?
Sí. scikit-learn es el nombre de la librería y del paquete que instalas (pip install scikit-learn), y sklearn es el nombre que importas en el código (from sklearn.linear_model import LinearRegression). Una hoja de trucos de sklearn y una de scikit-learn cubren lo mismo.
¿Cuál es la diferencia entre fit, transform y fit_transform?
fit aprende de los datos: un scaler aprende la media de cada columna y un modelo aprende sus pesos. transform aplica lo aprendido, y fit_transform hace las dos cosas en una sola llamada. Usa fit_transform con el conjunto de entrenamiento y solo transform con el de test, o los datos de test se filtran al entrenamiento. Un pipeline lo hace por ti.
¿Tengo que escalar mis features?
Para los modelos que usan distancias o gradientes, sí: k vecinos más cercanos, SVM, k-means, PCA y la regresión lineal y logística regularizadas funcionan mejor con datos escalados. Los modelos de árbol, como los árboles de decisión, random forest y gradient boosting, no necesitan escalado. Pon el scaler en un pipeline para que se ajuste solo con los datos de entrenamiento.
¿Con qué modelo de scikit-learn empiezo?
Empieza con un modelo simple y rápido como baseline: LinearRegression para predecir números y LogisticRegression para predecir clases. Después prueba RandomForestClassifier o HistGradientBoostingClassifier (o sus versiones de regresión), compáralos con validación cruzada y ajusta el mejor con GridSearchCV.
¿Qué versión de scikit-learn cubre esta hoja de trucos?
scikit-learn 1.9, la versión que usa Coddy, sobre NumPy 2 y pandas 3. Las llamadas antiguas que ahora fallan o lanzan avisos, como squared=False en mean_squared_error, sparse=False en OneHotEncoder y el argumento penalty de LogisticRegression, están en la tabla de formas antiguas junto a lo que debes escribir en su lugar.
¿Puedo ejecutar código de scikit-learn online?
Sí. El playground de Matplotlib, gratuito, ejecuta Python con scikit-learn, pandas, NumPy y Matplotlib en tu navegador, así que puedes pegar cualquier fragmento de esta hoja de trucos y ejecutarlo sin instalar nada. El curso de Machine Learning de Coddy enseña paso a paso todo el flujo de trabajo de esta página, desde dividir los datos hasta ajustar un modelo.
Ilustración de los lenguajes de programación de Coddy

Aprende Scikit-learn con Coddy

COMENZAR