Written and maintained by CASRAI Editorial Board
Last updated
Who this is for: researchers and analysts who have a numeric table (samples in rows, measured variables in columns) and need to run principal component analysis (PCA) with scikit-learn in Python, decide whether to scale first, and read the output correctly.
In scikit-learn, PCA is sklearn.decomposition.PCA. It centres each feature but does not scale it before the singular value decomposition (SVD), so unscaled columns with large variance dominate the result. The sections below give the install, a complete runnable example on the iris data, the scaling decision with measured numbers, a table for reading every attribute, troubleshooting and alternatives. Documentation checked 2026-11-07 against scikit-learn 1.9.1.
What PCA in Python is used for in research
PCA projects a data matrix onto a smaller number of orthogonal directions (principal components) ordered by the variance they capture. Researchers use it to summarise many correlated measurements, to inspect structure before clustering (see k-means clustering) and to reduce the columns of high-dimensional data before modelling. It works from the covariance structure of the variables. If you work in R instead, see PCA in R with prcomp.
Install or access (official source only)
The scikit-learn installation page (scikit-learn.org/stable/install.html) gives two routes: pip install -U scikit-learn, or a conda environment from conda-forge:
conda create -n sklearn-env -c conda-forge scikit-learn
conda activate sklearn-env
PCA ships inside scikit-learn; no separate package is needed. Check your version with import sklearn; print(sklearn.__version__), and read the documentation for that version if yours is older than 1.9.
Step-by-step: PCA with scikit-learn
This runs on the iris table that ships with scikit-learn, so every command is reproducible without a download. The numbers shown in this guide were produced by running this code with scikit-learn 1.9.
- Load the data as a table.
from sklearn.datasets import load_iris, thenX = load_iris(as_frame=True).data. This gives 150 rows and four columns: sepal length, sepal width, petal length and petal width, all in centimetres. - Decide on scaling. PCA centres but does not scale, so put a
StandardScalerin front when your columns are in different units or have very different spreads (the next section shows why). - Build and fit a pipeline.
from sklearn.decomposition import PCA,from sklearn.preprocessing import StandardScaler,from sklearn.pipeline import make_pipeline, thenpipe = make_pipeline(StandardScaler(), PCA(n_components=2))andscores = pipe.fit_transform(X).fit_transformreturns an array of shape (n_samples, n_components), here 150 by 2. - Read the fitted PCA step.
pca = pipe[-1], thenpca.explained_variance_ratio_,pca.components_andpca.singular_values_(interpreted in the output table below). - Project new observations.
pipe.transform(X_new)projects them onto the components previously extracted from the training set. Fit on training data only and calltransformon anything held out, so the centring, scaling and components never see the held-out rows. - Plot. The columns of
scoresare the component scores; a scatter plot of column 0 against column 1 in matplotlib is the usual first view. A scree plot ofexplained_variance_ratio_shows how many components matter.
Choosing n_components
The n_components argument accepts an integer (keep that many components), a float between 0 and 1 (keep as many components as needed to reach that share of variance, which requires svd_solver='full'), or 'mle' (Minka’s maximum-likelihood estimate of dimensionality, also with the full solver). For example, PCA(n_components=0.95, svd_solver='full') on the scaled iris data keeps 2 components.
Scaling changes the answer: measured on iris
Running the same data both ways with two components gives clearly different results.
| Setting | explained_variance_ratio_ (PC1, PC2) | Largest loadings on PC1 |
|---|---|---|
| PCA on raw columns | 0.9246, 0.0531 | petal length (0.8567) |
| StandardScaler, then PCA | 0.7296, 0.2285 | petal length (0.5804), petal width (0.5649), sepal length (0.5211) |
Without scaling, PC1 is dominated by petal length, the column with the largest spread, so the 92 percent figure partly reflects units rather than structure. After standardising, three variables contribute similarly to PC1. Which is right depends on your question; when variables are measured on different scales, standardising is the common choice. That is an editorial judgement, not a scikit-learn rule: the library only documents that it centres and does not scale.
Output and how to read it
These attributes come from the PCA reference page for scikit-learn 1.9.1. The values in the last column are from the scaled iris run above.
| Attribute or method | What it holds | Scaled iris result |
|---|---|---|
components_ |
Array of shape (n_components, n_features): each row is one principal axis, sorted by decreasing explained_variance_. |
Row 0: 0.5211, -0.2693, 0.5804, 0.5649 |
explained_variance_ |
Variance along each component, estimated with n_samples – 1 degrees of freedom. | 2.9381, 0.9202 |
explained_variance_ratio_ |
Share of total variance carried by each component. | 0.7296, 0.2285 |
singular_values_ |
Singular values corresponding to each kept component. | 20.9231, 11.7092 |
mean_ |
Per-feature mean, equal to X.mean(axis=0); it is what was subtracted when centring. |
Not applicable: it is the mean of the standardised data, which is zero |
n_components_ |
The number of components actually kept. | 2 |
transform(X) / fit_transform(X) |
Projection onto the components; shape (n_samples, n_components). | 150 by 2 |
inverse_transform(Z) |
Maps component scores back to the original feature space. | Not exact when components are dropped |
The documentation’s own small example uses X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]); PCA(n_components=2).fit(X) gives explained_variance_ratio_ of [0.9924, 0.0075] and singular_values_ of [6.30061, 0.54980].
Where the eigenvalues are
Searchers often ask for sklearn PCA eigenvalues. scikit-learn exposes the variances along the components as explained_variance_, with the matching directions in components_. There is no attribute literally named eigenvalues.
svd_solver and other arguments
| svd_solver | Documented behaviour |
|---|---|
'auto' (default) |
Uses covariance_eigh when there are fewer than 1000 features and more than 10 times as many samples as features; otherwise randomized when the data is larger than 500 by 500 and n_components is below 80 percent of the smaller dimension; otherwise full. |
'full' |
Required for a float n_components and for 'mle'. |
'covariance_eigh' |
Efficient when n_samples is much larger than n_features; the documentation notes it effectively doubles the condition number. |
'arpack' |
Requires 0 < n_components < min(X.shape). |
'randomized' |
inverse_transform is not the exact inverse even with whiten=False. |
Other arguments: whiten=True scales each component to unit variance, which the user guide describes as useful for downstream estimators that assume isotropy such as an RBF-kernel SVM or k-means; random_state is the seed argument of the signature.
Troubleshooting
- Float n_components is rejected or ignored. A value between 0 and 1 is a variance threshold and needs
svd_solver='full'; set it explicitly. - arpack raises an error on n_components. It needs n_components strictly between 0 and min(X.shape).
- Sparse input fails. Sparse matrices are accepted only by some solvers such as
'arpack'and'covariance_eigh'.TruncatedSVDis the documented alternative, but it does not centre the data, so its results differ from PCA. - Reconstruction does not match the input. With the randomized solver
inverse_transformis not exact, and dropping components loses information by design. - Data does not fit in memory.
PCAneeds all data in memory;IncrementalPCAwithpartial_fitprocesses chunks. - Results look driven by one variable. Check whether you forgot to scale (see the comparison above).
Free alternatives and related estimators
| Option | Use it when (per scikit-learn user guide) |
|---|---|
IncrementalPCA |
The data is too large for memory; fit with partial_fit on chunks. |
KernelPCA |
The structure is nonlinear. It supports transform and inverse_transform, the inverse being an approximation; it uses eigen_solver rather than svd_solver. |
SparsePCA / MiniBatchSparsePCA |
You want sparse components; alpha controls the L1 penalty. |
TruncatedSVD |
The input is sparse and should not be centred. |
| prcomp in R | You work in R rather than Python. |
FAQ
What is sklearn PCA and how do I run it?
It is the PCA class in sklearn.decomposition. Create PCA(n_components=k), call fit_transform(X), and read explained_variance_ratio_ and components_.
Does sklearn PCA standardise my data?
No. The documentation states the input is centred but not scaled for each feature before the SVD. Add StandardScaler in a pipeline if you need scaling.
How many components should I keep?
scikit-learn offers an integer, a variance fraction (with the full solver) or 'mle'. Which to use is an analytic decision; a scree plot of the explained variance ratios is a common aid.
What does fit_transform return?
An array of shape (n_samples, n_components) holding each sample’s scores on the components.
Where are the sklearn PCA components and eigenvalues?
components_ holds one component per row, sorted by decreasing explained_variance_; explained_variance_ holds the corresponding variances.
What is Kernel PCA?
KernelPCA is scikit-learn’s nonlinear variant; its inverse_transform is an approximation.
Sources (official documentation)
- scikit-learn: sklearn.decomposition.PCA (version 1.9.1), read 2026-11-07.
- scikit-learn user guide: Decomposing signals in components, read 2026-11-07.
- scikit-learn: Installing scikit-learn, read 2026-11-07.







