Regresja

Jak już wracać po ponad miesięcznej absencji, to z przytupem. Zapnijcie pasy i przygotujcie umysły!

No dobra, postaram się za bardzo nie namieszać – więc zacznijmy od tego, czym jest regresja?

Podejrzewam że nie przyszliście tu po ściśle naukową definicję i sztywną paplaninę, tego możecie doświadczyć na Wikipedii, jeśli tylko chcecie się pomęczyć. Zacznijmy od teorii. Wyobraźcie sobie 2 zbiory wartości, nazwijmy je X i Y. Ich liczność (ilość elementów) będzie równa, nazwiemy ją n. Każda wartość (x_{1,2\dots n}) z jednego zbioru posiada przyporządkowanie do wartości z drugiego zbioru (y_{1,2\dots n}). Można powiedzieć, że mamy funkcję (nazwijmy ją f(x)), która dla każdej wartości x_{1,2\dots n} da nam odpowiadające mu y_{1,2\dots n} (czyli matematycznie f(x_{1,2\dots n}) = y_{1,2\dots n},  x_{1,2\dots n} \in X, \quad y_{1,2\dots n} \in Y). My znamy wszystkie wartości w zbiorze X i Y. Nie znamy tylko funkcji f(x) i to właśnie ją chcemy poznać za pomocą regresji (funkcję uzyskaną za jej pomocą nazwijmy r(x)).

Najczęściej jest jednak tak, że analizujemy dane niedokładne, więc też f(x) \neq r(x) – w praktyce ta właściwość zawsze będzie prawdziwa (oprócz przypadków, w których poddajemy regresji dane idealnie pasujące do funkcji przekształcenia). Dlatego właśnie przyjęto wskaźnik R^{2}, który przyjmuje wartości od 0 do 1 włącznie (czyli R^2 \in [0,1]) i określa jak bardzo model (czyli wartości y wyliczone na podstawie funkcji r(x)) pasują do wartości oryginalnych – im większa wartość, tym lepiej.

No dobra, ale po co nam funkcja opisująca zależność między danymi? Spójrzmy szerzej – teraz mamy w rękach uniwersalną funkcję, która dla dowolnego x, w tym nienależącego do X da nam y! Jak by ktoś do tej pory nie zajarzył – możemy wyliczać nieznane wartości parametrów, przewidywać je (fachowo nazywa się to wyliczaniem linii trendu danych, co dobrze obrazuje to co dostajemy – linię, pokazującą w jakim kierunku zmierzają dane).

No, to na tyle z teorii – teraz prosty przykład, by potwierdzić że zrozumieliście, potem przejdziemy do kolejnych członów tytułu posta 😉

Posłużę się przykładem ze świata elektroniki. Diody, jak wiedzą zainteresowani, posiadają coś takiego jak charakterystyka napięciowo-prądowa. W uproszczeniu, mówi ona przy jakim napięciu dioda jest zdolna przewodzić dane natężenie prądu. Jest to charakterystyka wykładnicza (funkcja która opisuje taką zależność między danymi ma postać f(x)=ab^x) – natężenie prądu rośnie bardzo szybko w stosunku do napięcia przewodzenia.

Dzięki regresji będę mógł zobaczyć taką przybliżoną charakterystykę bez patrzenia na datasheet diody – wystarczy, że zmierzę natężenie prądu który przez nią przepływa przy różnych napięciach przewodzenia. Jako że to charakterystyka wykładnicza, nieco ciężko jest zmierzyć więcej punktów – myślę, że cztery wystarczą. Dokonałem pomiaru diody 1N4148 w temperaturze około 25°C, oto wyniki:

Napięcie przewodzenia (V) Prąd (mA)
0.60 0.0
0.80 16.7
1.00 102.5
1.20 341.2

Przyjmijmy za X napięcia przewodzenia a za Y natężenia prądu płynącego przez diodę. Teraz, gdy mamy dane, przydałoby się je potraktować regresją i zobaczyć wynik. Do tego celu napisałem swoją własną, prostą bibliotekę w pythonie. Realizuje ona regresję liniową, logarytmiczną, wykładniczą i potęgową. Nie będę was zadręczał szczegółami implementacji – ważne jest to, co tak naprawdę obliczamy. Każdy chyba zna postać funkcji liniowej – ax+b. To co daje nam regresja, to właśnie te dwa współczynniki – a i b. Regresję liniową realizuję za pomocą metody najmniejszych kwadratów, a pozostałe regresje obliczam dzięki spostrzeżeniu, że równania postaci a * log(x) + b (logarytmiczne), ab^x (wykładnicze) i ax^b (potęgowe) są możliwe do przekształcenia do postaci liniowej (przez przekształcenie zbiorów X lub/i Y lub/i przekształceniu wynikowych współczynników tak by pasowały do właściwego typu regresji)

Wiem że może dla niektórych poprzedni paragraf był niezrozumiały. Spokojnie, nie musiał być 😉 Ci bardziej dociekliwi mogą spojrzeć do kodu, a resztę zapraszam dalej 🙂

Wyniki wyglądają tak:

Wykres zależności napięciowo-prądowej diody 1N4148 wyliczony na podstawie pomiarów
Wykres zależności napięciowo-prądowej diody 1N4148 wyliczony na podstawie pomiarów

Wykresik narysowałem dzięki matplotlibowi – polecam spojrzeć, przydatna biblioteka 🙂

A więc, co mamy na wykresie? Czerwone kropki to punkty danych z początkowych zbiorów X i Y, a niebieska linia to wyliczona funkcja (była za długa by się zmieścić, jej postać to r(x)=0.04430149763038733*1886.8239419022345^x). Współczynnik R^2 jest całkiem spory, pokazuje zgodność modelu z oryginalnymi danymi na poziomie właściwie 77% (byłoby lepiej, gdybyśmy mieli po pierwsze dokładniejsze dane, a po drugie trochę więcej punktów pomiaru).

Tak jak widać, na podstawie tej linii można przewidzieć, jaki mniej więcej prąd będzie w stanie przewodzić dioda przy danym napięciu przewodzenia – czyż to nie przydatne? 🙂

To pierwsza część takiej miniserii o statystyce i matematyce w programowaniu – będę ją ciągnąć, póki starczy mi tematów. W następnej części – statki i 1/(5.35e+20) 🙂