Skip to main content
v2026.11,858 entries · CC-BY 4.0

Scikit-learn Tutorial: Install, Fit, Evaluate and Cite for Research

A scikit-learn tutorial for researchers: install, fit a leakage-safe pipeline, cross-validate, make results reproducible and cite the library.

Written and maintained by CASRAI Editorial Board

Last updated

This scikit-learn tutorial takes you from an empty environment to a fitted, cross-validated model that you can report in a methods section. It follows the official documentation and adds three things most beginner tutorials skip: keeping preprocessing inside a pipeline so no information leaks from the test data, fixing random seeds so a result can be reproduced, and citing the library correctly.

What scikit-learn is used for in research

Scikit-learn is a Python library for machine learning. Its documentation describes a consistent set of objects: estimators that learn from data with fit, predictors that produce output with predict, and transformers that change data with transform. In research it is typically used to fit a classifier or regressor, scale or encode variables, split data into training and test sets, and estimate how well a model generalises with cross-validation.

If you are still deciding what kind of model your question needs, start with supervised vs unsupervised learning. If your department works in R or SPSS, see SPSS vs R for how the statistical toolchains differ.

Install scikit-learn from the official source

The official install page (scikit-learn.org/stable/install.html) recommends creating a virtual environment, and says it is “optional but strongly recommended, in order to avoid potential conflicts with other packages.” Pick one of the routes below. Check the install page for the Python version the current release requires before you start.

pip with a virtual environment (Linux and macOS)

python3 -m venv sklearn-env
source sklearn-env/bin/activate
pip3 install -U scikit-learn

pip with a virtual environment (Windows)

python -m venv sklearn-env
sklearn-env\Scripts\activate
pip install -U scikit-learn

conda

conda create -n sklearn-env -c conda-forge scikit-learn
conda activate sklearn-env

Whichever route you use, confirm the installation and record what you have:

python -c "import sklearn; sklearn.show_versions()"

On Linux, the install page discourages installing pip packages alongside packages managed by the distribution’s package manager (apt, dnf, pacman); a virtual environment avoids the conflict. For sharing an environment with collaborators, see sharing a reproducible conda environment.

Step-by-step: fit, predict and evaluate a first model

These steps use the examples from the official “Getting Started” page (scikit-learn.org/stable/getting_started.html).

1. Fit an estimator and predict

  1. Import an estimator and create it with a fixed seed: from sklearn.ensemble import RandomForestClassifier then clf = RandomForestClassifier(random_state=0).
  2. Define samples as a two-dimensional array (rows are samples, columns are features) and a target: X = [[1, 2, 3], [11, 12, 13]] and y = [0, 1].
  3. Train with clf.fit(X, y).
  4. Predict with clf.predict(X), which returns array([0, 1]), or on new samples with clf.predict([[4, 5, 6], [14, 15, 16]]), which also returns array([0, 1]).

2. Transform data

Transformers follow the same pattern. StandardScaler().fit(X).transform(X) on X = [[0, 15], [1, -10]] returns array([[-1., 1.], [1., -1.]]).

3. Chain preprocessing and a model in a pipeline, and split before you fit

from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

pipe = make_pipeline(StandardScaler(), LogisticRegression())
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
pipe.fit(X_train, y_train)
accuracy_score(pipe.predict(X_test), y_test)

The official example reports an accuracy of 0.97… on the held-out test set.

4. Estimate performance with cross-validation

from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_validate

X, y = make_regression(n_samples=1000, random_state=0)
result = cross_validate(LinearRegression(), X, y)
result['test_score']

The documentation notes that cross_validate defaults to 5-fold cross-validation. The example returns five values, one per fold: array([1., 1., 1., 1., 1.]).

5. Tune hyperparameters with a randomised search

The same page shows RandomizedSearchCV on a RandomForestRegressor, with param_distributions of {'n_estimators': randint(1, 5), 'max_depth': randint(5, 10)}, n_iter=5 and random_state=0. It reports best_params_ of {'max_depth': 9, 'n_estimators': 4} and a score of 0.84… on the test set.

Keep preprocessing inside the pipeline to avoid data leakage

The “Common pitfalls” page (scikit-learn.org/stable/common_pitfalls.html) gives the rule directly: “The general rule is to never call fit on the test data.” It adds that using all the data, for example fit(X) on the full dataset before splitting, “can result in overly optimistic scores”, and that a scikit-learn pipeline “is a great way to prevent data leakage as it ensures that the appropriate method is performed on the correct data subset.”

In practice this means the scaler in step 3 is fitted on X_train only, inside the pipeline, and merely applied to X_test. Tutorials that standardise the whole dataset first and split afterwards break this rule. The same page also warns that preprocessing applied to later data must match the preprocessing used in training, or “the feature space will change”; a pipeline carries the fitted preprocessing with the model.

Make the result reproducible and report it

  • Fix the seed. The documentation states that if an integer is passed as random_state, calling fit or a split multiple times always yields the same results, and that for reproducible results across executions you should remove any use of random_state=None. For cross-validation splitters, passing an integer is usually safer.
  • Record the environment. Save the output of sklearn.show_versions() and the environment definition with your analysis files.
  • Report cross-validated scores, not only one train/test split: state the number of folds and the metric, and give the spread across folds rather than a single number.
  • Cite the library. The scikit-learn “About us” page asks users to cite Pedregosa et al., “Scikit-learn: Machine Learning in Python”, Journal of Machine Learning Research 12, pp. 2825-2830, 2011 (https://jmlr.csail.mit.edu/papers/v12/pedregosa11a.html). For the API design, it also lists Buitinck et al., “API design for machine learning software: experiences from the scikit-learn project”, 2013 (arXiv:1309.0238).

Output and how to read it

  • predict returns one predicted label or value per input row, so array([0, 1]) means class 0 for the first row and class 1 for the second.
  • accuracy_score returns the share of test samples predicted correctly; the iris example gives 0.97…. Accuracy is not the only metric: for imbalanced classes, see the F1 score, and for probabilistic forecasts, the Brier score.
  • cross_validate returns a dictionary; result['test_score'] holds one score per fold. For background on a common regression metric, see the coefficient of determination.
  • best_params_ (from RandomizedSearchCV) is the parameter combination with the best cross-validated result among those sampled.

Troubleshooting

Symptom What the documentation says to check
Test scores look unrealistically high Confirm that no fit was called on the test data, and that scaling or other preprocessing sits inside a pipeline (Common pitfalls).
Results change every run Replace random_state=None with an integer in estimators and splitters (Common pitfalls).
Different feature space on new data Apply the same fitted preprocessing used in training; a pipeline does this automatically (Common pitfalls).
Package conflicts, especially on Linux Install into a virtual environment or conda environment instead of alongside distribution-managed packages (Install page).
Unsure which version is running Run python -c "import sklearn; sklearn.show_versions()" and compare against the Python requirement on the install page.

Alternatives and companion libraries

Other Python libraries cover ground that scikit-learn does not, and each documents its own install route:

Library Install route from its official documentation
statsmodels Anaconda is the recommended method for most users (conda install -c conda-forge statsmodels); pip is also supported (python -m pip install statsmodels).
XGBoost Pre-built wheels are on PyPI (pip install xgboost); Windows users need the Visual C++ Redistributable unless Visual Studio is installed.

For a point-and-click or R-based workflow, see SPSS vs R.

Frequently asked questions

Is scikit-learn the same as sklearn?

The package is called scikit-learn on PyPI and conda-forge, and you import it as sklearn, as in import sklearn in the verification command above.

Do I need a virtual environment?

The official install page calls it optional but strongly recommended, to avoid conflicts with other packages. For research, an isolated environment also makes the analysis easier to reproduce.

How do I avoid data leakage?

Never call fit on test data, and put every preprocessing step in a pipeline so it is fitted only on the training subset.

How do I cite scikit-learn?

Cite Pedregosa et al. (2011), Journal of Machine Learning Research 12, 2825-2830, and optionally Buitinck et al. (2013), arXiv:1309.0238.

Sources

All sources checked on 2026-10-29.

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Scikit-learn Tutorial: Install, Fit, Evaluate and Cite for Research

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.