Урок курса
Первый fit и predict на своих данных
Машинное обучение с нуля на Python: первая модельВ прошлом уроке мы разобрались, что данные делятся на признаки и цель, и научились выделять X и y из готовой таблицы. Теперь пройдём полный цикл: создадим DataFrame вручную, обучим на нём линейную регрессию и попросим её предсказать значения для новых строк.
DataFrame с признаками и целевой переменной: создание X и y
Начнём с данных, которые будут нашим сквозным примером. Мы моделируем прокат велосипедов: два признака — температура воздуха и влажность — и одна цель — количество прокатов за день.
import pandas as pd
data = {
'температура': [10, 18, 25, 30],
'влажность': [60, 55, 70, 45],
'прокатов': [120, 210, 280, 350]
}
df = pd.DataFrame(data)
Таблица содержит четыре строки — это четыре наблюдения. Каждая строка описывает один день: какой была погода и сколько велосипедов взяли в аренду.
Теперь разделяем её на X и y:
y = df['прокатов']
X = df.drop(columns=['прокатов'])
y — это pandas Series с четырьмя числами: [120, 210, 280, 350]. X — DataFrame из двух столбцов, температура и влажность, и тех же четырёх строк.
Почему целевой столбец нельзя оставлять в X? Модель обучается искать связь между признаками и целью. Если передать прокатов как признак, правильный ответ окажется прямо во входных данных — это утечка целевой переменной в обучение. Качество модели на тренировочных данных может выглядеть искусственно высоким, но при реальном прогнозе значение цели недоступно: мы как раз и хотим его предсказать. После drop в X остаётся только то, что будет известно в момент прогноза: погодные условия без информации о результате.
Проверить, что столбцы разделены правильно, просто:
print(list(X.columns)) # ['температура', 'влажность']
print(y.name) # 'прокатов'
Этот список столбцов важен — он понадобится позже, когда будем формировать новые строки для предсказания.
Почему predict требует [[4]], а не [4]
В scikit-learn X — таблица формы «объекты × признаки». Даже один объект с одним признаком остаётся двумерной таблицей:
from sklearn.linear_model import LinearRegression
model = LinearRegression().fit([[1], [2], [3]], [3, 5, 7])
print(model.predict([[4]]).round(6).tolist())
print(model.predict([[4], [5]]).round(6).tolist())
Первый результат — [9.0], второй — [9.0, 11.0]. Запись [4] одномерная и приводит к ошибке Expected 2D array. Запись [[4, 5]] двумерная, но означает один объект с двумя признаками — такой вход тоже не подходит модели, обученной на одном. Число столбцов нового X должно совпадать с обучением.
LinearRegression: создание объекта и обучение через fit
Когда X и y готовы, создаём модель и обучаем её:
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X, y)
LinearRegression() не требует обязательных аргументов — класс берёт разумные значения по умолчанию. Главное понять, что model — это обычный Python-объект, и до вызова fit он пустой: внутри нет никаких обученных параметров.
fit(X, y) меняет это. Метод просматривает все четыре строки, находит веса для температура и влажность методом наименьших квадратов и записывает их внутрь объекта model. После возврата из fit объект несёт в себе эти веса — они хранятся в атрибутах model.coef_ и model.intercept_, хотя на текущем этапе нам не нужно их разбирать вручную.
Важный момент: fit возвращает сам объект model, а не какой-то новый объект с параметрами. Состояние меняется внутри — именно поэтому достаточно написать model.fit(X, y) без присвоения результата. Код вида trained_model = model.fit(X, y) тоже сработает, но trained_model и model будут указывать на один и тот же объект.
Чтобы убедиться, что обучение прошло без ошибок, достаточно того, что строка выполнилась — исключений не возникло. На этом этапе модель готова к предсказаниям.
predict для новых строк: схема признаков и результат
Модель обучена на X с колонками ['температура', 'влажность']. Чтобы получить прогноз для новых дней, нужно собрать DataFrame точно с теми же столбцами в том же порядке — без столбца прокатов.
X_new = pd.DataFrame({
'температура': [20, 27],
'влажность': [65, 50]
})
predictions = model.predict(X_new)
print(predictions)
Вывод:
[227.40235474 313.54886937]
predict возвращает NumPy-массив длиной 2 — по одному числу на каждую строку X_new. Первый элемент, 227.4, — прогноз для дня с температурой 20 и влажностью 65; второй, 313.5, — для температуры 27 и влажности 50. Именно такой вывод должен появиться у вас при запуске кода на тех же четырёх обучающих точках.
Теперь о том, что ломает предсказание. Схема X_new должна в точности совпадать со схемой X при fit. Два типичных нарушения:
Лишний столбец — например, если случайно добавить прокатов в X_new. Актуальный scikit-learn увидит несоответствие числа признаков и бросит ValueError.
Перестановка столбцов — если X_new содержит ['влажность', 'температура'] вместо ['температура', 'влажность']. При передаче именованного DataFrame sklearn использует имена столбцов и в последних версиях выдаст предупреждение или ошибку. При передаче безымянного NumPy-массива sklearn может выдать предупреждение о том, что у входа нет имён признаков — но это предупреждение касается только отсутствия имён, а не порядка значений. Если число столбцов совпадает, перепутанный порядок пройдёт без дополнительного сигнала: модель подставит значение влажности туда, где ожидает температуру, и вернёт неверный прогноз.
Диагностика простая:
print(list(X.columns)) # ['температура', 'влажность']
print(list(X_new.columns)) # должно быть то же самое
Если списки совпадают — схема верна, и predict вернёт корректный результат.
Задача 1
LinearRegression обучена на DataFrame X со столбцами ['скорость', 'груз']. X_new содержит те же столбцы в порядке ['груз', 'скорость']. Что произойдёт при вызове model.predict(X_new) в актуальном scikit-learn?
Задача 2
Модель обучена на DataFrame с колонками ['температура', 'влажность']. Для predict подготовили X_new в виде безымянного NumPy-массива, где первый столбец — влажность, а второй — температура (порядок перепутан). Что произойдёт?
Задача 3
Модель обучена на прошлых днях. В X_new сначала записан новый день A, затем новый день B. model.predict(X_new) вернул NumPy-массив [240., 310.]. Что можно сообщить о дне B и проверке качества прогноза?
Задача 4
Расход топлива для новых рейсов
Автопарк накапливает историю своих рейсов: для каждого из них диспетчеры записывают пройденное расстояние, среднюю скорость на маршруте и массу перевозимого груза, а также фиксируют, сколько топлива в итоге было израсходовано. Со временем эти записи превращаются в ценный архив, отражающий реальную зависимость между условиями поездки и аппетитом двигателя.
Зная, что расход топлива закономерно меняется вместе с тремя перечисленными характеристиками рейса, логистики хотят научиться предсказывать его заранее — до того как грузовик тронется в путь. Для этого накопленные данные используются как обучающий материал: три характеристики играют роль входных признаков, а фактический расход становится той величиной, которую модель учится воспроизводить.
Что уже дано
До вашего кода в том же пространстве имён создаются df — pandas DataFrame с историей рейсов — и new_trips — список двух словарей с данными будущих рейсов. В df столбцы расстояние_км, скорость_кмч, груз_т — числовые признаки, топливо_л — фактический расход. В new_trips цели нет.
Что нужно сделать
Создайте X и y, экземпляр LinearRegression с именем model, обучите его через fit(X, y). Из new_trips создайте DataFrame X_new с теми же тремя столбцами в том же порядке, что X. Сохраните результат model.predict(X_new) в predictions.
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно. После вашего кода проверяются верхнеуровневые X, y, model, X_new, predictions. predictions — NumPy-массив из двух числовых прогнозов расхода в литрах, по одному для каждого нового рейса.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 5
Исправление прогноза сушки керамики
В небольшой керамической мастерской каждое изделие проходит через обжиг только после того, как глиняная стенка полностью просохнет. Мастера годами фиксировали параметры своих работ: насколько толстой получилась стенка, какова была влажность воздуха в цеху, при какой температуре шла сушка — и сколько часов в итоге потребовалось изделию, чтобы достичь нужной готовности. Теперь эти записи превратились в таблицу, где три числовых показателя описывают условия, а время сушки отражает результат.
Мастерская решила использовать накопленный опыт, чтобы заранее планировать загрузку печи: если знать примерное время сушки ещё до её начала, проще выстраивать очерёдность изделий. Для этого была написана небольшая программа, обучающая линейную регрессию на старых записях и применяющая её к новым работам. Обучение завершается, но вызов predict для двух новых изделий выдаёт ошибку вместо времени сушки.
Что уже дано
Скрытая подготовка не создаёт данных: весь исходный код находится в редакторе. Он создаёт df с тремя числовыми признаками толщина_мм, влажность_проц, температура_с и целью сушка_ч. Из него уже выделены X и y и обучен model. Два новых изделия находятся в DataFrame X_new.
Что нужно сделать
Найдите причину сбоя и исправьте подготовку новых данных. Сохраните обучение LinearRegression на прошлых изделиях и два прогноза времени сушки в переменной predictions. Измерения новых изделий и их порядок в таблице должны сохраниться; целевое время сушки для них пока неизвестно.
Ввод и вывод
stdin не используется. Печатать через print в stdout ничего не нужно. После вашего кода проверяются верхнеуровневые df, X, y, model, X_new, predictions. predictions — NumPy-массив из двух прогнозов в часах.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задачи к уроку
- scikit-learn predict: совпадение столбцов Xtrain и Xnew
Исправьте новые данные для LinearRegression: признаки и порядок столбцов при predict должны совпадать с обучением.
Продолжить с сохранением прогресса
Перейдите к уроку в учебном кабинете.
