Spec-Zone.ru › scikit-learn

Примечание

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

Графики частичной зависимости и индивидуальных условных ожиданий

Графики частичной зависимости показывают зависимость целевой функции [2] и набора интересных признаков, учитывая значения всех других признаков (дополнительные признаки). Из-за ограничений восприятия человека размер набора интересных признаков должен быть небольшим (обычно один или два), поэтому они обычно выбираются среди самых важных признаков.

Аналогично, график индивидуального условного ожидания (ICE) [3] показывает зависимость целевой функции от интересующего признака. Однако, в отличие от графиков частичной зависимости, которые показывают среднее влияние интересующих признаков, графики ICE визуализируют зависимость предсказания от признака для каждого образца отдельно, с одной линией на каждый образец. Для графиков ICE поддерживается только один интересующий признак.

В этом примере показано, как получить графики частичной зависимости и ICE из MLPRegressor и HistGradientBoostingRegressor, обученных на наборе данных по прокату велосипедов. Пример вдохновлён [1].

[1]

Molnar, Christoph. “Interpretable machine learning. A Guide for Making Black Box Models Explainable”, 2019.

[2]

Для классификации можно представить это как регрессионный балл до применения функции связи.

[3]

Goldstein, A., Kapelner, A., Bleich, J., and Pitkin, E. (2015). “Peeking Inside the Black Box: Visualizing Statistical Learning With Plots of Individual Conditional Expectation”. Journal of Computational and Graphical Statistics, 24(1): 44-65

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

Предварительная обработка набора данных по прокату велосипедов

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

from sklearn.datasets import fetch_openml

bikes = fetch_openml("Bike_Sharing_Demand", version=2, as_frame=True)
# Make an explicit copy to avoid "SettingWithCopyWarning" from pandas
X, y = bikes.data.copy(), bikes.target

# We use only a subset of the data to speed up the example.
X = X.iloc[::5, :]
y = y[::5]

Признак "weather" имеет особенность: категория "heavy_rain" является редкой категорией.

X["weather"].value_counts()
weather
clear         2284
misty          904
rain           287
heavy_rain       1
Name: count, dtype: int64

Из-за этой редкой категории мы объединяем её в "rain".

X["weather"] = (
    X["weather"]
    .astype(object)
    .replace(to_replace="heavy_rain", value="rain")
    .astype("category")
)

Теперь мы более подробно рассмотрим признак "year":

X["year"].value_counts()
year
1    1747
0    1729
Name: count, dtype: int64

Мы видим, что у нас есть данные за два года. Мы используем первый год для обучения модели, а второй год для тестирования модели.

mask_training = X["year"] == 0.0
X = X.drop(columns=["year"])
X_train, y_train = X[mask_training], y[mask_training]
X_test, y_test = X[~mask_training], y[~mask_training]

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

X_train.info()
<class 'pandas.core.frame.DataFrame'>
Index: 1729 entries, 0 to 8640
Data columns (total 11 columns):
 #   Column      Non-Null Count  Dtype
---  ------      --------------  -----
 0   season      1729 non-null   category
 1   month       1729 non-null   int64
 2   hour        1729 non-null   int64
 3   holiday     1729 non-null   category
 4   weekday     1729 non-null   int64
 5   workingday  1729 non-null   category
 6   weather     1729 non-null   category
 7   temp        1729 non-null   float64
 8   feel_temp   1729 non-null   float64
 9   humidity    1729 non-null   float64
 10  windspeed   1729 non-null   float64
dtypes: category(4), float64(4), int64(3)
memory usage: 115.4 KB

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

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

numerical_features = [
    "temp",
    "feel_temp",
    "humidity",
    "windspeed",
]
categorical_features = X_train.columns.drop(numerical_features)

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

Мы строим график среднего количества проката велосипедов, сгруппировав данные по сезону и году.

from itertools import product

import matplotlib.pyplot as plt
import numpy as np

days = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
hours = tuple(range(24))
xticklabels = [f"{day}\n{hour}:00" for day, hour in product(days, hours)]
xtick_start, xtick_period = 6, 12

fig, axs = plt.subplots(nrows=2, figsize=(8, 6), sharey=True, sharex=True)
average_bike_rentals = bikes.frame.groupby(
    ["year", "season", "weekday", "hour"], observed=True
).mean(numeric_only=True)["count"]
for ax, (idx, df) in zip(axs, average_bike_rentals.groupby("year")):
    df.groupby("season", observed=True).plot(ax=ax, legend=True)

    # decorate the plot
    ax.set_xticks(
        np.linspace(
            start=xtick_start,
            stop=len(xticklabels),
            num=len(xticklabels) // xtick_period,
        )
    )
    ax.set_xticklabels(xticklabels[xtick_start::xtick_period])
    ax.set_xlabel("")
    ax.set_ylabel("Average number of bike rentals")
    ax.set_title(
        f"Bike rental for {'2010 (train set)' if idx == 0.0 else '2011 (test set)'}"
    )
    ax.set_ylim(0, 1_000)
    ax.set_xlim(0, len(xticklabels))
    ax.legend(loc=2)
Bike rental for 2010 (train set), Bike rental for 2011 (test set)

Первое заметное различие между набором обучающих и тестовых данных заключается в том, что количество проката велосипедов выше в тестовом наборе. Поэтому неудивительно, что модель машинного обучения недооценивает количество проката велосипедов. Также мы наблюдаем, что количество проката велосипедов меньше весной. Кроме того, мы видим, что в рабочие дни есть определённый паттерн примерно с 6-7 утра и с 17-18 часов с некоторыми пиками проката велосипедов. Мы можем помнить эти различия и использовать их для понимания графика частичной зависимости.

Препроцессор для моделей машинного обучения

Так как позже мы используем две разные модели, MLPRegressor и HistGradientBoostingRegressor, мы создаём два разных препроцессора, специфичных для каждой модели.

Препроцессор для модели нейронной сети

Мы будем использовать QuantileTransformer для масштабирования числовых признаков и кодировать категориальные признаки с помощью OneHotEncoder.

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, QuantileTransformer

mlp_preprocessor = ColumnTransformer(
    transformers=[
        ("num", QuantileTransformer(n_quantiles=100), numerical_features),
        ("cat", OneHotEncoder(handle_unknown="ignore"), categorical_features),
    ]
)
mlp_preprocessor
ColumnTransformer(transformers=[('num', QuantileTransformer(n_quantiles=100),
                                 ['temp', 'feel_temp', 'humidity',
                                  'windspeed']),
                                ('cat', OneHotEncoder(handle_unknown='ignore'),
                                 Index(['season', 'month', 'hour', 'holiday', 'weekday', 'workingday',
       'weather'],
      dtype='object'))])
В среде Jupyter, пожалуйста, перезапустите этот ячейку, чтобы показать HTML представление, или доверьтесь блокноту.
На GitHub, HTML представление не может быть отображено, пожалуйста, попробуйте загрузить эту страницу с nbviewer.org.
ColumnTransformer(transformers=[('num', QuantileTransformer(n_quantiles=100),
                                 ['temp', 'feel_temp', 'humidity',
                                  'windspeed']),
                                ('cat', OneHotEncoder(handle_unknown='ignore'),
                                 Index(['season', 'month', 'hour', 'holiday', 'weekday', 'workingday',
       'weather'],
      dtype='object'))])
['temp', 'feel_temp', 'humidity', 'windspeed']
QuantileTransformer(n_quantiles=100)
Index(['season', 'month', 'hour', 'holiday', 'weekday', 'workingday',
       'weather'],
      dtype='object')
OneHotEncoder(handle_unknown='ignore')


Препроцессор для модели градиентного бустинга

Для модели градиентного бустинга мы оставляем числовые признаки без изменений и кодируем только категориальные признаки с помощью OrdinalEncoder.

from sklearn.preprocessing import OrdinalEncoder

hgbdt_preprocessor = ColumnTransformer(
    transformers=[
        ("cat", OrdinalEncoder(), categorical_features),
        ("num", "passthrough", numerical_features),
    ],
    sparse_threshold=1,
    verbose_feature_names_out=False,
).set_output(transform="pandas")
hgbdt_preprocessor
ColumnTransformer(sparse_threshold=1,
                  transformers=[('cat', OrdinalEncoder(),
                                 Index(['season', 'month', 'hour', 'holiday', 'weekday', 'workingday',
       'weather'],
      dtype='object')),
                                ('num', 'passthrough',
                                 ['temp', 'feel_temp', 'humidity',
                                  'windspeed'])],
                  verbose_feature_names_out=False)
В среде Jupyter, пожалуйста, перезапустите этот ячейку, чтобы показать HTML представление, или доверьтесь блокноту.
На GitHub, HTML представление не может быть отображено, пожалуйста, попробуйте загрузить эту страницу с nbviewer.org.
ColumnTransformer(sparse_threshold=1,
                  transformers=[('cat', OrdinalEncoder(),
                                 Index(['season', 'month', 'hour', 'holiday', 'weekday', 'workingday',
       'weather'],
      dtype='object')),
                                ('num', 'passthrough',
                                 ['temp', 'feel_temp', 'humidity',
                                  'windspeed'])],
                  verbose_feature_names_out=False)
Index(['season', 'month', 'hour', 'holiday', 'weekday', 'workingday',
       'weather'],
      dtype='object')
OrdinalEncoder()
['temp', 'feel_temp', 'humidity', 'windspeed']
passthrough


Однофакторная частичная зависимость с различными моделями

В этом разделе мы вычислим однофакторную частичную зависимость с использованием двух различных моделей машинного обучения: (i) многослойный перцептрон и (ii) модель градиентного бустинга. С помощью этих двух моделей мы продемонстрируем, как вычислять и интерпретировать графики частичной зависимости (PDP) для числовых и категориальных признаков, а также индивидуальные условные ожидания (ICE).

Многослойный перцептрон

Давайте обучим MLPRegressor и вычислим графики частичной зависимости по одной переменной.

from time import time

from sklearn.neural_network import MLPRegressor
from sklearn.pipeline import make_pipeline

print("Training MLPRegressor...")
tic = time()
mlp_model = make_pipeline(
    mlp_preprocessor,
    MLPRegressor(
        hidden_layer_sizes=(30, 15),
        learning_rate_init=0.01,
        early_stopping=True,
        random_state=0,
    ),
)
mlp_model.fit(X_train, y_train)
print(f"done in {time() - tic:.3f}s")
print(f"Test R2 score: {mlp_model.score(X_test, y_test):.2f}")
Training MLPRegressor...
done in 0.861s
Test R2 score: 0.61

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

Важно отметить, что в этом табличном наборе данных диапазоны динамики признаков очень различны. Нейронные сети очень чувствительны к признакам с разными масштабами, и забыть о предобработке числовых признаков приведет к очень плохой модели.

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

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

Мы построим усредненную частичную зависимость.

import matplotlib.pyplot as plt

from sklearn.inspection import PartialDependenceDisplay

common_params = {
    "subsample": 50,
    "n_jobs": 2,
    "grid_resolution": 20,
    "random_state": 0,
}

print("Computing partial dependence plots...")
features_info = {
    # features of interest
    "features": ["temp", "humidity", "windspeed", "season", "weather", "hour"],
    # type of partial dependence plot
    "kind": "average",
    # information regarding categorical features
    "categorical_features": categorical_features,
}
tic = time()
_, ax = plt.subplots(ncols=3, nrows=2, figsize=(9, 8), constrained_layout=True)
display = PartialDependenceDisplay.from_estimator(
    mlp_model,
    X_train,
    **features_info,
    ax=ax,
    **common_params,
)
print(f"done in {time() - tic:.3f}s")
_ = display.figure_.suptitle(
    (
        "Partial dependence of the number of bike rentals\n"
        "for the bike rental dataset with an MLPRegressor"
    ),
    fontsize=16,
)
Partial dependence of the number of bike rentals for the bike rental dataset with an MLPRegressor
Computing partial dependence plots...
done in 0.705s

Градиентный бустинг

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

from sklearn.ensemble import HistGradientBoostingRegressor

print("Training HistGradientBoostingRegressor...")
tic = time()
hgbdt_model = make_pipeline(
    hgbdt_preprocessor,
    HistGradientBoostingRegressor(
        categorical_features=categorical_features,
        random_state=0,
        max_iter=50,
    ),
)
hgbdt_model.fit(X_train, y_train)
print(f"done in {time() - tic:.3f}s")
print(f"Test R2 score: {hgbdt_model.score(X_test, y_test):.2f}")
Training HistGradientBoostingRegressor...
done in 0.139s
Test R2 score: 0.62

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

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

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

print("Computing partial dependence plots...")
tic = time()
_, ax = plt.subplots(ncols=3, nrows=2, figsize=(9, 8), constrained_layout=True)
display = PartialDependenceDisplay.from_estimator(
    hgbdt_model,
    X_train,
    **features_info,
    ax=ax,
    **common_params,
)
print(f"done in {time() - tic:.3f}s")
_ = display.figure_.suptitle(
    (
        "Partial dependence of the number of bike rentals\n"
        "for the bike rental dataset with a gradient boosting"
    ),
    fontsize=16,
)
Partial dependence of the number of bike rentals for the bike rental dataset with a gradient boosting
Computing partial dependence plots...
done in 1.294s

Анализ графиков

Сначала рассмотрим графики частичной зависимости для числовых признаков. Для обеих моделей общая тенденция PDP температуры заключается в том, что количество велосипедных поездок увеличивается с повышением температуры. Мы можем провести аналогичный анализ, но с обратной тенденцией для признака влажности. Количество велосипедных поездок уменьшается по мере увеличения влажности. Наконец, мы наблюдаем ту же тенденцию для признака скорости ветра. Количество велосипедных поездок уменьшается по мере увеличения скорости ветра для обеих моделей. Мы также наблюдаем, что MLPRegressor имеет гораздо более плавные прогнозы, чем HistGradientBoostingRegressor.

Теперь рассмотрим графики частичной зависимости для категориальных признаков.

Мы наблюдаем, что весна имеет самый низкий показатель для признака сезона. Что касается признака погоды, категория дождь имеет самый низкий показатель. Относительно признака часа мы видим два пика около 7 утра и 18 часов. Эти выводы согласуются с ранее сделанными наблюдениями над данными.

Однако стоит отметить, что мы создаем потенциально бессмысленные синтетические образцы, если признаки коррелированы.

ICE против PDP

PDP представляет собой среднее значение краевых эффектов признаков. Мы усредняем ответ всех образцов из предоставленного набора. Таким образом, некоторые эффекты могут быть скрыты. В этом отношении можно построить каждый индивидуальный ответ. Это представление называется графиком индивидуального эффекта (ICE). На графике ниже мы построили 50 случайных ICE для признаков температуры и влажности.

print("Computing partial dependence plots and individual conditional expectation...")
tic = time()
_, ax = plt.subplots(ncols=2, figsize=(6, 4), sharey=True, constrained_layout=True)

features_info = {
    "features": ["temp", "humidity"],
    "kind": "both",
    "centered": True,
}

display = PartialDependenceDisplay.from_estimator(
    hgbdt_model,
    X_train,
    **features_info,
    ax=ax,
    **common_params,
)
print(f"done in {time() - tic:.3f}s")
_ = display.figure_.suptitle("ICE and PDP representations", fontsize=16)
ICE and PDP representations
Computing partial dependence plots and individual conditional expectation...
done in 0.594s

Мы видим, что ICE для признака температуры дает нам дополнительную информацию: некоторые линии ICE являются плоскими, а другие показывают уменьшение зависимости для температуры выше 35 градусов Цельсия. Мы наблюдаем аналогичный паттерн для признака влажности: некоторые линии ICE показывают резкое уменьшение, когда влажность превышает 80%.

Не все линии ICE параллельны, это указывает на то, что модель находит взаимодействия между признаками. Мы можем повторить эксперимент, ограничив модель градиентного бустинга на отсутствие взаимодействий между признаками, используя параметр interaction_cst:

from sklearn.base import clone

interaction_cst = [[i] for i in range(X_train.shape[1])]
hgbdt_model_without_interactions = (
    clone(hgbdt_model)
    .set_params(histgradientboostingregressor__interaction_cst=interaction_cst)
    .fit(X_train, y_train)
)
print(f"Test R2 score: {hgbdt_model_without_interactions.score(X_test, y_test):.2f}")
Test R2 score: 0.38
_, ax = plt.subplots(ncols=2, figsize=(6, 4), sharey=True, constrained_layout=True)

features_info["centered"] = False
display = PartialDependenceDisplay.from_estimator(
    hgbdt_model_without_interactions,
    X_train,
    **features_info,
    ax=ax,
    **common_params,
)
_ = display.figure_.suptitle("ICE and PDP representations", fontsize=16)
ICE and PDP representations

2D графики взаимодействия

Диаграммы частичной зависимости (PDP) с двумя интересующими признаками позволяют визуализировать взаимодействия между ними. Однако графики индивидуальных условных ожиданий (ICE) нельзя легко построить и интерпретировать. Мы покажем представление, доступное в from_estimator, которое представляет собой 2D тепловую карту.

print("Computing partial dependence plots...")
features_info = {
    "features": ["temp", "humidity", ("temp", "humidity")],
    "kind": "average",
}
_, ax = plt.subplots(ncols=3, figsize=(10, 4), constrained_layout=True)
tic = time()
display = PartialDependenceDisplay.from_estimator(
    hgbdt_model,
    X_train,
    **features_info,
    ax=ax,
    **common_params,
)
print(f"done in {time() - tic:.3f}s")
_ = display.figure_.suptitle(
    "1-way vs 2-way of numerical PDP using gradient boosting", fontsize=16
)
1-way vs 2-way of numerical PDP using gradient boosting
Computing partial dependence plots...
done in 9.495s

Диаграмма частичной зависимости по двум параметрам показывает зависимость количества прокат велосипедов от совместных значений температуры и влажности. Мы отчетливо видим взаимодействие между двумя признаками. При температуре выше 20 градусов Цельсия влажность оказывает влияние на количество проката велосипедов, которое кажется независимым от температуры.

С другой стороны, при температурах ниже 20 градусов Цельсия как температура, так и влажность непрерывно влияют на количество проката велосипедов.

Кроме того, наклон гребня влияния порога 20 градусов Цельсия сильно зависит от уровня влажности: гребень крутой при сухой погоде, но гораздо более плавный при более влажной погоде, превышающей 70% влажности.

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

print("Computing partial dependence plots...")
features_info = {
    "features": ["temp", "humidity", ("temp", "humidity")],
    "kind": "average",
}
_, ax = plt.subplots(ncols=3, figsize=(10, 4), constrained_layout=True)
tic = time()
display = PartialDependenceDisplay.from_estimator(
    hgbdt_model_without_interactions,
    X_train,
    **features_info,
    ax=ax,
    **common_params,
)
print(f"done in {time() - tic:.3f}s")
_ = display.figure_.suptitle(
    "1-way vs 2-way of numerical PDP using gradient boosting", fontsize=16
)
1-way vs 2-way of numerical PDP using gradient boosting
Computing partial dependence plots...
done in 8.072s

Графики частичной зависимости по одному параметру для модели, ограниченной не моделированием взаимодействий признаков, показывают локальные пики для каждого признака по отдельности, особенно для признака «влажность». Эти пики могут отражать ухудшение работы модели, которая пытается как-то компенсировать запрещенные взаимодействия, переобучая определённые тренировочные точки. Обратите внимание, что предсказательная производительность этой модели, измеренная на тестовом наборе, значительно хуже, чем у исходной, не ограниченной модели.

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

Эти локальные пики приводят к шумной сетчатой 2D диаграмме частичной зависимости. Довольно сложно определить, существуют ли взаимодействия между этими признаками из-за высоких частотных колебаний в признаке влажности. Однако можно чётко увидеть, что простое взаимодействие, наблюдаемое при пересечении температуры порога 20 градусов, больше не видно для этой модели.

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

print("Computing partial dependence plots...")
features_info = {
    "features": ["season", "weather", ("season", "weather")],
    "kind": "average",
    "categorical_features": categorical_features,
}
_, ax = plt.subplots(ncols=3, figsize=(14, 6), constrained_layout=True)
tic = time()
display = PartialDependenceDisplay.from_estimator(
    hgbdt_model,
    X_train,
    **features_info,
    ax=ax,
    **common_params,
)

print(f"done in {time() - tic:.3f}s")
_ = display.figure_.suptitle(
    "1-way vs 2-way PDP of categorical features using gradient boosting", fontsize=16
)
1-way vs 2-way PDP of categorical features using gradient boosting
Computing partial dependence plots...
done in 0.444s

3D представление

Давайте построим ту же диаграмму частичной зависимости для взаимодействия 2 признаков, на этот раз в 3 измерениях.

# unused but required import for doing 3d projections with matplotlib < 3.2
import mpl_toolkits.mplot3d  # noqa: F401
import numpy as np

from sklearn.inspection import partial_dependence

fig = plt.figure(figsize=(5.5, 5))

features = ("temp", "humidity")
pdp = partial_dependence(
    hgbdt_model, X_train, features=features, kind="average", grid_resolution=10
)
XX, YY = np.meshgrid(pdp["grid_values"][0], pdp["grid_values"][1])
Z = pdp.average[0].T
ax = fig.add_subplot(projection="3d")
fig.add_axes(ax)

surf = ax.plot_surface(XX, YY, Z, rstride=1, cstride=1, cmap=plt.cm.BuPu, edgecolor="k")
ax.set_xlabel(features[0])
ax.set_ylabel(features[1])
fig.suptitle(
    "PD of number of bike rentals on\nthe temperature and humidity GBDT model",
    fontsize=16,
)
# pretty init view
ax.view_init(elev=22, azim=122)
clb = plt.colorbar(surf, pad=0.08, shrink=0.6, aspect=10)
clb.ax.set_title("Partial\ndependence")
plt.show()
PD of number of bike rentals on the temperature and humidity GBDT model, Partial dependence

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

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_partial_dependence.ipynb

Download Python source code: plot_partial_dependence.py

Download zipped: plot_partial_dependence.zip

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

Расширенное построение с частичной зависимостью

Инженерия временных признаков

Основные моменты релиза scikit-learn 0.24

Сравнение TargetEncoder с другими кодерами

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

Spec-Zone.ru

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