Разработчики и компании используют данные временных рядов каждый день, знают они это или нет. Независимо от того, собираете ли вы данные с датчиков IoT, анализируете прошлую производительность на рынке, отслеживаете облачную инфраструктуру или инфраструктуру приложений или используете приложение для доставки продуктов по требованию, данные временных рядов помогут вашему бизнесу работать. Но что именно представляют собой данные временных рядов и как они полезны?
Этот пост призван дать ответы на эти вопросы и проиллюстрировать силу данных временных рядов в действии, рассматривая реальный сценарий с использованием общедоступного набора данных из Комиссии по такси и лимузинам Нью-Йорка. Во-первых, давайте углубимся в несколько основных концепций, чтобы заложить основу для запросов, которые мы напишем и проанализируем в разделе «Давайте кодировать».
Памятное (не очень теоретическое) определение данных временного ряда
На фундаментальном уровне данные временных рядов представляют, как что-то меняется со временем. Это «что-то» может быть системой, процессом, поведением или объектом.
Когда люди говорят о данных временных рядов, они имеют в виду ситуацию, когда с каждой точкой данных связана метка времени, и мы собираем и сохраняем все точки данных о системе, процессе, поведении или объекте, о которых идет речь. Вместо того, чтобы перезаписывать предыдущие данные, мы используем временную метку, чтобы различать значения (например, когда что-то произошло, так же, если не больше, важно, чем само значение).
Это приводит нас к двум определяющим характеристикам данных временных рядов:
- Время является главной осью данных временных рядов (то есть ось X на графике)
- Данные временных рядов является
INSERTS
, неUPDATES
(то есть, мы не перезаписывать данные)
Подводя итог, данные временных рядов представляют собой изменения во времени, где мы рассматриваем время как основную ось наших данных, а новые точки данных рассматриваются как INSERT
не UPDATE
.
Вы также можете быть заинтересованы в чтении:
Работа с данными временных рядов
Вот забавное упражнение: если подумать, все данные — это данные временных рядов!
Если вы чем-то похожи на меня, это может привести к тому, что вы скажете: «Подождите, что? Однако по сей день я до сих пор не могу вспомнить ни одного. Это связано с тем, что все данные по определению происходят в определенный момент времени (а время уходит вперед, насколько нам известно).
Если мы «выбрасываем» или игнорируем элемент времени наших данных, мы теряем ценную информацию. И наоборот, когда мы рассматриваем наши данные как данные временных рядов, мы (и наши команды) можем лучше понять, как меняются мир и вещи, которые нас интересуют.
Как данные временного ряда могут мне помочь?
Данные временных рядов важны, потому что, отслеживая, как все меняется со временем, данные временных рядов превращают точки данных в истории данных.
Мы можем представить, почему данные временных рядов полезны для трех категорий.
Данные временных рядов помогают людям:
- Проанализируйте прошлое
- Следи за настоящим
- Планируйте и предсказывайте будущее
Давайте посмотрим на пример, чтобы ехать домой. Большинство, если не все из нас, получили посылки от Amazon, DHL, UPS, FedEx или какой-либо другой службы доставки посылок. К настоящему времени вас не должно удивлять то, что информация о доставке вашей посылки является данными временного ряда!
В таблице ниже показано, как компания по доставке посылок могла (и должна) использовать свои данные для:
Проанализируйте прошлое |
Монитор присутствует |
Предсказывать будущее |
|
Компания по доставке посылок (Amazon, DHL, FedEx и др.) |
Анализ исторических данных доставки для оптимизации маршрутов доставки |
Мониторинг в реальном времени местоположения посылки и статуса доставки |
Используйте исторические данные для прогнозирования объема и времени доставки, реалистичных ожиданий клиентов и управления планированием мощностей (например, укомплектование достаточного количества водителей во время пиковых нагрузок). |
Поскольку все данные могут иметь временные ряды по своей природе, компании и команды всех размеров — от небольших стартапов и участников до проектов с открытым исходным кодом и крупных компаний с многомиллионными ценами — могут и должны использовать данные временных рядов.
Теперь, когда у нас есть кое-какие теории и определения, давайте разберемся с практикой и рассмотрим реальный пример.
Давайте код: данные такси Нью-Йорка
Я работаю в нью-йоркском офисе Timescale, поэтому использую пример того, что я и люди, живущие в больших городах, видим каждый день: такси. Этот пример иллюстрирует, как данные временных рядов помогают нам анализировать прошлое.
Сценарий, приведенный ниже, взят из Hello NYC , учебника из трех частей, посвященного анализу данных такси Нью-Йорка с использованием PostgreSQL и Timescale. Для завершения учебника не требуется никаких предварительных знаний, кроме базовых знаний по SQL.
Сценарий
Нью-Йорк поставил цель сократить выбросы парниковых газов на 20% к 2024 году. * Учитывая количество поездок на такси, совершаемых каждый день, они считают, что изучение прошлой истории водителей такси сыграет важную роль в достижении этой цели.
New York Data Team * наняла вас, чтобы помочь им разобраться в исторических данных о поездках на такси, получить представление и использовать свой анализ для планирования на будущее. Ваша цель — провести анализ всех поездок на такси в Нью-Йорке, проведенных в январе 2016 года.
* Примечание: это вымышленный сценарий. Однако мы разработали этот сценарий и связанные с ним цели, чтобы реалистично отразить вопросы, которые реальные градостроительные организации могут задать своим данным, и методы, используемые для ответа на эти вопросы.
Dataset
Мы рассмотрим набор данных всех поездок на такси, совершенных в Нью-Йорке в январе 2016 года. Данные получены из общедоступных наборов данных Комиссии по такси и лимузинам Нью-Йорка (NYC TLC). NYC TLC — это агентство, отвечающее за лицензирование и регулирование такси такси Yellow Taxi в Нью-Йорке и других транспортных средств. NYC TLC имеет более 200 000 автомобилей, на которые у лицензиата совершается около 1 миллиона поездок в день — это много поездок!
Они собирают следующие данные о каждой поездке:
- Дата и время выдачи (как отметка времени)
- Место выдачи (широта и долгота)
- Отбросить дату и время (как отметку времени)
- Место высадки (широта и долгота)
- Расстояние поездки (в милях)
- Тарифы (в долларах США)
- Количество пассажиров
- Тип тарифа (например, стандартный, аэропорт. Подробнее см. RateCodeID в этом документе )
- Тип платежа (Наличные, кредитная карта. Подробнее см. Payment_type в этом документе )
В первой части учебного пособия Hello NYC рассматривается схема, используемая для хранения этих данных в базе данных PostgreSQL, поэтому вы можете обратиться к ней, если хотите получить более подробную информацию. Тем не менее, давайте посмотрим на обзор ниже, чтобы мы могли ознакомиться с ним.
Для удобства использования мы создали три таблицы для хранения данных о поездке:
-
1 обычная таблица Postgres
payment_types
, которая отображает числовые коды типов платежей в английском описании (например, кредитная карта, наличные и т. Д.)
SQL
xxxxxxxxxx
1
SELECT * FROM payment_types
-
1 обычная таблица Postgres
rates
, которая отображает числовые коды тарифов в английском описании (например, стандартная поездка, поездка в аэропорту JFK, поездка в аэропорту Ньюарка и т. Д.).
SQL
xxxxxxxxxx
1
SELECT * FROM rates
-
1 Hypertable называется временной шкалой
rides
, в которой хранятся все вышеперечисленные данные, которые TLC NYC собрала для пассажира, едущего в 2016 году, о котором идет речь. Hypertables ведут себя так же, как обычные таблицы Postgres, но оптимизированы для автоматического разделения данных временных рядов на эффективность и производительность.
SQL
xxxxxxxxxx
1
SELECT * FROM rides
2
LIMIT 3;
Оболочка
xxxxxxxxxx
1
-[ RECORD 1 ]---------+---------------------------------------------------
2
vendor_id | 1
3
pickup_datetime | 2016-01-02 06:27:50
4
dropoff_datetime | 2016-01-02 06:39:17
5
passenger_count | 1
6
trip_distance | 4.30
7
pickup_longitude | 0
8
pickup_latitude | 0
9
rate_code | 1
10
dropoff_longitude | 0
11
dropoff_latitude | 0
12
payment_type | 2
13
fare_amount | 14
14
extra | 0
15
mta_tax | 0.5
16
tip_amount | 0
17
tolls_amount | 0
18
improvement_surcharge | 0.3
19
total_amount | 14.8
20
pickup_geom | 01010000207308000058937DADD91162413BC2471015063241
21
dropoff_geom | 01010000207308000058937DADD91162413BC2471015063241
22
-[ RECORD 2 ]---------+---------------------------------------------------
23
vendor_id | 1
24
pickup_datetime | 2016-01-02 08:59:50
25
dropoff_datetime | 2016-01-02 09:06:20
26
passenger_count | 2
27
trip_distance | 0.70
28
pickup_longitude | 0
29
pickup_latitude | 0
30
rate_code | 1
31
dropoff_longitude | 0
32
dropoff_latitude | 0
33
payment_type | 2
34
fare_amount | 6
35
extra | 0
36
mta_tax | 0.5
37
tip_amount | 0
38
tolls_amount | 0
39
improvement_surcharge | 0.3
40
total_amount | 6.8
41
pickup_geom | 01010000207308000058937DADD91162413BC2471015063241
42
dropoff_geom | 01010000207308000058937DADD91162413BC2471015063241
43
-[ RECORD 3 ]---------+---------------------------------------------------
44
vendor_id | 1
45
pickup_datetime | 2016-01-01 06:05:30
46
dropoff_datetime | 2016-01-01 06:11:48
47
passenger_count | 2
48
trip_distance | 2.00
49
pickup_longitude | 0
50
pickup_latitude | 0
51
rate_code | 1
52
dropoff_longitude | 0
53
dropoff_latitude | 0
54
payment_type | 2
55
fare_amount | 8
56
extra | 0
57
mta_tax | 0.5
58
tip_amount | 0
59
tolls_amount | 0
60
improvement_surcharge | 0.3
61
total_amount | 8.8
62
pickup_geom | 01010000207308000058937DADD91162413BC2471015063241
63
dropoff_geom | 01010000207308000058937DADD91162413BC2471015063241
Теперь, когда мы более знакомы с таблицами и схемами базы данных, пришло время приступить к анализу данных!
В этом разделе мы собираемся написать запросы, чтобы ответить на следующие вопросы и обсудить, как результаты могут применяться в реальных ситуациях.
- Какой среднесуточный тариф для поездок с 2+ пассажирами?
- Сколько поездок прошло по типу езды?
Вопрос 1: Какая средняя стоимость проезда для пассажиров 2+?
Это пример запроса, который вы часто видите в анализе временных рядов, где вы хотите отслеживать статистику о подмножестве данных.
Мы выполнили бы это следующим образом:
SQL
xxxxxxxxxx
1
-- Q: What is the daily average fare amount for rides with 2 or more passengers
2
SELECT date_trunc('day', pickup_datetime) as day, avg(fare_amount)
3
FROM rides
4
WHERE passenger_count > 1 AND pickup_datetime < '2016-02-01'
5
GROUP BY day ORDER BY day;
таблицы
В этом случае, если поездки с 2+ пассажирами — это вид поездки, который нас очень волнует, мы можем отслеживать статистику об этом и видеть, как они меняются со временем. Кроме того, мы, вероятно, расследуем то, что произошло в течение недели с 23 по 30 января 2016 года, что привело к резкому росту средней цены билета до 15,61 доллара. Эта идея запроса, анализа и просмотра подмножеств, которые вас интересуют, также применима к другим сценариям, таким как анализ ключевых клиентских сегментов или конфигурации популярных продуктов.
Вопрос 2: Сколько поездок прошло по каждому типу ставки?
Этот вопрос требует разбивки поездок по типам ставок с течением времени. Это типичный пример отслеживания различных сегментов пользователей или клиентов и того, как они растут с течением времени.
Мы выполнили бы это следующим образом:
SQL
xxxxxxxxxx
1
-- Q: How many rides of each rate type took place in the month?
2
SELECT rate_code, COUNT(vendor_id) as num_trips
3
FROM rides
4
WHERE pickup_datetime < '2016-02-01'
5
GROUP BY rate_code ORDER BY rate_code;
Мы получаем следующий вывод, который показывает, сколько поездок было выполнено для каждого кода ставки:
Хотя это технически правильно, мы хотим что-то более понятное для человека. Для этого мы можем использовать возможности SQL JOINS, поэтому давайте изменим наш запрос:
SQL
xxxxxxxxxx
1
-- How many rides of each rate type took place?
2
SELECT rates.description, COUNT(vendor_id) as num_trips
3
FROM rides
4
JOIN rates on rides.rate_code = rates.rate_code
5
WHERE pickup_datetime < '2016-02-01'
6
GROUP BY rates.description ORDER BY num_trips desc;
Отсюда мы можем легче интерпретировать, какие типы поездок были наиболее популярными, поскольку у нас есть более удобочитаемые описания типов поездок, при этом сохраняя эти типы поездок как целые числа в базе данных для гибкости.
Мы видим, что наиболее популярными типами поездок являются поездки по стандартному тарифу и поездки в международный аэропорт имени Джона Кеннеди, один из трех аэропортов Нью-Йорка. Мы также можем увидеть, насколько более популярны поездки в аэропорт JFK, чем в международный аэропорт Ньюарк Либерти (еще один аэропорт в районе Нью-Йорка), в 13 раз более популярный в зависимости от количества поездок в каждый пункт назначения.
Этот простой пример — объединение индивидуальных данных о поездке и типов скорости отображения данных с английскими описаниями — иллюстрирует мощный момент: объединяя данные временных рядов с вашими реляционными или бизнес-данными, вы можете упростить анализ, получить полезные сведения для вашего проекта, приложения, или бизнес, и сделать вещи более понятными для вас, членов вашей команды и ваших руководителей.
Заключение и последующие шаги
В этом посте мы ответили на вопрос «что, черт возьми, это данные временных рядов ?!» и мы узнали, что данные временных рядов представляют, как что-то меняется со временем. Мы также узнали, почему данные временных рядов полезны: они помогают нам анализировать прошлое, отслеживать настоящее, прогнозировать и планировать будущее. Наконец, мы получили представление о том, как данные временных рядов могут помочь реальной организации, анализируя данные такси Нью-Йорка с помощью TimescaleDB (и выполняя JOIN-операции по гипертекстовым таблицам Timescale и обычным таблицам PostgreSQL).
Чтобы продолжить обучение больше:
Завершите учебник NYC Taxicab : завершите учебник из 3 частей, который мы начали выше, и ответьте на более сложные вопросы, которые помогут нам лучше понять прошлое, например: «Сколько поездок было проведено с Таймс-сквер в Новый год?» или модель будущего, например: «Как анализ поездок в аэропорту может помочь нам построить более зеленый город?»