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
- Import an estimator and create it with a fixed seed:
from sklearn.ensemble import RandomForestClassifierthenclf = RandomForestClassifier(random_state=0). - Define samples as a two-dimensional array (rows are samples, columns are features) and a target:
X = [[1, 2, 3], [11, 12, 13]]andy = [0, 1]. - Train with
clf.fit(X, y). - Predict with
clf.predict(X), which returnsarray([0, 1]), or on new samples withclf.predict([[4, 5, 6], [14, 15, 16]]), which also returnsarray([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, callingfitor a split multiple times always yields the same results, and that for reproducible results across executions you should remove any use ofrandom_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
predictreturns one predicted label or value per input row, soarray([0, 1])means class 0 for the first row and class 1 for the second.accuracy_scorereturns 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_validatereturns a dictionary;result['test_score']holds one score per fold. For background on a common regression metric, see the coefficient of determination.best_params_(fromRandomizedSearchCV) 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.
- scikit-learn documentation, “Installing scikit-learn”: https://scikit-learn.org/stable/install.html
- scikit-learn documentation, “Getting Started”: https://scikit-learn.org/stable/getting_started.html
- scikit-learn documentation, “Common pitfalls and recommended practices”: https://scikit-learn.org/stable/common_pitfalls.html
- scikit-learn, “About us” (citing scikit-learn): https://scikit-learn.org/stable/about.html
- Pedregosa et al. (2011), JMLR 12: https://jmlr.csail.mit.edu/papers/v12/pedregosa11a.html
- statsmodels documentation, “Installing”: https://www.statsmodels.org/stable/install.html
- XGBoost documentation, “Installation Guide”: https://xgboost.readthedocs.io/en/stable/install.html








