Regresjon#
Når vi jobber med reelle datasett ønsker vi ofte å finne ut hvilken matematisk funksjon som passer best til dataene.
Når vi har funnet en matematisk funksjon er mulighetene mange. Vi kan lage en modell som ser hva som har skjedd mellom, før og etter datapunktene våre. Som en slags data-trollmann kan vi altså både spå fremtiden og se tilbake i tid 🧙♂️🔮
La oss starte med eksempelet om konsumprisindeks fra tidligere.
import matplotlib.pyplot as plt
x = [2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022] # År etter 2015
y = [100, 103.6, 105.5, 108.4, 110.8, 112.2, 116.1, 122.8] # Konsumprisindeks
plt.scatter(x, y)
plt.xlabel("År etter 2015")
plt.ylabel("Konsumprisindeks (KPI)")
plt.show()
Hvilken type matematisk funksjon tror du passer best her? En lineær funksjon? En andregradsfunksjon? Eller kanskje en eksponentiell funksjon?
I denne delen skal vi bruke
curve_fit
funksjonen frascipy
-pakken. Det kan hende du må installere denne ved å kjørepip install scipy
i terminalvinduet.
Eksempel: Lineære funksjoner#
Lineære funksjoner har funksjonsuttrykk på formen curve_fit
funksjonen kan vi finne hva koeffisientene
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
# Datapunkter (i arrays)
x = np.array([2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022]) # År etter 2015
y = np.array([100, 103.6, 105.5, 108.4, 110.8, 112.2, 116.1, 122.8]) # Konsumprisindeks
# Definerer den matematiske funksjonen
def f(x, a, b):
return a * x + b
# Finner koeffisienter
a, b = curve_fit(f, x, y)[0]
print("a:", a) # Skriver ut a-verdien
print("b:", b) # Skriver ut b-verdien
plt.scatter(x, y)
plt.plot(x, f(x, a, b), color = "tab:red")
plt.xlabel("År etter 2015")
plt.ylabel("Konsumprisindeks (KPI)")
plt.show()
a: 2.911904761909067
b: -5767.7547619176175
curve_fit
funksjonen fant altså koeffisientene til å være
Siden koeffisienten
Noen kommentarer til koden
Vi må gjøre listene med data om til arrays med
np.array()
for å kunne brukecurve_fit
-funksjonen på denne måten.curve_fit
-funksjonen gir ut flere verdier i en liste, men vi er bare interessert i den første verdien i denne listen, som er en liste med koeffisientene. Derfor skriver vikoeffisienter = curve_fit(f, x, y)[0]
Sette inn verdier i modellen#
La oss bruke modellen vår til å spå fremtiden eller se tilbake i tid.
Hva sier modellen oss at konsumprisindeksen blir i 2030?
Hva sier modellen vår at konsumprisindeksen var i 2005?
Når vi har brukt curve_fit
for å finne koeffisientene a
og b
er det enkelt å finne konsumprisindeksen i et gitt år ved å skrive f(år, a, b)
.
from scipy.optimize import curve_fit
import numpy as np
# Datapunkter (i arrays)
x = np.array([2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022]) # År etter 2015
y = np.array([100, 103.6, 105.5, 108.4, 110.8, 112.2, 116.1, 122.8]) # Konsumprisindeks
# Definerer den matematiske funksjonen
def f(x, a, b):
return a * x + b
# Finner koeffisienter
a, b = curve_fit(f, x, y)[0]
print("KPI i 2030 (modell):", f(2030, a, b))
print("KPI i 2005 (modell):", f(2005, a, b))
KPI i 2030 (modell): 143.41190475778876
KPI i 2005 (modell): 70.61428571006218
Hvordan passer modellen?
Modellen sier altså at konsumprisindeksen i
Den sier også at konsumprisindeksen i
Det kan være flere grunner for at modellen vår ikke passer godt med virkeligheten.
Vi har for få datapunkter.
Det siste datapunktet gikk opp mye mer enn alle de andre. Hva skjedde i 2022?
Å bruke en lineær funksjon var kanskje ikke riktig valg.
Andre matematiske funksjoner#
La oss prøve å lage en modell med en andregradsfunksjon. Andregradsfunksjoner har funksjonsuttrykk på formen
Det eneste vi må endre i koden over er hvordan vi definerer den matematiske funksjonen og hvilke koeffisienter vi skal finne med curve_fit
.
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt
# Datapunkter (i arrays)
x = np.array([2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022]) # År etter 2015
y = np.array([100, 103.6, 105.5, 108.4, 110.8, 112.2, 116.1, 122.8]) # Konsumprisindeks
# Definerer den matematiske funksjonen
def f(x, a, b, c):
return a * x**2 + b * x + c
# Finner koeffisienter
a, b, c = curve_fit(f, x, y)[0]
print("a:", a) # Skriver ut a-verdien
print("b:", b) # Skriver ut b-verdien
print("c:", c) # Skriver ut c-verdien
plt.scatter(x, y)
plt.plot(x, f(x, a, b, c), color = "tab:red")
plt.xlabel("År etter 2015")
plt.ylabel("Konsumprisindeks (KPI)")
plt.show()
a: 0.1797608181738
b: -722.7825181950592
c: 726638.397852397
curve_fit
funksjonen fant altså koeffisientene til å være
På samme måte kan vi også finne modeller med andre matematiske funksjonstyper som
Tredjegradsfunksjoner
Eksponentialfunksjoner
Potensfunksjoner
Sinusfunksjoner
Eksponentiell og potensregresjon
Når vi gjør regresjon med potenser og eksponentialfunksjoner kan vi ende opp med å få noen helt utrolig store tall fordi vi ender opp med tall som
Den enkleste måten for å fikse dette er å normalisere datasettet.
x = np.array([2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022])
x = np.array(x - 2015)
print(x)
[0 1 2 3 4 5 6 7]
I stedet for år bruker vi altså år etter.
Kilde til data om konsumprisindeks: SSB
Oppgaver#
Oppgave 1
Konsumprisindeksen for boligprisene for brukte boliger i Oslo og Bærum har utviklet seg på følgende måte.
2015 |
2016 |
2017 |
2018 |
2019 |
2020 |
2021 |
2022 |
---|---|---|---|---|---|---|---|
a) Lag en linær modell for konsumprisindeksen. Hva blir konsumprisindeksen for brukte boliger i
Finne endring i verdi fra KPI.
Man kan finne en tilnærming for hvor mye en bolig er verdt, gitt at den følger indeksen, ved å bruke formelen
For eksempel vil en bolig som er verdt
b) Hvis man kjøper en bolig for
Løsningsforslag
import numpy as np
from scipy.optimize import curve_fit
x = np.array([2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022])
y = np.array([100, 115.5, 124.24, 125.5, 130.4, 137.3, 152.1, 158.9])
def f(x, a, b):
return a*x + b
a, b = curve_fit(f, x, y)[0]
print("KPI (2023):", f(2023, a, b)) # KPI (2023): 164.74499999594627
print("KPI (2030):", f(2030, a, b)) # KPI (2030): 218.02666666271762
print("Boligen blir verdt:", round(f(2030, a, b)/f(2023, a, b) * 4000000), "i 2030")
Da får vi at boligen blir verdt
Kilde til data om konsumprisindeks: SSB