Doprinos 1 · detaljni vodič s kodom
Geolokacija iz teksta: regex naspram LLM-a
Cijela prva faza objašnjena korak-po-korak — što radimo, zašto, i kako kod radi. Nije potrebno otvarati Python datoteke; sve se može pročitati ovdje.
1. Što želimo postići
Požarni tekstovi (vatrogasna izvješća i Facebook objave) napisani su običnim jezikom i ne sadrže koordinate — samo opise poput „požar na području Zablača" ili „gorí iznad Omiša". Cilj je iz takvog teksta automatski izvući:
- 📍 Mjesto → naziv naselja i njegove koordinate
- 🕐 Vrijeme → datum i sat događaja
Isti zadatak rješavamo na dva načina i uspoređujemo ih — to je sam istraživački doprinos:
Pristup A — Regex
Pravila koja prepoznaju obrasce u tekstu. Brzo i besplatno, ali „krhko" — lako pogriješi kad je tekst neobičan.
Pristup B — LLM
Veliki jezični model (Claude) koji razumije kontekst rečenice i prepoznaje mjesto/vrijeme čak i kad je nejasno napisano.
2. Zašto je to teško
Dva izvora izgledaju vrlo različito:
HVZ izvješća — uredna i strukturirana
Dana 02. veljače u 16:51 sati ŽVOC Šibenik zaprimio je dojavu o požaru
otvorenog prostora na području Zablača. Radilo se o požaru trave na
površini 4 ha. Na intervenciji je sudjelovalo 28 vatrogasaca...
Ovdje regex radi dobro jer je oblik uvijek sličan („Dana … u … sati … na području …").
Facebook — neformalno i puno šuma
"Tooooooo. VATRENIIII ❤️" → nogomet, NIJE požar
"Vatrogasci - 193 mijenja profilnu" → objava stranice, NIJE događaj
"Požar kod Dubrave, Bilica" → pravi požar s lokacijom ✅
Obična pretraga ključnih riječi („vatra", „vatrogasci") lovi i nogometne objave. Tu razumijevanje konteksta (LLM) ima najviše smisla.
3. Regex pristup — objašnjen s kodom
Sav kod je u datoteci doprinos1_geolokacija/geolokator_regex.py 📄 Otvori kod. Radi u tri koraka za mjesto i posebno izvlači vrijeme. Prolazimo redom.
Korak A — pronađi „kandidate" za mjesto
Nazivi mjesta gotovo uvijek počinju velikim slovom. Zato prvo iz teksta izvučemo sve takve riječi:
def velike_rijeci(tekst):
# makni brojke i interpunkciju (zamijeni razmakom)
for s in "!\"#$%&()*+-./:;<=>?...1234567890":
tekst = tekst.replace(s, " ")
kandidati = []
for r in tekst.split(" "):
if len(r) > 1 and r[0].isupper(): # počinje velikim slovom?
kandidati.append(r)
return kandidati
Objašnjenje: za tekst „…na području Zablača" ova funkcija vrati npr. ["Dana", "ŽVOC", "Šibenik", "Zablača"]. Neke od njih (ŽVOC) nisu mjesta — to rješava sljedeći korak.
Korak B — pronađi najsličnije naselje na karti
Imamo kartu s 6758 naselja Hrvatske. Za svaki kandidat tražimo naselje s najsličnijim imenom, koristeći udaljenost uređivanja (koliko slova treba promijeniti da jedna riječ postane druga):
def nadji_toponim(kandidat, naselja):
najbolji = None
najmanja = len(kandidat)
for z in naselja_na_isto_slovo(kandidat): # samo naselja na isto početno slovo (brzina)
d = edit_distance(kandidat.lower(), z["ime"].lower())
if d < najmanja:
najmanja = d
najbolji = z
# prihvati samo ako je razlika mala (manje od trećine duljine riječi)
if najbolji and najmanja < len(kandidat) / 3:
return najbolji
return None
Ovdje se vidi krhkost regex pristupa! Za „Zablača" najbliže naselje po slovima je „Zamlača" (razlika 1 slovo) — ali to je selo kod Siska, a ne „Zablaće" kod Šibenika (razlika 2 slova). Bez konteksta, računalo bira krivo. Baš ovakve greške mjerimo protiv LLM-a.
Korak C — ako ima više mjesta, uzmi najmanje
Ako tekst spomene više naselja, biramo najmanje po površini — jer se požar obično opisuje najužim, najkonkretnijim mjestom (selo, a ne cijeli grad):
def odaberi_najmanje(pogodci):
return min(pogodci, key=lambda z: z["povrsina_km2"])
Vrijeme — regex na hrvatski datum
Za vrijeme koristimo obrasce koji hvataju „Dana DD. mjesec" i „u HH:MM sati", uz popis hrvatskih mjeseci:
MJESECI = {"siječnja":1, "veljače":2, "ožujka":3, "travnja":4, ...}
DATUM = re.compile(r"Dana\s*(\d{1,2})\.?\s*([A-Za-zČĆĐŠŽčćđšž]+)")
SAT = re.compile(r"u\s*(\d{1,2}):(\d{2})\s*sati")
Rezultat: vrijeme se iz HVZ izvješća izvlači vrlo pouzdano (npr. {dan: 2, mjesec: 2, sat: "16:51"}). Problem je uglavnom kod mjesta.
4. Kako pokrenuti (uživo isprobati)
Kad je okruženje uključeno (vidi Kako pokrenuti), u terminalu:
cd doprinos1_geolokacija
python geolokator_regex.pyIspisat će nekoliko primjera. Za jedno HVZ izvješće izlaz izgleda ovako:
-> mjesto: Zamlača | općina: DVOR | koord: (45.09, 16.38)
-> vrijeme: {dan: 2, mjesec: 2, sat: "16:51"} | kandidati: ["Zamlača"]
(Mjesto je namjerno prikazano „kako regex vidi" — pogrešno Zamlača umjesto Zablaće — da se vidi problem koji rješavamo.)
5. Gold set — „ispravni odgovori" za mjerenje
Da bismo izmjerili koliko točno rade regex i LLM, treba nam skup tekstova s ručno provjerenim točnim odgovorom. To zovemo „gold set" (zlatni standard).
Pripremili smo Excel tablicu s 150 primjera (90 HVZ + 60 Facebook), gdje je računalo već upisalo svoj prijedlog, a čovjek samo potvrdi ili ispravi:
| Boja polja | Značenje | Što raditi |
|---|---|---|
| sivo | regex_* — prijedlog računala | NE dirati |
| zeleno | tocno_mjesto, tocan_datum, tocno_vrijeme, ima_lokaciju, napomena | potvrdi ili ispravi |
→ Vodič: Kako označiti gold set
korak-po-korak, s primjerima prije/poslije
Datoteka: doprinos1_geolokacija/rezultati/gold_set_za_oznacavanje.xlsx (u njoj je i list „Upute"). Kako je nastala:
python napravi_gold_set.pyZašto ovako: ispravljanje gotovog prijedloga puno je brže od upisivanja od nule, a odgovor ostaje ljudski provjeren — što je za istraživanje ključno.
6. LLM pristup
Isti zadatak damo modelu Claude: pošaljemo mu tekst i pitamo ga da vrati mjesto i vrijeme u urednom obliku. Model razumije kontekst, pa bi trebao izbjeći greške tipa „Zablača → Zamlača" i prepoznati da je „VATRENIII" nogomet, a ne požar.
Kod je napisan i spreman (doprinos1_geolokacija/geolokator_llm.py). Objašnjen je korak-po-korak, s isječcima, na zasebnoj stranici:
→ Detaljni vodič: LLM pristup s kodom
shema odgovora, uputa modelu, poziv, geokodiranje, trošak
Za pokretanje treba Anthropic API ključ. Napravi datoteku .env u glavnoj mapi sa sadržajem ANTHROPIC_API_KEY=sk-ant-... (kopiraj .env.primjer). Ključ nikad ne ide u git (već je zaštićen). Dobiva se na console.anthropic.com.
7. Kako ćemo usporediti (jednostavno objašnjeno)
Kad imamo točne odgovore (gold set) i odgovore oba pristupa, mjerimo tri broja:
| Mjera | Pitanje na koje odgovara |
|---|---|
| Preciznost | Kad pristup kaže mjesto — koliko često je u pravu? |
| Odziv | Od svih mjesta koja postoje — koliko ih pronađe? |
| F1 | Zajednička ocjena (spoj preciznosti i odziva) — glavni broj za usporedbu. |
Uz brojke radimo i analizu grešaka: gdje i zašto jedan pristup pobjeđuje drugoga. To je najvredniji dio doprinosa.
Kod je napisan (doprinos1_geolokacija/usporedba.py) — objašnjen korak-po-korak, s načinom pokretanja u fazama:
→ Detaljni vodič: Usporedba (mjerenje) s kodom
TP/FP/FN, preciznost/odziv/F1, predmemorija, grafovi
Trenutni status svih koraka prati se na stranici Napredak. Sav kod je u folderu doprinos1_geolokacija/ (svaka datoteka je i komentirana iznutra).