Коэффициенты линейной регрессии
Содержание курса
coef_ и intercept_ на трёх точках
Пусть известна зависимость: при x=1 получаем y=3, при x=2 — y=5, при x=3 — y=7. Ей соответствует прямая y = 2*x + 1. Проверим, что найдёт scikit-learn:
from sklearn.linear_model import LinearRegression
model = LinearRegression().fit([[1], [2], [3]], [3, 5, 7])
print(round(model.coef_[0], 6))
print(round(model.intercept_, 6))
print(round(model.predict([[4]])[0], 6))
Вывод — 2.0, 1.0, 9.0. coef_[0] — множитель при единственном признаке, intercept_ — свободный член. Для x=4 модель вычисляет 2*4+1. Список [[4]] означает один объект с одним признаком. Это иллюстрация формулы, а не проверка качества прогноза; далее перейдём к нескольким признакам и их единицам.
На предыдущих уроках мы вызывали model.fit и model.predict как инструмент, не заглядывая внутрь результата. Сейчас посмотрим, что именно модель сохраняет после обучения — и что эти числа означают.
Атрибуты coef_ и intercept_: что хранит модель после fit и как их прочитать
После вызова model.fit(X_train, y_train) объект LinearRegression хранит два атрибута. model.intercept_ — одно число, свободный член. model.coef_ — NumPy-массив, где i-й элемент соответствует i-му столбцу того DataFrame, который был передан в fit. Длина массива равна числу признаков: если их 10, в coef_ ровно 10 чисел.
Важный момент: оба атрибута появляются только после fit. До обучения атрибут coef_ у объекта просто отсутствует, и обращение к нему вызывает AttributeError. Это стандартное поведение всех оценщиков sklearn: атрибуты с подчёркиванием на конце всегда означают «посчитано в результате fit». Схожая ошибка — NotFittedError — возникает, если вызвать model.predict до fit.
Чтобы увидеть коэффициенты осмысленно, нужно сопоставить их с именами признаков. Порядок элементов в model.coef_ совпадает с порядком столбцов в том X_train, который был передан в fit. Поэтому безопаснее зафиксировать список имён сразу после разделения данных и использовать именно его при выводе:
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
bunch = load_diabetes(as_frame=True)
X = bunch.data
y = bunch.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Сохраняем порядок столбцов до fit
feature_names = list(X_train.columns)
model = LinearRegression()
model.fit(X_train, y_train)
for name, coef in zip(feature_names, model.coef_):
print(f"{name}: {coef:.4f}")
print("intercept:", model.intercept_)
Датасет diabetes содержит 10 числовых признаков (возраст, индекс массы тела, давление и т.д.), все уже стандартизованы авторами датасета. После fit каждая строка вывода покажет пару «имя признака — его коэффициент». intercept_ — отдельное число, не входящее в coef_.
Ключевое правило: model.coef_ фиксирует порядок столбцов на момент вызова fit. Если после обучения переупорядочить DataFrame (например, переставить столбцы через iloc или переиндексировать), сам coef_ не изменится — он по-прежнему соответствует тому порядку, который был при обучении. Поэтому сопоставлять коэффициенты с именами нужно именно через список, сохранённый до fit, а не через текущее состояние DataFrame.
