Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере через 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)

В следующем разделе мы обучаем модели для прогнозирования, поэтому отделяем целевой столбец от остальных признаков и разделяем данные на обучающую и тестовую выборки.
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()

Прогнозирование дохода при частично наблюдаемых переменных
На практике интеллектуальные способности не наблюдаются или оцениваются лишь по косвенным показателям, которые непреднамеренно измеряют также уровень образования (например, с помощью тестов на 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()

Чтобы компенсировать пропущенную переменную, модель завышает коэффициент признака наличия высшего образования. Поэтому неверно интерпретировать значение этого коэффициента как причинно-следственный эффект истинной порождающей модели.
Выводы
Модели машинного обучения не предназначены для оценки причинно-следственных эффектов. Мы показали это на примере линейной модели, но смещение из-за пропущенных переменных может влиять на модели любого типа.
При интерпретации коэффициента или изменения прогнозов, вызванного изменением одного из признаков, важно учитывать потенциально ненаблюдаемые переменные, которые могут быть связаны как с рассматриваемым признаком, так и с целевой переменной. Такие переменные называются смешивающими переменными. Чтобы по-прежнему оценивать причинно-следственный эффект при наличии смешивающих факторов, исследователи обычно проводят эксперименты, в которых переменная воздействия (например, наличие высшего образования) рандомизируется. Если эксперимент непозволительно дорог или неэтичен, исследователи иногда могут использовать другие методы причинно-следственного анализа, например оценивание с помощью инструментальных переменных (IV).
Общее время выполнения скрипта: (0 минут 2.129 секунды)
Связанные примеры
© 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