IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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:

Vzorec pre predpis lineárnej funkcie - Neurónové siete a deep learning v Pythone

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árom y 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áklade b = 500 jabĺk a výsledok funkcia bude vždy o 500 jabĺk vyššia, bez ohľadu na hodnoty x a y.

Zlato

Prejdime na zaujímavejšie komoditu. Povedzme, že programujeme jednoduchý předpovídač ceny zlata a historické dáta už máme.

Zlaté tehly - Neurónové siete a deep learning v Pythone

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ásledne b
  • Gradientné metóda - U tejto metódy vyberieme a a b 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é
Lineárna regresia v Pythone - Neurónové siete a deep learning v Pythone

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:

Súbory nášho notebooku - Neurónové siete a deep learning v Pythone

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:

Lineárna regresia vývoja ceny zlata v Pythone - Neurónové siete a deep learning v Pythone

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

 

Predchádzajúci článok
Neurónové siete v Pythone - Prostredie Jupyter
Všetky články v sekcii
Neurónové siete a deep learning v Pythone
Preskočiť článok
(neodporúčame)
Zjednodušená gradientný metóda optimalizácia lineárna regresia
Článok pre vás napísal MQ .
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity