Trafiłem ostatnio na bardzo interesujące narzędzie do czyszczenia
danych – np. normalizowania zapisu nazw, nazwisk czy kodów,
wyłapywania nietypowych rekordów itp itd. Nadaje się do właściwie
dowolnych danych zapisanych w postaci tabelarycznej (najprostszą formą
importu jest plik .csv
lub podobny).
Pierwszym zastosowaniem jakie wpadło mi do głowy mogłoby być porządkowanie katalogów produktów w agregujących sklepach internetowych czy porównywarkach, gdzie normą jest pojawianie się tego samego produktu pod kilkoma nazwami czy różnorodne metody zapisu tej samej cechy. A w warunkach domowych – katalogów książek czy filmów, list wydatków, spisów danych kontaktowych.
Google Refine
Zabawką jest Google Refine (dawniej Freebase Gridworks, narzędzie przejęte przez Google przy okazji przejęcia Freebase, gdzie służy(ło) do czyszczenia danych agregowanych z internetu).
Autorzy przygotowali świetne wprowadzenie w formie filmików/screencastów, dlatego zamiast rozwijać opis pozwolę sobie zachęcić do obejrzenia:
a następnie
(jest też trzecia część ale dotyczy nieco mniej w polskich warunkach przydatnej funkcjonalności uzupełniania danych w oparciu o API internetowe).
Instalacja i uruchamianie
Google Refine, nie jest usługą internetową, trzeba je pobrać,
zainstalować i uruchomić (i dobrze, można bez obaw używać go także do
prywatnych czy poufnych danych). Zarazem … jest to aplikacja webowa
(napisana w Javie, z przeglądarkowym interfejsem), tyle że domyślnie
uruchamiamy ją na własnym komputerze i obsługujemy w przeglądarce
otwierając lokalny adres (domyślnie http://127.0.0.1:3333/
) –
przypomina tym
np. Sage Notebook.
Nie testowałem tego ale prawdopodobnie można ją uruchomić w sieci lokalnej, choć nie wiem jak wygląda wtedy zabezpieczenie przed równoczesną pracą paru osób nad jednym projektem.
Instalacja jest prosta -
pobieramy wersję dla odpowiedniego systemu operacyjnego,
rozpakowujemy i uruchamiamy poleceniem ./refine
. Wymagane jest
zainstalowane Java JDK. Pod Linuksem może to wyglądać np. tak:
wget http://google-refine.googlecode.com/files/google-refine-2.1-r2136.tar.gz tar xzvf google-refine-2.1-r2136.tar.gz cd google-refine-2.1 # Ewentualna edycja refine.ini ./refine
(po czym zostawiamy terminal w spokoju i pracujemy przy pomocy przeglądarki).
Pierwsze uwagi po używaniu
Moje korzystanie z Google Refine na razie ogranicza się do prostych eksperymentów, których nie warto szczegółowo relacjonować, mam już jednak kilka pierwszych obserwacji:
-
narzędzie jest zaskakująco sprawne i szybkie nawet na całkiem sporych plikach,
-
o ile dzielenie kolumn, reformatowanie, łączenie ich itp daje się robić bardzo szybko i wygodnie, o tyle łączenie wierszy jest kłopotliwe (patrz przykładowa porada); można dość łatwo sobie poradzić z niejednorodną strukturą pliku, można pociąć dane wczytane pierwotnie jako jedna kolumna ale lepiej by jedna krotka nie była rozrzucona w kilku wierszach,
-
nie należy się bać Google Refine Expression Language, po obejrzeniu paru przykładów daje się zgadywać, co napisać,
-
gdy coś dzieje się źle warto zerknąć na terminal, może tam być techniczny opis błędu,
-
to nie jest Excel, raz stworzona nowa kolumna nie zostaje przeliczona gdy zmieni się bazowa (ani nie znika, gdy bazową skasujemy), dane wyliczone formułami pojawiają się raz a dobrze i żyją własnym życiem,
-
złożoną sekwencję kroków można sobie zachować odwiedzając zakładkę
Undo/Redo
i klikającExtract…
(schemat działań zostaje zapisany jako plik.json
który od biedy można traktować jako swoisty kod programu i np. reużyć później dla innych danych), -
tenże kod jest bardzo wrażliwy na nazwy kolumn, jeśli chcemy obrabiać przygotowanym schematem nowy plik, musi on mieć tak samo nazwane kolumny.
Mój jedyny jak dotąd techniczny problem z Refine był związany właśnie
z tym ostatnim - próbowałem zastosować zestaw reguł do innego pliku
wklejając JSONowy kod i aplikacja po prostu wydawała się ignorować
moje polecenie. Dopiero rzut oka na terminal na którym działało ./refine
ujawnił przyczynę:
22:34:45.754 [ refine] POST /command/core/apply-operations (42406ms) java.lang.Exception: No column named Nazwa elementu at com.google.refine.operations.column.ColumnAdditionOperation.createHistoryEntry(ColumnAdditionOperation.java:139) at com.google.refine.model.AbstractOperation$1.createHistoryEntry(AbstractOperation.java:52) (… pomijam kilkaset dalszych wierszy backtrace …) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:679)
Pomogło proste poprawienie nazwy w JSONie przed jego ponownym wklejeniem.
Do poczytania
Polecam też ten artykuł, stanowiący element większego, ciekawego cyklu opisującego zbieranie i opracowanie danych na potrzeby dziennikarskiego śledztwa.