GCP: Завантаження даних у BigQuery
Хмарні технології обробки даних
Вимоги
Створіть обліковий запис на Google Cloud Platform (безкоштовно)
Наступні інструкції є важливими, тому, будь ласка, уважно прочитайте їх.
- Підпишіться на [3-місячну ($300+$100 кредит) безкоштовну пробну версію] (https://console.cloud.google.com/freetrial) Google Cloud Platform (GCP). Для цього потрібен наявний обліковий запис Google/Gmail1. Під час реєстрації вам буде запропоновано ввести дані кредитної картки для виставлення рахунку. Не хвилюйтеся, з вас не стягуватимуться кошти доти, доки ви не зробите активний запит на продовження доступу до GCP після завершення безкоштовної пробної версії. Але для отримання доступу до платформи необхідно мати ідентифікатор проекту, який підлягає оплаті.
- (Опціонально) Завантажте та дотримуйтесь інструкцій з встановлення утиліти командного рядка Google Cloud SDK
gcloud.
Вступ
До хмари!
Найпростіший і найдешевший спосіб отримати доступ до більших обчислювальних потужностей сьогодні - це хмара2. Хоча є багато чудових постачальників хмарних послуг, я зосереджуся на Google Cloud Platform (GCP)3. GCP пропонує низку неймовірно корисних сервісів, про деякі з яких ми розповімо в наступних лекціях, а 3-місячна безкоштовна пробна версія є ідеальною відправною точкою для вивчення хмарних обчислень.
Початок роботи
- Увійдіть в Google Cloud Console.
- Виберіть або створіть проект.
- Відкрийте Cloud Shell4.
- Введіть команду для копіювання файлів з цього репозиторію:
git clone https://github.com/aranaur/data-science-on-gcp
cd data-science-on-gcpДослідження даних у GCP
Дані
В якості даних будемо використовувати Airline On-Time Performance Data.
Усі великі авіаперевізники США зобов’язані подавати статистичні дані про кожен свій внутрішній рейс до Служби транспортної безпеки (BTS).
Дані, які вони зобов’язані подавати, включають запланований час вильоту та прибуття, а також фактичний час вильоту та прибуття. На основі запланованого та фактичного часу прибуття можна розрахувати затримку прибуття, пов’язану з кожним рейсом.
Фактичний час вильоту і прибуття визначається досить точно, виходячи з того, коли відпускається стоянкове гальмо літака і коли воно знову вмикається в пункті призначення. Правила навіть визначають, що станеться, якщо пілот забуде увімкнути стоянкове гальмо - в такому випадку замість нього використовується час закриття або відкриття пасажирських дверей.

Змінні
Датасет містить понад 100 змінних, але ми використаємо лише деякі з них:
| Змінна | Опис |
|---|---|
FlightDate |
Дата польоту (yyyymmdd) |
Reporting_Airline |
Унікальний код оператора. Якщо один і той самий код використовувався кількома перевізниками, для більш ранніх користувачів використовується цифровий суфікс, наприклад, PA, PA(1), PA(2). Використовуйте це поле для аналізу за різні роки. |
Origin |
Аеропорт вильоту |
Dest |
Аеропорт призначення |
CRSDepTime |
Час відправлення комп’ютерної системи бронювання (CRS) (місцевий час: hhmm) |
DepTime |
Фактичний час відправлення (місцевий час: hhmm) |
DepDelay |
Різниця в хвилинах між запланованим і фактичним часом відправлення. Ранні відправлення показують від’ємні числа. |
TaxiOut |
Тривалість таксі-ауту, в хвилинах |
WheelsOff |
Час висадки (місцевий час: hhmm) |
WheelsOn |
Час відправлення (місцевий час: hhmm) |
TaxiIn |
Тривалість таксі (хвилини) |
CRSArrTime |
Час прибуття CRS (місцевий час: hhmm) |
ArrTime |
Фактичний час прибуття (місцевий час: hhmm) |
ArrDelay |
Різниця в хвилинах між запланованим і фактичним часом прибуття. Ранні прибуття показують від’ємні значення. |
Cancelled |
Індикатор скасованого польоту (1 = Так) |
CancellationCode |
Причину скасування |
Diverted |
Індикатор відхиленого польоту (1 = Так) |
Distance |
Відстань між аеропортами (милі) |
Весь перелік змінних доступний за посиланням https://www.transtats.bts.gov/Fields.asp?gnoyr_VQ=FGJ.
Завантаження
За допомогою інструмента розробника браузера подивимось куди звертається веб-сайт, коли ми вводимо запит на завантаження даних.
Перейдіть за посиланням https://www.transtats.bts.gov/DL_SelectFields.aspx?gnoyr_VQ=FGJ&QO_fu146_anzr=b0-gvzr та оберіть опцію “Prezipped File”.
Відкрийте вкладку “Network” в інструментах розробника браузера та введіть запит на завантаження даних.
Ми побачимо, що відбувається запит до https://transtats.bts.gov/PREZIP/On_Time_Reporting_Carrier_On_Time_Performance_1987_present_2023_1.zip.
Видно, з чого складається шаблон запиту:
${Базовий_рік}_${Рік}_${Місяць}.zip
Спробуємо з командного рядка:
BTS=https://transtats.bts.gov/PREZIP
BASEURL="${BTS}/On_Time_Reporting_Carrier_On_Time_Performance_1987_present"
YEAR=2015
MONTH=3
curl -k -o temp.zip ${BASEURL}_${YEAR}_${MONTH}.zipcurl- це утиліта командного рядка для взаємодії з серверами за допомогою різних протоколів. В даному випадку ми використовуємо протокол HTTP.-kвказує на те, що ми дозволяємоcurlвикористовувати незахищене з’єднання.-oвказує на те, що ми хочемо зберегти результат у файлtemp.zip.
Розпакуємо архів:
unzip temp.zipТепер видно, що у середині архіву знаходиться CSV-файл. Подивимось на перші кілька рядків:
head -n 5 *.csvЗамість того, щоб назвати завантажений файл temp.zip, давайте назвемо його 201503.zip і помістимо у тимчасовий каталог. Щоб замінити місяць 3 на 03, ми можемо скористатися командою printf у bash:
MONTH2=$(printf "%02d" $MONTH)Для створення каталогу використаємо команду mkdir:
TMPDIR=$(mktemp -d)Тепер для завантаження даних використаємо команду curl:
ZIPFILE=${TMPDIR}/${YEAR}_${MONTH2}.zip
curl -o $ZIPFILE ${BASEURL}_${YEAR}_${MONTH}.zipТепер ми можемо розархівувати файл, витягти CSV-файл до поточного каталогу (./) і видалити решту вмісту ZIP-файлу:
unzip -d $TMPDIR $ZIPFILE
mv $TMPDIR/*.csv ./${YEAR}${MONTH2}.csv
rm -rf $TMPDIRВсі попередні команди містяться у файлі під назвою download.sh, а потім у скрипті ingest.sh викликаємо їх з циклу for:
for MONTH in `seq 1 12`; do
bask download.sh $YEAR $MONTH
doneВиконаємо скрипт:
for MONTH in `seq 1 12`; do bash ../02_ingest/download.sh 2015 $MONTH; doneПодивимось на кількість рядків у файлах:
wc -l *.csvЗавантаження даних у Google Cloud Storage
Тепер, коли ми завантажили дані, давайте завантажимо їх у Google Cloud Storage (GCS). Це дозволить нам використовувати їх у інших сервісах GCP, таких як BigQuery, Dataflow, Dataproc, AI Platform тощо.
Спочатку треба створити новий бакет - це контейнер для зберігання даних з унікальним іменем.
Ви можете створити унікальне бакет в командному рядку за допомогою:
PROJECT=$(gcloud config get-value project)
BUCKET=${PROJECT}-dsongcp
REGION=us-central1 # Дивіться https://cloud.google.com/storage/docs/locations
gsutil mb -l $REGION gs://$BUCKETТепер, коли бакет створено, ми можемо завантажити файли у нього:
gsutil -m cp *.csv gs://fit-cloud-course-dsongcp/flights/raw/BigQuery
Першим кроком для отримання даних у BigQuery є створення набору даних - набору даних, який є контейнером для таблиць. У проекті можна створити кілька наборів даних. Перейдіть до веб-консолі і виберіть опцію Create Dataset. Потім створіть набір даних з назвою dsongcp.
Або використайте командний рядок:
bq mk dsongcpЗавантаження даних
Ми можемо завантажити дані безпосередньо у власне сховище BigQuery за допомогою утиліти командного рядка bq:
PROJECT=$(gcloud config get-value project)
BUCKET=${PROJECT}-dsongcp
bq load --autodetect --source_format=CSV \
dsongcp.flights_auto \
gs://${BUCKET}/flights/raw/201501.csvМи можемо спробувати зробити запит на дані, щоб знайти середню затримку вильоту та прильоту в найбільш завантажених аеропортах:
SELECT
ORIGIN,
AVG(DepDelay) AS dep_delay,
AVG(ArrDelay) AS arr_delay,
COUNT(ArrDelay) AS num_flights
FROM
`dsongcp.flights_auto`
GROUP BY
ORIGIN
ORDER BY num_flights DESC
LIMIT 10Автоматичне визначення схеми дозволяє нам завантажити дані без необхідності визначення схеми. Але це може бути не найкращим варіантом для великих наборів даних. В такому випадку краще визначити схему вручну.
Наразі ми мало що знаємо про поля, тому можемо попросити BigQuery обробляти всі стовпці, окрім FlightDate, як рядки:
SCHEMA=Year:STRING,...,FlightDate:DATE,Reporting_Airline:STRING,...Крім того, ми можемо розбити дані на партіції за допомогою поля FlightDate:
--time_partitioning_field=FlightDate --time_partitioning_type=MONTHТоді код для завантаження даних у BigQuery буде виглядати наступним чином:
PROJECT=$(gcloud config get-value project)
BUCKET=${PROJECT}-dsongcp
YEAR=2015
SCHEMA=Year:STRING,Quarter:STRING,Month:STRING,DayofMonth:STRING,DayOfWeek:STRING,FlightDate:DATE,Reporting_Airline:STRING,DOT_ID_Reporting_Airline:STRING,IATA_CODE_Reporting_Airline:STRING,Tail_Number:STRING,Flight_Number_Reporting_Airline:STRING,OriginAirportID:STRING,OriginAirportSeqID:STRING,OriginCityMarketID:STRING,Origin:STRING,OriginCityName:STRING,OriginState:STRING,OriginStateFips:STRING,OriginStateName:STRING,OriginWac:STRING,DestAirportID:STRING,DestAirportSeqID:STRING,DestCityMarketID:STRING,Dest:STRING,DestCityName:STRING,DestState:STRING,DestStateFips:STRING,DestStateName:STRING,DestWac:STRING,CRSDepTime:STRING,DepTime:STRING,DepDelay:STRING,DepDelayMinutes:STRING,DepDel15:STRING,DepartureDelayGroups:STRING,DepTimeBlk:STRING,TaxiOut:STRING,WheelsOff:STRING,WheelsOn:STRING,TaxiIn:STRING,CRSArrTime:STRING,ArrTime:STRING,ArrDelay:STRING,ArrDelayMinutes:STRING,ArrDel15:STRING,ArrivalDelayGroups:STRING,ArrTimeBlk:STRING,Cancelled:STRING,CancellationCode:STRING,Diverted:STRING,CRSElapsedTime:STRING,ActualElapsedTime:STRING,AirTime:STRING,Flights:STRING,Distance:STRING,DistanceGroup:STRING,CarrierDelay:STRING,WeatherDelay:STRING,NASDelay:STRING,SecurityDelay:STRING,LateAircraftDelay:STRING,FirstDepTime:STRING,TotalAddGTime:STRING,LongestAddGTime:STRING,DivAirportLandings:STRING,DivReachedDest:STRING,DivActualElapsedTime:STRING,DivArrDelay:STRING,DivDistance:STRING,Div1Airport:STRING,Div1AirportID:STRING,Div1AirportSeqID:STRING,Div1WheelsOn:STRING,Div1TotalGTime:STRING,Div1LongestGTime:STRING,Div1WheelsOff:STRING,Div1TailNum:STRING,Div2Airport:STRING,Div2AirportID:STRING,Div2AirportSeqID:STRING,Div2WheelsOn:STRING,Div2TotalGTime:STRING,Div2LongestGTime:STRING,Div2WheelsOff:STRING,Div2TailNum:STRING,Div3Airport:STRING,Div3AirportID:STRING,Div3AirportSeqID:STRING,Div3WheelsOn:STRING,Div3TotalGTime:STRING,Div3LongestGTime:STRING,Div3WheelsOff:STRING,Div3TailNum:STRING,Div4Airport:STRING,Div4AirportID:STRING,Div4AirportSeqID:STRING,Div4WheelsOn:STRING,Div4TotalGTime:STRING,Div4LongestGTime:STRING,Div4WheelsOff:STRING,Div4TailNum:STRING,Div5Airport:STRING,Div5AirportID:STRING,Div5AirportSeqID:STRING,Div5WheelsOn:STRING,Div5TotalGTime:STRING,Div5LongestGTime:STRING,Div5WheelsOff:STRING,Div5TailNum:STRING
for MONTH in `seq -w 1 12`; do
CSVFILE=gs://${BUCKET}/flights/raw/${YEAR}${MONTH}.csv
bq --project_id $PROJECT \
load --time_partitioning_field=FlightDate \
--time_partitioning_type=MONTH \
--source_format=CSV --ignore_unknown_values \
--skip_leading_rows=1 --schema=$SCHEMA \
${PROJECT}:dsongcp.flights_raw\$${YEAR}${MONTH} $CSVFILE
doneПовний код для завантаження даних у BigQuery міститься у файлі bqload.sh.
Дашборди
Створення представлень
Представлення - це віртуальні таблиці, які можна використовувати для спрощення складних запитів. Вони не зберігають жодних даних, але можуть бути використані для обмеження доступу до даних, агрегації даних, об’єднання таблиць тощо.
Створимо представлення для затримок вильоту та прильоту:
CREATE OR REPLACE VIEW dsongcp.flights AS
SELECT
FlightDate AS FL_DATE,
Reporting_Airline AS UNIQUE_CARRIER,
OriginAirportSeqID AS ORIGIN_AIRPORT_SEQ_ID,
Origin AS ORIGIN,
DestAirportSeqID AS DEST_AIRPORT_SEQ_ID,
Dest AS DEST,
CRSDepTime AS CRS_DEP_TIME,
DepTime AS DEP_TIME,
CAST(DepDelay AS FLOAT64) AS DEP_DELAY,
CAST(TaxiOut AS FLOAT64) AS TAXI_OUT,
WheelsOff AS WHEELS_OFF,
WheelsOn AS WHEELS_ON,
CAST(TaxiIn AS FLOAT64) AS TAXI_IN,
CRSArrTime AS CRS_ARR_TIME,
ArrTime AS ARR_TIME,
CAST(ArrDelay AS FLOAT64) AS ARR_DELAY,
IF(Cancelled = '1.00', True, False) AS CANCELLED,
IF(Diverted = '1.00', True, False) AS DIVERTED,
DISTANCE
FROM dsongcp.flights_raw;Перша візуалізація
Перейдіть до Looker Studio за посиланням https://lookerstudio.google.com/ та виберіть опцію “Створити” -> Джерело даних.
У меню виберіть BigQuery та вкажіть проект та набір даних/представлення, яка Вас цікавить (у нашому випадку це представлення flights з набору даних dsongcp). За необхідності змініть тип даних та інші необхідні маніпуляції з даними і натисніть Створити звіт.
За замовчуванням Looker видасть базову таблицю та/або графік. За необхідності видаліть все зайве.
Додайте новий графік за допомогою кнопки Додати діаграму -> Точкова діаграма.
Поки що проігноруйте Параметр діапазону дат і використайте три характеристики: Параметр, Показник X, Показник X.
Змініть (за необхідності) Параметр на UNIQUE_CARRIER, Показник X на DEP_DELAY, Показник X на ARR_DELAY і змініть метрику агрегування для X і Y на Середнє. Ми маємо отримати усереднену затримку відправлення та прибуття для різних перевізників.
Перейдіть на вкладку Стиль, додайте лінію тренду і додайте мітки даних:

Керування даними
Додамо можливість контролювати діапазон дат, який відображається на графіку.
Оберіть меню Додати елемент керування -> Діапазон дат та оберіть місце його розташування. В налаштуваннях меню оберіть Фікосваний діапазон дат і вкажіть початкову дату 1 січня 2015, а кінцеву - 31 грудня 2015.
Перейдіть у меню Переглянути у верхній частині екрану і спробуйте змінити кінцеву дату на 31 травня 2015:

Друга візуалізація
Схоже між часом затримки вильоту та прильоту є деяка кореляція. Але давайте будемо вважати, що рейс затримався, якщо літак прибуває на 15 хвилин пізніше очікуваного часу. Спробуємо продемонструвати відносний показник затримки.
Додайте новий графік за допомогою кнопки Додати діаграму -> Кільцева діаграма.
Нам треба показати співвідношення рейсів із запізненням до рейсів без запізнення. Як нам отримати ці дані?
В базі даних немає стовпця, який би вказував на загальну кількість вильотів. Однак у Looker Studio є спеціальне значення Record Count, яке ми можемо використовувати як матрику, попередньо змінивши тип агрегації на Кількість.
Додамо нову змінну Параметр з назвою is_late. Клікніть у поле Параметр -> Додати поле. Дайте назву новій змінній та вкажіть формулу:
CASE WHEN
(ARR_DELAY < 15)
THEN
'ON TIME'
ELSE
'LATE'
END
Третя візуалізація
Додамо ще один графік, який показуватиме затримки для кожного перевізника.
Додайте новий графік за допомогою кнопки Додати діаграму -> Стовпчаста діаграма
Налаштування:
- Параметр:
UNIQUE_CARRIER - Показник X:
DEP_DELAY - Показник Y:
ARR_DELAY - Агрегація:
Середнє - Сортування:
UNIQUE_CARRIER(за зростанням)
Стиль:
- Стовпчики:
20 - Осі:
Одинарна

Додаткові візуалізації
Додамо ще декілька схожих візуалізацій, але цього разу з різними порогами затримки вильоту: 10, 15, 20+ хвилин.
Для цього нам знадобиться створити нові представлення даних:
CREATE OR REPLACE VIEW dsongcp.delayed_10 AS
SELECT * FROM dsongcp.flights WHERE dep_delay >= 10;
CREATE OR REPLACE VIEW dsongcp.delayed_15 AS
SELECT * FROM dsongcp.flights WHERE dep_delay >= 15;
CREATE OR REPLACE VIEW dsongcp.delayed_20 AS
SELECT * FROM dsongcp.flights WHERE dep_delay >= 20;
Які висновки можемо зробити з цих графіків?
Примітки
Якщо у вас є кілька облікових записів Gmail, виберіть один і постійно використовуйте його, коли з’являється запит на автентифікацію нового API сервісу GCP↩︎
Хоча хмара - це не єдина гра в місті, вона пропонує безліч переваг, які, на мою думку, роблять її безпроблемною для більшості людей: економія на масштабах робить її набагато дешевшою; турботи про обслуговування та амортизацію зняті; доступ не залежить від інституційної приналежності або статусу викладача; хмарні провайдери пропонують безліч інших корисних послуг; тощо↩︎
Альтернативи GCP включають AWS та Digital Ocean. Posit нещодавно також запустила власний хмарний сервіс: Posit Cloud, який має вужчу спрямованість, але чудово підходить для навчання і є (наразі) безкоштовним для використання. Хороша новина полягає в тому, що це все чудові варіанти, а загальні принципи хмарних обчислень переносяться дуже легко. Тож використовуйте те, що вам зручніше↩︎
Cloud Shell - це мікро-ВМ, яка існує протягом усього часу, поки відкрито вікно браузера, і надає вам термінальний доступ до мікро-ВМ. Закрийте вікно браузера, і мікро-ВМ зникне. ВМ Cloud Shell безкоштовна і постачається з багатьма інструментами, які знадобляться розробникам на Google Cloud Platform. Наприклад, на ній встановлені Python, Git, Google Cloud SDK та Orion (веб-редактор коду). Хоча віртуальна машина Cloud Shell є ефемерною, вона прикріплена до постійного диска, який прив’язаний до вашого облікового запису користувача. Файли, які ви зберігаєте в домашньому каталозі, зберігаються під час різних сеансів Cloud Shell.↩︎