Kernelalapú interpoláció két szomszédos mintából

A természeti jelenségek és fizikai törvények általában folytonos függvényekkel írhatók le. A méréseket vagy megfigyeléseket azonban csak diszkrét pontokban tudjuk végrehajtani. Ezért az adatok mindig csak véges számban állnak rendelkezésre, miközben az ezek közötti értékekre is gyakran szükség van, például további számításokhoz, vizualizációhoz vagy modellezéshez.  

Az interpoláció célja, hogy ismert adatpontok alapján becslést adjunk közbenső, ismeretlen értékekre. Számos interpolációs módszer létezik: lineáris, polinom-, spline- és kernelalapú interpoláció.

A lineáris interpoláció a legegyszerűbb módszer, amelyben a szomszédos pontokat egyenes szakaszokkal kötjük össze.

A polinominterpoláció esetén egyetlen, magas fokszámú polinomot illesztünk az összes n mintapontra. A legismertebb változatok a Lagrange- és a Newton-féle interpolációk.

A spline interpoláció a polinomalapú módszer egy fejlettebb változata: az adatsort kisebb szakaszokra osztja, és minden szakaszra külön, alacsony fokszámú (gyakran harmadfokú) polinomot illeszt. A szomszédos szakaszok találkozási pontjainál biztosítja a folytonosságot és a deriváltak egyezőségét is.

A kernelalapú interpoláció olyan eljárás, amely súlyozott átlagot használ az interpolált érték kiszámítására. Minden mintapont egy kernel (magfüggvény) segítségével hat a környezetére. Az interpolált érték a mintapontok súlyozott összege, ahol a súlyokat a kernelfüggvény adja meg a távolság függvényében: a közelebbi pontok nagyobb, a távolabbiak kisebb súllyal szerepelnek.

Az interpolációs módszerek eltérnek a becslés pontosságában, a görbe simaságában és a számítási igényben. A lineáris interpoláció gyors, de töréspontokat eredményez a mintapontoknál. A többi módszer simább görbét ad, viszont több mintapont esetén a számításigény nő.

A továbbiakban a kernelalapú interpolációval foglalkozunk.

Ez a módszer számos előnnyel rendelkezik:

  • A kernel alakja és paraméterei testreszabhatók az adott probléma jellegéhez.
  • Az íveltebb görbéjű (például Gauss-jellegű) kernelek általában simább — matematikai nyelven: folytonosan differenciálható — interpolációs függvényt eredményeznek.
  • Nem szükséges előzetesen megadni a modellstruktúrát, mint például a polinominterpolációnál.
  • Kis mintaszám esetén is jól működhet, ha a kernel megfelelően van megválasztva.

Hátránya, hogy minden új becsült pont kiszámításakor a módszer újra meghatározza a kernel súlyokat az összes releváns mintaponthoz viszonyítva. Ez jelentős számítási igénnyel jár, ezért nagy adathalmazok esetén a módszer lassú lehet.

Bizonyos kernelfüggvények csak egy szűk tartományban vesznek fel nem nulla értéket. Ezeket a matematikai szakzsargonban kompakt tartójú kernelfüggvényeknek nevezik. Az interpoláció eredménye érzékenyen függ a kernelfüggvény típusától és a kompakt tartó hosszától is.

A kernelalapú interpoláció számításigényének csökkentésére most a következő megközelítést alkalmazzuk:

  1. egyenközű mintavétel.
  2. két minta közötti interpolációhoz csak a két minta értékét vesszük figyelembe.
    Ehhez olyan K(x) kerneleket alkalmazunk, amelyek csak a [−1,1] intervallumon belül vesznek fel nem nulla értéket, azaz K(-1)=K(1)=0, továbbá a nullában 1 értékűek, azaz K(0)=1. Ekkor, ha a kerneleket az egyes adatpontokra (x= 0, 1, 2, 3…) helyezzük, akkor azok a szomszédos pozíciók mintáinak értékeire nem hatnak. Így, ha minden minta értékével megszorozzuk az adott pontra illesztett kernelt, és ezeket összegezzük, olyan interpolációs függvényt kapunk, amely az eredeti mintáknál azok pontos értékét adja vissza.
  3. Annak érdekében, hogy egy konstans függvényt is helyesen interpoláljunk a kernelnek páros szimmetriájúnak kell lennie, valamint teljesülnie kell, hogy K(0.5) = K(-0.5) = 0.5. Ez biztosítja, hogy a két szomszédos pont súlyozott átlaga valóban az eredeti (konstans) értéket adja vissza középen is.

E feltételeknek megfelelő három eltérő kernelfüggvényt mutat az alábbi ábra. Ezek a háromszög alakú (triangular), a köbös (cubic) és az emelt koszinusz (raised cosine).

Az egyes grafikonokon egy adott kernelt két szomszédos mintapontra (x=0 és x=1) illesztve láthatunk, ahol az egyik minta 4, a másik 2 értékű. A két minta közötti értékeket a kernelek összegével becsüljük. A kiadódó interpolációs függvénygörbe kék színnel lett kirajzolva. Megfigyelhetjük, hogy a háromszög alakú kernel a lineáris interpolációt valósítja meg, ami egyébként képletekkel is egyszerűen bizonyítható.

A következőkben azt vizsgáljuk, hogy tetszőlegesen kiválasztott interpolálandó tesztfüggvényekre milyen pontos az interpoláció a három kernel esetén. A pontosságot az egzakt függvényértékek és az interpolált értékek négyzetes eltérésének átlagával (mean squared error, MSE) fogjuk mérni, amihez egy mse() nevű függvényt írunk.

Az egyenközű mintavétel után előálló x és y értékeket egy sorozattípusú konténerben tároljuk, amelyeket jelölje xs és ys. Ahhoz, hogy megtudjuk, hogy egy adott vizsgált x érték mely két szomszédos minta által meghatározott intervallumba, vagyis az xs sorozat mely két indexe közé esik, szükségünk van egy gyors indexkereső függvényre. Ennek megvalósításában az O(log n) időkomplexitású bináris keresést megvalósító bisect() függvényt használjuk fel, amely a szabványos könyvtár bisect moduljában található.

Az interpoláció eredményét grafikonon is meg akarjuk jeleníteni. Ehhez is készítünk egy függvényt.

Az eddig említett függvények még nem az interpolációt végzik, hanem csak közreműködők a célunk elérésében. Ezért ezeket a segédfüggvényeket külön, egy util nevű modulban gyűjtjük össze.

Szintén külön modulban definiáljuk a kernelfüggvényeket. E modul neve kernels lesz.

A main modulban definiáljuk az egyenközű mintavételt és az interpolációt végző függvényeket, valamint a tesztelő függvényt. A main természetesen használja a kernels és a util modulokat, ezért ezeket beimportáljuk. Az eddig leírtak és a részletes kommentek segítik a megértést.

Három tesztfüggvényre végezett interpolációk eredményét láthatjuk a következő ábrán grafikonon ábrázolva, ahol feltüntettük az egyes kernelekkel elért négyzetes hibaátlagokat is. (A könnyebb olvashatóság és összehasonlítás érdekében a tényleges értéket egy adott konstanssal szorozva)

Az eredmények azt mutatják, hogy minden vizsgált esetben a háromszög alakú kernel – azaz a lineáris interpoláció – adja a legkisebb átlagos négyzetes hibát. Más tesztfüggvényekkel végzett próbák is ugyanezt az eredményt hozzák.

Ez elsőre meglepő lehet, mivel a kernelalapú interpolációban általában a lekerekített görbéjű kernelek simább és pontosabb interpolációs függvényt eredményeznek. Ez a simaság azonban nagyobb számításigénnyel jár.

Mivel jelen esetben a kernelek csak két mintapontot használnak az interpolációhoz, a simább kernelek előnye nem tud érvényesülni; így a legegyszerűbb, lineáris megközelítés bizonyul a leghatékonyabbnak.

E bejegyzésben a matematika egy erős elméleti alapokon nyugvó, és a gyakorlatban számos területen alkalmazott módszerének kis szeletét érintetettük, amelynek numerikus vizsgálatához a Python megfelelő nyelvi elemeit használtuk. Ezekről a Python tudásépítés lépésről lépésre című e-könyv „Készétel fogyasztás – a szabványos könyvtár moduljainak használata” fejezet „Matematikai számítások támogatása” alfejezetben lehet bővebben olvasni.

Érdekel a Python tudásépítés lépésről lépésre az alapoktól az első asztali alkalmazásig című e-könyv.