scikit-learn sklearn manifold Manifold learning manifold Look for the bare necessities

Answer:
.. currentmodule:: sklearn.manifold

.. _manifold:

=================
Manifold learning
=================

| Look for the bare necessities
| The simple bare necessities
| Forget about your worries and your strife
| I mean the bare necessities
| Old Mother Nature's recipes
| That bring the bare necessities of life
|
|             -- Baloo's song [The Jungle Book]

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_compare_methods_001.png
   :target: ../auto_examples/manifold/plot_compare_methods.html
   :align: center
   :scale: 70%

.. |manifold_img3| image:: ../auto_examples/manifold/images/sphx_glr_plot_compare_methods_003.png
  :target: ../auto_examples/manifold/plot_compare_methods.html
  :scale: 60%

.. |manifold_img4| image:: ../auto_examples/manifold/images/sphx_glr_plot_compare_methods_004.png
    :target: ../auto_examples/manifold/plot_compare_methods.html
    :scale: 60%

.. |manifold_img5| image:: ../auto_examples/manifold/images/sphx_glr_plot_compare_methods_005.png
    :target: ../auto_examples/manifold/plot_compare_methods.html
    :scale: 60%

.. |manifold_img6| image:: ../auto_examples/manifold/images/sphx_glr_plot_compare_methods_006.png
    :target: ../auto_examples/manifold/plot_compare_methods.html
    :scale: 60%

.. centered:: |manifold_img3| |manifold_img4| |manifold_img5| |manifold_img6|

Manifold learning is an approach to non-linear dimensionality reduction.
Algorithms for this task are based on the idea that the dimensionality of
many data sets is only artificially high.

Introduction
============

High-dimensional datasets can be very difficult to visualize.  While data
in two or three dimensions can be plotted to show the inherent
structure of the data, equivalent high-dimensional plots are much less
intuitive.  To aid visualization of the structure of a dataset, the
dimension must be reduced in some way.

The simplest way to accomplish this dimensionality reduction is by taking
a random projection of the data.  Though this allows some degree of
visualization of the data structure, the randomness of the choice leaves much
to be desired.  In a random projection, it is likely that the more
interesting structure within the data will be lost.

.. |digits_img| image:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_001.png
    :target: ../auto_examples/manifold/plot_lle_digits.html
    :scale: 50

.. |projected_img| image::  ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_002.png
    :target: ../auto_examples/manifold/plot_lle_digits.html
    :scale: 50

.. centered:: |digits_img| |projected_img|

To address this concern, a number of supervised and unsupervised linear
dimensionality reduction frameworks have been designed, such as Principal
Component Analysis (PCA), Independent Component Analysis, Linear
Discriminant Analysis, and others.  These algorithms define specific
rubrics to choose an "interesting" linear projection of the data.
These methods can be powerful, but often miss important non-linear
structure in the data.

.. |PCA_img| image:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_003.png
    :target: ../auto_examples/manifold/plot_lle_digits.html
    :scale: 50

.. |LDA_img| image::  ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_004.png
    :target: ../auto_examples/manifold/plot_lle_digits.html
    :scale: 50

.. centered:: |PCA_img| |LDA_img|

Manifold Learning can be thought of as an attempt to generalize linear
frameworks like PCA to be sensitive to non-linear structure in data. Though
supervised variants exist, the typical manifold learning problem is
unsupervised: it learns the high-dimensional structure of the data
from the data itself, without the use of predetermined classifications.

.. rubric:: Examples

* See :ref:`sphx_glr_auto_examples_manifold_plot_lle_digits.py` for an example of
  dimensionality reduction on handwritten digits.

* See :ref:`sphx_glr_auto_examples_manifold_plot_compare_methods.py` for an example of
  dimensionality reduction on a toy "S-curve" dataset.

* See :ref:`sphx_glr_auto_examples_applications_plot_stock_market.py` for an example of
  using manifold learning to map the stock market structure based on historical stock
  prices.

The manifold learning implementations available in scikit-learn are
summarized below

.. _isomap:

Isomap
======

One of the earliest approaches to manifold learning is the Isomap
algorithm, short for Isometric Mapping.  Isomap can be viewed as an
extension of Multi-dimensional Scaling (MDS) or Kernel PCA.
Isomap seeks a lower-dimensional embedding which maintains geodesic
distances between all points.  Isomap can be performed with the object
:class:`Isomap`.

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_005.png
   :target: ../auto_examples/manifold/plot_lle_digits.html
   :align: center
   :scale: 50

.. dropdown:: Complexity

  The Isomap algorithm comprises three stages:

  1. **Nearest neighbor search.**  Isomap uses
     :class:`~sklearn.neighbors.BallTree` for efficient neighbor search.
     The cost is approximately :math:`O[D \log(k) N \log(N)]`, for :math:`k`
     nearest neighbors of :math:`N` points in :math:`D` dimensions.

  2. **Shortest-path graph search.**  The most efficient known algorithms
     for this are *Dijkstra's Algorithm*, which is approximately
     :math:`O[N^2(k + \log(N))]`, or the *Floyd-Warshall algorithm*, which
     is :math:`O[N^3]`.  The algorithm can be selected by the user with
     the ``path_method`` keyword of ``Isomap``.  If unspecified, the code
     attempts to choose the best algorithm for the input data.

  3. **Partial eigenvalue decomposition.**  The embedding is encoded in the
     eigenvectors corresponding to the :math:`d` largest eigenvalues of the
     :math:`N \times N` isomap kernel.  For a dense solver, the cost is
     approximately :math:`O[d N^2]`.  This cost can often be improved using
     the ``ARPACK`` solver.  The eigensolver can be specified by the user
     with the ``eigen_solver`` keyword of ``Isomap``.  If unspecified, the
     code attempts to choose the best algorithm for the input data.

  The overall complexity of Isomap is
  :math:`O[D \log(k) N \log(N)] + O[N^2(k + \log(N))] + O[d N^2]`.

  * :math:`N` : number of training data points
  * :math:`D` : input dimension
  * :math:`k` : number of nearest neighbors
  * :math:`d` : output dimension

.. rubric:: References

* `"A global geometric framework for nonlinear dimensionality reduction"
  <http://science.sciencemag.org/content/290/5500/2319.full>`_
  Tenenbaum, J.B.; De Silva, V.; & Langford, J.C.  Science 290 (5500)

.. _locally_linear_embedding:

Locally Linear Embedding
========================

Locally linear embedding (LLE) seeks a lower-dimensional projection of the data
which preserves distances within local neighborhoods.  It can be thought
of as a series of local Principal Component Analyses which are globally
compared to find the best non-linear embedding.

Locally linear embedding can be performed with function
:func:`locally_linear_embedding` or its object-oriented counterpart
:class:`LocallyLinearEmbedding`.

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_006.png
   :target: ../auto_examples/manifold/plot_lle_digits.html
   :align: center
   :scale: 50

.. dropdown:: Complexity

  The standard LLE algorithm comprises three stages:

  1. **Nearest Neighbors Search**.  See discussion under Isomap above.

  2. **Weight Matrix Construction**. :math:`O[D N k^3]`.
     The construction of the LLE weight matrix involves the solution of a
     :math:`k \times k` linear equation for each of the :math:`N` local
     neighborhoods.

  3. **Partial Eigenvalue Decomposition**. See discussion under Isomap above.

  The overall complexity of standard LLE is
  :math:`O[D \log(k) N \log(N)] + O[D N k^3] + O[d N^2]`.

  * :math:`N` : number of training data points
  * :math:`D` : input dimension
  * :math:`k` : number of nearest neighbors
  * :math:`d` : output dimension

.. rubric:: References

* `"Nonlinear dimensionality reduction by locally linear embedding"
  <http://www.sciencemag.org/content/290/5500/2323.full>`_
  Roweis, S. & Saul, L.  Science 290:2323 (2000)

Modified Locally Linear Embedding
=================================

One well-known issue with LLE is the regularization problem.  When the number
of neighbors is greater than the number of input dimensions, the matrix
defining each local neighborhood is rank-deficient.  To address this, standard
LLE applies an arbitrary regularization parameter :math:`r`, which is chosen
relative to the trace of the local weight matrix.  Though it can be shown
formally that as :math:`r \to 0`, the solution converges to the desired
embedding, there is no guarantee that the optimal solution will be found
for :math:`r > 0`.  This problem manifests itself in embeddings which distort
the underlying geometry of the manifold.

One method to address the regularization problem is to use multiple weight
vectors in each neighborhood.  This is the essence of *modified locally
linear embedding* (MLLE).  MLLE can be  performed with function
:func:`locally_linear_embedding` or its object-oriented counterpart
:class:`LocallyLinearEmbedding`, with the keyword ``method = 'modified'``.
It requires ``n_neighbors > n_components``.

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_007.png
   :target: ../auto_examples/manifold/plot_lle_digits.html
   :align: center
   :scale: 50

.. dropdown:: Complexity

  The MLLE algorithm comprises three stages:

  1. **Nearest Neighbors Search**.  Same as standard LLE

  2. **Weight Matrix Construction**. Approximately
     :math:`O[D N k^3] + O[N (k-D) k^2]`.  The first term is exactly equivalent
     to that of standard LLE.  The second term has to do with constructing the
     weight matrix from multiple weights.  In practice, the added cost of
     constructing the MLLE weight matrix is relatively small compared to the
     cost of stages 1 and 3.

  3. **Partial Eigenvalue Decomposition**. Same as standard LLE

  The overall complexity of MLLE is
  :math:`O[D \log(k) N \log(N)] + O[D N k^3] + O[N (k-D) k^2] + O[d N^2]`.

  * :math:`N` : number of training data points
  * :math:`D` : input dimension
  * :math:`k` : number of nearest neighbors
  * :math:`d` : output dimension

.. rubric:: References

* `"MLLE: Modified Locally Linear Embedding Using Multiple Weights"
  <https://citeseerx.ist.psu.edu/doc_view/pid/0b060fdbd92cbcc66b383bcaa9ba5e5e624d7ee3>`_
  Zhang, Z. & Wang, J.

Hessian Eigenmapping
====================

Hessian Eigenmapping (also known as Hessian-based LLE: HLLE) is another method
of solving the regularization problem of LLE.  It revolves around a
hessian-based quadratic form at each neighborhood which is used to recover
the locally linear structure.  Though other implementations note its poor
scaling with data size, ``sklearn`` implements some algorithmic
improvements which make its cost comparable to that of other LLE variants
for small output dimension.  HLLE can be  performed with function
:func:`locally_linear_embedding` or its object-oriented counterpart
:class:`LocallyLinearEmbedding`, with the keyword ``method = 'hessian'``.
It requires ``n_neighbors > n_components * (n_components + 3) / 2``.

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_008.png
   :target: ../auto_examples/manifold/plot_lle_digits.html
   :align: center
   :scale: 50

.. dropdown:: Complexity

  The HLLE algorithm comprises three stages:

  1. **Nearest Neighbors Search**.  Same as standard LLE

  2. **Weight Matrix Construction**. Approximately
     :math:`O[D N k^3] + O[N d^6]`.  The first term reflects a similar
     cost to that of standard LLE.  The second term comes from a QR
     decomposition of the local hessian estimator.

  3. **Partial Eigenvalue Decomposition**. Same as standard LLE.

  The overall complexity of standard HLLE is
  :math:`O[D \log(k) N \log(N)] + O[D N k^3] + O[N d^6] + O[d N^2]`.

  * :math:`N` : number of training data points
  * :math:`D` : input dimension
  * :math:`k` : number of nearest neighbors
  * :math:`d` : output dimension

.. rubric:: References

* `"Hessian Eigenmaps: Locally linear embedding techniques for
  high-dimensional data" <http://www.pnas.org/content/100/10/5591>`_
  Donoho, D. & Grimes, C. Proc Natl Acad Sci USA. 100:5591 (2003)

.. _spectral_embedding:

Spectral Embedding
====================

Spectral Embedding is an approach to calculating a non-linear embedding.
Scikit-learn implements Laplacian Eigenmaps, which finds a low dimensional
representation of the data using a spectral decomposition of the graph
Laplacian. The graph generated can be considered as a discrete approximation of
the low dimensional manifold in the high dimensional space. Minimization of a
cost function based on the graph ensures that points close to each other on
the manifold are mapped close to each other in the low dimensional space,
preserving local distances. Spectral embedding can be  performed with the
function :func:`spectral_embedding` or its object-oriented counterpart
:class:`SpectralEmbedding`.

.. dropdown:: Complexity

  The Spectral Embedding (Laplacian Eigenmaps) algorithm comprises three stages:

  1. **Weighted Graph Construction**. Transform the raw input data into
     graph representation using affinity (adjacency) matrix representation.

  2. **Graph Laplacian Construction**. unnormalized Graph Laplacian
     is constructed as :math:`L = D - A` for and normalized one as
     :math:`L = D^{-\frac{1}{2}} (D - A) D^{-\frac{1}{2}}`.

  3. **Partial Eigenvalue Decomposition**. Eigenvalue decomposition is
     done on graph Laplacian.

  The overall complexity of spectral embedding is
  :math:`O[D \log(k) N \log(N)] + O[D N k^3] + O[d N^2]`.

  * :math:`N` : number of training data points
  * :math:`D` : input dimension
  * :math:`k` : number of nearest neighbors
  * :math:`d` : output dimension

.. rubric:: References

* `"Laplacian Eigenmaps for Dimensionality Reduction
  and Data Representation"
  <https://web.cse.ohio-state.edu/~mbelkin/papers/LEM_NC_03.pdf>`_
  M. Belkin, P. Niyogi, Neural Computation, June 2003; 15 (6):1373-1396

Local Tangent Space Alignment
=============================

Though not technically a variant of LLE, Local tangent space alignment (LTSA)
is algorithmically similar enough to LLE that it can be put in this category.
Rather than focusing on preserving neighborhood distances as in LLE, LTSA
seeks to characterize the local geometry at each neighborhood via its
tangent space, and performs a global optimization to align these local
tangent spaces to learn the embedding.  LTSA can be performed with function
:func:`locally_linear_embedding` or its object-oriented counterpart
:class:`LocallyLinearEmbedding`, with the keyword ``method = 'ltsa'``.

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_009.png
   :target: ../auto_examples/manifold/plot_lle_digits.html
   :align: center
   :scale: 50

.. dropdown:: Complexity

  The LTSA algorithm comprises three stages:

  1. **Nearest Neighbors Search**.  Same as standard LLE

  2. **Weight Matrix Construction**. Approximately
     :math:`O[D N k^3] + O[k^2 d]`.  The first term reflects a similar
     cost to that of standard LLE.

  3. **Partial Eigenvalue Decomposition**. Same as standard LLE

  The overall complexity of standard LTSA is
  :math:`O[D \log(k) N \log(N)] + O[D N k^3] + O[k^2 d] + O[d N^2]`.

  * :math:`N` : number of training data points
  * :math:`D` : input dimension
  * :math:`k` : number of nearest neighbors
  * :math:`d` : output dimension

.. rubric:: References

* :arxiv:`"Principal manifolds and nonlinear dimensionality reduction via
  tangent space alignment"
  <cs/0212008>`
  Zhang, Z. & Zha, H. Journal of Shanghai Univ. 8:406 (2004)

.. _multidimensional_scaling:

Multi-dimensional Scaling (MDS)
===============================

`Multidimensional scaling <https://en.wikipedia.org/wiki/Multidimensional_scaling>`_
(:class:`MDS`) seeks a low-dimensional
representation of the data in which the distances respect well the
distances in the original high-dimensional space.

In general, :class:`MDS` is a technique used for analyzing similarity or
dissimilarity data. It attempts to model similarity or dissimilarity data as
distances in a geometric spaces. The data can be ratings of similarity between
objects, interaction frequencies of molecules, or trade indices between
countries.

There exists two types of MDS algorithm: metric and non metric. In
scikit-learn, the class :class:`MDS` implements both. In Metric MDS, the input
similarity matrix arises from a metric (and thus respects the triangular
inequality), the distances between output two points are then set to be as
close as possible to the similarity or dissimilarity data. In the non-metric
version, the algorithms will try to preserve the order of the distances, and
hence seek for a monotonic relationship between the distances in the embedded
space and the similarities/dissimilarities.

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_010.png
   :target: ../auto_examples/manifold/plot_lle_digits.html
   :align: center
   :scale: 50

Let :math:`S` be the similarity matrix, and :math:`X` the coordinates of the
:math:`n` input points. Disparities :math:`\hat{d}_{ij}` are transformation of
the similarities chosen in some optimal ways. The objective, called the
stress, is then defined by :math:`\sum_{i < j} d_{ij}(X) - \hat{d}_{ij}(X)`

.. dropdown:: Metric MDS

  The simplest metric :class:`MDS` model, called *absolute MDS*, disparities are defined by
  :math:`\hat{d}_{ij} = S_{ij}`. With absolute MDS, the value :math:`S_{ij}`
  should then correspond exactly to the distance between point :math:`i` and
  :math:`j` in the embedding point.

  Most commonly, disparities are set to :math:`\hat{d}_{ij} = b S_{ij}`.

.. dropdown:: Nonmetric MDS

  Non metric :class:`MDS` focuses on the ordination of the data. If
  :math:`S_{ij} > S_{jk}`, then the embedding should enforce :math:`d_{ij} <
  d_{jk}`. For this reason, we discuss it in terms of dissimilarities
  (:math:`\delta_{ij}`) instead of similarities (:math:`S_{ij}`). Note that
  dissimilarities can easily be obtained from similarities through a simple
  transform, e.g. :math:`\delta_{ij}=c_1-c_2 S_{ij}` for some real constants
  :math:`c_1, c_2`. A simple algorithm to enforce proper ordination is to use a
  monotonic regression of :math:`d_{ij}` on :math:`\delta_{ij}`, yielding
  disparities :math:`\hat{d}_{ij}` in the same order as :math:`\delta_{ij}`.

  A trivial solution to this problem is to set all the points on the origin. In
  order to avoid that, the disparities :math:`\hat{d}_{ij}` are normalized. Note
  that since we only care about relative ordering, our objective should be
  invariant to simple translation and scaling, however the stress used in metric
  MDS is sensitive to scaling. To address this, non-metric MDS may use a
  normalized stress, known as Stress-1 defined as

  .. math::
      \sqrt{\frac{\sum_{i < j} (d_{ij} - \hat{d}_{ij})^2}{\sum_{i < j} d_{ij}^2}}.

  The use of normalized Stress-1 can be enabled by setting `normalized_stress=True`,
  however it is only compatible with the non-metric MDS problem and will be ignored
  in the metric case.

  .. figure:: ../auto_examples/manifold/images/sphx_glr_plot_mds_001.png
    :target: ../auto_examples/manifold/plot_mds.html
    :align: center
    :scale: 60

.. rubric:: References

* `"Modern Multidimensional Scaling - Theory and Applications"
  <https://www.springer.com/fr/book/9780387251509>`_
  Borg, I.; Groenen P. Springer Series in Statistics (1997)

* `"Nonmetric multidimensional scaling: a numerical method"
  <http://cda.psych.uiuc.edu/psychometrika_highly_cited_articles/kruskal_1964b.pdf>`_
  Kruskal, J. Psychometrika, 29 (1964)

* `"Multidimensional scaling by optimizing goodness of fit to a nonmetric hypothesis"
  <http://cda.psych.uiuc.edu/psychometrika_highly_cited_articles/kruskal_1964a.pdf>`_
  Kruskal, J. Psychometrika, 29, (1964)

.. _t_sne:

t-distributed Stochastic Neighbor Embedding (t-SNE)
===================================================

t-SNE (:class:`TSNE`) converts affinities of data points to probabilities.
The affinities in the original space are represented by Gaussian joint
probabilities and the affinities in the embedded space are represented by
Student's t-distributions. This allows t-SNE to be particularly sensitive
to local structure and has a few other advantages over existing techniques:

* Revealing the structure at many scales on a single map
* Revealing data that lie in multiple, different, manifolds or clusters
* Reducing the tendency to crowd points together at the center

While Isomap, LLE and variants are best suited to unfold a single continuous
low dimensional manifold, t-SNE will focus on the local structure of the data
and will tend to extract clustered local groups of samples as highlighted on
the S-curve example. This ability to group samples based on the local structure
might be beneficial to visually disentangle a dataset that comprises several
manifolds at once as is the case in the digits dataset.

The Kullback-Leibler (KL) divergence of the joint
probabilities in the original space and the embedded space will be minimized
by gradient descent. Note that the KL divergence is not convex, i.e.
multiple restarts with different initializations will end up in local minima
of the KL divergence. Hence, it is sometimes useful to try different seeds
and select the embedding with the lowest KL divergence.

The disadvantages to using t-SNE are roughly:

* t-SNE is computationally expensive, and can take several hours on million-sample
  datasets where PCA will finish in seconds or minutes
* The Barnes-Hut t-SNE method is limited to two or three dimensional embeddings.
* The algorithm is stochastic and multiple restarts with different seeds can
  yield different embeddings. However, it is perfectly legitimate to pick the
  embedding with the least error.
* Global structure is not explicitly preserved. This problem is mitigated by
  initializing points with PCA (using `init='pca'`).

.. figure:: ../auto_examples/manifold/images/sphx_glr_plot_lle_digits_013.png
   :target: ../auto_examples/manifold/plot_lle_digits.html
   :align: center
   :scale: 50

.. dropdown:: Optimizing t-SNE

  The main purpose of t-SNE is visualization of high-dimensional data. Hence,
  it works best when the data will be embedded on two or three dimensions.

  Optimizing the KL divergence can be a little bit tricky sometimes. There are
  five parameters that control the optimization of t-SNE and therefore possibly
  the quality of the resulting embedding:

  * perplexity
  * early exaggeration factor
  * learning rate
  * maximum number of iterations
  * angle (not used in the exact method)

  The perplexity is defined as :math:`k=2^{(S)}` where :math:`S` is the Shannon
  entropy of the conditional probability distribution. The perplexity of a
  :math:`k`-sided die is :math:`k`, so that :math:`k` is effectively the number of
  nearest neighbors t-SNE considers when generating the conditional probabilities.
  Larger perplexities lead to more nearest neighbors and less sensitive to small
  structure. Conversely a lower perplexity considers a smaller number of
  neighbors, and thus ignores more global information in favour of the
  local neighborhood. As dataset sizes get larger more points will be
  required to get a reasonable sample of the local neighborhood, and hence
  larger perplexities may be required. Similarly noisier datasets will require
  larger perplexity values to encompass enough local neighbors to see beyond
  the background noise.

  The maximum number of iterations is usually high enough and does not need
  any tuning. The optimization consists of two phases: the early exaggeration
  phase and the final optimization. During early exaggeration the joint
  probabilities in the original space will be artificially increased by
  multiplication with a given factor. Larger factors result in larger gaps
  between natural clusters in the data. If the factor is too high, the KL
  divergence could increase during this phase. Usually it does not have to be
  tuned. A critical parameter is the learning rate. If it is too low gradient
  descent will get stuck in a bad local minimum. If it is too high the KL
  divergence will increase during optimization. A heuristic suggested in
  Belkina et al. (2019) is to set the learning rate to the sample size
  divided by the early exaggeration factor. We implement this heuristic
  as `learning_rate='auto'` argument. More tips can be found in
  Laurens van der Maaten's FAQ (see references). The last parameter, angle,
  is a tradeoff between performance and accuracy. Larger angles imply that we
  can approximate larger regions by a single point, leading to better speed
  but less accurate results.

  `"How to Use t-SNE Effectively" <https://distill.pub/2016/misread-tsne/>`_
  provides a good discussion of the effects of the various parameters, as well
  as interactive plots to explore the effects of different parameters.

.. dropdown:: Barnes-Hut t-SNE

  The Barnes-Hut t-SNE that has been implemented here is usually much slower than
  other manifold learning algorithms. The optimization is quite difficult
  and the computation of the gradient is :math:`O[d N log(N)]`, where :math:`d`
  is the number of output dimensions and :math:`N` is the number of samples. The
  Barnes-Hut method improves on the exact method where t-SNE complexity is
  :math:`O[d N^2]`, but has several other notable differences:

  * The Barnes-Hut implementation only works when the target dimensionality is 3
    or less. The 2D case is typical when building visualizations.
  * Barnes-Hut only works with dense input data. Sparse data matrices can only be
    embedded with the exact method or can be approximated by a dense low rank
    projection for instance using :class:`~sklearn.decomposition.PCA`
  * Barnes-Hut is an approximation of the exact method. The approximation is
    parameterized with the angle parameter, therefore the angle parameter is
    unused when method="exact"
  * Barnes-Hut is significantly more scalable. Barnes-Hut can be used to embed
    hundred of thousands of data points while the exact method can handle
    thousands of samples before becoming computationally intractable

  For visualization purpose (which is the main use case of t-SNE), using the
  Barnes-Hut method is strongly recommended. The exact t-SNE method is useful
  for checking the theoretically properties of the embedding possibly in higher
  dimensional space but limit to small datasets due to computational constraints.

  Also note that the digits labels roughly match the natural grouping found by
  t-SNE while the linear 2D projection of the PCA model yields a representation
  where label regions largely overlap. This is a strong clue that this data can
  be well separated by non linear methods that focus on the local structure (e.g.
  an SVM with a Gaussian RBF kernel). However, failing to visualize well
  separated homogeneously labeled groups with t-SNE in 2D does not necessarily
  imply that the data cannot be correctly classified by a supervised model. It
  might be the case that 2 dimensions are not high enough to accurately represent
  the internal structure of the data.

.. rubric:: References

* `"Visualizing High-Dimensional Data Using t-SNE"
  <https://jmlr.org/papers/v9/vandermaaten08a.html>`_
  van der Maaten, L.J.P.; Hinton, G. Journal of Machine Learning Research (2008)

* `"t-Distributed Stochastic Neighbor Embedding"
  <https://lvdmaaten.github.io/tsne/>`_ van der Maaten, L.J.P.

* `"Accelerating t-SNE using Tree-Based Algorithms"
  <https://lvdmaaten.github.io/publications/papers/JMLR_2014.pdf>`_
  van der Maaten, L.J.P.; Journal of Machine Learning Research 15(Oct):3221-3245, 2014.

* `"Automated optimized parameters for T-distributed stochastic neighbor
  embedding improve visualization and analysis of large datasets"
  <https://www.nature.com/articles/s41467-019-13055-y>`_
  Belkina, A.C., Ciccolella, C.O., Anno, R., Halpert, R., Spidlen, J.,
  Snyder-Cappione, J.E., Nature Communications 10, 5415 (2019).

Tips on practical use
=====================

* Make sure the same scale is used over all features. Because manifold
  learning methods are based on a nearest-neighbor search, the algorithm
  may perform poorly otherwise.  See :ref:`StandardScaler <preprocessing_scaler>`
  for convenient ways of scaling heterogeneous data.

* The reconstruction error computed by each routine can be used to choose
  the optimal output dimension.  For a :math:`d`-dimensional manifold embedded
  in a :math:`D`-dimensional parameter space, the reconstruction error will
  decrease as ``n_components`` is increased until ``n_components == d``.

* Note that noisy data can "short-circuit" the manifold, in essence acting
  as a bridge between parts of the manifold that would otherwise be
  well-separated.  Manifold learning on noisy and/or incomplete data is
  an active area of research.

* Certain input configurations can lead to singular weight matrices, for
  example when more than two points in the dataset are identical, or when
  the data is split into disjointed groups.  In this case, ``solver='arpack'``
  will fail to find the null space.  The easiest way to address this is to
  use ``solver='dense'`` which will work on a singular matrix, though it may
  be very slow depending on the number of input points.  Alternatively, one
  can attempt to understand the source of the singularity: if it is due to
  disjoint sets, increasing ``n_neighbors`` may help.  If it is due to
  identical points in the dataset, removing these points may help.

.. seealso::

   :ref:`random_trees_embedding` can also be useful to derive non-linear
   representations of feature space, also it does not perform
   dimensionality reduction.

currentmodule   sklearn manifold      manifold                     Manifold learning                      Look for the bare necessities   The simple bare necessities   Forget about your worries and your strife   I mean the bare necessities   Old Mother Nature s recipes   That bring the bare necessities of life                    Baloo s song  The Jungle Book        figure      auto examples manifold images sphx glr plot compare methods 001 png     target     auto examples manifold plot compare methods html     align  center     scale  70       manifold img3  image      auto examples manifold images sphx glr plot compare methods 003 png    target     auto examples manifold plot compare methods html    scale  60       manifold img4  image      auto examples manifold images sphx glr plot compare methods 004 png      target     auto examples manifold plot compare methods html      scale  60       manifold img5  image      auto examples manifold images sphx glr plot compare methods 005 png      target     auto examples manifold plot compare methods html      scale  60       manifold img6  image      auto examples manifold images sphx glr plot compare methods 006 png      target     auto examples manifold plot compare methods html      scale  60      centered    manifold img3   manifold img4   manifold img5   manifold img6    Manifold learning is an approach to non linear dimensionality reduction  Algorithms for this task are based on the idea that the dimensionality of many data sets is only artificially high    Introduction               High dimensional datasets can be very difficult to visualize   While data in two or three dimensions can be plotted to show the inherent structure of the data  equivalent high dimensional plots are much less intuitive   To aid visualization of the structure of a dataset  the dimension must be reduced in some way   The simplest way to accomplish this dimensionality reduction is by taking a random projection of the data   Though this allows some degree of visualization of the data structure  the randomness of the choice leaves much to be desired   In a random projection  it is likely that the more interesting structure within the data will be lost        digits img  image      auto examples manifold images sphx glr plot lle digits 001 png      target     auto examples manifold plot lle digits html      scale  50      projected img  image       auto examples manifold images sphx glr plot lle digits 002 png      target     auto examples manifold plot lle digits html      scale  50     centered    digits img   projected img    To address this concern  a number of supervised and unsupervised linear dimensionality reduction frameworks have been designed  such as Principal Component Analysis  PCA   Independent Component Analysis  Linear Discriminant Analysis  and others   These algorithms define specific rubrics to choose an  interesting  linear projection of the data  These methods can be powerful  but often miss important non linear structure in the data        PCA img  image      auto examples manifold images sphx glr plot lle digits 003 png      target     auto examples manifold plot lle digits html      scale  50      LDA img  image       auto examples manifold images sphx glr plot lle digits 004 png      target     auto examples manifold plot lle digits html      scale  50     centered    PCA img   LDA img   Manifold Learning can be thought of as an attempt to generalize linear frameworks like PCA to be sensitive to non linear structure in data  Though supervised variants exist  the typical manifold learning problem is unsupervised  it learns the high dimensional structure of the data from the data itself  without the use of predetermined classifications       rubric   Examples    See  ref  sphx glr auto examples manifold plot lle digits py  for an example of   dimensionality reduction on handwritten digits     See  ref  sphx glr auto examples manifold plot compare methods py  for an example of   dimensionality reduction on a toy  S curve  dataset     See  ref  sphx glr auto examples applications plot stock market py  for an example of   using manifold learning to map the stock market structure based on historical stock   prices   The manifold learning implementations available in scikit learn are summarized below      isomap   Isomap         One of the earliest approaches to manifold learning is the Isomap algorithm  short for Isometric Mapping   Isomap can be viewed as an extension of Multi dimensional Scaling  MDS  or Kernel PCA  Isomap seeks a lower dimensional embedding which maintains geodesic distances between all points   Isomap can be performed with the object  class  Isomap       figure      auto examples manifold images sphx glr plot lle digits 005 png     target     auto examples manifold plot lle digits html     align  center     scale  50     dropdown   Complexity    The Isomap algorithm comprises three stages     1    Nearest neighbor search     Isomap uses       class   sklearn neighbors BallTree  for efficient neighbor search       The cost is approximately  math  O D  log k  N  log N     for  math  k       nearest neighbors of  math  N  points in  math  D  dimensions     2    Shortest path graph search     The most efficient known algorithms      for this are  Dijkstra s Algorithm   which is approximately       math  O N 2 k    log N      or the  Floyd Warshall algorithm   which      is  math  O N 3     The algorithm can be selected by the user with      the   path method   keyword of   Isomap     If unspecified  the code      attempts to choose the best algorithm for the input data     3    Partial eigenvalue decomposition     The embedding is encoded in the      eigenvectors corresponding to the  math  d  largest eigenvalues of the       math  N  times N  isomap kernel   For a dense solver  the cost is      approximately  math  O d N 2     This cost can often be improved using      the   ARPACK   solver   The eigensolver can be specified by the user      with the   eigen solver   keyword of   Isomap     If unspecified  the      code attempts to choose the best algorithm for the input data     The overall complexity of Isomap is    math  O D  log k  N  log N     O N 2 k    log N      O d N 2          math  N    number of training data points      math  D    input dimension      math  k    number of nearest neighbors      math  d    output dimension     rubric   References      A global geometric framework for nonlinear dimensionality reduction     http   science sciencemag org content 290 5500 2319 full      Tenenbaum  J B   De Silva  V     Langford  J C   Science 290  5500       locally linear embedding   Locally Linear Embedding                           Locally linear embedding  LLE  seeks a lower dimensional projection of the data which preserves distances within local neighborhoods   It can be thought of as a series of local Principal Component Analyses which are globally compared to find the best non linear embedding   Locally linear embedding can be performed with function  func  locally linear embedding  or its object oriented counterpart  class  LocallyLinearEmbedding       figure      auto examples manifold images sphx glr plot lle digits 006 png     target     auto examples manifold plot lle digits html     align  center     scale  50     dropdown   Complexity    The standard LLE algorithm comprises three stages     1    Nearest Neighbors Search     See discussion under Isomap above     2    Weight Matrix Construction     math  O D N k 3         The construction of the LLE weight matrix involves the solution of a       math  k  times k  linear equation for each of the  math  N  local      neighborhoods     3    Partial Eigenvalue Decomposition    See discussion under Isomap above     The overall complexity of standard LLE is    math  O D  log k  N  log N     O D N k 3    O d N 2          math  N    number of training data points      math  D    input dimension      math  k    number of nearest neighbors      math  d    output dimension     rubric   References      Nonlinear dimensionality reduction by locally linear embedding     http   www sciencemag org content 290 5500 2323 full      Roweis  S    Saul  L   Science 290 2323  2000    Modified Locally Linear Embedding                                    One well known issue with LLE is the regularization problem   When the number of neighbors is greater than the number of input dimensions  the matrix defining each local neighborhood is rank deficient   To address this  standard LLE applies an arbitrary regularization parameter  math  r   which is chosen relative to the trace of the local weight matrix   Though it can be shown formally that as  math  r  to 0   the solution converges to the desired embedding  there is no guarantee that the optimal solution will be found for  math  r   0    This problem manifests itself in embeddings which distort the underlying geometry of the manifold   One method to address the regularization problem is to use multiple weight vectors in each neighborhood   This is the essence of  modified locally linear embedding   MLLE    MLLE can be  performed with function  func  locally linear embedding  or its object oriented counterpart  class  LocallyLinearEmbedding   with the keyword   method    modified     It requires   n neighbors   n components        figure      auto examples manifold images sphx glr plot lle digits 007 png     target     auto examples manifold plot lle digits html     align  center     scale  50     dropdown   Complexity    The MLLE algorithm comprises three stages     1    Nearest Neighbors Search     Same as standard LLE    2    Weight Matrix Construction    Approximately       math  O D N k 3    O N  k D  k 2     The first term is exactly equivalent      to that of standard LLE   The second term has to do with constructing the      weight matrix from multiple weights   In practice  the added cost of      constructing the MLLE weight matrix is relatively small compared to the      cost of stages 1 and 3     3    Partial Eigenvalue Decomposition    Same as standard LLE    The overall complexity of MLLE is    math  O D  log k  N  log N     O D N k 3    O N  k D  k 2    O d N 2          math  N    number of training data points      math  D    input dimension      math  k    number of nearest neighbors      math  d    output dimension     rubric   References      MLLE  Modified Locally Linear Embedding Using Multiple Weights     https   citeseerx ist psu edu doc view pid 0b060fdbd92cbcc66b383bcaa9ba5e5e624d7ee3      Zhang  Z    Wang  J    Hessian Eigenmapping                       Hessian Eigenmapping  also known as Hessian based LLE  HLLE  is another method of solving the regularization problem of LLE   It revolves around a hessian based quadratic form at each neighborhood which is used to recover the locally linear structure   Though other implementations note its poor scaling with data size    sklearn   implements some algorithmic improvements which make its cost comparable to that of other LLE variants for small output dimension   HLLE can be  performed with function  func  locally linear embedding  or its object oriented counterpart  class  LocallyLinearEmbedding   with the keyword   method    hessian     It requires   n neighbors   n components    n components   3    2        figure      auto examples manifold images sphx glr plot lle digits 008 png     target     auto examples manifold plot lle digits html     align  center     scale  50     dropdown   Complexity    The HLLE algorithm comprises three stages     1    Nearest Neighbors Search     Same as standard LLE    2    Weight Matrix Construction    Approximately       math  O D N k 3    O N d 6     The first term reflects a similar      cost to that of standard LLE   The second term comes from a QR      decomposition of the local hessian estimator     3    Partial Eigenvalue Decomposition    Same as standard LLE     The overall complexity of standard HLLE is    math  O D  log k  N  log N     O D N k 3    O N d 6    O d N 2          math  N    number of training data points      math  D    input dimension      math  k    number of nearest neighbors      math  d    output dimension     rubric   References      Hessian Eigenmaps  Locally linear embedding techniques for   high dimensional data   http   www pnas org content 100 10 5591      Donoho  D    Grimes  C  Proc Natl Acad Sci USA  100 5591  2003       spectral embedding   Spectral Embedding                       Spectral Embedding is an approach to calculating a non linear embedding  Scikit learn implements Laplacian Eigenmaps  which finds a low dimensional representation of the data using a spectral decomposition of the graph Laplacian  The graph generated can be considered as a discrete approximation of the low dimensional manifold in the high dimensional space  Minimization of a cost function based on the graph ensures that points close to each other on the manifold are mapped close to each other in the low dimensional space  preserving local distances  Spectral embedding can be  performed with the function  func  spectral embedding  or its object oriented counterpart  class  SpectralEmbedding       dropdown   Complexity    The Spectral Embedding  Laplacian Eigenmaps  algorithm comprises three stages     1    Weighted Graph Construction    Transform the raw input data into      graph representation using affinity  adjacency  matrix representation     2    Graph Laplacian Construction    unnormalized Graph Laplacian      is constructed as  math  L   D   A  for and normalized one as       math  L   D    frac 1  2    D   A  D    frac 1  2        3    Partial Eigenvalue Decomposition    Eigenvalue decomposition is      done on graph Laplacian     The overall complexity of spectral embedding is    math  O D  log k  N  log N     O D N k 3    O d N 2          math  N    number of training data points      math  D    input dimension      math  k    number of nearest neighbors      math  d    output dimension     rubric   References      Laplacian Eigenmaps for Dimensionality Reduction   and Data Representation     https   web cse ohio state edu  mbelkin papers LEM NC 03 pdf      M  Belkin  P  Niyogi  Neural Computation  June 2003  15  6  1373 1396   Local Tangent Space Alignment                                Though not technically a variant of LLE  Local tangent space alignment  LTSA  is algorithmically similar enough to LLE that it can be put in this category  Rather than focusing on preserving neighborhood distances as in LLE  LTSA seeks to characterize the local geometry at each neighborhood via its tangent space  and performs a global optimization to align these local tangent spaces to learn the embedding   LTSA can be performed with function  func  locally linear embedding  or its object oriented counterpart  class  LocallyLinearEmbedding   with the keyword   method    ltsa         figure      auto examples manifold images sphx glr plot lle digits 009 png     target     auto examples manifold plot lle digits html     align  center     scale  50     dropdown   Complexity    The LTSA algorithm comprises three stages     1    Nearest Neighbors Search     Same as standard LLE    2    Weight Matrix Construction    Approximately       math  O D N k 3    O k 2 d     The first term reflects a similar      cost to that of standard LLE     3    Partial Eigenvalue Decomposition    Same as standard LLE    The overall complexity of standard LTSA is    math  O D  log k  N  log N     O D N k 3    O k 2 d    O d N 2          math  N    number of training data points      math  D    input dimension      math  k    number of nearest neighbors      math  d    output dimension     rubric   References     arxiv   Principal manifolds and nonlinear dimensionality reduction via   tangent space alignment     cs 0212008     Zhang  Z    Zha  H  Journal of Shanghai Univ  8 406  2004       multidimensional scaling   Multi dimensional Scaling  MDS                                    Multidimensional scaling  https   en wikipedia org wiki Multidimensional scaling      class  MDS   seeks a low dimensional representation of the data in which the distances respect well the distances in the original high dimensional space   In general   class  MDS  is a technique used for analyzing similarity or dissimilarity data  It attempts to model similarity or dissimilarity data as distances in a geometric spaces  The data can be ratings of similarity between objects  interaction frequencies of molecules  or trade indices between countries   There exists two types of MDS algorithm  metric and non metric  In scikit learn  the class  class  MDS  implements both  In Metric MDS  the input similarity matrix arises from a metric  and thus respects the triangular inequality   the distances between output two points are then set to be as close as possible to the similarity or dissimilarity data  In the non metric version  the algorithms will try to preserve the order of the distances  and hence seek for a monotonic relationship between the distances in the embedded space and the similarities dissimilarities      figure      auto examples manifold images sphx glr plot lle digits 010 png     target     auto examples manifold plot lle digits html     align  center     scale  50   Let  math  S  be the similarity matrix  and  math  X  the coordinates of the  math  n  input points  Disparities  math   hat d   ij   are transformation of the similarities chosen in some optimal ways  The objective  called the stress  is then defined by  math   sum  i   j  d  ij  X     hat d   ij  X        dropdown   Metric MDS    The simplest metric  class  MDS  model  called  absolute MDS   disparities are defined by    math   hat d   ij    S  ij    With absolute MDS  the value  math  S  ij     should then correspond exactly to the distance between point  math  i  and    math  j  in the embedding point     Most commonly  disparities are set to  math   hat d   ij    b S  ij        dropdown   Nonmetric MDS    Non metric  class  MDS  focuses on the ordination of the data  If    math  S  ij    S  jk    then the embedding should enforce  math  d  ij      d  jk    For this reason  we discuss it in terms of dissimilarities     math   delta  ij    instead of similarities   math  S  ij     Note that   dissimilarities can easily be obtained from similarities through a simple   transform  e g   math   delta  ij  c 1 c 2 S  ij   for some real constants    math  c 1  c 2   A simple algorithm to enforce proper ordination is to use a   monotonic regression of  math  d  ij   on  math   delta  ij    yielding   disparities  math   hat d   ij   in the same order as  math   delta  ij       A trivial solution to this problem is to set all the points on the origin  In   order to avoid that  the disparities  math   hat d   ij   are normalized  Note   that since we only care about relative ordering  our objective should be   invariant to simple translation and scaling  however the stress used in metric   MDS is sensitive to scaling  To address this  non metric MDS may use a   normalized stress  known as Stress 1 defined as       math          sqrt  frac  sum  i   j   d  ij     hat d   ij   2   sum  i   j  d  ij  2       The use of normalized Stress 1 can be enabled by setting  normalized stress True     however it is only compatible with the non metric MDS problem and will be ignored   in the metric case        figure      auto examples manifold images sphx glr plot mds 001 png      target     auto examples manifold plot mds html      align  center      scale  60     rubric   References      Modern Multidimensional Scaling   Theory and Applications     https   www springer com fr book 9780387251509      Borg  I   Groenen P  Springer Series in Statistics  1997       Nonmetric multidimensional scaling  a numerical method     http   cda psych uiuc edu psychometrika highly cited articles kruskal 1964b pdf      Kruskal  J  Psychometrika  29  1964       Multidimensional scaling by optimizing goodness of fit to a nonmetric hypothesis     http   cda psych uiuc edu psychometrika highly cited articles kruskal 1964a pdf      Kruskal  J  Psychometrika  29   1964       t sne   t distributed Stochastic Neighbor Embedding  t SNE                                                       t SNE   class  TSNE   converts affinities of data points to probabilities  The affinities in the original space are represented by Gaussian joint probabilities and the affinities in the embedded space are represented by Student s t distributions  This allows t SNE to be particularly sensitive to local structure and has a few other advantages over existing techniques     Revealing the structure at many scales on a single map   Revealing data that lie in multiple  different  manifolds or clusters   Reducing the tendency to crowd points together at the center  While Isomap  LLE and variants are best suited to unfold a single continuous low dimensional manifold  t SNE will focus on the local structure of the data and will tend to extract clustered local groups of samples as highlighted on the S curve example  This ability to group samples based on the local structure might be beneficial to visually disentangle a dataset that comprises several manifolds at once as is the case in the digits dataset   The Kullback Leibler  KL  divergence of the joint probabilities in the original space and the embedded space will be minimized by gradient descent  Note that the KL divergence is not convex  i e  multiple restarts with different initializations will end up in local minima of the KL divergence  Hence  it is sometimes useful to try different seeds and select the embedding with the lowest KL divergence   The disadvantages to using t SNE are roughly     t SNE is computationally expensive  and can take several hours on million sample   datasets where PCA will finish in seconds or minutes   The Barnes Hut t SNE method is limited to two or three dimensional embeddings    The algorithm is stochastic and multiple restarts with different seeds can   yield different embeddings  However  it is perfectly legitimate to pick the   embedding with the least error    Global structure is not explicitly preserved  This problem is mitigated by   initializing points with PCA  using  init  pca          figure      auto examples manifold images sphx glr plot lle digits 013 png     target     auto examples manifold plot lle digits html     align  center     scale  50     dropdown   Optimizing t SNE    The main purpose of t SNE is visualization of high dimensional data  Hence    it works best when the data will be embedded on two or three dimensions     Optimizing the KL divergence can be a little bit tricky sometimes  There are   five parameters that control the optimization of t SNE and therefore possibly   the quality of the resulting embedding       perplexity     early exaggeration factor     learning rate     maximum number of iterations     angle  not used in the exact method     The perplexity is defined as  math  k 2   S    where  math  S  is the Shannon   entropy of the conditional probability distribution  The perplexity of a    math  k  sided die is  math  k   so that  math  k  is effectively the number of   nearest neighbors t SNE considers when generating the conditional probabilities    Larger perplexities lead to more nearest neighbors and less sensitive to small   structure  Conversely a lower perplexity considers a smaller number of   neighbors  and thus ignores more global information in favour of the   local neighborhood  As dataset sizes get larger more points will be   required to get a reasonable sample of the local neighborhood  and hence   larger perplexities may be required  Similarly noisier datasets will require   larger perplexity values to encompass enough local neighbors to see beyond   the background noise     The maximum number of iterations is usually high enough and does not need   any tuning  The optimization consists of two phases  the early exaggeration   phase and the final optimization  During early exaggeration the joint   probabilities in the original space will be artificially increased by   multiplication with a given factor  Larger factors result in larger gaps   between natural clusters in the data  If the factor is too high  the KL   divergence could increase during this phase  Usually it does not have to be   tuned  A critical parameter is the learning rate  If it is too low gradient   descent will get stuck in a bad local minimum  If it is too high the KL   divergence will increase during optimization  A heuristic suggested in   Belkina et al   2019  is to set the learning rate to the sample size   divided by the early exaggeration factor  We implement this heuristic   as  learning rate  auto   argument  More tips can be found in   Laurens van der Maaten s FAQ  see references   The last parameter  angle    is a tradeoff between performance and accuracy  Larger angles imply that we   can approximate larger regions by a single point  leading to better speed   but less accurate results       How to Use t SNE Effectively   https   distill pub 2016 misread tsne       provides a good discussion of the effects of the various parameters  as well   as interactive plots to explore the effects of different parameters      dropdown   Barnes Hut t SNE    The Barnes Hut t SNE that has been implemented here is usually much slower than   other manifold learning algorithms  The optimization is quite difficult   and the computation of the gradient is  math  O d N log N     where  math  d    is the number of output dimensions and  math  N  is the number of samples  The   Barnes Hut method improves on the exact method where t SNE complexity is    math  O d N 2    but has several other notable differences       The Barnes Hut implementation only works when the target dimensionality is 3     or less  The 2D case is typical when building visualizations      Barnes Hut only works with dense input data  Sparse data matrices can only be     embedded with the exact method or can be approximated by a dense low rank     projection for instance using  class   sklearn decomposition PCA      Barnes Hut is an approximation of the exact method  The approximation is     parameterized with the angle parameter  therefore the angle parameter is     unused when method  exact      Barnes Hut is significantly more scalable  Barnes Hut can be used to embed     hundred of thousands of data points while the exact method can handle     thousands of samples before becoming computationally intractable    For visualization purpose  which is the main use case of t SNE   using the   Barnes Hut method is strongly recommended  The exact t SNE method is useful   for checking the theoretically properties of the embedding possibly in higher   dimensional space but limit to small datasets due to computational constraints     Also note that the digits labels roughly match the natural grouping found by   t SNE while the linear 2D projection of the PCA model yields a representation   where label regions largely overlap  This is a strong clue that this data can   be well separated by non linear methods that focus on the local structure  e g    an SVM with a Gaussian RBF kernel   However  failing to visualize well   separated homogeneously labeled groups with t SNE in 2D does not necessarily   imply that the data cannot be correctly classified by a supervised model  It   might be the case that 2 dimensions are not high enough to accurately represent   the internal structure of the data      rubric   References      Visualizing High Dimensional Data Using t SNE     https   jmlr org papers v9 vandermaaten08a html      van der Maaten  L J P   Hinton  G  Journal of Machine Learning Research  2008       t Distributed Stochastic Neighbor Embedding     https   lvdmaaten github io tsne     van der Maaten  L J P       Accelerating t SNE using Tree Based Algorithms     https   lvdmaaten github io publications papers JMLR 2014 pdf      van der Maaten  L J P   Journal of Machine Learning Research 15 Oct  3221 3245  2014       Automated optimized parameters for T distributed stochastic neighbor   embedding improve visualization and analysis of large datasets     https   www nature com articles s41467 019 13055 y      Belkina  A C   Ciccolella  C O   Anno  R   Halpert  R   Spidlen  J     Snyder Cappione  J E   Nature Communications 10  5415  2019    Tips on practical use                          Make sure the same scale is used over all features  Because manifold   learning methods are based on a nearest neighbor search  the algorithm   may perform poorly otherwise   See  ref  StandardScaler  preprocessing scaler     for convenient ways of scaling heterogeneous data     The reconstruction error computed by each routine can be used to choose   the optimal output dimension   For a  math  d  dimensional manifold embedded   in a  math  D  dimensional parameter space  the reconstruction error will   decrease as   n components   is increased until   n components    d       Note that noisy data can  short circuit  the manifold  in essence acting   as a bridge between parts of the manifold that would otherwise be   well separated   Manifold learning on noisy and or incomplete data is   an active area of research     Certain input configurations can lead to singular weight matrices  for   example when more than two points in the dataset are identical  or when   the data is split into disjointed groups   In this case    solver  arpack      will fail to find the null space   The easiest way to address this is to   use   solver  dense    which will work on a singular matrix  though it may   be very slow depending on the number of input points   Alternatively  one   can attempt to understand the source of the singularity  if it is due to   disjoint sets  increasing   n neighbors   may help   If it is due to   identical points in the dataset  removing these points may help      seealso        ref  random trees embedding  can also be useful to derive non linear    representations of feature space  also it does not perform    dimensionality reduction


scikit-learn Installing the development version of scikit learn advanced installation mindependencysubstitutions rst This section introduces how to install the main branch of scikit learn

Answer:
.. _advanced-installation:

.. include:: ../min_dependency_substitutions.rst

==================================================
Installing the development version of scikit-learn
==================================================

This section introduces how to install the **main branch** of scikit-learn.
This can be done by either installing a nightly build or building from source.

.. _install_nightly_builds:

Installing nightly builds
=========================

The continuous integration servers of the scikit-learn project build, test
and upload wheel packages for the most recent Python version on a nightly
basis.

Installing a nightly build is the quickest way to:

- try a new feature that will be shipped in the next release (that is, a
  feature from a pull-request that was recently merged to the main branch);

- check whether a bug you encountered has been fixed since the last release.

You can install the nightly build of scikit-learn using the `scientific-python-nightly-wheels`
index from the PyPI registry of `anaconda.org`:

.. prompt:: bash $

  pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple scikit-learn

Note that first uninstalling scikit-learn might be required to be able to
install nightly builds of scikit-learn.

.. _install_bleeding_edge:

Building from source
====================

Building from source is required to work on a contribution (bug fix, new
feature, code or documentation improvement).

.. _git_repo:

#. Use `Git <https://git-scm.com/>`_ to check out the latest source from the
   `scikit-learn repository <https://github.com/scikit-learn/scikit-learn>`_ on
   Github.:

   .. prompt:: bash $

     git clone git@github.com:scikit-learn/scikit-learn.git  # add --depth 1 if your connection is slow
     cd scikit-learn

   If you plan on submitting a pull-request, you should clone from your fork
   instead.

#. Install a recent version of Python (3.9 or later at the time of writing) for
   instance using Miniforge3_. Miniforge provides a conda-based distribution of
   Python and the most popular scientific libraries.

   If you installed Python with conda, we recommend to create a dedicated
   `conda environment`_ with all the build dependencies of scikit-learn
   (namely NumPy_, SciPy_, Cython_, meson-python_ and Ninja_):

   .. prompt:: bash $

     conda create -n sklearn-env -c conda-forge python numpy scipy cython meson-python ninja

   It is not always necessary but it is safer to open a new prompt before
   activating the newly created conda environment.

   .. prompt:: bash $

     conda activate sklearn-env

#. **Alternative to conda:** You can use alternative installations of Python
   provided they are recent enough (3.9 or higher at the time of writing).
   Here is an example on how to create a build environment for a Linux system's
   Python. Build dependencies are installed with `pip` in a dedicated virtualenv_
   to avoid disrupting other Python programs installed on the system:

   .. prompt:: bash $

     python3 -m venv sklearn-env
     source sklearn-env/bin/activate
     pip install wheel numpy scipy cython meson-python ninja

#. Install a compiler with OpenMP_ support for your platform. See instructions
   for :ref:`compiler_windows`, :ref:`compiler_macos`, :ref:`compiler_linux`
   and :ref:`compiler_freebsd`.

#. Build the project with pip:

   .. prompt:: bash $

     pip install --editable . \
        --verbose --no-build-isolation \
        --config-settings editable-verbose=true

#. Check that the installed scikit-learn has a version number ending with
   `.dev0`:

   .. prompt:: bash $

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

#. Please refer to the :ref:`developers_guide` and :ref:`pytest_tips` to run
   the tests on the module of your choice.

.. note::

    `--config-settings editable-verbose=true` is optional but recommended
    to avoid surprises when you import `sklearn`. `meson-python` implements
    editable installs by rebuilding `sklearn` when executing `import sklearn`.
    With the recommended setting you will see a message when this happens,
    rather than potentially waiting without feed-back and wondering
    what is taking so long. Bonus: this means you only have to run the `pip
    install` command once, `sklearn` will automatically be rebuilt when
    importing `sklearn`.

    Note that `--config-settings` is only supported in `pip` version 23.1 or
    later. To upgrade `pip` to a compatible version, run `pip install -U pip`.

Dependencies
------------

Runtime dependencies
~~~~~~~~~~~~~~~~~~~~

Scikit-learn requires the following dependencies both at build time and at
runtime:

- Python (>= 3.8),
- NumPy (>= |NumpyMinVersion|),
- SciPy (>= |ScipyMinVersion|),
- Joblib (>= |JoblibMinVersion|),
- threadpoolctl (>= |ThreadpoolctlMinVersion|).

Build dependencies
~~~~~~~~~~~~~~~~~~

Building Scikit-learn also requires:

..
    # The following places need to be in sync with regard to Cython version:
    # - .circleci config file
    # - sklearn/_build_utils/__init__.py
    # - advanced installation guide

- Cython >= |CythonMinVersion|
- A C/C++ compiler and a matching OpenMP_ runtime library. See the
  :ref:`platform system specific instructions
  <platform_specific_instructions>` for more details.

.. note::

   If OpenMP is not supported by the compiler, the build will be done with
   OpenMP functionalities disabled. This is not recommended since it will force
   some estimators to run in sequential mode instead of leveraging thread-based
   parallelism. Setting the ``SKLEARN_FAIL_NO_OPENMP`` environment variable
   (before cythonization) will force the build to fail if OpenMP is not
   supported.

Since version 0.21, scikit-learn automatically detects and uses the linear
algebra library used by SciPy **at runtime**. Scikit-learn has therefore no
build dependency on BLAS/LAPACK implementations such as OpenBlas, Atlas, Blis
or MKL.

Test dependencies
~~~~~~~~~~~~~~~~~

Running tests requires:

- pytest >= |PytestMinVersion|

Some tests also require `pandas <https://pandas.pydata.org>`_.

Building a specific version from a tag
--------------------------------------

If you want to build a stable version, you can ``git checkout <VERSION>``
to get the code for that particular version, or download an zip archive of
the version from github.

.. _platform_specific_instructions:

Platform-specific instructions
==============================

Here are instructions to install a working C/C++ compiler with OpenMP support
to build scikit-learn Cython extensions for each supported platform.

.. _compiler_windows:

Windows
-------

First, download the `Build Tools for Visual Studio 2019 installer
<https://aka.ms/vs/17/release/vs_buildtools.exe>`_.

Run the downloaded `vs_buildtools.exe` file, during the installation you will
need to make sure you select "Desktop development with C++", similarly to this
screenshot:

.. image:: ../images/visual-studio-build-tools-selection.png

Secondly, find out if you are running 64-bit or 32-bit Python. The building
command depends on the architecture of the Python interpreter. You can check
the architecture by running the following in ``cmd`` or ``powershell``
console:

.. prompt:: bash $

    python -c "import struct; print(struct.calcsize('P') * 8)"

For 64-bit Python, configure the build environment by running the following
commands in ``cmd`` or an Anaconda Prompt (if you use Anaconda):

.. sphinx-prompt 1.3.0 (used in doc-min-dependencies CI task) does not support `batch` prompt type,
.. so we work around by using a known prompt type and an explicit prompt text.
..
.. prompt:: bash C:\>

    SET DISTUTILS_USE_SDK=1
    "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64

Replace ``x64`` by ``x86`` to build for 32-bit Python.

Please be aware that the path above might be different from user to user. The
aim is to point to the "vcvarsall.bat" file that will set the necessary
environment variables in the current command prompt.

Finally, build scikit-learn with this command prompt:

.. prompt:: bash $

    pip install --editable . \
        --verbose --no-build-isolation \
        --config-settings editable-verbose=true

.. _compiler_macos:

macOS
-----

The default C compiler on macOS, Apple clang (confusingly aliased as
`/usr/bin/gcc`), does not directly support OpenMP. We present two alternatives
to enable OpenMP support:

- either install `conda-forge::compilers` with conda;

- or install `libomp` with Homebrew to extend the default Apple clang compiler.

For Apple Silicon M1 hardware, only the conda-forge method below is known to
work at the time of writing (January 2021). You can install the `macos/arm64`
distribution of conda using the `miniforge installer
<https://github.com/conda-forge/miniforge#miniforge>`_

macOS compilers from conda-forge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you use the conda package manager (version >= 4.7), you can install the
``compilers`` meta-package from the conda-forge channel, which provides
OpenMP-enabled C/C++ compilers based on the llvm toolchain.

First install the macOS command line tools:

.. prompt:: bash $

    xcode-select --install

It is recommended to use a dedicated `conda environment`_ to build
scikit-learn from source:

.. prompt:: bash $

    conda create -n sklearn-dev -c conda-forge python numpy scipy cython \
        joblib threadpoolctl pytest compilers llvm-openmp meson-python ninja

It is not always necessary but it is safer to open a new prompt before
activating the newly created conda environment.

.. prompt:: bash $

    conda activate sklearn-dev
    make clean
    pip install --editable . \
        --verbose --no-build-isolation \
        --config-settings editable-verbose=true

.. note::

    If you get any conflicting dependency error message, try commenting out
    any custom conda configuration in the ``$HOME/.condarc`` file. In
    particular the ``channel_priority: strict`` directive is known to cause
    problems for this setup.

You can check that the custom compilers are properly installed from conda
forge using the following command:

.. prompt:: bash $

    conda list

which should include ``compilers`` and ``llvm-openmp``.

The compilers meta-package will automatically set custom environment
variables:

.. prompt:: bash $

    echo $CC
    echo $CXX
    echo $CFLAGS
    echo $CXXFLAGS
    echo $LDFLAGS

They point to files and folders from your ``sklearn-dev`` conda environment
(in particular in the bin/, include/ and lib/ subfolders). For instance
``-L/path/to/conda/envs/sklearn-dev/lib`` should appear in ``LDFLAGS``.

In the log, you should see the compiled extension being built with the clang
and clang++ compilers installed by conda with the ``-fopenmp`` command line
flag.

macOS compilers from Homebrew
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Another solution is to enable OpenMP support for the clang compiler shipped
by default on macOS.

First install the macOS command line tools:

.. prompt:: bash $

    xcode-select --install

Install the Homebrew_ package manager for macOS.

Install the LLVM OpenMP library:

.. prompt:: bash $

    brew install libomp

Set the following environment variables:

.. prompt:: bash $

    export CC=/usr/bin/clang
    export CXX=/usr/bin/clang++
    export CPPFLAGS="$CPPFLAGS -Xpreprocessor -fopenmp"
    export CFLAGS="$CFLAGS -I/usr/local/opt/libomp/include"
    export CXXFLAGS="$CXXFLAGS -I/usr/local/opt/libomp/include"
    export LDFLAGS="$LDFLAGS -Wl,-rpath,/usr/local/opt/libomp/lib -L/usr/local/opt/libomp/lib -lomp"

Finally, build scikit-learn in verbose mode (to check for the presence of the
``-fopenmp`` flag in the compiler commands):

.. prompt:: bash $

    make clean
    pip install --editable . \
        --verbose --no-build-isolation \
        --config-settings editable-verbose=true

.. _compiler_linux:

Linux
-----

Linux compilers from the system
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Installing scikit-learn from source without using conda requires you to have
installed the scikit-learn Python development headers and a working C/C++
compiler with OpenMP support (typically the GCC toolchain).

Install build dependencies for Debian-based operating systems, e.g.
Ubuntu:

.. prompt:: bash $

    sudo apt-get install build-essential python3-dev python3-pip

then proceed as usual:

.. prompt:: bash $

    pip3 install cython
    pip3 install --editable . \
        --verbose --no-build-isolation \
        --config-settings editable-verbose=true

Cython and the pre-compiled wheels for the runtime dependencies (numpy, scipy
and joblib) should automatically be installed in
``$HOME/.local/lib/pythonX.Y/site-packages``. Alternatively you can run the
above commands from a virtualenv_ or a `conda environment`_ to get full
isolation from the Python packages installed via the system packager. When
using an isolated environment, ``pip3`` should be replaced by ``pip`` in the
above commands.

When precompiled wheels of the runtime dependencies are not available for your
architecture (e.g. ARM), you can install the system versions:

.. prompt:: bash $

    sudo apt-get install cython3 python3-numpy python3-scipy

On Red Hat and clones (e.g. CentOS), install the dependencies using:

.. prompt:: bash $

    sudo yum -y install gcc gcc-c++ python3-devel numpy scipy

Linux compilers from conda-forge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Alternatively, install a recent version of the GNU C Compiler toolchain (GCC)
in the user folder using conda:

.. prompt:: bash $

    conda create -n sklearn-dev -c conda-forge python numpy scipy cython \
        joblib threadpoolctl pytest compilers meson-python ninja

It is not always necessary but it is safer to open a new prompt before
activating the newly created conda environment.

.. prompt:: bash $

    conda activate sklearn-dev
    pip install --editable . \
        --verbose --no-build-isolation \
        --config-settings editable-verbose=true

.. _compiler_freebsd:

FreeBSD
-------

The clang compiler included in FreeBSD 12.0 and 11.2 base systems does not
include OpenMP support. You need to install the `openmp` library from packages
(or ports):

.. prompt:: bash $

    sudo pkg install openmp

This will install header files in ``/usr/local/include`` and libs in
``/usr/local/lib``. Since these directories are not searched by default, you
can set the environment variables to these locations:

.. prompt:: bash $

    export CFLAGS="$CFLAGS -I/usr/local/include"
    export CXXFLAGS="$CXXFLAGS -I/usr/local/include"
    export LDFLAGS="$LDFLAGS -Wl,-rpath,/usr/local/lib -L/usr/local/lib -lomp"

Finally, build the package using the standard command:

.. prompt:: bash $

    pip install --editable . \
        --verbose --no-build-isolation \
        --config-settings editable-verbose=true

For the upcoming FreeBSD 12.1 and 11.3 versions, OpenMP will be included in
the base system and these steps will not be necessary.

.. _OpenMP: https://en.wikipedia.org/wiki/OpenMP
.. _Cython: https://cython.org
.. _meson-python: https://mesonbuild.com/meson-python
.. _Ninja: https://ninja-build.org/
.. _NumPy: https://numpy.org
.. _SciPy: https://www.scipy.org
.. _Homebrew: https://brew.sh
.. _virtualenv: https://docs.python.org/3/tutorial/venv.html
.. _conda environment: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html
.. _Miniforge3: https://github.com/conda-forge/miniforge#miniforge3

advanced installation      include      min dependency substitutions rst                                                     Installing the development version of scikit learn                                                     This section introduces how to install the   main branch   of scikit learn  This can be done by either installing a nightly build or building from source       install nightly builds   Installing nightly builds                            The continuous integration servers of the scikit learn project build  test and upload wheel packages for the most recent Python version on a nightly basis   Installing a nightly build is the quickest way to     try a new feature that will be shipped in the next release  that is  a   feature from a pull request that was recently merged to the main branch      check whether a bug you encountered has been fixed since the last release   You can install the nightly build of scikit learn using the  scientific python nightly wheels  index from the PyPI registry of  anaconda org       prompt   bash      pip install   pre   extra index https   pypi anaconda org scientific python nightly wheels simple scikit learn  Note that first uninstalling scikit learn might be required to be able to install nightly builds of scikit learn       install bleeding edge   Building from source                       Building from source is required to work on a contribution  bug fix  new feature  code or documentation improvement        git repo      Use  Git  https   git scm com     to check out the latest source from the     scikit learn repository  https   github com scikit learn scikit learn    on    Github          prompt   bash         git clone git github com scikit learn scikit learn git    add   depth 1 if your connection is slow      cd scikit learn     If you plan on submitting a pull request  you should clone from your fork    instead      Install a recent version of Python  3 9 or later at the time of writing  for    instance using Miniforge3   Miniforge provides a conda based distribution of    Python and the most popular scientific libraries      If you installed Python with conda  we recommend to create a dedicated     conda environment   with all the build dependencies of scikit learn     namely NumPy   SciPy   Cython   meson python  and Ninja           prompt   bash         conda create  n sklearn env  c conda forge python numpy scipy cython meson python ninja     It is not always necessary but it is safer to open a new prompt before    activating the newly created conda environment         prompt   bash         conda activate sklearn env       Alternative to conda    You can use alternative installations of Python    provided they are recent enough  3 9 or higher at the time of writing      Here is an example on how to create a build environment for a Linux system s    Python  Build dependencies are installed with  pip  in a dedicated virtualenv     to avoid disrupting other Python programs installed on the system         prompt   bash         python3  m venv sklearn env      source sklearn env bin activate      pip install wheel numpy scipy cython meson python ninja     Install a compiler with OpenMP  support for your platform  See instructions    for  ref  compiler windows    ref  compiler macos    ref  compiler linux     and  ref  compiler freebsd       Build the project with pip         prompt   bash         pip install   editable               verbose   no build isolation             config settings editable verbose true     Check that the installed scikit learn has a version number ending with      dev0          prompt   bash         python  c  import sklearn  sklearn show versions        Please refer to the  ref  developers guide  and  ref  pytest tips  to run    the tests on the module of your choice      note           config settings editable verbose true  is optional but recommended     to avoid surprises when you import  sklearn    meson python  implements     editable installs by rebuilding  sklearn  when executing  import sklearn       With the recommended setting you will see a message when this happens      rather than potentially waiting without feed back and wondering     what is taking so long  Bonus  this means you only have to run the  pip     install  command once   sklearn  will automatically be rebuilt when     importing  sklearn        Note that    config settings  is only supported in  pip  version 23 1 or     later  To upgrade  pip  to a compatible version  run  pip install  U pip    Dependencies               Runtime dependencies                       Scikit learn requires the following dependencies both at build time and at runtime     Python     3 8     NumPy      NumpyMinVersion      SciPy      ScipyMinVersion      Joblib      JoblibMinVersion      threadpoolctl      ThreadpoolctlMinVersion     Build dependencies                     Building Scikit learn also requires            The following places need to be in sync with regard to Cython version           circleci config file         sklearn  build utils   init   py         advanced installation guide    Cython     CythonMinVersion    A C C   compiler and a matching OpenMP  runtime library  See the    ref  platform system specific instructions    platform specific instructions   for more details      note       If OpenMP is not supported by the compiler  the build will be done with    OpenMP functionalities disabled  This is not recommended since it will force    some estimators to run in sequential mode instead of leveraging thread based    parallelism  Setting the   SKLEARN FAIL NO OPENMP   environment variable     before cythonization  will force the build to fail if OpenMP is not    supported   Since version 0 21  scikit learn automatically detects and uses the linear algebra library used by SciPy   at runtime    Scikit learn has therefore no build dependency on BLAS LAPACK implementations such as OpenBlas  Atlas  Blis or MKL   Test dependencies                    Running tests requires     pytest     PytestMinVersion   Some tests also require  pandas  https   pandas pydata org       Building a specific version from a tag                                         If you want to build a stable version  you can   git checkout  VERSION    to get the code for that particular version  or download an zip archive of the version from github       platform specific instructions   Platform specific instructions                                 Here are instructions to install a working C C   compiler with OpenMP support to build scikit learn Cython extensions for each supported platform       compiler windows   Windows          First  download the  Build Tools for Visual Studio 2019 installer  https   aka ms vs 17 release vs buildtools exe      Run the downloaded  vs buildtools exe  file  during the installation you will need to make sure you select  Desktop development with C     similarly to this screenshot      image      images visual studio build tools selection png  Secondly  find out if you are running 64 bit or 32 bit Python  The building command depends on the architecture of the Python interpreter  You can check the architecture by running the following in   cmd   or   powershell   console      prompt   bash        python  c  import struct  print struct calcsize  P     8    For 64 bit Python  configure the build environment by running the following commands in   cmd   or an Anaconda Prompt  if you use Anaconda       sphinx prompt 1 3 0  used in doc min dependencies CI task  does not support  batch  prompt type     so we work around by using a known prompt type and an explicit prompt text        prompt   bash C         SET DISTUTILS USE SDK 1      C  Program Files  x86  Microsoft Visual Studio 2019 BuildTools VC Auxiliary Build vcvarsall bat  x64  Replace   x64   by   x86   to build for 32 bit Python   Please be aware that the path above might be different from user to user  The aim is to point to the  vcvarsall bat  file that will set the necessary environment variables in the current command prompt   Finally  build scikit learn with this command prompt      prompt   bash        pip install   editable               verbose   no build isolation             config settings editable verbose true      compiler macos   macOS        The default C compiler on macOS  Apple clang  confusingly aliased as   usr bin gcc    does not directly support OpenMP  We present two alternatives to enable OpenMP support     either install  conda forge  compilers  with conda     or install  libomp  with Homebrew to extend the default Apple clang compiler   For Apple Silicon M1 hardware  only the conda forge method below is known to work at the time of writing  January 2021   You can install the  macos arm64  distribution of conda using the  miniforge installer  https   github com conda forge miniforge miniforge     macOS compilers from conda forge                                   If you use the conda package manager  version    4 7   you can install the   compilers   meta package from the conda forge channel  which provides OpenMP enabled C C   compilers based on the llvm toolchain   First install the macOS command line tools      prompt   bash        xcode select   install  It is recommended to use a dedicated  conda environment   to build scikit learn from source      prompt   bash        conda create  n sklearn dev  c conda forge python numpy scipy cython           joblib threadpoolctl pytest compilers llvm openmp meson python ninja  It is not always necessary but it is safer to open a new prompt before activating the newly created conda environment      prompt   bash        conda activate sklearn dev     make clean     pip install   editable               verbose   no build isolation             config settings editable verbose true     note        If you get any conflicting dependency error message  try commenting out     any custom conda configuration in the    HOME  condarc   file  In     particular the   channel priority  strict   directive is known to cause     problems for this setup   You can check that the custom compilers are properly installed from conda forge using the following command      prompt   bash        conda list  which should include   compilers   and   llvm openmp     The compilers meta package will automatically set custom environment variables      prompt   bash        echo  CC     echo  CXX     echo  CFLAGS     echo  CXXFLAGS     echo  LDFLAGS  They point to files and folders from your   sklearn dev   conda environment  in particular in the bin   include  and lib  subfolders   For instance    L path to conda envs sklearn dev lib   should appear in   LDFLAGS     In the log  you should see the compiled extension being built with the clang and clang   compilers installed by conda with the    fopenmp   command line flag   macOS compilers from Homebrew                                Another solution is to enable OpenMP support for the clang compiler shipped by default on macOS   First install the macOS command line tools      prompt   bash        xcode select   install  Install the Homebrew  package manager for macOS   Install the LLVM OpenMP library      prompt   bash        brew install libomp  Set the following environment variables      prompt   bash        export CC  usr bin clang     export CXX  usr bin clang       export CPPFLAGS   CPPFLAGS  Xpreprocessor  fopenmp      export CFLAGS   CFLAGS  I usr local opt libomp include      export CXXFLAGS   CXXFLAGS  I usr local opt libomp include      export LDFLAGS   LDFLAGS  Wl  rpath  usr local opt libomp lib  L usr local opt libomp lib  lomp   Finally  build scikit learn in verbose mode  to check for the presence of the    fopenmp   flag in the compiler commands       prompt   bash        make clean     pip install   editable               verbose   no build isolation             config settings editable verbose true      compiler linux   Linux        Linux compilers from the system                                  Installing scikit learn from source without using conda requires you to have installed the scikit learn Python development headers and a working C C   compiler with OpenMP support  typically the GCC toolchain    Install build dependencies for Debian based operating systems  e g  Ubuntu      prompt   bash        sudo apt get install build essential python3 dev python3 pip  then proceed as usual      prompt   bash        pip3 install cython     pip3 install   editable               verbose   no build isolation             config settings editable verbose true  Cython and the pre compiled wheels for the runtime dependencies  numpy  scipy and joblib  should automatically be installed in    HOME  local lib pythonX Y site packages    Alternatively you can run the above commands from a virtualenv  or a  conda environment   to get full isolation from the Python packages installed via the system packager  When using an isolated environment    pip3   should be replaced by   pip   in the above commands   When precompiled wheels of the runtime dependencies are not available for your architecture  e g  ARM   you can install the system versions      prompt   bash        sudo apt get install cython3 python3 numpy python3 scipy  On Red Hat and clones  e g  CentOS   install the dependencies using      prompt   bash        sudo yum  y install gcc gcc c   python3 devel numpy scipy  Linux compilers from conda forge                                   Alternatively  install a recent version of the GNU C Compiler toolchain  GCC  in the user folder using conda      prompt   bash        conda create  n sklearn dev  c conda forge python numpy scipy cython           joblib threadpoolctl pytest compilers meson python ninja  It is not always necessary but it is safer to open a new prompt before activating the newly created conda environment      prompt   bash        conda activate sklearn dev     pip install   editable               verbose   no build isolation             config settings editable verbose true      compiler freebsd   FreeBSD          The clang compiler included in FreeBSD 12 0 and 11 2 base systems does not include OpenMP support  You need to install the  openmp  library from packages  or ports       prompt   bash        sudo pkg install openmp  This will install header files in    usr local include   and libs in    usr local lib    Since these directories are not searched by default  you can set the environment variables to these locations      prompt   bash        export CFLAGS   CFLAGS  I usr local include      export CXXFLAGS   CXXFLAGS  I usr local include      export LDFLAGS   LDFLAGS  Wl  rpath  usr local lib  L usr local lib  lomp   Finally  build the package using the standard command      prompt   bash        pip install   editable               verbose   no build isolation             config settings editable verbose true  For the upcoming FreeBSD 12 1 and 11 3 versions  OpenMP will be included in the base system and these steps will not be necessary       OpenMP  https   en wikipedia org wiki OpenMP     Cython  https   cython org     meson python  https   mesonbuild com meson python     Ninja  https   ninja build org      NumPy  https   numpy org     SciPy  https   www scipy org     Homebrew  https   brew sh     virtualenv  https   docs python org 3 tutorial venv html     conda environment  https   docs conda io projects conda en latest user guide tasks manage environments html     Miniforge3  https   github com conda forge miniforge miniforge3