Menu
CoddyTech

Scikit-learn (sklearn) Cheat Sheet

Last updated

Load and split the data

Hold back a test set before anything else, and only look at it at the very end.

TaskCode
Import the splitterfrom sklearn.model_selection import train_test_split
Features and target from a DataFrameX = df.drop(columns="target") y = df["target"]
Built-in dataset as pandasfrom sklearn.datasets import load_iris X, y = load_iris(return_X_y=True, as_frame=True)
Synthetic data to experiment withfrom sklearn.datasets import make_classification X, y = make_classification(n_samples=500, n_features=8, random_state=0)
80/20 train and test splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Keep class proportions in both partstrain_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
Train, validation and 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)

Preprocess features

Fit a transformer on the training data only, then transform both sets. Fitting on test data leaks information.

TaskCode
Importsfrom sklearn.preprocessing import StandardScaler, MinMaxScaler, OneHotEncoder, OrdinalEncoder
Scale to mean 0 and standard deviation 1scaler = StandardScaler() X_train_s = scaler.fit_transform(X_train[["age", "income"]]) X_test_s = scaler.transform(X_test[["age", "income"]])
Scale to the range 0 to 1MinMaxScaler().fit_transform(X_train[["age", "income"]])
One-hot encode categoriesenc = OneHotEncoder(handle_unknown="ignore", sparse_output=False) enc.fit_transform(X_train[["city"]])
Encode ordered categories as numbersOrdinalEncoder(categories=[["low", "mid", "high"]]).fit_transform([["mid"], ["high"]])
Fill missing valuesfrom sklearn.impute import SimpleImputer SimpleImputer(strategy="median").fit_transform(X_train[["age", "income"]])
Polynomial and interaction featuresfrom sklearn.preprocessing import PolynomialFeatures PolynomialFeatures(degree=2, include_bias=False).fit_transform(X_train[["age", "income"]])
Get DataFrames back instead of arraysscaler.set_output(transform="pandas")
Text labels to integersfrom sklearn.preprocessing import LabelEncoder LabelEncoder().fit_transform(["cat", "dog", "cat"])

Choose a model

Start simple and keep the simple model as the score to beat.

ProblemStart withThen try
Predict a number (regression)LinearRegression(), Ridge(alpha=1.0)RandomForestRegressor(), HistGradientBoostingRegressor()
Predict a class (classification)LogisticRegression(max_iter=1000)RandomForestClassifier(), HistGradientBoostingClassifier()
Small data, similar points share a labelKNeighborsClassifier(n_neighbors=5)SVC(kernel="rbf")
Rules you can readDecisionTreeClassifier(max_depth=3)RandomForestClassifier()
Group rows without labelsKMeans(n_clusters=3)DBSCAN(eps=0.5)
Fewer features for plots or speedPCA(n_components=2)TSNE(n_components=2)
Find unusual rowsIsolationForest(random_state=0)LocalOutlierFactor()

Fit a model

Every estimator follows the same pattern: create it with its settings, then call fit.

TaskCode
The pattern for every modelmodel = LogisticRegression(max_iter=1000) model.fit(X_train, y_train)
Linear regressionfrom sklearn.linear_model import LinearRegression LinearRegression()
Regularized linear regressionfrom sklearn.linear_model import Ridge, Lasso Ridge(alpha=1.0), Lasso(alpha=0.1)
Logistic regression (classification)from sklearn.linear_model import LogisticRegression LogisticRegression(C=1.0, max_iter=1000)
k nearest neighborsfrom sklearn.neighbors import KNeighborsClassifier KNeighborsClassifier(n_neighbors=5)
Decision treefrom 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, fast on big datafrom sklearn.ensemble import HistGradientBoostingClassifier HistGradientBoostingClassifier(random_state=0)
Support vector machinefrom sklearn.svm import SVC SVC(kernel="rbf", C=1.0)
Naive Bayesfrom sklearn.naive_bayes import GaussianNB GaussianNB()
Baseline that always guesses the majorityfrom sklearn.dummy import DummyClassifier DummyClassifier(strategy="most_frequent")

Predict and inspect

TaskCode
Predict classes or valuesy_pred = model.predict(X_test)
Probability of the positive classmodel.predict_proba(X_test)[:, 1]
Quick score: accuracy or R²model.score(X_test, y_test)
Coefficients of a linear modelmodel.coef_, model.intercept_
Feature importance of a tree modelpd.Series(forest.feature_importances_, index=X_train.columns).sort_values()
Importance by shuffling each featurefrom sklearn.inspection import permutation_importance permutation_importance(model, X_test, y_test, random_state=0).importances_mean
Class labels the model knowsmodel.classes_
Read and change settingsmodel.get_params(), model.set_params(C=0.5)
Draw a decision treefrom sklearn.tree import plot_tree plot_tree(tree, filled=True, feature_names=list(X_train.columns))

Classification metrics

Accuracy alone hides the errors on a rare class. Check precision, recall and the confusion matrix too.

TaskCode
Importsfrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
Accuracyaccuracy_score(y_test, y_pred)
Precision, recall and F1precision_score(y_test, y_pred), recall_score(y_test, y_pred), f1_score(y_test, y_pred)
F1 for several classesf1_score(y_test, y_pred, average="macro")
Every metric per classfrom sklearn.metrics import classification_report print(classification_report(y_test, y_pred))
Confusion matrixfrom sklearn.metrics import confusion_matrix confusion_matrix(y_test, y_pred)
Plot the confusion matrixfrom sklearn.metrics import ConfusionMatrixDisplay ConfusionMatrixDisplay.from_estimator(model, X_test, y_test)
ROC AUC from probabilitiesfrom sklearn.metrics import roc_auc_score roc_auc_score(y_test, model.predict_proba(X_test)[:, 1])
Plot the ROC curvefrom sklearn.metrics import RocCurveDisplay RocCurveDisplay.from_estimator(model, X_test, y_test)
Accuracy for imbalanced classesfrom sklearn.metrics import balanced_accuracy_score balanced_accuracy_score(y_test, y_pred)
Your own decision thresholdy_pred = (model.predict_proba(X_test)[:, 1] >= 0.3).astype(int)

Regression metrics

Error metrics are in the target's units (lower is better). R² is the share of variance explained (1 is perfect).

TaskCode
Importsfrom sklearn.metrics import mean_absolute_error, mean_squared_error, root_mean_squared_error, r2_score
Mean absolute errormean_absolute_error(y_test, y_pred)
Mean squared error and its rootmean_squared_error(y_test, y_pred), root_mean_squared_error(y_test, y_pred)
R² scorer2_score(y_test, y_pred)
Mean absolute percentage errorfrom sklearn.metrics import mean_absolute_percentage_error mean_absolute_percentage_error(y_test, y_pred)
Plot predicted against actualfrom sklearn.metrics import PredictionErrorDisplay PredictionErrorDisplay.from_predictions(y_test, y_pred, kind="actual_vs_predicted")

Pipelines

A pipeline chains preprocessing and a model into one estimator, so cross-validation and grid search fit every step on training folds only.

TaskCode
Importsfrom sklearn.pipeline import make_pipeline, Pipeline
Scale, then fit a modelpipe = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000)) pipe.fit(X_train, y_train)
Steps with your own namespipe = Pipeline([("scale", StandardScaler()), ("model", LogisticRegression(max_iter=1000))])
Reach a step insidepipe.named_steps["model"], pipe[-1]
Different steps for different columnsfrom sklearn.compose import ColumnTransformer pre = ColumnTransformer([ ("num", StandardScaler(), ["age", "income"]), ("cat", OneHotEncoder(handle_unknown="ignore"), ["city"]), ])
Preprocessing and model in one objectmodel = make_pipeline(pre, RandomForestClassifier(random_state=0)) model.fit(X_train, y_train) model.score(X_test, y_test)
Pick columns by typefrom sklearn.compose import make_column_selector make_column_selector(dtype_include="number")(X_train)
Impute, then scalemake_pipeline(SimpleImputer(strategy="median"), StandardScaler())
Names of the output featurespre.get_feature_names_out()

Cross-validation

Cross-validation trains and scores the model on several splits, which gives a steadier estimate than one test set.

TaskCode
Importsfrom sklearn.model_selection import cross_val_score, cross_validate, KFold, StratifiedKFold
Score on 5 foldsscores = cross_val_score(pipe, X, y, cv=5) scores.mean(), scores.std()
Choose the metriccross_val_score(pipe, X, y, cv=5, scoring="f1_macro")
Shuffled foldscv = KFold(n_splits=5, shuffle=True, random_state=0)
Same class balance in each foldcv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
Several metrics and train scorescross_validate(pipe, X, y, cv=cv, scoring=["accuracy", "f1"], return_train_score=True)
A prediction for every row, made out of foldfrom sklearn.model_selection import cross_val_predict cross_val_predict(pipe, X, y, cv=5)
Folds by group, folds in time orderfrom sklearn.model_selection import GroupKFold, TimeSeriesSplit GroupKFold(n_splits=5), TimeSeriesSplit(n_splits=5)
Every valid scoring namefrom sklearn.metrics import get_scorer_names get_scorer_names()

Grid search and tuning

A search fits the model for each setting with cross-validation, keeps the best one and refits it on all the training data.

TaskCode
Importsfrom sklearn.model_selection import GridSearchCV, RandomizedSearchCV
Try every combinationgrid = GridSearchCV(RandomForestClassifier(random_state=0), {"n_estimators": [50, 100], "max_depth": [None, 5]}, cv=5) grid.fit(X_train, y_train)
Best settings and their scoregrid.best_params_, grid.best_score_
Use the best modelgrid.best_estimator_.predict(X_test), grid.score(X_test, y_test)
Tune a step inside a pipelineGridSearchCV(pipe, {"logisticregression__C": [0.1, 1, 10]}, cv=5).fit(X_train, y_train)
Random settings from distributionsfrom 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)
Use every CPU coreGridSearchCV(pipe, {"logisticregression__C": [0.1, 1]}, cv=5, n_jobs=-1)
All results as a tablepd.DataFrame(grid.cv_results_).sort_values("rank_test_score")

Clustering and dimensionality reduction

Unsupervised models learn from X alone. Scale the features first, because both use distances.

TaskCode
k-means clustersfrom sklearn.cluster import KMeans km = KMeans(n_clusters=3, random_state=0) labels = km.fit_predict(X)
Cluster centers and inertiakm.cluster_centers_, km.inertia_
How well separated the clusters arefrom sklearn.metrics import silhouette_score silhouette_score(X, labels)
Density-based clusters, noise is -1from sklearn.cluster import DBSCAN DBSCAN(eps=0.5, min_samples=5).fit_predict(X)
Project onto 2 componentsfrom sklearn.decomposition import PCA pca = PCA(n_components=2) X_2d = pca.fit_transform(X)
Variance each component explainspca.explained_variance_ratio_
Keep 95% of the variancePCA(n_components=0.95).fit_transform(X)

scikit-learn 1.9: old forms and what to write now

Code copied from older tutorials can fail or warn in scikit-learn 1.9. Write the forms in the scikit-learn 1.9 column instead.

Taskscikit-learn 1.9Old form
Root mean squared errorroot_mean_squared_error(y_test, y_pred)mean_squared_error(y_test, y_pred, squared=False)
Dense one-hot outputOneHotEncoder(sparse_output=False)OneHotEncoder(sparse=False)
L1 (lasso) logistic regressionLogisticRegression(l1_ratio=1, solver="liblinear")LogisticRegression(penalty="l1", solver="liblinear")
Logistic regression without regularizationLogisticRegression(C=np.inf)LogisticRegression(penalty=None)

Save, load and reproduce

TaskCode
Save a fitted model or pipelineimport joblib joblib.dump(model, "model.joblib")
Load it backmodel = joblib.load("model.joblib")
Same result on every runrandom_state=0
Which version is installedimport sklearn sklearn.__version__

The scikit-learn code behind a real machine learning workflow, in the order you write it: load and split the data, preprocess it, pick a model, fit and predict, measure the result, chain the steps into a pipeline, cross-validate and tune with grid search. Each row is a short snippet you can paste, plus one line on what it does.

Every model in scikit-learn shares one API: fit learns from training data, predict and transform apply what it learned. Everything here is written for scikit-learn 1.9, the version Coddy runs, with X for the features and y for the target. scikit-learn works on NumPy arrays and pandas DataFrames, and the Matplotlib cheat sheet covers the plots. New to Python itself? Start with the Python cheat sheet.

Scikit-learn cheat sheet FAQ

Is this scikit-learn cheat sheet free?
Yes. This scikit-learn cheat sheet is completely free, with no sign-up required. Bookmark it, or print it to PDF from your browser, and come back whenever you need the exact call for a pipeline, a metric or a grid search.
Is sklearn the same as scikit-learn?
Yes. scikit-learn is the name of the library and of the package you install (pip install scikit-learn), and sklearn is the name you import in code (from sklearn.linear_model import LinearRegression). An sklearn cheat sheet and a scikit-learn cheat sheet cover the same thing.
What is the difference between fit, transform and fit_transform?
fit learns from data: a scaler learns each column's mean, a model learns its weights. transform applies what was learned, and fit_transform does both in one call. Use fit_transform on the training set and only transform on the test set, or the test data leaks into training. A pipeline does this for you.
Do I need to scale my features?
For models that use distances or gradients, yes: k nearest neighbors, SVMs, k-means, PCA and regularized linear and logistic regression all work better on scaled data. Tree models such as decision trees, random forests and gradient boosting do not need scaling. Put the scaler in a pipeline so it is fitted on training data only.
Which scikit-learn model should I start with?
Start with a simple, fast model as a baseline: LinearRegression to predict numbers, LogisticRegression to predict classes. Then try RandomForestClassifier or HistGradientBoostingClassifier (or their regressor versions), compare them with cross-validation, and tune the best one with GridSearchCV.
Which scikit-learn version does this cheat sheet cover?
scikit-learn 1.9, the version Coddy runs, on NumPy 2 and pandas 3. Older calls that now fail or warn, such as squared=False in mean_squared_error, sparse=False in OneHotEncoder and the penalty argument of LogisticRegression, are in the old forms table next to what to write instead.
Can I run scikit-learn code online?
Yes. The free Matplotlib playground runs Python with scikit-learn, pandas, NumPy and Matplotlib in your browser, so you can paste any snippet from this cheat sheet and run it without installing anything. Coddy's Machine Learning course teaches the whole workflow on this page step by step, from splitting data to tuning a model.
Coddy programming languages illustration

Learn Scikit-learn with Coddy

GET STARTED