Временной ряд и почему он особенный
Разбираемся, чем последовательность наблюдений во времени отличается от обычной таблицы признаков.
Временной ряд — это последовательность значений одной величины, измеренных в упорядоченные моменты времени: продажи по дням, трафик по часам, температура по минутам.
Зачем это отдельная дисциплина
В обычной задаче машинного обучения строки таблицы считаются независимыми: можно перемешать клиентов и ничего не сломается. Во временном ряде всё наоборот. Значение продаж сегодня связано с продажами вчера, а спрос в декабре похож на спрос прошлого декабря. Если выкинуть порядок — мы выкинем самую ценную информацию. Именно поэтому прогнозирование спроса, трафика и продаж выделено в отдельную область со своими моделями и своими правилами валидации.
Практический мотив прост: бизнесу нужно знать будущее. Сколько товара заказать на склад, сколько серверов поднять под нагрузку, сколько курьеров вывести в смену. Все эти вопросы — про прогноз следующих точек ряда.
Представьте интернет-магазин перед «чёрной пятницей». Если закупить слишком мало, полки опустеют и выручка уйдёт к конкуренту; если слишком много — деньги застрянут в нераспроданных остатках, а склад придётся оплачивать. Правильный ответ скрыт именно в истории прошлых распродаж: как рос спрос в предыдущие годы, какой была динамика по дням недели, как реагировали продажи на скидки. Ровно та же логика работает для онлайн-сервиса, который планирует мощность дата-центра под пиковый трафик, или для службы доставки, рассчитывающей число смен. Во всех этих сценариях решение принимают заранее, а единственный источник знания о будущем — упорядоченная во времени история.
Ещё одна причина, по которой временные ряды живут отдельно от «обычного» ML, — структура ошибки. В табличной задаче мы стремимся объяснить целевую переменную через признаки. В ряде же признаком чаще всего выступает само прошлое: вчерашнее значение, значение неделю назад, среднее за месяц. Такая «оглядка на себя» (автокорреляция) одновременно и сила метода, и его ловушка, поэтому ей посвящены целые разделы курса.
Три свойства, которые меняют правила
Порядок несёт смысл. Перестановка строк во временном ряде уничтожает информацию. В таблице клиентов порядок случаен, здесь — это ось времени.
Наблюдения зависимы. Соседние точки коррелируют. Это нарушает предположение независимости, на котором стоят многие классические методы.
Будущее нельзя подсматривать. Когда мы оцениваем модель, тест обязан лежать строго после обучающей выборки по времени. Случайное разбиение train/test даёт утечку из будущего и красивые, но лживые метрики.
Эти три свойства тесно связаны. Раз порядок несёт смысл, значит соседние точки зависимы; раз они зависимы, обучающая и тестовая выборки не могут пересекаться во времени, иначе модель «увидит» подсказку из будущего. Хорошая привычка — с первой минуты работы держать ряд отсортированным по времени и думать о любой операции как о действии вдоль этой оси. Тогда большинство грубых ошибок отсекается само собой.
Как выглядит ряд в коде
Простейшее представление — список значений плюс параллельный список меток времени. Уже на таком уровне видно, что мы работаем с упорядоченной структурой.
days = ["Пн","Вт","Ср","Чт","Пт","Сб","Вс"]
sales = [120, 135, 130, 150, 190, 240, 95]
avg = sum(sales) / len(sales)
print("Средние продажи:", round(avg, 1))
print("Максимум:", max(sales), "в", days[sales.index(max(sales))])
print("Разница Сб-Вс:", sales[5] - sales[6])
Вывод:
Средние продажи: 151.4 Максимум: 240 в Сб Разница Сб-Вс: 145
Обратите внимание: суббота резко выше, воскресенье резко ниже. Это не шум, а недельная сезонность — устойчивый паттерн, привязанный к позиции внутри недели. Мы научимся выделять такие паттерны в следующих разделах.
Заметьте, что среднее (151.4) здесь почти бесполезно как прогноз: ни один реальный день к нему не близок. Это первый намёк на то, почему наивные методы «усреднения» проваливаются на рядах с сезонностью — они растворяют как раз ту структуру, ради которой мы и затевали анализ. Куда полезнее сравнивать каждый день с тем же днём прошлой недели, а не со средним по всем дням.
Как работает под капотом
Формально ряд записывают как множество пар: момент времени t и значение x_t. Если интервалы между t одинаковы (каждый день, каждый час) — ряд называют регулярным, и большинство методов рассчитаны именно на него. Если же измерения приходят как попало (логи кликов, сделки на бирже) — ряд нерегулярный, его обычно сначала приводят к регулярной сетке через агрегацию по бакетам.
Внутри библиотек ряд хранится как массив значений с отдельным индексом времени. Индекс — не украшение: по нему делается выравнивание, ресемплинг и сдвиги. Когда вы видите <date, value> пару — это и есть атом временного ряда.
Полезно держать в голове мысленную картину: ряд — это «лента», которая движется только в одну сторону. Мы стоим в текущей точке и видим всё, что слева (прошлое), но ничего справа (будущее). Любая операция, которая случайно заглядывает вправо — например, нормировка по среднему всего ряда, включая тестовый период, — это утечка. Поэтому опытные аналитики проверяют каждый шаг пайплайна вопросом: «А мог бы я выполнить это вычисление в реальном времени, не зная будущего?» Если нет — шаг придётся переделать.
Частые ошибки
- Перемешать ряд перед обучением «как обычные данные» — мгновенная потеря всей временной структуры.
- Считать соседние точки независимыми и применять методы, требующие независимости.
- Игнорировать пропуски и неравные интервалы, подавая нерегулярный ряд в модель для регулярного.
- Считать признаки по всему ряду сразу (среднее, максимум), захватывая будущее, — скрытая утечка, которая раздувает метрики.
- Путать сезонный провал (воскресенье) с аномалией и «чинить» его как ошибку данных.
Итоги
- Временной ряд — упорядоченная во времени последовательность значений одной величины.
- Главные отличия от таблиц: порядок важен, наблюдения зависимы, будущее подсматривать нельзя.
- Цель анализа чаще всего — прогноз будущих точек для бизнес-решений.
- Прошлое ряда — главный признак для прогноза, поэтому автокорреляция одновременно сила и ловушка метода.