Code Monkey home page Code Monkey logo

od's Introduction

Česká otevřená data

Cílem tohoto repozitáře je sjednotit přístup k otevřeným datům, které se týkají finančních výdajů státu. Jde nám o shromáždění dat v konzistentním formátu a přidání číselníků, které rozklíčují vztahy státu a firem, případně organizačních složek státu.

Před několika lety se stát začal víc a víc otevírat vůči veřejnosti, ale často tak činil pouze formálně. Do veřejné sféry se dostala data, ale často ve formátech špatně zpracovatelných, s chybami, případně obojí. Komunitě tak často trvalo dlouhou dobu, než data zpracovala, na některé datasety se vůbec nedostalo.

I když proběhlo samotné zpracování, často se nedostalo na klíčovou část - fúzi jednotlivých datasetů, aby se na veřejnost dostaly předem neznámé skutečnosti. I to je jeden z účelů této práce.

Ačkoliv se tu nenachází příliš mnoho kódu, věřte, že tato práce stojí na letech námahy a komunikace s úřady, na nekonečných diskusích s lidmi ze všech sfér státní správy i soukromých účastníků. I přes tyto nástrahy se nám za ta léta podařilo vytvořit dialog mezi uživateli a poskytovateli dat a jen doufáme, že se nám podaří jej udržet.

Účel repozitáře

Najdete zde několik sad kódů, v tuto chvíli nejsou nějak značně sešňerované, jde o spíše samostatné skripty, časem snad vymyslíme nějakou koherentní orchestraci.

Účely skriptů budou zhruba následující:

  1. Stažení dat - většinou jsou definované adresy, odkud se dají čerstvá data strojově stáhnout, občas je třeba ručního zásahu (zejm. u evropských dotací od MMR).
  2. Konverze dat a prvotní čištění. Po tomto kroku bude každý dataset v CSV, které pak člověk může nahrát prakticky kamkoliv, včetně Excelu.
  3. Export dat z CSV do databáze, v našem případě PostgreSQL. Můžete si zvolit svoji vlastní, my jsme náš systém indexů, datových verifikací a dalších mechanismů postavili nad PostgreSQL.

Posledním aspektem je aktualizace dat. V tuto chvíli máme hotové jednorázové nalití všech dat, postupně promýšlíme, jak by se ideálně dal provádět update.

Již v tuto chvíli ale funguje základní princip tohoto projektu - jakmile člověk dostane datasety do jednoho systému/databáze, může se dotazovat napříč - například seznam zakázek pro firmu, která splňuje nějaká kritéria na základě informací z ARES a je propojena s určitými politicky aktivními lidmi.

Lokální spuštění

Účelem projektu je, aby se dal snadno použít nejen autorem. Pro základní použití vám postačí Python (3.7+) a nic jiného. Stačí si nainstalovat pár základních závislostí a můžete data nahrát do CSV nebo i databáze - podporovaná je SQLite (vestavěná do Pythonu) nebo PostgreSQL.

python3 -m venv .venv
. .venv/bin/activate
pip3 install -r requirements.txt
python3 main.py --all --partial

Tato sekvence příkazů nainstaluje potřebné závislosti do virtuálního prostředí a zpracuje všechna data do CSV.

Selektivní zpracování jde udělat pomocí specifikace datasetu jako pozičního argumentu

python3 main.py --partial ares volby

A nahrání do databáze se řídí argumentem --connstring. Při specifikaci databáze proběhne vše - stažení dat, konverze do CSV a nahrání do databáze. Bez specifikace databáze skončíte u CSV.

python3 main.py --connstring sqlite:///soubor.db --partial ares volby
python3 main.py --connstring postgresql://localhost/data --partial ares volby

Název schématu u Postgresu, či tabulky u SQLite lze prefixovat parametrem --schema_prefix.

python3 main.py --connstring postgresql://localhost/data --schema_prefix opendata_ --partial ares volby

Spuštění v Docker kontejneru

Pokud si nechcete lokálne instalovat Python, můžete využít přiložený Dockerfile, vytvořit si Docker image a spustit vše v kontejneru.

Všechna generovaná data včetně stažených zdrojových souborů se zapisují do složky /data v kontejneru. Zpracované CSV výstupy najdete v /data/csv.

Tvorba Docker image

docker build -t kokes-od .

Spuštění

docker run -it --rm -v $PWD:/data kokes-od --partial ares volby

Doménová znalost a kvalita dat

Než se dostaneme k datasetům samotným, je třeba zmínit klíčový předpoklad pro správnou interpretaci dat, tím je doménová znalost, tedy pochopení dané problematiky na věcné úrovni, ne pouhé technické zpracování dat.

Člověk musí pochopit, proč je něco v IS ReD a ne v DotInfo a naopak. Většina dat obsahuje jisté informace o platnosti dat, datum podpisu není to samé jako datum čerpání. Když pak člověk informace páruje např. s obchodním rejstříkem, jsou tyto atribuce klíčové.

Je tu též věcný překryv, kdy dotace by měly mít sepsané smlouvy a pokud byly uzavřeny v určitou dobu, budu i v registru smluv (ale nemusí!).

V neposlední řadě jsou všechny datasety zatíženy jistou chybovostí. Neznamená to, že bychom měli rezignovat na jisté analýzy, spíš že bychom měli být extrémně opatrní v tom, co z dat vyčteme.

Formát dat

Při zpracování dat se řídíme jedním hlavním principem - snažíme se neměnit strukturu dat nad nezbytnou mez. To znamená, že bereme všechny sloupce ze zdrojových datasetů, až na extrémní případy neměníme obsah dat (i tak jen kvůli párování dat - tedy IČO).

Jde nám o to, aby člověk mohl vždy dohledat primární zdroj, což se mu v případě naší manipulaci s daty nepodaří.

I přes naši značnou snahu se může stát, že při našem zpracování dat něco změníme či smažeme. Jakoukoliv takovouto chybu nám prosím hlašte, pokusíme se ji opravit v co možná nejkratším termínu. Je důležité zdůraznit, že nejsme autory žádných těchto dat, pouze je zpřístupňujeme veřejnosti.

Datasety

Plánujeme zde zapojit dva typy datasetů - transakční a klasifikační, byť toto rozdělení není čisté, budou zde jisté překryvy.

  • IS ReD - centrální evidence dotací (dříve známá jako CEDR) je jeden z větších datasetů, obsahuje dotace pro soukromé i veřejné subjekty a tento dataset sahá až do roku 1999. Hlavní nevýhodou je absence metadat u velké části záznamů. Aktualizován je kvartálně.
  • Dotace EU - mediálně asi nejpropíranější téma, dataset je až překvapivě přímočarý, jde o jednu tabulku, resp. dvě, jednu pro každé rozpočtové období. Dataset spadá pod MMR, aktualizován je měsíčně.
  • DotInfo - třetí informační systém pro dotace, bohužel zatím není jasné, co je ve kterém. Puristicky vzato by Dotace EU měl být subset CEDR/ReD a DotInfo by nemělo existovat. Bohužel je DotInfo do velké míry překryvem CEDR/ReD, ale ne úplným. Je též mnohem kratší, sahá jen do cca roku 2011.
  • Veřejné zakázky - shromáždění dat z několika systémů zadávání veřejných zakázek, pro nás doposud nejméně prostudovaný dataset, s ním budeme potřebovat nejvíce pomoci. Je asi nejvíce ošemetný co se týče rozklíčování složité struktury dat.
  • Registr smluv - od léta 2016 mají veřejné subjekty povinnost zveřejňovat smlouvy nad 50 tisíc Kč hodnoty, tento revoluční zákon dramaticky zvýšil transparentnost veřejného utrácení. Zpřístupnil informace o výdajích mimo veřejné zakázky, ke všem výdajům též přidal samotné smlouvy, byť místy začerněné. Dataset patří pod MVČR a je aktualizován denně.
  • Monitor státní pokladny - jeden z nejčitších datasetů státu nabízí pohled do vyúčtování jednotlivých subjektů státu, ať už jde o ministerstva nebo obce. Zatím dataset nemáme zpracovaný, plánujeme jej použít na obohacení informací o veřejných subjektech. (Např. u smlouvy na 1 miliardu člověk uvidí, kolik procent z ročního rozpočtu to je.)
  • ARES - nechvalně známý administrativní rejstřík ekonomických subjektů nabízí vhled nejen do právnických subjektů Česka. Klíčové jsou základní informace o subjektech, možná využijeme i obchodní rejstřík. Nová otevřená data ARES nám bohužel moc platná nebudou, více v README (TODO). Tento dataset bude bohužel jediný, který nejde volně stáhnout najednou.
  • PSP - Poslanecká sněmovna Parlamentu nabízí velmi zajímavé datasety pro další zpracování, u nás najdete dva hlavní - informace o osobách (a nejen poslancích, ale i senátorech nebo členech vlád) a zpracování stenoprotokolů.
  • Volby - statistický úřad již nějaký pátek nabízí otevřená data, se kterými se celkem snadno pracuje, ale nejsou připravené k analytice hned po stažení. Navíc se jejich formát měnil v čase, takže se snažíme toto unifikovat.
  • Justice - data od Ministerstva spravedlnosti obsahují informace o jednotlivých ekonomických subjektech, jde o export z veřejných rejstříků, jak jsou mj. dostupné na webu Justice.
  • SZIF - data od Státního zemědělského intervenčního fondu obsahují informace o příjemcích dotací, včetně rozdělení na národní a evropské zdroje

Identifikace podniků

Jedním z hlavních zásahů do dat je nahrazení identifikace podniků našimi “vlastními” daty, konkrétně daty z ARES. Problémem je, že místo odkazování do ARES se každý z poskytovatelů dat snaží tvořit si vlastní databázi podniků a v oněch datech jsou často chyby. Z důvodu konzistence a kvality dat proto používáme většinou pouze IČO podniků a dál přebíráme informace z ARES.

od's People

Contributors

hlad avatar kokes avatar michalblaha avatar mira01 avatar pavelzbornik avatar smallhillcz avatar vlki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

od's Issues

Github Pages

Možná by se hodilo mít webovku, kde se vysvětlí, co všechno tu je - něco jako naše README, ale s trochou víc informací, třeba i pandas profiling output (#15).

Databázové migrace

Bylo by fajn, kdyby každej commit specifikoval někde změny do databáze, aby člověk mohl dělat evoluce bez nějakejch dramat. Pár lidí mi doporučilo yoyo.

[smlouvy] Rozklíčování smluvních stran

V datech je poměrně zvláštní specifikace smluvních stran - není ihned jasné, kdo je poskytovatel a kdo dodavatel - je tam booleanovský indentifikátor, ale občas je zavádějící, občas jsou vyplněny dva najednou, je to celé trochu domotané. Jde to nějak rozšifrovat, ale zatím jsem se k tomu nedostal a pamatuju, že když sem to řešil posledně, nasekal jsem tam nějaké chyby, protože to není dvakrát intuitivní.

Spolu s tímhle bych rád vyřešil to, že občas je tam smluvní strana dvakrát - jako poskytovatel i jako dodavatel.

[psp] priklady - tisky a jejich stavy

SELECT
	tts.popis_stavu, tt.*
FROM
	psp.tisky_tisky tt
	INNER JOIN psp.poslanci_organy org ON org.id_organ = tt.id_org_obd and org.zkratka in ('PSP6', 'PSP7', 'PSP8')
	INNER JOIN psp.tisky_stavy using(id_stav)
	INNER JOIN psp.tisky_typ_stavu tts using(id_typ)

order by zkratka desc

Misleading repository name

Based on the owner/repository name, I expected to find some information about applications of benzoylmethylecgonine in quantities greater than are recommended.

My curiosity was not satisfied.

Zpracovat data Justice

https://dataor.justice.cz/

Pozor:

  • jak je zakódován aktuální název subjektu?
  • jak zjistit seznam všech datasetů
  • je to nekomprimované, tak to bude trvat věčnost
  • iterativní xml parse bude třeba, jako vždy
  • data narození jsou zatim špatně

Relativní načítání dat

Všechno načítáme relativně, ale chtělo by to předělat na abspath, kdybychom ty skripty pouštěli z rootu.

[cedr] indexy až po copy

Indexy se teď přidávaj přímo v init.sql... ale asi bychom to chtěli dělat v postcopy jako jinde - ale chtělo by to tuhle dvojfázovou indexaci nějak domyslet.

[psp] Chybějící data narození

K dnešnímu dni máme 6551 osob v datasetu od PSP, ale jen 5635 z nich má vyplněné datum narození, které je odlišné od 1900-01-01 (jejich sentinel value místo NULL).

Je třeba udělat nějaký export (vč. id_osoby, máme spoustu Nováků) a ručně něco z toho doplnit. Ideálně v tom exportu bude i nějaká agregace funkcí, ať člověk ví, kde má zhruba hledat, pokud člověka nezná. Případně aby si mohl filtrovat a doplnit jen ty, které potřebuje (třeba jen současné senátory).

Je možná komunikace s odborem informatiky při PSP, ale uvidíme, jestli budou chtít přijmout externí data, možná kdyby byla ozdrojovaná a oni to mohli ověřit... nevím.

[DQ] pandas_profiling

Mohli bychom použít pandas profiling (možná v rámci CI? nebo jako shell skript?) a jeho output někde zobrazit. Ať má člověk přehled o tom, co v těch datech je (a možná i pro nás, najdem tak chyby).

Kontrola IČO z datasetů vůči RES/OR

Udělat distinct list všech IČ z našich datasetů a udělat difference oproti RES/OR, ať najdeme chybějící data.

select ic_ucastnika from dotinfo.dotace
UNION
select ic_poskytovatele from dotinfo.dotace
UNION
select idprijemce from cedr.dotace
-- atd.

[ares] Datum zániku v OR

 hds = {
-    'udaje': ['ico', 'aktualizace_db', 'datum_vypisu', 'platnost_od', 'datum_zapisu', 'stav_subjektu'],
+    'udaje': ['ico', 'aktualizace_db', 'datum_vypisu', 'platnost_od', 'datum_zapisu', 'datum_zaniku', 'stav_subjektu'],

[...]

'datum_zaniku': './D:ZAU/D:DZ'

[smlouvy] Dodělat

  • projit specku, jestli jsem nejaky pole nezapomnel
  • prilohy?
  • projit pripady, kdy smluvni strana je stejna jako zadavatel (filtrovat?)
  • interpretovat, kdo je vlastne ktera smluvni strana (mame tri booleany) - #5
  • pridat moznost updatovat jednotlivy mesice (sloupec v obou tabulkach zminujici dump mesic info)
  • brin index na 'ts'? obecne indexy; bitmap index na platne smlouvy?
  • zrusit odkazy? muzem je rekreovat na zaklade id verze
  • lookup přes datovky - #26

[cedr] prázdný idprijemce

idprijemce v tabulce dotace je často prázdný, protože nejde o společnost v obchodním rejstříku - chceme tohle nějak řešit? Loadovat ROB a linkovat ho sem? Nebo prostě replikovat tabulku PrijemcePomoci? My ji teď osekáváme jen na IČ, který vkládáme přímo do dotace.

[volby] priklady - opakovany kandidat

Uklidit trochu, mozna rozsirit na jine volby

with kand as (
	select
	datum, jmeno || ' ' || prijmeni as jmeno, vek, nazev_vs
	
	from volby.senat_kandidati
), jmena as (select jmeno from kand
group by jmeno
having count(distinct nazev_vs) > 1)

select * from volby.senat_kandidati where jmeno || ' ' || prijmeni in (select jmeno from jmena)

order by prijmeni, jmeno, datum```

[zakazky] Neplatná IČ

Spousta identifikátorů je neplatných. Občas to jsou blbosti (1), občas to je kombinace IČO a nějakého jiného identifikátoru, třeba "44992785-28", když bylo myšleno Brno, 44992785.

[zakazky] Ano/ne -> bool

Někde v zakázkách byly sloupce, který měly hodnoty ano/ne, z těch bychom mohli udělat boolean.

[ares] Průběžné stahování RES

Průběžné stahování obchodního rejstříku už máme (d4d4d70, 4eb954e), pro RES to bude třeba dodělat.

Chybí:

  • abstrakce res.py funkcí, abychom je mohli importnout
  • zlepšení alertingu, že nenaparsujem danou firmu - v tuhle chvíli ukládáme prázdná data do ares.raw, a mažem si stará (když RES přestane data publikovat) - tomuhle musíme předejít

[volby] priklad na volebni historii

bez prezidentskych

with kand_flat as (
	select unnest(string_to_array('Adam Novák, Jarmil Černý', ', ')) as jmeno
), kand as (
	select split_part(jmeno, ' ', 1) as jmeno, split_part(jmeno, ' ', 2) as prijmeni
	from kand_flat
)

select
jmeno, prijmeni, datum, 'senat' as volby, nazev_vs as strana
from volby.senat_kandidati inner join kand using(jmeno, prijmeni)

union

select
jmeno, prijmeni, datum, 'ep' as volby, nazevcelk as strana
from volby.ep_kandidati inner join kand using(jmeno, prijmeni)
inner join volby.ep_strany using(datum, estrana)

union

select
jmeno, prijmeni, kn.datum, 'komunalni' as volby, nazevcelk as strana
from volby.komunalni_kandidati kn inner join kand using(jmeno, prijmeni)
inner join volby.komunalni_strany ks on kn.nstrana = ks.vstrana and kn.datum = ks.datum

union

select
jmeno, prijmeni, datum, 'kraje' as volby, null as strana
from volby.kraje_kandidati inner join kand using(jmeno, prijmeni)

union

select
jmeno, prijmeni, kn.datum, 'psp' as volby, nazevcelk as strana
from volby.psp_kandidati kn inner join kand using(jmeno, prijmeni)
inner join volby.psp_strany ks on ks.datum = kn.datum and ks.vstrana = kn.nstrana
;

Specifikuj závislosti skriptů

Kde to je možné, tak nepoužívám nic mimo základní Python 3, ale někde to prostě nejde. Měl sem jeden Pipfile pro všechno, ale nevim, jestli tim chci zatěžovat - třeba xlrd a openpyxl, když jsou potřeba jen pro evropské dotace. Na druhou stranu zas ale nechci Pipfile/requirements pro každej dataset... nebo chci?

[doc] Přidat info o architektuře

Jaké technologie jsou použité, co by se dalo změnit (třeba ze shellu na něco přenositelnějšího) a s čim je to implicitně kompatibilní (v případě DB třeba).

Komentáře u sloupců

Ke všem datasetům by to chtělo přidat komentáře ke sloupcům podle definic od zdrojových systémů.

  • ares
  • cedr
  • czechinvest
  • dotinfo
  • eufondy
  • psp
  • smlouvy
  • volby
  • wikidata
  • zakazky

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.