Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.

Обучение на многообразиях для рукописных цифр: локально-линейное вложение, Isomap…

Мы демонстрируем различные методы вложения на наборе данных с цифрами.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Загрузка набора данных с цифрами

Мы загрузим набор данных с цифрами и будем использовать только первые шесть из десяти доступных классов.

from sklearn.datasets import load_digits

digits = load_digits(n_class=6)
X, y = digits.data, digits.target
n_samples, n_features = X.shape
n_neighbors = 30

Можно построить график первых ста цифр из этого набора данных.

import matplotlib.pyplot as plt

fig, axs = plt.subplots(nrows=10, ncols=10, figsize=(6, 6))
for idx, ax in enumerate(axs.ravel()):
    ax.imshow(X[idx].reshape((8, 8)), cmap=plt.cm.binary)
    ax.axis("off")
_ = fig.suptitle("A selection from the 64-dimensional digits dataset", fontsize=16)
A selection from the 64-dimensional digits dataset

Вспомогательная функция для построения графика вложения

Ниже мы применим различные методы для вложения набора данных с цифрами. Мы построим проекцию исходных данных на каждое вложение. Это позволит проверить, группируются ли цифры вместе в пространстве вложений или распределяются по нему.

import numpy as np
from matplotlib import offsetbox

from sklearn.preprocessing import MinMaxScaler


def plot_embedding(X, title):
    _, ax = plt.subplots()
    X = MinMaxScaler().fit_transform(X)

    for digit in digits.target_names:
        ax.scatter(
            *X[y == digit].T,
            marker=f"${digit}$",
            s=60,
            color=plt.cm.Dark2(digit),
            alpha=0.425,
            zorder=2,
        )
    shown_images = np.array([[1.0, 1.0]])  # just something big
    for i in range(X.shape[0]):
        # plot every digit on the embedding
        # show an annotation box for a group of digits
        dist = np.sum((X[i] - shown_images) ** 2, 1)
        if np.min(dist) < 4e-3:
            # don't show points that are too close
            continue
        shown_images = np.concatenate([shown_images, [X[i]]], axis=0)
        imagebox = offsetbox.AnnotationBbox(
            offsetbox.OffsetImage(digits.images[i], cmap=plt.cm.gray_r), X[i]
        )
        imagebox.set(zorder=1)
        ax.add_artist(imagebox)

    ax.set_title(title)
    ax.axis("off")

Сравнение методов вложения

Ниже мы сравним различные методы. Однако следует учесть несколько моментов:

  • RandomTreesEmbedding формально не является методом вложения многообразий, поскольку он обучает представление высокой размерности, к которому мы применяем метод снижения размерности. Однако часто бывает полезно преобразовать набор данных в представление, в котором классы линейно разделимы.
  • LinearDiscriminantAnalysis и NeighborhoodComponentsAnalysis — это методы снижения размерности с учителем, то есть они используют заданные метки, в отличие от других методов.
  • TSNE в этом примере инициализируется вложением, полученным с помощью PCA. Это обеспечивает глобальную стабильность вложения, то есть оно не зависит от случайной инициализации.
from sklearn.decomposition import TruncatedSVD
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.ensemble import RandomTreesEmbedding
from sklearn.manifold import (
    MDS,
    TSNE,
    ClassicalMDS,
    Isomap,
    LocallyLinearEmbedding,
    SpectralEmbedding,
)
from sklearn.neighbors import NeighborhoodComponentsAnalysis
from sklearn.pipeline import make_pipeline
from sklearn.random_projection import SparseRandomProjection

embeddings = {
    "Random projection embedding": SparseRandomProjection(
        n_components=2, random_state=42
    ),
    "Truncated SVD embedding": TruncatedSVD(n_components=2),
    "Linear Discriminant Analysis embedding": LinearDiscriminantAnalysis(
        n_components=2
    ),
    "Isomap embedding": Isomap(n_neighbors=n_neighbors, n_components=2),
    "Standard LLE embedding": LocallyLinearEmbedding(
        n_neighbors=n_neighbors, n_components=2, method="standard"
    ),
    "Modified LLE embedding": LocallyLinearEmbedding(
        n_neighbors=n_neighbors, n_components=2, method="modified"
    ),
    "Hessian LLE embedding": LocallyLinearEmbedding(
        n_neighbors=n_neighbors, n_components=2, method="hessian"
    ),
    "LTSA LLE embedding": LocallyLinearEmbedding(
        n_neighbors=n_neighbors, n_components=2, method="ltsa"
    ),
    "Metric MDS embedding": MDS(n_components=2, n_init=1, init="classical_mds"),
    "Non-metric MDS embedding": MDS(
        n_components=2, n_init=1, init="classical_mds", metric_mds=False
    ),
    "Classical MDS embedding": ClassicalMDS(n_components=2),
    "Random Trees embedding": make_pipeline(
        RandomTreesEmbedding(n_estimators=200, max_depth=5, random_state=0),
        TruncatedSVD(n_components=2),
    ),
    "Spectral embedding": SpectralEmbedding(
        n_components=2, random_state=0, eigen_solver="arpack"
    ),
    "t-SNE embedding": TSNE(
        n_components=2,
        max_iter=500,
        n_iter_without_progress=150,
        n_jobs=2,
        random_state=0,
    ),
    "NCA embedding": NeighborhoodComponentsAnalysis(
        n_components=2, init="pca", random_state=0
    ),
}

Определив все интересующие нас методы, можно выполнить проекцию исходных данных. Мы сохраним спроецированные данные и время вычислений, необходимое для каждой проекции.

from time import time

projections, timing = {}, {}
for name, transformer in embeddings.items():
    if name.startswith("Linear Discriminant Analysis"):
        data = X.copy()
        data.flat[:: X.shape[1] + 1] += 0.01  # Make X invertible
    else:
        data = X

    print(f"Computing {name}...")
    start_time = time()
    projections[name] = transformer.fit_transform(data, y)
    timing[name] = time() - start_time
Computing Random projection embedding...
Computing Truncated SVD embedding...
Computing Linear Discriminant Analysis embedding...
Computing Isomap embedding...
Computing Standard LLE embedding...
Computing Modified LLE embedding...
Computing Hessian LLE embedding...
Computing LTSA LLE embedding...
Computing Metric MDS embedding...
Computing Non-metric MDS embedding...
Computing Classical MDS embedding...
Computing Random Trees embedding...
Computing Spectral embedding...
Computing t-SNE embedding...
Computing NCA embedding...

Наконец, можно построить график проекции, полученной каждым методом.

for name in timing:
    title = f"{name} (time {timing[name]:.3f}s)"
    plot_embedding(projections[name], title)

plt.show()
  • Random projection embedding (time 0.002s)
  • Truncated SVD embedding (time 0.004s)
  • Linear Discriminant Analysis embedding (time 0.007s)
  • Isomap embedding (time 0.347s)
  • Standard LLE embedding (time 0.201s)
  • Modified LLE embedding (time 2.616s)
  • Hessian LLE embedding (time 1.954s)
  • LTSA LLE embedding (time 2.295s)
  • Metric MDS embedding (time 2.624s)
  • Non-metric MDS embedding (time 17.657s)
  • Classical MDS embedding (time 0.115s)
  • Random Trees embedding (time 0.263s)
  • Spectral embedding (time 0.151s)
  • t-SNE embedding (time 2.628s)
  • NCA embedding (time 2.913s)

Общее время выполнения скрипта: (0 минут 38.445 секунд)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_lle_digits.ipynb

Download Python source code: plot_lle_digits.py

Download zipped: plot_lle_digits.zip

Связанные примеры

Визуализация структуры фондового рынка

Сравнение методов обучения на многообразиях

Различные методы агломеративной кластеризации на двумерном вложении цифр

Преобразование признаков с помощью ансамблей деревьев

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/manifold/plot_lle_digits.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API