Содержание
  1. Как устроена линейная регрессия
  2. Класс LinearRegression в sklearn: параметры и атрибуты
  3. Пример: линейная регрессия sklearn на ценах на недвижимость
  4. Как читать r2_score и MSE
  5. LinearRegression, Ridge, Lasso и SGDRegressor: что выбрать
  6. Частые ошибки
  7. Куда двигаться после линейной регрессии
  8. Вопросы и ответы
  9. Заключение
СправочникОбновлено · 08.2026

Data Science на Python: линейная регрессия

8 февраля 2024 · 11 минут чтения

Линейная регрессия sklearn — это класс LinearRegression из модуля sklearn.linear_model. Метод fit обучает модель по методу наименьших квадратов, predict возвращает прогноз, score считает коэффициент детерминации R². Разберём полный цикл на примере цен на недвижимость: подготовка данных, разбиение на выборки, обучение, оценка по R² и MSE, прогноз для новой квартиры. Код из статьи запускается целиком и не требует внешних CSV-файлов.

  • LinearRegression — обычный метод наименьших квадратов: внутри вызывается scipy.linalg.lstsq.
  • Схема работы: train_test_split → fit → predict → r2_score и mean_squared_error.
  • R² равен 1.0 у идеальной модели и 0.0 у модели, которая всегда предсказывает среднее; бывают и отрицательные значения.
  • Ridge добавляет к той же модели L2-регуляризацию, Lasso — L1 с обнулением лишних коэффициентов.
  • Пример ниже проверен на scikit-learn 1.9: коэффициенты, R² и прогноз приведены из реального запуска.

Как устроена линейная регрессия

Линейная регрессия — метод моделирования связи между зависимой переменной и одной или несколькими независимыми. Модель ищет такие коэффициенты, при которых взвешенная сумма признаков максимально близко воспроизводит целевое значение: y = β₀ + β₁x₁ + β₂x₂ + … + ε. Для цен на жильё это читается так: цена складывается из вклада площади, вклада количества комнат и вклада возраста дома плюс необъяснённый остаток.

Ключевые понятия

  • Зависимая переменная (y): величина, которую нужно предсказать, — в нашем примере цена.
  • Независимые переменные (X): признаки, на основе которых делается предсказание, — площадь, комнаты, возраст.
  • Коэффициенты (β): параметры модели, определяющие вклад каждого признака. После обучения лежат в атрибуте coef_.
  • Свободный член (β₀): значение прогноза при нулевых признаках, атрибут intercept_.
  • Ошибка модели (ε): разница между наблюдаемыми и предсказанными значениями.

Сильные стороны и ограничения

Метод простой, быстрый и интерпретируемый: каждый коэффициент прямо показывает, на сколько изменится прогноз при изменении признака на единицу. За это приходится платить тремя ограничениями. Модель предполагает линейную зависимость между признаками и целью — кривые зависимости она спрямляет. Она чувствительна к выбросам: одна аномальная сделка заметно сдвигает коэффициенты. И при сильной корреляции признаков между собой (мультиколлинеарности) коэффициенты становятся нестабильными — эту проблему решает Ridge-регрессия, о ней ниже. Если вы только начинаете путь в анализе данных, общая картина области — в статье Data Science на Python: разгадывание будущего через данные.

Класс LinearRegression в sklearn: параметры и атрибуты

Путь модели: от данных до прогноза
Путь модели: от данных до прогноза

Именно так линейная регрессия sklearn выглядит в коде: импортируется класс, создаётся объект, дальше работают три метода — fit, predict и score. Сигнатура конструктора в scikit-learn 1.9:

from sklearn.linear_model import LinearRegression

model = LinearRegression(
    fit_intercept=True,
    copy_X=True,
    tol=1e-06,
    n_jobs=None,
    positive=False
)

По документации scikit-learn, внутри класса нет градиентного спуска: это обычный метод наименьших квадратов, обёрнутый в интерфейс модели, — на плотных данных решение считает scipy.linalg.lstsq, а при positive=True — scipy.optimize.nnls. Решение точное: итераций, подбора шага обучения и критериев остановки здесь нет.

Параметр По умолчанию Что делает
fit_intercept True Считать ли свободный член β₀. При False данные должны быть заранее центрированы
copy_X True Копировать ли матрицу признаков. При False исходный массив может быть перезаписан
tol 1e-06 Точность решения: критерий сходимости внутреннего решателя
n_jobs None Число потоков. Даёт выигрыш только при нескольких целевых переменных и разреженном X либо при positive=True
positive False При True коэффициенты принудительно неотрицательные. Работает только с плотными массивами

После вызова fit у модели появляются атрибуты:

  • coef_ — коэффициенты при признаках, массив длины n_features;
  • intercept_ — свободный член; равен 0.0, если fit_intercept=False;
  • rank_ и singular_ — ранг и сингулярные числа матрицы X, доступны на плотных данных;
  • n_features_in_ и feature_names_in_ — сколько признаков и с какими именами модель видела при обучении.

Метод score(X, y) возвращает коэффициент детерминации R² — тот же результат, что r2_score из sklearn.metrics.

Пример: линейная регрессия sklearn на ценах на недвижимость

Чтобы пример воспроизводился у любого читателя, данные генерируются кодом — скачивать CSV-файл не нужно. Мы создаём 300 квартир с площадью, количеством комнат и возрастом дома, а цену собираем по известной формуле: 90 000 ₽ за квадратный метр, 250 000 ₽ за комнату, минус 15 000 ₽ за каждый год возраста, плюс случайный рыночный шум. Такой приём даёт честную проверку: мы заранее знаем истинные коэффициенты и увидим, сумеет ли модель их восстановить.

Шаг 1: подготовка данных

import numpy as np
import pandas as pd

rng = np.random.default_rng(42)
n = 300

area = rng.uniform(30, 150, n).round(1)      # площадь, кв. м
rooms = rng.integers(1, 6, n)                # количество комнат
age = rng.integers(0, 40, n)                 # возраст дома, лет

# цена = вклад площади + вклад комнат - вклад возраста + рыночный шум
price = 90_000 * area + 250_000 * rooms - 15_000 * age
price = price + rng.normal(0, 400_000, n)

data = pd.DataFrame({
    'area': area,
    'rooms': rooms,
    'age': age,
    'price': price.round()
})
print(data.head(3))

Первые строки таблицы выглядят так:

    area  rooms  age       price
0  122.9      4    0  12560180.0
1   82.7      4    1   8326993.0
2  133.0      4    8  12995382.0

Шаг 2: разбиение на обучающую и тестовую выборки

from sklearn.model_selection import train_test_split

X = data[['area', 'rooms', 'age']]
y = data['price']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=0
)
print(X_train.shape, X_test.shape)  # (240, 3) (60, 3)

Тестовые 20% данных модель не увидит при обучении — на них мы проверим качество прогноза. Параметр random_state фиксирует разбиение, чтобы результат воспроизводился от запуска к запуску.

Шаг 3: обучение модели

from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train, y_train)

for name, coef in zip(X.columns, model.coef_):
    print(f'{name}: {coef:.0f}')
print(f'intercept_: {model.intercept_:.0f}')

Вывод при запуске на scikit-learn 1.9:

area: 90629
rooms: 254452
age: -14122
intercept_: -118259

Модель восстановила заложенные зависимости: 90 629 против истинных 90 000 за метр, 254 452 против 250 000 за комнату, −14 122 против −15 000 за год возраста. Отклонения — следствие шума в 400 000 ₽, который мы сами добавили в цены.

Шаг 4: оценка качества

from sklearn.metrics import mean_squared_error, r2_score

y_pred = model.predict(X_test)

mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f'MSE: {mse:.0f}')    # 187454214425
print(f'RMSE: {mse ** 0.5:.0f}')  # 432960
print(f'R2: {r2:.3f}')      # 0.982

R² = 0.982 — модель объяснила 98,2% разброса цен на тестовой выборке. Корень из MSE (RMSE) равен 432 960 ₽ и почти совпал с величиной шума 400 000 ₽, который мы заложили в данные: модель выжала из признаков практически всё, остаток — чистая случайность. Это полезный ориентир и для рабочих задач: если RMSE перестал падать при добавлении признаков, возможно, вы упёрлись в естественный шум данных.

Шаг 5: прогноз для новой квартиры

new_flat = pd.DataFrame(
    [[120, 4, 5]],
    columns=['area', 'rooms', 'age']
)
predicted_price = model.predict(new_flat)
print(f'Прогноз цены: {predicted_price[0]:.0f}')  # 11704482

Для квартиры площадью 120 кв. м с четырьмя комнатами в доме пятилетнего возраста модель предсказала 11 704 482 ₽. Обратите внимание: новый объект передаётся как DataFrame с теми же именами колонок, что и при обучении, — почему это важно, разберём в разделе про ошибки.

Как читать r2_score и MSE

Документация scikit-learn задаёт для коэффициента детерминации три опорные точки. Лучшее значение — 1.0: прогноз совпал с фактом. Значение 0.0 получает константная модель, которая всегда предсказывает среднее значение y и игнорирует признаки. Отрицательный результат возможен и означает, что модель хуже такой константы: для y_true = [3, -0.5, 2, 7] и y_pred = [2.5, 0.0, 2, 8] функция r2_score возвращает 0.948, а для перевёрнутого прогноза y_pred = [3, 2, 1] при y_true = [1, 2, 3] — ровно −3.0.
MSE измеряется в квадратах единиц целевой переменной — «квадратные рубли» напрямую не интерпретируются, поэтому на практике смотрят RMSE (корень из MSE): он в тех же единицах, что и цена, и читается как типичная ошибка прогноза. Сравнивать MSE двух моделей имеет смысл только на одной и той же выборке.

LinearRegression, Ridge, Lasso и SGDRegressor: что выбрать

Выбор линейной модели под данные
Выбор линейной модели под данные

LinearRegression — базовый вариант без регуляризации. В sklearn у него есть три близких родственника, и выбор между ними диктуют сами данные.

Модель Регуляризация Когда брать
LinearRegression Нет Признаков немного, они слабо коррелируют между собой, нужна прямая интерпретация коэффициентов
Ridge L2 — штраф за размер коэффициентов Признаки коррелируют (мультиколлинеарность): штраф делает коэффициенты устойчивыми к коллинеарности
Lasso L1 — штраф за сумму модулей Признаков много и часть лишние: Lasso обнуляет ненужные коэффициенты и работает как отбор признаков
SGDRegressor Настраиваемая (L1, L2, elasticnet) Очень большая выборка: обучение стохастическим градиентным спуском, метод partial_fit дообучает модель порциями

Руководство scikit-learn прямо описывает эту связку: оценки обычного метода наименьших квадратов опираются на независимость признаков, и при коррелирующих колонках прогноз становится сверхчувствительным к случайным ошибкам; Ridge решает эту проблему штрафом за размер коэффициентов, Lasso оценивает разреженные коэффициенты и способен ставить их точно в ноль, а стохастический градиентный спуск полезен, когда число объектов и признаков очень велико. Все четыре класса живут в одном модуле sklearn.linear_model и взаимозаменяемы по интерфейсу: те же fit, predict и score.

Частые ошибки

Три ситуации, на которые уходит больше всего времени у новичков. Каждую мы воспроизвели на scikit-learn 1.9 — предупреждения и ошибки приведены дословно.

Прогноз списком после обучения на DataFrame

Вызов model.predict([[120, 4, 5]]) после обучения на DataFrame срабатывает, но выдаёт предупреждение: «X does not have valid feature names, but LinearRegression was fitted with feature names». Модель запомнила имена колонок и не может проверить, что признаки переданы в правильном порядке. Лечение — передавать новые объекты как DataFrame с теми же колонками, как в шаге 5 примера.

Одномерный массив вместо двумерного

Если признак один и X передан как плоский вектор, fit и predict падают с ошибкой «Expected 2D array, got 1D array instead» и подсказкой в тексте: преобразуйте данные через array.reshape(-1, 1), если у вас один признак, или array.reshape(1, -1), если один объект. Матрица признаков всегда обязана иметь форму (n_samples, n_features), даже когда признак единственный.

Оценка на обучающей выборке

R², посчитанный на тех же данных, где модель училась, систематически завышен — модель частично запомнила шум. Качество судят только по отложенной тестовой выборке, как в шаге 4, а при малых данных — по кросс-валидации через cross_val_score.

Куда двигаться после линейной регрессии

Линейная регрессия — задача обучения с учителем: у каждой строки данных есть правильный ответ. Второй базовый тип моделей работает без ответов и сам находит группы похожих объектов — это разобрано в статье Data Science на Python: кластеризация как основной тип модели. А если вы выбираете, какой инструмент учить первым для работы с данными, сравнение двух главных кандидатов — в материале SQL против Python: что следует изучить.

Вопросы и ответы

Как импортировать линейную регрессию из sklearn?

Командой from sklearn.linear_model import LinearRegression. Дальше создайте объект model = LinearRegression() и вызовите model.fit(X, y), где X — таблица признаков формы (n_samples, n_features), а y — целевая переменная.

Что показывает r2_score в sklearn?

Коэффициент детерминации R² — долю разброса целевой переменной, которую объяснила модель. Лучшее значение — 1.0. Модель, которая всегда предсказывает среднее значение y, получает ровно 0.0, а прогноз хуже такой константы уходит в минус.

Может ли R² быть отрицательным?

Да. По документации scikit-learn R² может быть сколь угодно отрицательным: для y_true = [1, 2, 3] и y_pred = [3, 2, 1] функция r2_score возвращает −3.0. Отрицательное значение означает, что модель предсказывает хуже, чем константа, равная среднему значению y.

Чем LinearRegression отличается от Ridge и Lasso?

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

Можно ли обучить LinearRegression на numpy-массивах без pandas?

Да. Метод fit принимает любой array-like формы (n_samples, n_features), numpy-массив подходит без преобразований. Единственное требование — двумерная форма X: для одного признака вектор преобразуют через reshape(-1, 1).

Заключение

Линейная регрессия в sklearn — это пять строк рабочего кода: импорт LinearRegression, fit на обучающей выборке, predict на тестовой, r2_score и MSE для оценки. В нашем прогоне модель восстановила заложенные в данные коэффициенты с точностью до рыночного шума и дала R² = 0.982. Когда признаки начинают коррелировать или их становится слишком много, тот же интерфейс предлагают Ridge, Lasso и SGDRegressor — переход на них не потребует переписывать пайплайн.

Читайте также

3 материала