Нотатки Дата Саентиста: персональний огляд мов запитів до даних

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
Розповідаю з особистого досвіду, що де і коли стало в нагоді. Оглядно і тезово, щоб зрозуміло було, що й куди можна копати далі — але тут у мене винятково суб'єктивний особистий досвід, у вас, можливо, все зовсім інакше.

Чому важливо знати та вміти поводитися з мовами запитів? За своєю суттю в Data Science є кілька найважливіших етапів роботи і найперший і найважливіший (без нього точно нічого працювати не буде!) - Це отримання або вилучення даних. Найчастіше дані в якомусь вигляді десь сидять і їх треба звідти дістати. 

Мови запитів якраз і дозволяють ці дані отримати! І сьогодні я розповім, про ті мови запитів, які мені знадобилися і розповім-покажу, де і як саме — навіщо вона потрібна для вивчення.

Усього буде три основні блоки типів запитів до даних, які ми розберемо в цій статті:

  • "Стандартні" мови запитів - те, що зазвичай розуміють, коли говорять про мову запитів, як, наприклад, реляційна алгебра або SQL.
  • Скриптові мови запитів: наприклад, пітонів штучки pandas, numpy або shell scripting.
  • Мови запитів до граф знань та графових баз даних.

Все написане тут — це просто персональний досвід, що знадобилося, з описом ситуацій і «навіщо воно було потрібне» — кожен може приміряти, наскільки подібні ситуації можуть зустрітися вам і спробувати підготуватися до них заздалегідь, розібравшись із цими мовами до того, як їх доведеться у (терміновому порядку) застосовувати на проекті або взагалі потрапити на проект, де вони потрібні.

«Стандартні» мови запитів

Стандартні мови запитів саме у тому плані, що ми саме про них і думаємо, коли говоримо про запити.

Реляційна алгебра

Навіщо сьогодні потрібна реляційна алгебра? Для того щоб мати гарне уявлення, чому мови запитів влаштовані певним чином і усвідомлено використовувати їх потрібно розібратися з ядром, що лежить в основі.

Що таке реляційна алгебра?

Формальне визначення таке: реляційна алгебра - замкнута система операцій над відносинами реляційної моделі даних. Якщо трохи по-людськи, це система операцій над таблицями, така результатом теж завжди є таблиця.

всі реляційні операції в цій статті з Хабра - тут же ми описуємо, навіщо потрібно знати і де знадобиться.

Навіщо?

Починаєш розуміти, на що взагалі складаються мови запитів і які операції стоять за виразами конкретних мов запитів — часто дає більш глибоке розуміння того, що та як працює у мовах запитів.

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
Взято з цій статті. Приклад операції: join, який поєднує таблиці.

Матеріали для вивчення:

Хороший вступний курс від Стенфорда. Взагалі, матеріалів з реляційної алгебри та теорії дуже багато – Сoursera, Udacity. Є також безліч матеріалів онлайн, у тому числі хороших академічних курсів. Моя персональна порада: треба розуміти реляційну алгебру дуже добре – це основа основ.

SQL

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
Взято з цій статті.

SQL - це, по суті, імплементація реляційної алгебри - з важливим застереженням, SQL - декларативний! Тобто записуючи запит мовою реляційної алгебри, ви фактично кажете, як треба рахувати — а ось із SQL ви задаєте, що хочете витягти, а далі СУБД вже генерує (ефективне) вираження мовою реляційної алгебри (їхня еквівалентність відома нам під теорема Кодда).

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
Взято з цій статті.

Навіщо?

Реляційні СУБД: Oracle, Postgres, SQL Server, etc - як і практично всюди і неймовірно великий шанс того, що вам доведеться з ними взаємодіяти, а це означає, що доведеться або читати SQL (що дуже ймовірно), або писати на ньому ( теж малоймовірно).

Що читати та вивчати

За тими ж посиланнями вище (про реляційну алгебру), є неймовірна кількість матеріалу, наприклад, цей.

До речі, а що таке NoSQL?

«Варто ще раз наголосити, що термін «NoSQL» має абсолютно стихійне походження і не має загальновизнаного визначення чи наукової установи за спиною.» Відповідна стаття на Хабрі.

По суті, люди зрозуміли, що повна реляційна модель не потрібна для вирішення багатьох завдань, особливо для тих, де, наприклад, принципова продуктивність і домінують певні прості запити з агрегацією — критично швидко рахувати метрики і писати їх в базу, а більшість фіч реляційної виявилися не тільки непотрібними, а й шкідливими — навіщо щось нормалізувати, якщо це псуватиме найважливіше для нас (для деякого конкретного завдання) — продуктивність?

Також часто потрібні гнучкі схеми замість фіксованих математичних схем класичної реляційної моделі - і це неймовірно спрощує розробку додатків, коли критично розгорнути систему і почати працювати швидко, обробляючи результати - або схема і типи даних, що зберігаються, не такі вже й важливі.

Наприклад, ми створюємо експертну систему і хочемо зберігати інформацію за певним доменом разом із деякою метаінформацією — ми можемо і не знати всіх полів і банально зберігати JSON для кожного запису — це дає нам дуже гнучке середовище для розширення моделі даних та швидкого ітерування — тому в такому У разі NoSQL буде навіть кращим і читаним. Приклад запису (з одного мого проекту, де NoSQL був прямий там, де потрібно).

{"en_wikipedia_url":"https://en.wikipedia.org/wiki/Johnny_Cash",
"ru_wikipedia_url":"https://ru.wikipedia.org/wiki/?curid=301643",
"ru_wiki_pagecount":149616,
"entity":[42775,"Джонни Кэш","ru"],
"en_wiki_pagecount":2338861}

Детальніше можна прочитати тут про NoSQL.

Що вивчати?

Тут скоріше потрібно бути просто добре проаналізувати своє завдання, які у неї властивості і які є NoSQL системи, які б підходили під цей опис - і займатися вивченням цієї системи.

Скриптові мови запитів

Спочатку, здається, причому тут взагалі Python — це мова програмування, а не про запити.

Нотатки Дата Саентиста: персональний огляд мов запитів до даних

  • Pandas - це прямий швейцарський ніж Data Science, величезна кількість трансформації даних, агрегації тощо відбувається в ньому.
  • Numpy — векторні обчислення, матриці та лінійна алгебра там.
  • Scipy — багато математики в цьому пакеті, особливо стати.
  • Jupyter lab – багато exploratory data analysis добре вписується в ноутбуки – корисно вміти.
  • Requests – робота з мережею.
  • Pyspark - дуже популярні серед інженерів даних, швидше за все, вам доведеться взаємодіяти з цією або спарком, просто в силу їх популярності.
  • *Selenium - дуже корисний для збору даних сайтів і ресурсів, іноді просто інакше дані ніяк не отримати.

Моя головна порада: навчайте Python!

Панди

Візьмемо як приклад наступний код:

import pandas as pd
df = pd.read_csv(“data/dataset.csv”)
# Calculate and rename aggregations
all_together = (df[df[‘trip_type’] == “return”]
    .groupby(['start_station_name','end_station_name'])
                  	    .agg({'trip_duration_seconds': [np.size, np.mean, np.min, np.max]})
                           .rename(columns={'size': 'num_trips', 
           'mean': 'avg_duration_seconds',    
           'amin': min_duration_seconds', 
           ‘amax': 'max_duration_seconds'}))

По суті, бачимо, що код вписується в класичний SQL патерн.

SELECT start_station_name, end_station_name, count(trip_duration_seconds) as size, …..
FROM dataset
WHERE trip_type = ‘return’
GROUPBY start_station_name, end_station_name

Але важлива частина — цей код є частиною скрипту та пайплайну, фактично ми вбудовуємо запити до Пітонівського пайплайну. У цій ситуації мова запитів до нас надходить з бібліотек, таких як Pandas або pySpark.

Загалом у pySpark ми бачимо схожий тип трансформації даних через мову запитів на кшталт:

df.filter(df.trip_type = “return”)
  .groupby(“day”)
  .agg({duration: 'mean'})
  .sort()

Де і що почитати

За самим пітоном взагалі не проблема знайти матеріали для вивчення. У мережі величезна кількість тьюторіалів по панди, pySpark та курсів з Іскритися (а також по самому DS). Загалом тут матеріали чудово гуглиться і якби мені потрібно було вибрати один пакет, на якому варто сфокусуватися, то це був би pandas, звичайно. По зв'язці DS+Python матеріалів теж дуже багато.

Shell як мова запитів

Чимало проектів з обробки та аналізу даних, з якими мені доводилося працювати — це, по суті, shell скрипти, які викликають код на пітоні, на java та власне самі shell команди. Тому в цілому можна розглядати пайплайни в баші/zsh/etc, як деякий високорівневий запит (можна туди, звичайно, і цикли запхати, але це нетипово для DS коду шелл мовами), наведемо простий приклад - мені потрібно було зробити мапінг QID вікідати і повного посилання на російську та англійську вікі, для цього я написав простий запит із команд у баші і для виведення написав простий скприт на пітоні, які я зібрав разом ось так:

pv “data/latest-all.json.gz” | 
unpigz -c  | 
jq --stream $JQ_QUERY | 
python3 scripts/post_process.py "output.csv"

де

JQ_QUERY = 'select((.[0][1] == "sitelinks" and (.[0][2]=="enwiki" or .[0][2] =="ruwiki") and .[0][3] =="title") or .[0][1] == "id")' 

Це був по суті весь пайплайн, який створював потрібний mapping, як ми бачимо все, працювало в режимі потоку:

  • pv filepath - дає прогрес бар на основі розміру файлу і передає його далі
  • unpigz -c читав частину архіву та віддавав jq
  • jq з ключем - stream відразу видавав результат і передавав його постпроцесору (так само як і з першим прикладом) на пітоні
  • всередині постпроцесор - це проста машина станів, яка форматувала висновок 

Разом складний пайплайн працює в режимі потоку на великих даних (0.5TB), без істотних ресурсів і зроблений з простого пайплайну та пари тулзів.

Ще одна важлива порада: вмійте добре та ефективно працювати в терміналі та писати на bash/zsh/etc.

Де знадобиться? Та майже скрізь — матеріалів для вивчення знову ж таки дуже в мережі. Зокрема, ось ця моя попередня стаття.

R scripting

Знову ж таки читач може вигукнути — ну це ж ціла мова програмування! І звичайно ж, матиме рацію. Однак, звичайно, мені доводилося стикатися з R завжди в такому контексті, що, по суті, це було дуже схоже на мову запитів.

R — це середовище статистичних обчислень та мова статичних обчислень та візуалізації (згідно з цього).

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
взято звідси. До речі, рекомендую непоганий матеріал.

Навіщо дата саєнтистові знати R? Принаймні тому, що є величезний пласт людей не з IT, які займаються аналізом даних на R. Мені зустрічалося в наступних місцях:

  • Фармацевтичний сектор.
  • Біологи.
  • Фінансовий сектор.
  • Люди з суто математичною освітою займаються статами.
  • Спеціалізовані статистичні моделі та моделі машинного навчання (які часто можна знайти тільки в авторській версії у вигляді пакета R).

Чому це фактично мова запитів? У тому вигляді, в якому він часто зустрічається – це фактично запит на створення моделі, включаючи читання даних та фіксування параметрів запиту (моделі), а також візуалізація даних у таких пакетах як ggplot2 – це також форма написання запитів.

Приклад запитів для візуалізації

ggplot(data = beav, 
       aes(x = id, y = temp, 
           group = activ, color = activ)) +
  geom_line() + 
  geom_point() +
  scale_color_manual(values = c("red", "blue"))

Загалом багато ідей R перекочували в пакети python, такі як pandas, numpy або scipy, як датафрейми і векторизація даних — тому в цілому дуже багато речей в R здадуться вам знайомими і зручними.

Джерел для вивчення багато, наприклад, цей.

Графи знань (Knowledge graph)

Тут у мене трохи незвичайний досвід, тому що мені таки часто доводиться працювати з графами знань і мови запитів до графів. Тому лише коротко пройдемося з основ, так ця частина трохи екзотичніша.

У класичних реляційних базах у нас фіксована схема — тут схема гнучка, кожен предикат — це фактично «колонка» і навіть більше.

Уявіть, що ви б моделювали людину і хотіли описати ключові речі, наприклад візьмемо конкретну людину Дугласа Адамса, за основу візьмемо ось цей опис.

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
www.wikidata.org/wiki/Q42

Якби ми використовували реляційну базу, нам довелося б створити величезну таблицю або таблиці з величезною кількістю колонок, більша частина з яких була б NULL або заповнена якимось дефолтним False значенням, наприклад, навряд чи у багатьох з нас є запис у національній корейській бібліотеці — звичайно, ми могли б виносити їх в окремі таблиці, але це зрештою була б спроба змоделювати гнучку логічну схему з предикатами, за допомогою фіксованої реляційної.

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
Тому уявіть собі, що всі дані зберігаються у вигляді графа або у вигляді бінарних та унарних логічних виразів.

Де ви взагалі можете з таким зіткнутися? По-перше, працюючи з вікі данимита з будь-якими графовими базами даних або зв'язковими даними.

Далі йдуть основні мови запитів, які мені доводилося застосовувати та з якими доводилося працювати.

SPARQL

Wiki:
SPARQL (рекурсивний акронім від англ. Протокол SPARQL і мова запитів RDF) - мова запитів до даних, представленим за моделлю RDF, а також протокол передачі цих запитів і відповіді них. SPARQL є рекомендацією консорціуму W3C та однією з технологій семантичного павутиння.

А реально це мова запитів до логічних унарних та бінарних предикатів. Ви просто умовно вказується, що є фіксованим у логічному вираженні, а що ні (дуже спрощено).

Сама база RDF (Resource Description Framework), над якою виконуються SPARQL запити – це трійка object, predicate, subject - і запит вибирає потрібні трійки за вказаними обмеженнями в дусі: знайти такий X, що p_55(X, q_33) вірно - де, зрозуміло, p_55 - це якесь відношення з айді 55, а q_33 - це об'єкт з айді 33 (ось і всю оповідь, знову ж таки опускаючи всілякі деталі).

Приклад подання даних:

Нотатки Дата Саентиста: персональний огляд мов запитів до даних
Картинки та приклад з країнами ось звідси.

Приклад базового запиту

Нотатки Дата Саентиста: персональний огляд мов запитів до даних

Фактично ми хочемо знайти значення змінної ?country, такий що для предикату
member_of, мабуть, що member_of(?country,q458), а q458 — це ID європейського союзу.

Приклад реального запиту SPARQL всередині python:

Нотатки Дата Саентиста: персональний огляд мов запитів до даних

Як правило, мені доводилося читати SPARQL, а не писати — у такій ситуації, швидше за все, це буде корисною навичкою розуміти мову хоча б на базовому рівні, щоб зрозуміти, як витягуються дані. 

Онлайн багато матеріалів для вивчення: наприклад, ось цей и цей. Сам зазвичай гуглю конкретні конструкції та приклади і поки що вистачає.

Логічні мови запитів

Докладніше по темі можна прочитати у моїй статті тут. А тут ми лише коротко розберемо, чому логічні мови добре підходять для написання запитів. По суті, RDF це просто набір виду логічних тверджень виду p(X) і h(X,Y), а логічний запит має такий вигляд:

output(X) :- country(X), member_of(X,“EU”).

Тут ми говоримо про створення нового предикату output/1 (/1 — означає унарний), за умови, що для X вірно, що country(X) — тобто, Х — це країна і member_of(X,“EU ”).

Тобто у нас і дані, і правила в такому разі представлені взагалі однаково, що дозволяє дуже легко та добре моделювати завдання.

Де зустрічалися в промисловості: цілий великий проект із компанією, яка пише такою мовою запити, а також на поточному проекті в ядрі системи — здавалося б, річ досить екзотична, проте іноді трапляється.

Приклад фрагмента коду логічною мовою, що обробляє wikidata:

Нотатки Дата Саентиста: персональний огляд мов запитів до даних

Матеріали: наведу тут кілька посилань на сучасну логічну мову програмування Answer Set Programming — рекомендую вивчати саме її:

Нотатки Дата Саентиста: персональний огляд мов запитів до даних

Джерело: habr.com

Додати коментар або відгук