Привет! Ты уже знаком с машинным обучением и знаешь, что модели предсказывают значения. Но с чего начинают все специалисты по данным? Чаще всего — с линейной регрессии. Это самый простой и понятный алгоритм, который лежит в основе многих более сложных методов.
В этой статье мы разберём:
- Что такое линейная регрессия и зачем она нужна
- Математическая формула:
y = wx + b - Метод наименьших квадратов
- Пошаговая реализация на Python
- Оценка качества модели (MSE, R²)
- Ключевые допущения линейной регрессии
- Что нужно знать перед началом
- Основная часть
- Что такое линейная регрессия?
- Математическая основа
- Метод наименьших квадратов (Ordinary Least Squares)
- Коэффициент детерминации (R²)
- Реализация на Python
- Загрузка данных
- Разделение на train/test
- Обучение модели
- Предсказание и оценка
- Визуализация
- Ключевые допущения линейной регрессии
- Линейность
- Независимость наблюдений
- Гомоскедастичность
- Нормальность остатков
- Отсутствие мультиколлинеарности
- Улучшение модели
- Добавление признаков
- Регуляризация
- Задачи для закрепления
- Нюансы и подводные камни
- Переобучение
- Мультиколлинеарность
- Выбросы
- Частые ошибки и как их избежать
- Ошибка 1: Не разделил данные до обучения
- Ошибка 2: Использование линейной регрессии для классификации
- Ошибка 3: Игнорирование предобработки
- Шпаргалка
- Заключение
- КВИЗ
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный scikit-learn (
pip install scikit-learn) - Базовое понимание машинного обучения (признаки, целевая переменная)
- Знание NumPy и Pandas на начальном уровне
Совет: Линейная регрессия — это не просто «первая модель». Это фундамент, без которого невозможно понять более сложные алгоритмы. Начни с неё, и всё остальное станет понятнее!
Основная часть
Что такое линейная регрессия?
Линейная регрессия — это алгоритм машинного обучения для предсказания непрерывных значений. Её цель — найти линейную зависимость между входными признаками (X) и целевой переменной (y) . Если коротко: мы ищем прямую линию, которая лучше всего описывает наши данные.
Простая (одномерная) регрессия:
y = w × x + b
y— предсказанное значение (зависимая переменная)x— признак (независимая переменная)w— вес (коэффициент наклона)b— смещение (intercept)
Множественная регрессия: Когда признаков несколько, формула расширяется:
y = w₁ × x₁ + w₂ × x₂ + … + wₙ × xₙ + b
Совет: Линейная регрессия остаётся одной из самых широко применяемых техник даже в эпоху глубокого обучения . Она проста, интерпретируема и часто даёт отличные результаты!
Математическая основа
Метод наименьших квадратов (Ordinary Least Squares)
Чтобы найти лучшую прямую, мы минимизируем сумму квадратов ошибок между предсказанными и фактическими значениями . Это называется методом наименьших квадратов (OLS).
Функция потерь (MSE):
MSE = (1/n) × Σ(y_i — ŷ_i)²
Где:
y_i— фактическое значениеŷ_i— предсказанное значениеn— количество наблюдений
Модель находит такие w и b, при которых MSE минимальна.
Коэффициент детерминации (R²)
R² показывает, насколько хорошо модель объясняет дисперсию данных. Значение от 0 до 1: чем ближе к 1, тем лучше модель.
R² = 1 — (SS_res / SS_tot)
Где:
SS_res— сумма квадратов остатковSS_tot— общая сумма квадратов
Совет: R² = 0.7 означает, что модель объясняет 70% вариации целевой переменной. Это хороший показатель для многих задач.
Реализация на Python
Загрузка данных
Для примера используем встроенный датасет диабета из scikit-learn. Он содержит медицинские показатели пациентов и уровень развития диабета через год.
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
import numpy as np
# Загружаем датасет
X, y = load_diabetes(return_X_y=True)
# Берём только один признак для простоты (индекс 2 — BMI)
X = X[:, [2]]
print(f"Размер данных: {X.shape}")
print(f"Первые 5 значений BMI: {X[:5].flatten()}")
print(f"Первые 5 значений целевой переменной: {y[:5]}")Совет: Для обучения используем только один признак (индекс массы тела), чтобы легко визуализировать результат.
Разделение на train/test
# Разделяем на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"Обучающая выборка: {X_train.shape[0]} строк")
print(f"Тестовая выборка: {X_test.shape[0]} строк")Обучение модели
# Создаём и обучаем модель
model = LinearRegression()
model.fit(X_train, y_train)
# Выводим коэффициенты
print(f"Коэффициент (вес): {model.coef_[0]:.4f}")
print(f"Смещение (intercept): {model.intercept_:.4f}")Предсказание и оценка
# Предсказываем на тестовых данных
y_pred = model.predict(X_test)
# Метрики качества
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"Среднеквадратичная ошибка (MSE): {mse:.2f}")
print(f"Корень из MSE (RMSE): {rmse:.2f}")
print(f"Коэффициент детерминации (R²): {r2:.2f}")Результат (примерный):
Коэффициент (вес): 949.4353
Смещение (intercept): 152.7646
Среднеквадратичная ошибка (MSE): 2548.07
Корень из MSE (RMSE): 50.48
Коэффициент детерминации (R²): 0.47Совет: R² = 0.47 означает, что модель объясняет 47% вариации уровня диабета на основе BMI. С добавлением большего количества признаков R² улучшается.
Визуализация
# Визуализируем результаты
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
# Обучающая выборка
ax1.scatter(X_train, y_train, label='Обучающие данные', alpha=0.6)
ax1.plot(X_train, model.predict(X_train), color='red', linewidth=2, label='Модель')
ax1.set_xlabel('BMI')
ax1.set_ylabel('Уровень диабета')
ax1.set_title('Обучающая выборка')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Тестовая выборка
ax2.scatter(X_test, y_test, label='Тестовые данные', alpha=0.6)
ax2.plot(X_test, y_pred, color='red', linewidth=2, label='Предсказания')
ax2.set_xlabel('BMI')
ax2.set_ylabel('Уровень диабета')
ax2.set_title('Тестовая выборка')
ax2.legend()
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()Ключевые допущения линейной регрессии
Для того чтобы модель была корректной, данные должны удовлетворять определённым условиям :
Линейность
Связь между признаками и целевой переменной должна быть линейной (или линейной после преобразований).
Независимость наблюдений
Наблюдения должны быть независимы друг от друга.
Гомоскедастичность
Дисперсия остатков (ошибок) должна быть постоянной при всех значениях предсказаний.
Нормальность остатков
Остатки должны быть распределены нормально.
Отсутствие мультиколлинеарности
Признаки не должны быть сильно коррелированы друг с другом .
Совет: На практике линейная регрессия часто работает хорошо, даже если некоторые допущения нарушены. Но для серьёзных выводов важно проверять их выполнение .
Улучшение модели
Добавление признаков
Вместо одного признака (BMI) можно использовать все 10 признаков из датасета диабета:
X_full, y_full = load_diabetes(return_X_y=True)
# Используем все признаки
X_full_train, X_full_test, y_full_train, y_full_test = train_test_split(
X_full, y_full, test_size=0.2, random_state=42
)
model_full = LinearRegression()
model_full.fit(X_full_train, y_full_train)
y_full_pred = model_full.predict(X_full_test)
r2_full = r2_score(y_full_test, y_full_pred)
print(f"R² с 10 признаками: {r2_full:.3f}")Регуляризация
Когда признаков много, модель может переобучаться. Для борьбы с этим используют регуляризацию :
- Ridge (L2) — штрафует большие коэффициенты
- Lasso (L1) — может обнулять коэффициенты (отбор признаков)
- ElasticNet — комбинация L1 и L2
from sklearn.linear_model import Ridge
ridge = Ridge(alpha=1.0)
ridge.fit(X_full_train, y_full_train)
y_ridge_pred = ridge.predict(X_full_test)
print(f"R² с Ridge: {r2_score(y_full_test, y_ridge_pred):.3f}")Задачи для закрепления
Задача 1. Загрузи датасет load_diabetes() и выведи форму признаков и целевой переменной.
Задача 2. Раздели данные на train/test с test_size=0.3 и random_state=123.
Задача 3. Обучи модель LinearRegression на всех признаках и выведи коэффициенты.
Задача 4. Вычисли MSE и R² на тестовой выборке.
Задача 5. Сравни результаты с использованием одного признака (BMI) и всех 10 признаков.
Ответы:
Задача 1.
from sklearn.datasets import load_diabetes
X, y = load_diabetes(return_X_y=True)
print(f"X: {X.shape}, y: {y.shape}")Задача 2.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=123
)Задача 3.
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
print("Коэффициенты:", model.coef_)
print("Смещение:", model.intercept_)Задача 4.
from sklearn.metrics import mean_squared_error, r2_score
y_pred = model.predict(X_test)
print(f"MSE: {mean_squared_error(y_test, y_pred):.2f}")
print(f"R²: {r2_score(y_test, y_pred):.3f}")Задача 5.
Используя один признак (BMI), R² = 0.47. С 10 признаками R² = 0.52. Добавление признаков улучшило модель.
Нюансы и подводные камни
Переобучение
Если модель показывает отличные результаты на train, но плохие на test — это переобучение. Используй регуляризацию или уменьшай количество признаков.
Мультиколлинеарность
Если признаки сильно коррелированы, коэффициенты теряют стабильность. Используй корреляционную матрицу для проверки.
Выбросы
Выбросы могут сильно повлиять на линейную регрессию. Рассмотри робастные методы.
Частые ошибки и как их избежать
Ошибка 1: Не разделил данные до обучения
# Неправильно
model.fit(X, y) # Модель видит все данные
# Потом train_test_split — утечка данных
# Правильно
X_train, X_test, y_train, y_test = train_test_split(X, y)
model.fit(X_train, y_train)Ошибка 2: Использование линейной регрессии для классификации
Линейная регрессия предназначена для предсказания непрерывных значений. Для классификации используй логистическую регрессию.
Ошибка 3: Игнорирование предобработки
Перед обучением проверь пропуски, выбросы и масштабирование (для некоторых моделей).
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Импорт модели | from sklearn.linear_model import LinearRegression |
| Создание модели | model = LinearRegression() |
| Обучение | model.fit(X_train, y_train) |
| Предсказание | y_pred = model.predict(X_test) |
| MSE | from sklearn.metrics import mean_squared_error |
| R² | from sklearn.metrics import r2_score |
| Коэффициенты | model.coef_ |
| Смещение | model.intercept_ |
| Разделение данных | from sklearn.model_selection import train_test_split |
Заключение
Сегодня мы узнали:
- Что такое линейная регрессия и как она работает
- Математическую формулу и метод наименьших квадратов
- Как реализовать линейную регрессию на Python с scikit-learn
- Как оценивать качество модели (MSE, R²)
- Ключевые допущения и как их проверять
КВИЗ
Что дальше?




