3. diel - Predpoveď ceny zlata pomocou lineárnej regresie v Pythone
V minulej lekcii, Neurónové siete v Pythone - Prostredie Jupyter , sme si predstavili prostredie Jupyter notebook
pre Python, v ktorom budeme naše neurónové siete programovať. Vitajte u
ďalšej lekcie, dnes si skúsime predpovedať dáta pomocou lineárnej regresie
a pracovať s .csv
súbory pomocou knižnice Pandas. Ako viete,
než sa dostaneme k neuronkám nám ešte chvíľu potrvá
Lineárna regresia
Určite sa mnohí z vás stretli s týmto vzorom:
Je to predpis lineárnej funkcie. Tieto funkcie sú nám ľuďom veľmi blízke a tiež jednoduché na pochopenie.
Jablká
Predstavme si napríklad. Úlohu na zber jabĺk v sadu. 1
farmár zoberie 200
jabĺk za hodinu. x
farmárov
zoberie y = ax
jabĺk za hodinu, v našom prípade sa
a = 200
. Máme tu jednoduchý lineárny vzťah medzi x
a y
.
- Koeficient
a
je sklon funkcie, čím viac jeden formar dokáže jabĺk zobrať, tým viac nám s každým farmáromy
povyrastie. b
je tzv. bias (tento výraz rozoberieme neskôr u neurónových sieťach) a dovoľuje funkciu posun, aby sa lepšie prispôsobila dátam. Môžeme napr. Povedať, že v sklade je už v základeb = 500
jabĺk a výsledok funkcia bude vždy o500
jabĺk vyššia, bez ohľadu na hodnotyx
ay
.
Zlato
Prejdime na zaujímavejšie komoditu. Povedzme, že programujeme jednoduchý předpovídač ceny zlata a historické dáta už máme.
Pre predpoveď potrebujeme vytvoriť priamku tak, aby prešla čo najviac bodmi v datasete (jednoducho súbor dát, ktorý chceme predpovedať) a teda zodpovedala čo najpresnejšie tomu, ako cena zlata rastie alebo klesá. Práve pomocou lineárnej regresie zjednodušíme veľké množstvo bodov (cien zlata v daný okamih) na obyčajnú priamku, čím samozrejme stratíme určitú presnosť. Tejto metóde "osekanie" nejaké zložité funkcie na podobnú jednoduchšie funkcii sa v matematike všeobecne hovorí aproximácie.
Aby sme lineárne funkciu prispôsobili, potrebujeme ju takzvane
"optimalizovať". To sa týka premenných a
a b
,
keďže x
je vstup (v tomto prípade čas). Ukážeme si 2
spôsoby, ako môžeme funkciu optimalizovať:
- Dopočítania z dát - Spočítame sklon
a
a následneb
- Gradientné metóda - U tejto metódy vyberieme
a
ab
náhodne a postupne ich podľa nami definovanej chybové funkcie optimalizujeme, kým nie je chyba čo najmenšie
Výpočet ceny zlata v Pythone
Teraz už poznáme vzorec pre lineárne funkciu a môžeme si teda ukázať jednoduchý príklad v Pythone. Spustite si prostredie, ktoré sme si predstavili v minulej lekcii, a podľa potreby si vytvorme nový notebook.
Import knižníc
Najskôr je potrebné importovať knižnice s ktorými budeme pracovať:
from sklearn.linear_model import LinearRegression import numpy as np import matplotlib.pyplot as plt
Zjednodušený príklad
Než sa vrhneme na reálne ceny zlata, začneme jednoduchším príkladom.
Vstupné a výstupné dáta
Pre ukážku si definujeme jednoduchý príklad: Chceme výstup o
2
väčšia ako vstup. V tomto prípade chceme sklon
a = 1
a bias b = 2
.
Funkciu môžeme rýchlo overiť pri vstupe 3
:
y = 1 * 3 + 2
y = 5
V kóde pre tieto hodnoty definujeme vstupné a výstupné dáta, čím Nasimulujeme podobný prípad ako so zlatom - máme hodnoty pred a po zmene, ale nevieme vzorček, akým zmeny predpovedať. Budeme sa teda snažiť uhádnuť našu lineárnej funkcii:
# Definujeme si vstupní data, v tomto případě 1 a 3 x = np.array([[1], [3]]) # Definujeme si výstup, který chceme. # Pokud je vstup 1, chceme výstup 3 # Pokud je vstup 3, chceme výstup 5 y = np.array([[3], [5]])
Regressor
Dáta sú pripravené, teraz si môžeme vytvoriť Regressor
čiže lineárnu funkciu a optimalizovať ju na naše dáta:
# Vytvoříme regressor neboli lineární funkci reg = LinearRegression() # Optimalizujeme reg.fit(x, y)
Metóde fit()
jednoducho odovzdáme vstupné a výstupné dáta
a ona zistí vzťah medzi nimi. Ako si funkcie vedie overíme pomocou metódy
score()
.
reg.score(x, y)
výsledok:
1
Metóda vrátila výsledok 1
, čo znamená, že medzi
x
a y
je vysoká korelácia čiže vzťah. Keď
x
stúpa, y
tiež stúpa, presnejšie o
2
. Zjednodušene to znamená, že naša funkcia pretína všetky
body, ako aj uvidíte ďalej v grafe.
Vytvoríme si teda graf pre vizualizáciu funkcie, ktorú zisťujeme, a bodov, ktoré už máme z dát:
# Pomocí funkce plot() se vykreslí čárový graf plt.plot(x, reg.predict(x)) # Pomocí funkce scatter() vykreslíme jednotlivé body v grafu # V tomto případě body [1, 3] a [3, 5] plt.scatter(x, y, c="r") # v parametru c specifikujeme styl bodů, chceme je červené
Vidíme, že metóda predict()
nám zobrazila priamku
zodpovedajúce zmene našich dát. Metóda scatter()
na ňu potom
ďalej vykreslila body, v našom prípade len dva.
Zobrazíme si sklon a bias funkcie a overíme si tak, že sme mali pravdu:
a = reg.coef_ b = reg.intercept_ print("Sklon je {} a bias je {}".format(a, b))
Výsledkom sú naozaj koeficienty lineárnej funkcie, podľa ktorej sme dáta vytvorili:
Sklon je [[1.]] a bias je [2.]
Zlato!
Už vieme predpovedať dáta za pomoci knižnice scikit-learn
,
preto sa vrhneme na príklad s reálnymi dátami o cene zlata.
Príprava reálnych dát
Ešte predtým než začneme, potrebujeme dáta. Tá môžeme stiahnuť napr.
Tu: https://pkgstore.datahub.io/...thly_csv.csv.
Stiahnutý .csv
súbor presunieme do zložky s aktuálnym
.ipynb
notebookom. Ak neviete, kde sa nachádza, presuňte sa na
predchádzajúcu záložku v prehliadači a tam bude bežiaci notebook
označený zelene:
Výborne, súbor monthly_csv.csv
máme v našej pracovnej
zložke a môžeme sa teda vrhnúť na tvorbu předpovídače.
Importy
Importujeme si teda ešte knižnicu Pandas
pre čítanie dát z
.csv
, naša prvotná importy ponecháme:
import pandas as pd
Čítanie dát
Prečítame dáta zo súboru a zobrazíme si hlavičku čiže prvých 5
riadkov .csv
súboru:
data = pd.read_csv("monthly_csv.csv")
data.head()
výsledok:
Date Price 0 1950-01 34.73 1 1950-02 34.73 2 1950-03 34.73 3 1950-04 34.73 4 1950-05 34.73
Ako môžeme vidieť, dataset obsahuje 2 vlastnosti: Datum
a
Cenu
. Datum
budeme reprezentovať ako počet mesiacov
od 1.1.1950, čo je začiatok datasete. V deň, keď som tento článok písal,
je maximálna index 833
, čo je 1.6.2019.
Vstupy a výstupy
Pripravíme si teda opäť vstupy a výstupy:
# numpy pole od 0 do 833 ve dne 14.6.2019 x = np.arange(len(data)) # Ceny převedeme na numpy pole y = data["Price"].to_numpy()
Dáta ešte musíme previesť do tvaru, ktorý funkcie fit()
požaduje, čo je (vzorek, vlastnosti)
. My zatiaľ máme len
(hodnoty)
.
Predstavte si vzorku ako človeka a hodnoty ako nejaké jeho vlastnosti, ako
napr. výška
a váha
. Vstup by v tomto prípade
vyzeral takto: [ [173, 71] ]
. Ak by sme chceli viac ľudí, vyzeral
by vstup takto: [ [173, 71], [183, 86] ]
.
My teda potrebujeme previesť Cena
a Datum
na tento
tvar, pretože zatiaľ majú tvar:
[34.73, 34.73, 34.73, 34.73, 34.73]
a
[0, 1, 2, 3 4, 5]
. Náš požadovaný tvar vyzerá takto:
[ [34.73], [34.73], [34.73], [34.73], [34.73] ]
a
[ [0], [1], [2], [3], [4], [5] ]
.
Keďže je knižnica NumPy
robená na prácu s
n-dimenzionálnymi poli, toto je jednoduchšie, než sa zdá. Stačí použiť
funkciu reshape()
a zadať žiadaný tvar. Funkciu môžeme zadať
tvar napríklad (32, 2)
, ak veľkosť poľa sedí, teda je
64 => 32 * 2
. Ak funkciu zadáme (-1, 2)
,
automaticky si dopočíta chýbajúce dimenziu, takto možno použiť len na
jednu dimenziu.
Najskôr si zobrazíme tvar x
pred zmenou tvaru:
x.shape
výsledok:
(834,)
Zmeníme tvar x
a y
:
x = x.reshape(-1, 1) y = y.reshape(-1, 1)
A tvary si vypíšeme:
x.shape, y.shape
výsledok:
((834, 1), (834, 1))
Lineárna regresia
Teraz poďme zovšeobecniť pohyb ceny zlata na jednoduchú lineárnu
funkciu. Dáta sú pripravené, vytvoríme si teda
LinearRegression()
a optimalizujeme funkciu pomocou metódy
fit()
:
reg = LinearRegression() reg.fit(x, y)
Pozrieme sa, ako si funkcie vedie pomocou metódy score()
.
reg.score(x, y)
výsledok:
0.6859359867746044
Ako sme asi tušili, také jednoduché to nebude Funkcia si nevedie nejako dobre, to
nám značí, že Cena
nie je tak moc závislá na
Datum
. Vizualizuje si všetko v grafe, aby sme sa presvedčili:
plt.plot(x, reg.predict(x))
plt.scatter(x, y, c="r")
výsledok:
Aj napriek tomu, že funkcia nie je ideálna, bude zaujímavé zistiť, akú
predpovie Cenu
pre dátum 1.7.2025 oproti dnešku. To je podľa
mojich výpočtov index 906
. Cena dnes je:
data["Price"][833]
výsledok:
1358.4879999999998
A cena v roku 2025:
reg.predict([[906]]).item()
výsledok:
1126.481982068847
Náš jednoduchý předpovídač predpovedá, že zlato rozhodne nie je vhodná investícia. O tom či je to pravda, sa ešte dozvieme u polynomiálnej regresie, ktorá si s tým dokáže poradiť lepšie. To všetko sa čoskoro dozviete v nasledujúcich lekciách. V budúcej lekcii, Zjednodušená gradientný metóda optimalizácia lineárna regresia , našu dnešnú predpoveď porovnáme s druhou gradientný metódou lineárnej regresie.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 139x (59.61 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python