Линейная регрессия — это модель, которая описывает зависимость числовой целевой переменной y от одного или нескольких признаков x линейной функцией: y = a + b*x. Модель обучают на данных, подбирая коэффициенты a и b так, чтобы предсказания были как можно ближе к реальным значениям. Ниже — как работает подбор (метод наименьших квадратов), как оценивать качество (R2 и MSE), какие у модели допущения, что такое переобучение и чем линейная регрессия отличается от логистической. Весь код на Python (numpy и scikit-learn), выводы получены прогоном с фиксированным seed и воспроизводятся.
Содержание
Чтобы не путать близкие понятия, договоримся о словаре сразу:
- Простая (парная) регрессия — один признак x, модель y = a + b*x.
- Множественная регрессия — несколько признаков, модель y = a + b1x1 + … + bkxk.
- Регрессия предсказывает число (цену, температуру), классификация — метку класса. Логистическая регрессия, несмотря на слово «регрессия», решает задачу классификации.
- Остаток — разница между реальным y и предсказанным y для конкретной точки. Не путать со случайной ошибкой модели: остаток — это наблюдаемая величина, посчитанная после обучения.
Как устроена модель
В парной регрессии два коэффициента: a — свободный член (значение y при x = 0), b — угловой коэффициент (на сколько в среднем меняется y при росте x на единицу). Геометрически модель — прямая, проведенная сквозь облако точек так, чтобы точки лежали к ней как можно ближе.
В множественной регрессии каждый признак получает свой коэффициент b_i — вклад этого признака при фиксированных остальных. Модель перестает быть прямой на плоскости и становится гиперплоскостью, но принцип тот же: линейная комбинация признаков плюс свободный член.
Метод наименьших квадратов (МНК)
Коэффициенты подбирают так, чтобы сумма квадратов остатков была минимальной. Это и есть метод наименьших квадратов (МНК, англ. OLS). Квадраты берут, чтобы отклонения вверх и вниз не гасили друг друга и чтобы крупные промахи штрафовались сильнее.
Начнем с полного рабочего примера: сгенерируем данные с известной зависимостью y = 2.5*x + 4 плюс шум и обучим модель через scikit-learn.
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
rng = np.random.default_rng(42) # фиксируем seed - результат воспроизводим
n = 50
x = np.linspace(0, 10, n)
y = 2.5 * x + 4.0 + rng.normal(0, 2.0, n) # истинные a=4.0, b=2.5, шум sd=2
X = x.reshape(-1, 1) # sklearn ждет 2D-массив признаков
model = LinearRegression().fit(X, y)
y_pred = model.predict(X)
print(f"a = {model.intercept_:.4f}")
print(f"b = {model.coef_[0]:.4f}")
print(f"MSE = {mean_squared_error(y, y_pred):.4f}")
print(f"R2 = {r2_score(y, y_pred):.4f}")
Фактический вывод:
a = 3.7301
b = 2.5905
MSE = 2.2428
R2 = 0.9629
Модель восстановила коэффициенты близко к истинным (a около 4, b около 2.5) — точного совпадения нет, потому что в данные добавлен шум. Разбор по строкам: reshape(-1, 1) превращает вектор в матрицу признаков (столбец), fit подбирает коэффициенты по МНК, predict считает предсказания, intercept_ и coef_ — это a и b.
Для парной регрессии те же коэффициенты можно получить по формуле МНК вручную, без обучения:
x_mean, y_mean = x.mean(), y.mean()
b = np.sum((x - x_mean) * (y - y_mean)) / np.sum((x - x_mean) ** 2)
a = y_mean - b * x_mean
print(f"a = {a:.4f}, b = {b:.4f}") # a = 3.7301, b = 2.5905
Числа совпали с выводом scikit-learn — это подтверждает, что LinearRegression под капотом решает ту же задачу минимизации суммы квадратов.
Метрики качества: R2 и MSE
Две базовые метрики регрессии измеряют качество по-разному, у каждой своя граница применимости.
| Метрика | Что показывает | Единицы | Диапазон |
|---|---|---|---|
| MSE | средний квадрат остатка | квадрат единиц y | от 0 (идеал) и выше |
| R2 | долю дисперсии y, объясненную моделью | безразмерная | до 1; на новых данных бывает отрицательной |
MSE (mean squared error) — средний квадрат ошибки; чем меньше, тем лучше. Она в квадрате единиц целевой переменной, поэтому часто берут корень (RMSE), чтобы вернуться к исходным единицам. Сравнивать MSE между разными задачами нельзя — масштаб y у них разный.
R2 (коэффициент детерминации) = 1 — (сумма квадратов остатков) / (сумма квадратов отклонений y от среднего). На обучающей выборке у МНК R2 лежит в диапазоне от 0 до 1, где 1 — идеальная подгонка. Но на новых данных R2 может стать отрицательной: это значит, что модель предсказывает хуже, чем простое среднее. В парной линейной регрессии R2 равен квадрату коэффициента корреляции Пирсона (r2), в множественной — уже нет.
Множественная регрессия
Добавим несколько признаков. Смоделируем цену жилья по площади, числу комнат и расстоянию до центра:
rng2 = np.random.default_rng(0)
m = 200
area = rng2.uniform(30, 100, m) # площадь, кв.м
rooms = rng2.integers(1, 5, m) # число комнат
dist = rng2.uniform(1, 20, m) # расстояние до центра, км
price = 50 + 3.0*area + 20*rooms - 4.0*dist + rng2.normal(0, 15, m)
X = np.column_stack([area, rooms, dist])
model = LinearRegression().fit(X, price)
print("intercept =", round(float(model.intercept_), 3))
print("coefs [area, rooms, dist] =", np.round(model.coef_, 3).tolist())
print(f"R2 = {r2_score(price, model.predict(X)):.4f}")
Фактический вывод:
intercept = 49.841
coefs [area, rooms, dist] = [3.066, 19.202, -4.209]
R2 = 0.9642
Знаки коэффициентов читаются содержательно: площадь и число комнат поднимают цену (плюс), расстояние до центра снижает (минус). Величина коэффициента — вклад признака при прочих равных, но сравнивать коэффициенты между собой напрямую можно только если признаки в сопоставимых масштабах (иначе их предварительно стандартизируют).
Допущения модели
Классическая линейная регрессия дает надежные оценки при ряде условий. Это упрощенная рамка: на практике допущения выполняются частично, и их проверяют по остаткам.
- Линейность. Связь между признаками и y близка к линейной. Если нет — помогает преобразование признаков (например логарифм) или другая модель.
- Независимость остатков. Остатки не связаны между собой (нарушается, например, во временных рядах).
- Постоянная дисперсия остатков (гомоскедастичность). Разброс остатков одинаков по всему диапазону предсказаний.
- Отсутствие сильной мультиколлинеарности. Признаки не должны быть почти линейно зависимы друг от друга, иначе коэффициенты становятся неустойчивыми.
Нормальность остатков нужна не для самих оценок коэффициентов, а для корректных доверительных интервалов и проверки значимости. Нарушение допущения — не всегда приговор модели, но повод осторожнее трактовать выводы.
Переобучение
Если усложнять модель (добавлять степени признака), она все точнее описывает обучающие данные, но теряет обобщающую способность. Это переобучение: низкая ошибка на обучении и высокая на новых данных. Проверим на данных, где истинная зависимость линейна, сравнив прямую (степень 1) и полином степени 15 по метрике на отложенной выборке:
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import train_test_split
rng3 = np.random.default_rng(1)
xo = np.sort(rng3.uniform(-3, 3, 40))
yo = xo + rng3.normal(0, 1.0, 40) # истинная зависимость линейна
X = xo.reshape(-1, 1)
Xtr, Xte, ytr, yte = train_test_split(X, yo, test_size=0.4, random_state=1)
for deg in (1, 15):
pipe = make_pipeline(PolynomialFeatures(deg), LinearRegression()).fit(Xtr, ytr)
r2_tr = r2_score(ytr, pipe.predict(Xtr))
r2_te = r2_score(yte, pipe.predict(Xte))
print(f"degree {deg:2d}: R2_train={r2_tr:.3f} R2_test={r2_te:.3f}")
Фактический вывод:
degree 1: R2_train=0.846 R2_test=0.806
degree 15: R2_train=0.943 R2_test=-715379.945
Полином степени 15 показал R2 на обучении выше (0.943 против 0.846), но на тесте метрика рухнула в глубокий минус — модель подстроилась под шум и на новых точках предсказывает абсурдно. Прямая скромнее на обучении, зато держит качество на тесте. Отсюда правило: качество судят по отложенной выборке или кросс-валидации, а не по обучающей; лишнюю сложность гасят регуляризацией (Ridge, Lasso).
Отличие от логистической регрессии
Названия похожи, задачи разные. Ключевое различие — что предсказывает модель.
| Признак | Линейная регрессия | Логистическая регрессия |
|---|---|---|
| Задача | регрессия (число) | классификация (метка) |
| Что на выходе | любое число | вероятность класса от 0 до 1 |
| Форма | y = a + b*x | сигмоида от a + b*x |
| Функция потерь | сумма квадратов (МНК) | логистическая (log-loss) |
| Метрики | R2, MSE, MAE | accuracy, precision, recall, ROC-AUC |
Логистическая регрессия строит ту же линейную комбинацию признаков, но пропускает ее через сигмоиду, чтобы получить вероятность, и обучается на другой функции потерь. Поэтому для предсказания цены берут линейную регрессию, а для ответа «купит или нет» — логистическую.
Выводы
- Линейная регрессия предсказывает число линейной функцией признаков; парная — один признак, множественная — несколько.
- Коэффициенты подбирает метод наименьших квадратов, минимизируя сумму квадратов остатков; формула МНК и scikit-learn дают один и тот же результат.
- MSE меряет ошибку в квадрате единиц y, R2 — долю объясненной дисперсии; на новых данных R2 может быть отрицательной.
- Модель опирается на допущения (линейность, независимость и постоянная дисперсия остатков, отсутствие сильной мультиколлинеарности) — их проверяют по остаткам.
- Слишком сложная модель переобучается: качество надо смотреть на отложенной выборке, а логистическая регрессия — это уже про классификацию, не про предсказание числа.
Где применяется / связь с практикой
Линейная регрессия — первая модель, которую разбирают в анализе данных и машинном обучении: на ней проще всего понять обучение по данным, метрики и переобучение, а уже потом переходить к деревьям, ансамблям и нейросетям. Она реально работает в оценке недвижимости, прогнозе спроса, анализе A/B-тестов и как быстрый бейзлайн для более сложных задач.
Освойте тему на практике
Разобрать регрессию, метрики и подготовку данных на практике, с проверкой моделей на реальных выборках, можно на курсе Machine Learning. Basic. Посмотреть формат и уровень до записи помогают открытые уроки Otus — там разбирают отдельные темы в прямом эфире с преподавателем.
FAQ
Чем R2 отличается от коэффициента корреляции? Коэффициент корреляции r показывает силу и направление линейной связи двух величин (от -1 до 1). R2 показывает долю дисперсии, объясненную моделью. В парной линейной регрессии R2 численно равен r в квадрате, в множественной — нет.
Нужно ли масштабировать признаки для линейной регрессии? Для самих оценок МНК — нет, результат не изменится. Масштабирование нужно, чтобы сравнивать коэффициенты между признаками, а также для регуляризованных версий (Ridge, Lasso), где масштаб влияет на штраф.
Что делать с выбросами? Не удалять автоматически: сначала выяснить природу (ошибка данных или редкое, но реальное наблюдение). Проверить влияние можно, обучив модель с выбросами и без и сравнив коэффициенты; при устойчивых выбросах помогает робастная регрессия (например Huber).



