Spec-Zone.ru › scikit-learn

Примечание

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

Неспособность машинного обучения выявлять причинно-следственные эффекты

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

Чтобы это показать, мы смоделируем ситуацию, в которой попытаемся ответить на один из важнейших вопросов экономики образования: каков причинно-следственный эффект получения высшего образования на почасовую оплату труда? Хотя ответ на этот вопрос крайне важен для политиков, смещение из-за пропущенных переменных (OVB) не позволяет нам выявить этот причинно-следственный эффект.

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

Набор данных: смоделированная почасовая оплата труда

Процесс генерации данных описан в коде ниже. Опыт работы в годах и показатель способностей выбираются из нормальных распределений; почасовая оплата труда одного из родителей — из бета-распределения. Затем мы создаём индикатор наличия высшего образования, на который положительно влияют способности и почасовая оплата труда родителя. Наконец, мы моделируем почасовую оплату труда как линейную функцию всех предыдущих переменных и случайной составляющей. Обратите внимание, что все переменные оказывают положительное влияние на почасовую оплату труда.

import numpy as np
import pandas as pd

n_samples = 10_000
rng = np.random.RandomState(32)

experiences = rng.normal(20, 10, size=n_samples).astype(int)
experiences[experiences < 0] = 0
abilities = rng.normal(0, 0.15, size=n_samples)
parent_hourly_wages = 50 * rng.beta(2, 8, size=n_samples)
parent_hourly_wages[parent_hourly_wages < 0] = 0
college_degrees = (
    9 * abilities + 0.02 * parent_hourly_wages + rng.randn(n_samples) > 0.7
).astype(int)

true_coef = pd.Series(
    {
        "college degree": 2.0,
        "ability": 5.0,
        "experience": 0.2,
        "parent hourly wage": 1.0,
    }
)
hourly_wages = (
    true_coef["experience"] * experiences
    + true_coef["parent hourly wage"] * parent_hourly_wages
    + true_coef["college degree"] * college_degrees
    + true_coef["ability"] * abilities
    + rng.normal(0, 1, size=n_samples)
)

hourly_wages[hourly_wages < 0] = 0

Описание смоделированных данных

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

import seaborn as sns

df = pd.DataFrame(
    {
        "college degree": college_degrees,
        "ability": abilities,
        "hourly wage": hourly_wages,
        "experience": experiences,
        "parent hourly wage": parent_hourly_wages,
    }
)

grid = sns.pairplot(df, diag_kind="kde", corner=True)
plot causal interpretation

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

from sklearn.model_selection import train_test_split

target_name = "hourly wage"
X, y = df.drop(columns=target_name), df[target_name]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

Прогнозирование дохода при полностью наблюдаемых переменных

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

from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

features_names = ["experience", "parent hourly wage", "college degree", "ability"]

regressor_with_ability = LinearRegression()
regressor_with_ability.fit(X_train[features_names], y_train)
y_pred_with_ability = regressor_with_ability.predict(X_test[features_names])
R2_with_ability = r2_score(y_test, y_pred_with_ability)

print(f"R2 score with ability: {R2_with_ability:.3f}")
R2 score with ability: 0.975

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

import matplotlib.pyplot as plt

model_coef = pd.Series(regressor_with_ability.coef_, index=features_names)
coef = pd.concat(
    [true_coef[features_names], model_coef],
    keys=["Coefficients of true generative model", "Model coefficients"],
    axis=1,
)
ax = coef.plot.barh()
ax.set_xlabel("Coefficient values")
ax.set_title("Coefficients of the linear regression including the ability features")
_ = plt.tight_layout()
Coefficients of the linear regression including the ability features

Прогнозирование дохода при частично наблюдаемых переменных

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

features_names = ["experience", "parent hourly wage", "college degree"]

regressor_without_ability = LinearRegression()
regressor_without_ability.fit(X_train[features_names], y_train)
y_pred_without_ability = regressor_without_ability.predict(X_test[features_names])
R2_without_ability = r2_score(y_test, y_pred_without_ability)

print(f"R2 score without ability: {R2_without_ability:.3f}")
R2 score without ability: 0.968

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

model_coef = pd.Series(regressor_without_ability.coef_, index=features_names)
coef = pd.concat(
    [true_coef[features_names], model_coef],
    keys=["Coefficients of true generative model", "Model coefficients"],
    axis=1,
)
ax = coef.plot.barh()
ax.set_xlabel("Coefficient values")
_ = ax.set_title("Coefficients of the linear regression excluding the ability feature")
plt.tight_layout()
plt.show()
Coefficients of the linear regression excluding the ability feature

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

Выводы

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

При интерпретации коэффициента или изменения прогнозов, вызванного изменением одного из признаков, важно учитывать потенциально ненаблюдаемые переменные, которые могут быть связаны как с рассматриваемым признаком, так и с целевой переменной. Такие переменные называются смешивающими переменными. Чтобы по-прежнему оценивать причинно-следственный эффект при наличии смешивающих факторов, исследователи обычно проводят эксперименты, в которых переменная воздействия (например, наличие высшего образования) рандомизируется. Если эксперимент непозволительно дорог или неэтичен, исследователи иногда могут использовать другие методы причинно-следственного анализа, например оценивание с помощью инструментальных переменных (IV).

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

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_causal_interpretation.ipynb

Download Python source code: plot_causal_interpretation.py

Download zipped: plot_causal_interpretation.zip

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

Типичные ошибки при интерпретации коэффициентов линейных моделей

Метод наименьших квадратов с неотрицательными коэффициентами

Коэффициенты Ridge-регрессии в зависимости от L2-регуляризации

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

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

Spec-Zone.ru

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