Spec-Zone.ru › scikit-learn

Примечание

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

Значение масштабирования признаков

Масштабирование признаков с помощью стандартизации, также называемой Z-нормализацией, является важным этапом предобработки для многих алгоритмов машинного обучения. Оно включает в себя перемасштабирование каждого признака таким образом, чтобы он имел стандартное отклонение 1 и среднее 0.

Даже если алгоритмы на основе деревьев практически не чувствительны к масштабированию, многие другие алгоритмы требуют нормализации признаков, часто по разным причинам: для облегчения сходимости (например, для нерегуляризованной логистической регрессии), для создания совершенно другой модели подгонки по сравнению с подгонкой на нес-масштабированных данных (например, для моделей KNeighbors). Последнее показано в первой части данного примера.

Во второй части примера показано, как на анализ главных компонент (PCA) влияет нормализация признаков. Для иллюстрации этого мы сравниваем главные компоненты, полученные с помощью PCA на нес-масштабированных данных с полученными при использовании StandardScaler для предварительного масштабирования данных.

В последней части примера показано влияние нормализации на точность модели, обученной на данных, уменьшенных с помощью PCA.

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

Загрузка и подготовка данных

Используемый набор данных — это набор данных по распознаванию вин набора данных UCI. В этом наборе данных непрерывные признаки неоднородны по масштабу из-за различных свойств, которые они измеряют (например, содержание алкоголя и яблочная кислота).

from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

X, y = load_wine(return_X_y=True, as_frame=True)
scaler = StandardScaler().set_output(transform="pandas")

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.30, random_state=42
)
scaled_X_train = scaler.fit_transform(X_train)

Влияние перемасштабирования на модели k-ближайших соседей

Для визуализации границ решений KNeighborsClassifier в данном разделе мы выбираем подмножество из 2 признаков, значения которых имеют разные порядки величины.

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

import matplotlib.pyplot as plt

from sklearn.inspection import DecisionBoundaryDisplay
from sklearn.neighbors import KNeighborsClassifier

X_plot = X[["proline", "hue"]]
X_plot_scaled = scaler.fit_transform(X_plot)
clf = KNeighborsClassifier(n_neighbors=20)


def fit_and_plot_model(X_plot, y, clf, ax):
    clf.fit(X_plot, y)
    disp = DecisionBoundaryDisplay.from_estimator(
        clf,
        X_plot,
        response_method="predict",
        alpha=0.5,
        ax=ax,
    )
    disp.ax_.scatter(X_plot["proline"], X_plot["hue"], c=y, s=20, edgecolor="k")
    disp.ax_.set_xlim((X_plot["proline"].min(), X_plot["proline"].max()))
    disp.ax_.set_ylim((X_plot["hue"].min(), X_plot["hue"].max()))
    return disp.ax_


fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 6))

fit_and_plot_model(X_plot, y, clf, ax1)
ax1.set_title("KNN without scaling")

fit_and_plot_model(X_plot_scaled, y, clf, ax2)
ax2.set_xlabel("scaled proline")
ax2.set_ylabel("scaled hue")
_ = ax2.set_title("KNN with scaling")
KNN without scaling, KNN with scaling

Здесь граница решений показывает, что обучение на масштабированных или не масштабированных данных приводит к совершенно разным моделям. Причина в том, что переменная «proline» имеет значения, варьирующиеся от 0 до 1000, в то время как переменная «hue» варьируется от 1 до 10. Из-за этого расстояния между образцами в основном зависят от различий в значениях «proline», в то время как значения «hue» будут сравнительно игнорироваться. Если использовать StandardScaler для нормализации этой базы данных, оба масштабированных значения окажутся примерно в диапазоне от -3 до 3, и структура соседей будет примерно одинаково зависеть от обеих переменных.

Влияние перемасштабирования на снижение размерности с помощью PCA

Снижение размерности с помощью PCA заключается в поиске признаков, которые максимизируют дисперсию. Если один признак меняется сильнее других только из-за своих масштабов, PCA определит, что такой признак доминирует в направлении главных компонент.

Мы можем изучить первые главные компоненты, используя все исходные признаки:

import pandas as pd

from sklearn.decomposition import PCA

pca = PCA(n_components=2).fit(X_train)
scaled_pca = PCA(n_components=2).fit(scaled_X_train)
X_train_transformed = pca.transform(X_train)
X_train_std_transformed = scaled_pca.transform(scaled_X_train)

first_pca_component = pd.DataFrame(
    pca.components_[0], index=X.columns, columns=["without scaling"]
)
first_pca_component["with scaling"] = scaled_pca.components_[0]
first_pca_component.plot.bar(
    title="Weights of the first principal component", figsize=(6, 8)
)

_ = plt.tight_layout()
Weights of the first principal component

Действительно, мы видим, что признак «proline» доминирует в направлении первой главной компоненты без масштабирования, имея примерно на два порядка величины больше, чем другие признаки. Это контрастирует с наблюдением первой главной компоненты для масштабированной версии данных, где порядки величин примерно одинаковы для всех признаков.

Мы можем визуализировать распределение главных компонент в обоих случаях:

fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))

target_classes = range(0, 3)
colors = ("blue", "red", "green")
markers = ("^", "s", "o")

for target_class, color, marker in zip(target_classes, colors, markers):
    ax1.scatter(
        x=X_train_transformed[y_train == target_class, 0],
        y=X_train_transformed[y_train == target_class, 1],
        color=color,
        label=f"class {target_class}",
        alpha=0.5,
        marker=marker,
    )

    ax2.scatter(
        x=X_train_std_transformed[y_train == target_class, 0],
        y=X_train_std_transformed[y_train == target_class, 1],
        color=color,
        label=f"class {target_class}",
        alpha=0.5,
        marker=marker,
    )

ax1.set_title("Unscaled training dataset after PCA")
ax2.set_title("Standardized training dataset after PCA")

for ax in (ax1, ax2):
    ax.set_xlabel("1st principal component")
    ax.set_ylabel("2nd principal component")
    ax.legend(loc="upper right")
    ax.grid()

_ = plt.tight_layout()
Unscaled training dataset after PCA, Standardized training dataset after PCA

Из графика выше мы видим, что масштабирование признаков перед уменьшением размерности приводит к компонентам с одинаковым порядком величины. В этом случае это также улучшает разделимость классов. Действительно, в следующем разделе мы подтвердим, что лучшая разделимость хорошо сказывается на общей производительности модели.

Влияние перемасштабирования на производительность модели

Сначала мы покажем, как оптимальная регуляризация LogisticRegressionCV зависит от масштабирования или не масштабирования данных:

import numpy as np

from sklearn.linear_model import LogisticRegressionCV
from sklearn.pipeline import make_pipeline

Cs = np.logspace(-5, 5, 20)

unscaled_clf = make_pipeline(pca, LogisticRegressionCV(Cs=Cs))
unscaled_clf.fit(X_train, y_train)

scaled_clf = make_pipeline(scaler, pca, LogisticRegressionCV(Cs=Cs))
scaled_clf.fit(X_train, y_train)

print(f"Optimal C for the unscaled PCA: {unscaled_clf[-1].C_[0]:.4f}\n")
print(f"Optimal C for the standardized data with PCA: {scaled_clf[-1].C_[0]:.2f}")
Optimal C for the unscaled PCA: 0.0004

Optimal C for the standardized data with PCA: 20.69

Потребность в регуляризации выше (меньшие значения C) для данных, которые не были масштабированы до применения PCA. Теперь мы оценим влияние масштабирования на точность и средний логарифмический убыток оптимальных моделей:

from sklearn.metrics import accuracy_score, log_loss

y_pred = unscaled_clf.predict(X_test)
y_pred_scaled = scaled_clf.predict(X_test)
y_proba = unscaled_clf.predict_proba(X_test)
y_proba_scaled = scaled_clf.predict_proba(X_test)

print("Test accuracy for the unscaled PCA")
print(f"{accuracy_score(y_test, y_pred):.2%}\n")
print("Test accuracy for the standardized data with PCA")
print(f"{accuracy_score(y_test, y_pred_scaled):.2%}\n")
print("Log-loss for the unscaled PCA")
print(f"{log_loss(y_test, y_proba):.3}\n")
print("Log-loss for the standardized data with PCA")
print(f"{log_loss(y_test, y_proba_scaled):.3}")
Test accuracy for the unscaled PCA
35.19%

Test accuracy for the standardized data with PCA
96.30%

Log-loss for the unscaled PCA
0.957

Log-loss for the standardized data with PCA
0.0825

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

Обратите внимание, что в этом случае модели с масштабированными признаками работают лучше, чем модели с не масштабированными признаками, потому что все переменные, как ожидается, предсказывающие, и мы скорее избегаем того, чтобы некоторые из них были сравнительно игнорируемыми.

Если переменные с меньшими масштабами не являются предсказывающими, после масштабирования признаков может наблюдаться снижение производительности: шумные признаки будут в большей степени влиять на прогноз после масштабирования, и поэтому масштабирование увеличит переобучение.

И наконец, мы видим, что с помощью шага масштабирования достигается более низкий логарифмический убыток.

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

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_scaling_importance.ipynb

Download Python source code: plot_scaling_importance.py

Download zipped: plot_scaling_importance.zip

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

Масштабирование параметра регуляризации для SVC

Сравнение линейных байесовских регрессоров

Kernel PCA

Классификация ближайших соседей

© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/preprocessing/plot_scaling_importance.html

Spec-Zone.ru

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