Andrea Martáková & Lenka Matúšová
DVĚ CHYTRÉ HOLKY A JEDNA CHYTRÁ MAPA :)
ANALÝZA POMOCÍ LOCATION INTELLIGENCE – CLEVERMAPS
Belgie & Nizozemsko Demografie, zemědělství, zemědělské technologie
JAK JEN ZAČÍT - S KÝM, S ČÍM A PROČ?
Po prvních týdnech seznámení se všemi holkami a celkově s režimem digitální akademie, jsme stály před rozhodnutím, co bude předmětem našeho projektu. Vzhledem k tomu, že jsme za sebou měly jen pár hodin, ve kterých jsme se obeznámily jen s částí nástrojů sloužících ke zpracování a vizualizaci dat, vůbec jsme si v tu chvíli nedokázaly představit, čeho všeho budeme ke konci digitální akademie schopny. Prvním úkolem bylo najít si parťáka pro projekt. Tahle část šla docela hladce. Naši spolupráci svedly dohromady zřejmě ♊hvězdy (jsme stejného znamení),🆎abeceda (jsme v ní hned za sebou) a 🌍vystudované obory velmi blízkého zaměření (geografie a geodezie). Právě kvůli zmíněným oborům, které jsme na škole studovaly, jsme začaly uvažovat nad projektem, který by s nimi byl určitým způsobem provázán. Zároveň jsme chtěly dělat na projektu z reálného prostředí, který bude mít potenciál dalšího využití. Vzhledem k tomu, že jsme měly povědomí o Brněnském startupu CleverMaps, který se věnuje využitím a vizualizací dat v tzv. chytrých mapách, napadlo nás oslovit právě tuto firmu. CleverAnalytics (jeden ze čtyř projektů, kterým se firma CleverMaps věnuje), se zaměřuje na mapovou Business Intelligence. Dává do souvislosti interní data klientů s veřejně dostupnými daty, jako jsou např. demografické údaje a všechny tyto údaje vztahují na souřadnice (lokalizují). Kombinací těchto dat získávají různé souvislosti a dávají tak podklad svým klientům pro efektivnější rozhodování a plánovaní dalších kroků v jejich fungování a rozvoji. V CleverMaps se nás rozhodli v projektu podpořit a navrhli nám, abychom pro ně zpracovali vybraná demografická data, která postupně propojíme s územními jednotkami vybraných států. Na speed dating s mentory jsme šly tedy už s určitou představou, jak by náš projekt mohl zhruba vypadat. Večer uběhl jak voda a my se na jeho konci k našemu štěstí dozvěděly, že se nám pro náš projekt podařilo získat mentora Martina z firmy Lectura. S Martinem jsme si udělali malý brainstorming a hned se náš projekt začal rýsovat v trochu jasnějších barvách. Jelikož společnost Lectura disponuje s velkým množstvím dat o zemědělských strojích, rozhodli jsme se, že by bylo zajímavé zjistit, jak to vypadá s jejich cenami, nabídkami, v jednotlivých regionech zemí Beneluxu a to v souvislosti s veřejně dostupnými demografickými údaji. Jako analytický a vizualizační nástroj, by nám pak měly posloužit právě CleverAnalytics. Představa projektu byla tedy zhruba jasná a už jen zbývalo pustit se do jeho samotné realizace.
HLEDÁME DATA
Naším prvním krokem bylo vyhledání demografických dat (data obsahující údaje o zemědělských technologiích jsme měly přislíbeny od našeho mentora Martina). Pátraly jsme zejména na webu Eurostatu a stránkách statistických úřadů jednotlivých zemí. Vzhledem k tomu, že získaná data se budou napojovat na územní jednotky, bylo potřeba, aby jednotlivé datasety v sobě mj. obsahovaly informaci o územní jednotce, ke které se data vztahují. Ideálně tedy v úrovni LAU2 (obce) NUTS3 (v ČR odpovídá velikosti kraje). Zde se začaly objevovat první malé komplikace. Velké množství zajímavých datasetů, v sobě totiž tuto informaci o regionu neneslo a údaje bylo možné získat např. jen pro úroveň celých států (NUTS0). Také se nám stávalo, že např. jeda ze zemí data do úrovně regionů sice poskytovala, ale zbývající státy ne. Hledání nám také sem tam zpestřovaly cizí jazyky, jelikož ne všechna data bylo možné dohledat přímo v angličtině. Naštěstí tady byl náš dobrý kamarád Google translator, který nám byl v této záležitosti velkou oporou💪. Nakonec, se nám podařilo přece jen potřebná demografická data z různých zdrojů dohledat (datasety – pohlaví a věk obyvatel, počet, typ a velikost domácností, počet farem, rozloha zemědělské půdy) a mohly jsme se tak pomalu posunout k dalšímu kroku.
SBLIŽOVÁNÍ S CLEVERANALYTICS
A je to tady, první oťukávání s nástrojem CleverAnalytics. Pro to, abychom pochopily, jakým způsobem tato platforma funguje (tzn. jakým způsobem se staví datové modely, do jaké podoby musejí být data zpracována, jakým způsobem je dostaneme do aplikace apod.), musely jsme si projít online tutoriál pro developery a vyzkoušet si fungování nástroje na vlastní kůži na vzorovém projektu.
Nutno konstatovat, že naše první 💗rande s touto aplikací, neprobíhalo zrovna podle našich romantických představ 😰. Vše pro nás bylo na začátku nové a zorientovat se jen v terminologii byla docela fuška. Po překonání prvotních rozpaků a několikerým projitím tutoriálu a demo projektů jsme se však odhodlaly posunout náš vztah dále. Pokusily jsme se v rámci aplikace vytvořit náš vlastní projekt a nahrát do něj jeden z našich vlastních datasetů ☝. Záměrně volíme slovo „pokusily“, jelikož překonání této fáze nám nakonec zabralo poměrně dost času. V aplikaci se pracuje se soubory JSON (formát pro výměnu dat vycházející ze syntaxe JavaScriptu), ze kterých je celý projekt poskládán a s tzv. Shell (nástroj pro rozhraní příkazové řádky navržený pro správu platformy, který umožňuje uživatelům s odpovídajícími uživatelskými právy spravovat různé aspekty projektu CleverAnalytics).
Nejprve je potřeba založit nový projekt. Spouštíme proto příkazový řádek, podle návodu z tutoriálu se přes něj přihlašujeme do svého účtu na CleverAnalytics a postupnými příkazy jako createProject --title „FirstProject“ zakládáme náš první projekt. Od Káti (která pracuje v CleverMaps a prostřednictvím které s firmou komunikujeme), dostáváme odkaz na projekt s předpřipravenými polygony (GEOJSONY) pokrývající území Beneluxu. Na tyto polygony (obsahující administrativní jednotky jednotlivých zemí Beneluxu) budeme postupně vlastní data napojovat. Polygony je tak potřeba naimportovat do našeho nově založeného projektu, takže pokračujeme zadáním příkazu import -- project. V příkazovém řádku se objevuje hláška Import successful! Radujeme se (ale bohužel nám to nevydrží příliš dlouho). Dalším krokem je vytvořit vlastní skript (JSON) pro náš dataset. Při psaní skriptu si dáváme záležet (hlavně nezapomenout na žádný sloupec) hotovo a jde se nahrávat přes příkaz addMetadata. Chvilka napětí přichází, ale ejhle při pokusu nahrát JSON do aplikace se v příkazovém řádku objeví to nesympatické slovíčko, které nás bude v průběhu práce na projektu provázet ještě nesčetněkrát - ERROR. Kontrolujeme proto veškeré závorky, čárky, ale všechno sedí. JSON validátor taky nehlásí žádnou chybu a tak zkoušíme to znovu a znovu. ERROR se ale jen tak lehce nevzdává a po několikanásobném neúspěšném pokusu zavíráme vyčerpaně PC s tím, že zítra je taky den.
Náš první ERROR |
Zdroj: https://www.cleveranalytics.com/ Takto vypadá nově založený projekt, který prozatím neobsahuje žádná data. |
Příklad zápisu skriptu JSON pro jeden z našich zkušebních datasetů |
Nový den, nový začátek říkáme si a raději konzultujeme naši ERROR záležitost s Káťou z CleverMaps. Dozvídáme se, že v aplikaci CleverAnalytics není možné ve skriptu ani našich tabulkách používat velká písmena. Přepisujeme tedy JSON znovu (tentokrát žádná velká písmena), v příkazovém řádku zadáváme addMetadata opět chvilka napětí a jupííí je to tam🎉. Další fází je nahrání samotných dat ve formátu.csv. Prvotní zkušební tabulku máme nachystanou, doufáme, že tahle část půjde hladce. V příkazovém řádku napjatě zadáváme pushProject, ale né, zase ten prokletý ERROR. Pátráme po chybě, upravujeme tabulky, kontrolujeme znovu skript (zda sedí názvy sloupců, datový typ apod.), ale ERROR si stále nedá pokoj. Z tutoriálu víme, že pro potřeby aplikace, je jako oddělovač v souboru .csv nutné používat čárky a ne středníky (při stahování dat z webu proto vždy volíme jako oddělovač čárku).
V excelu pak provádíme v dokumentu .csv potřebné úpravy tak, aby byla data připravena na nahrání do aplikace a ukládáme. A v tomto kroku se schovává ten zakopaný pes 🐕. Ačkoliv jsme si data stáhly ve formátu .csv, kdy byla jako oddělovač zvolena čárka, po otevření v excelu a opětovném uložení jako soubor .csv, excel automaticky mění oddělovač na středník, aniž by nás o tom samozřejmě jakkoliv informoval😵. Odhalení této skutečnosti zabralo opět poměrně dost času a tak představa, že se těmito „mílovými kroky“ 👞 budeme posunovat i nadále nás začíná házet do mírné skepse. Nevzdáváme se však a pokoušíme se na svém zkušebním „First projektu“ vytvořit také první JSON pro metriku, indikátor metriky, drill, dashboard a view. První pokusy se nakonec jakš takš daří. Tak to by pro začátek bylo a teď už se jen začít naostro aneb jdeme si připravit a vyčistit data.
ČISTÍME A PŘIPRAVUJEME DATA
První dataset, který si musíme připravit obsahuje údaje o věku a pohlaví obyvatel Beneluxu v úrovni municipalit LAU2. Bude potřeba jej napojit na připravené polygony LAU2.
Napojení provedeme přes kód lau2_id který je obsažen v přechodové tabulce polygonů. Náš dataset, ale prozatím specifický kód lau2_id neobsahuje a bude tak potřeba jej vytvořit. Lau2_id je složen z dvoupísmenné zkratky státu (NL, BE či LU) a posledních 4 (v případě NL a LU) nebo 5 (v případě BE) čísel obsažených v kódu GEO.
PROPOJENÍ NAŠICH DAT S CLEVERANALYTICS
Jelikož máme tabulky připraveny, je opět potřeba dostat je do aplikace CleverAnalytics. K tomu nám opět poslouží vytvoření syntaxe (JSON) pro naše datasety.
{
"name": "benelux_demography_age_and_sex_dwh",
"type": "dataset",
"title": " Demographic targeting that uses age and gender.",
"properties": {},
"ref": {
"subtype": "basic",
"type": "dwh",
"table": "benelux_demography_age_and_sex_dwh",
"primaryKey": "id",
"properties": [
{
"filterable": true,
"name": "lau2_id",
"title": "lau2_id",
"column": "lau2_id",
"type": "string",
"foreignKey": "lau2_prechod_tabul"
},
{
"filterable": true,
"name": "geo",
"title": "geo",
"column": "geo",
"type": "string"
},
{
"filterable": true,
"name": "sex",
"title": "Gender",
"column": "sex",
"type": "string"
},
{
"filterable": true,
"name": "age",
"title": "Age category",
"column": "age",
"type": "string"
},
{
"filterable": true,
"name": "year",
"title": "Consensus 2011",
"column": "year",
"type": "integer"
},
{
"filterable": true,
"name": "value",
"title": "Value",
"column": "value",
"type": "integer"
},
{
"filterable": true,
"name": "order",
"title": "Order",
"column": "order",
"type": "integer"
},
{
"filterable": true,
"name": "id",
"title": "ID",
"column": "id",
"type": "integer"
},
{
"filterable": true,
"name": "code",
"title": "Country code",
"column": "code",
"type": "string"
}
]
}
}
Nahrání dat jde tentokrát naštěstí hladce. Vytváříme ještě skript JSON pro metriku, indikátor a dashboard, (prozatím ne příliš propracovaně, na to přijde řada později), aktuálně však potřebujeme ověřit, zda se data propojují s našimi polygony správně. Kontrolujeme proto celkový počet obyvatel Belgie s celkovým počtem obyvatel v tabulce .csv a čísla se shodují…paráda👍. To samé provádíme i u Nizozemska a Lucemburska. Tady však s překvapením zjišťujeme, že rozdíl mezi součtem obyvatel v našem .csv a hodnotou která se zobrazuje v aplikaci CleverAnalytics činí v případě Lcemburska cca 190 000 obyvatel a v případě Nizozemska dokonce 760 000 obyvatel😱. Snažíme se přijít na to, čím je tento rozdíl způsoben. Procházíme naše .csv tabulky, porovnáváme počet lau2_id v našich datasetech, s lau2_id v přechodových tabulkách pro polygony. Postupně zjišťujeme, že v našich tabulkám je cca o 50 lau2_id více v případě Nizozemska, obdobně je tomu i v případě Lucemburska. Googlíme jak diví a konzultujeme náš problém s Káťou z CleverMaps. Postupně však docházíme k velmi neradostnému zjištění. Zatímco většina našich dat se vztahuje k roku 2011, kdy proběhlo sčítání lidu. Administrativní členění a síť polygonů na kterou data napojujeme pochází z roku 2018. U Belgie toto není problém. V případě Nizozemí a Lucemburska však ano. Mezi roky 2018 a 2011 totiž došlo v těchto zemích k poměrně rozsáhlým změnám v administrativním členění. Některé municipality (LAU) se sloučily, jejich původní název zanikl a vytvořil se sdružený region nesoucí nové jméno a geo kód. Další municipality se zase přidružily k již existujícím a převzaly jejich název geo kód atd. atd. Co teď? Jak to vyřešit? Čas nás začíná nelítostně tlačit😰. Zatínáme zuby a pouštíme se do pátrací akce na internetu. Zjišťujeme, které municipality zanikly, které se sloučily a s čím, v kterém roce se tak stalo apod. Začínáme Nizozemskem, je to mravenčí práce. Ne vždy je snadné změny dohledat. Celý proces nás stojí spoustu hodin, oči se začínají červeně podbarvovat 👀 a zápěstí pravé ruky pomalu tuhne👎. Postupně vytváříme přechodovou tabulku, kam tyto změny zanášíme.
Vzhledem k velké časové náročnosti postupně docházíme k závěru, že dohledat veškeré administrativní přesuny také pro území Lucemburska je momentálně nad naše síly. Soustředíme se tedy raději na Nizozemsko a jdeme zanést zjištěné administrativní změny do našich datových tabulek (tab. obyvatelstvo podle věku a pohlaví, a tab. počty a typy domácností). Pomocí funkce =SVYHLEDAT přiřazujeme díky vytvořené přechodové tabulce zaniklým municipalitám (lau) aktuálně platný kód lau2_id. Prostřednictvím kontingenční tabulky pak na novém listu sčítáme hodnoty souvisejících řádků u sloučených či přidružených regionů. Nakonec je potřeba z původních tabulek vymazat zaniklé regiony (původní lau2_id) a zkopírovat do nich nově vzniklé regiony (nové lau2_id) z kontingenční tabulky.
Úpravy máme skoro hotovy, ale zbývá dořešit poslední problém. U tří z 380 municipalit došlo k jejich úplnému rozdrobení. V jednom případě na dvě a ve zbylých dvou případech na 3 části. Jednotlivé části původních regionů se pak přidružily k některému z dalších regionů. Např. původní LAU Littenseradiel, se rozdělil na tři části - jedna část se nově připojila k LAU Waadhoeke, další k LAU Leeuwarden a poslední k LAU Sdwest-Frysln (původní region LAU Littenseradiel zanikl). Vzhledem k tomu, že se jednalo opravdu pouze o tři případy, rozhodly jsme se, že hodnoty vztahující se k původně existujícímu regionu vydělíme buďto 2 nebo 3 a tyto podíly přičteme k relevantním regionům se kterými se slučují. Jelikož jsme tyto změny potřebovaly udělat ve dvou tabulkách, usoudily jsme, že bude nejlepší čištění s pomocí Martina dokončit v SQL. Obdobně upravujeme i naše další tabulky. Jakmile máme upraveno, napojujeme přes příkazový řádek naše data v CleverAnalytics na připravené územní jednotky (polygony).
Na řadu se dostávají raw data obsahující informace o jednotlivých nabídkách technologií🚜. Po krátkém seznámení s daty rychle opouštíme představu o tom, že nám na přiřazení lau2_id bude stačit naše přechodová tabulka polygonů. Více jak polovina dealerů, totiž sídlí v ještě menší sídelní jednotce, než je region LAU2. Než se pustíme do čistění těchto dat, je tedy potřeba dohledat seznamy všech obci BE a NL. Poté vytváříme tabulku obce.xlsx, kde jsou jednotlivým obcím přiděleny lau2_id kódy podle municipality, pod kterou patří.
Pomocí této tabulky jsme, na základě názvu měst a fragmentu adres přiřadili lau2_id jednotlivým položkám v našem datasetu.
Ukázka raw dat o nabídkách zemědělských strojů |
Ukázka vyčištěných dat s přiděleným lau2_id
Takto vyčištěná data s přirazeným lau2 kódem jsme
konečně mohli naimportovat do aplikace. Byly jsme velmi zvědavé, co nám chytrá
mapa po zadání metadat (metriky, indicatory, indicator drilly, dashboard a
view) konečně ukáže🌐. Zkoumáme pro kontrolu např. průměrné ceny
traktoru 4wd a jaksi se nám nepozdává, že v některých regionech je
průměrná cena cca 500 000€ a jiných 30 000€💰. Po přezkoumání jednotlivých
údajů o cenách, si hned vzpomeneme na první přednášku Úvod do datové
analytiky a statistiky s Marienkou Královou. Zaznívají nám
v hlavě její slova o tom, že když dostaneme data od zákazníka, tak je
v první řade potřebné se s nimi dostatečně obeznámit a udělat si
základní statistické výpočty☝. Na řadu se tak dostávají medián a průměr cen
jednotlivých typů technologií dle „machine family“ a postupně odstraňujeme
odlehlé hodnoty. Po konzultaci o výšce výsledných průměrných cen
s Martinem, konečně dostáváme vyčištěná data machines_benelux.csv, která
následně importujeme do aplikace CleverAnalytics.
|
Výsledný datový model projektu. |
JAKÉ METRIKY ZVOLIT?
Jelikož v aplikaci CleverAnalytics již máme natažena všechna potřebná data, zamýšlíme se nad tím, jaké metriky budou pro naši analýzu nejzajímavější. Nakonec jsme se rozhodly pro následující (vždy vztahující se k dané územní jednotce): celkový počet obyvatel, celkový počet domácností, podíl žen a mužů na celkovém počtu obyvatel, podíl různých věkových skupin na celkovém počtu obyvatel, celkový počet farem, celková rozloha zemědělské půdy, počet obyvatel připadající na jednu farmu, rozloha zemědělské půdy připadající na jednu farmu, celkový počet nabídek zemědělských technologií, celkový počet dealerů, průměrná cena jednotlivých typů zemědělských technologií, počet nabídek zemědělských technologií na dealera, počet nabídek zemědělských technologií připadající na počet farem. K zanesení vybraných metrik do aplikace je vždy potřeba vytvořit syntaxi (JSON).
{
"name": "benelux_demography_age_and_sex_deleni_metric",
"type": "metric",
"title": "Ratio of females to total population.",
"description": "Ratio of females to total population.",
"content": {
"type": "function_divide",
"content": [
{
"type": "function_sum",
"content": [
{
"type": "property",
"value": "benelux_demography_age_and_sex_dwh.value"
}
],
"options": {
"filterBy": [
{
"property": "benelux_demography_age_and_sex_dwh.sex",
"value": "F",
"operator": "eq"
}
]
}
},
{
"type": "function_sum",
"content": [
{
"type": "property",
"value": "benelux_demography_age_and_sex_dwh.value"
}
]
}
]
}
}
{
"name": "benelux_demography_age_and_sex_dwh_deleni_indicator",
"type": "indicator",
"title": "Ratio of females to total population",
"description": "Ratio of females to total population",
"content": {
"metric": "/rest/projects/$projectId/md/metrics?name=benelux_demography_age_and_sex_deleni_metric",
"scale": "standard",
"distribution": "geometric",
"format": {
"type": "percentage",
"fraction": 1
}
}
}
{
"name": "benelux_demography_age_and_sex_indicator_drill",
"type": "indicatorDrill",
"content": {
"blocks": [
{
"type": "distribution"
},
{
"type": "ranking",
"size": 10
},
{
"type": "categories",
"title": "Residents by age groups",
"description": "Number of residents sort by age groups.",
"splitProperty": "benelux_demography_age_and_sex_dwh.age",
"orderBy": {
"property": "benelux_demography_age_and_sex_dwh.age",
"direction": "asc",
"sort": "asc"
}
},
{
"type": "categories",
"title": "Residents by sex",
"description": "Number of residents sort by sex .",
"splitProperty": "benelux_demography_age_and_sex_dwh.sex",
"orderBy": {
"property": "benelux_demography_age_and_sex_dwh.sex",
"direction": "asc",
"sort": "asc"
}
}
]
}
}
Příklad zápisu skriptu ( JSON) pro jeden z našich indikátor drillů.
{
"name": "benelux_demography_dashboard",
"type": "dashboard",
"content": {
"indicators": [
{
"indicator": "/rest/projects/$projectId/md/indicators?name=benelux_demography_age_and_sex_sum_indicator",
"indicatorDrill": "/rest/projects/$projectId/md/indicatorDrills?name=benelux_demography_age_and_sex_indicator_drill"
},
{
"indicator": "/rest/projects/$projectId/md/indicators?name=household_benelux_type_size_2011_sum_indicator",
"indicatorDrill": "/rest/projects/$projectId/md/indicatorDrills?name=household_benelux_type_size_2011_indicator_drill"
},
{
"indicator": "/rest/projects/$projectId/md/indicators?name=benelux_demography_age_and_sex_dwh_deleni_indicator",
"indicatorDrill": "/rest/projects/$projectId/md/indicatorDrills?name=benelux_demography_ratio_indicator_drill"
},
{
"indicator": "/rest/projects/$projectId/md/indicators?name=benelux_demography_age_and_sex_dwh_deleni2_indicator",
"indicatorDrill": "/rest/projects/$projectId/md/indicatorDrills?name=benelux_demography_ratio_indicator_drill"
}
]
}
}
{
"name": "agriculture_view",
"type": "view",
"title": "2. Agriculture",
"description": " ",
"content": {
"icon": "rent_a_house",
"dashboard": "/rest/projects/$projectId/md/dashboards?name=agriculture_dashboard",
"filterGroup": [
{
"type": "indicator",
"indicator": "/rest/projects/$projectId/md/indicators?name=benelux_demography_age_and_sex_sum_indicator"
},
{
"type": "indicator",
"indicator": "/rest/projects/$projectId/md/indicators?name=be_agriculture_2016-2011_sum_farms_indicator"
},
{
"type": "indicator",
"indicator": "/rest/projects/$projectId/md/indicators?name=nl_agriculture_2011_sum_farms_indicator"
},
{
"type": "multiSelect",
"property": "benelux_nuts0_dwh.name_asci",
"orderBy": [
{
"property": "benelux_nuts0_dwh.name_asci",
"direction": "asc"
}
]
}
],
"mapOptions": {
"center": {
"lat": 50.9,
"lng": 4.4
},
"zoom": 7,
"minZoom": 5,
"maxZoom": 18,
"tileLayer": "mapbox"
}
}
}
Příklad zápisu skriptu ( JSON) pro jeden z našich view
Komentáře
Okomentovat