IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - Předpověď ceny zlata pomocí lineární regrese v Pythonu

V minulé lekci, Neuronové sítě v Pythonu - Prostředí Jupyter, jsme si představili prostředí Jupyter notebook pro Python.

Vítejte u další lekce, dnes si zkusíme předpovídat data pomocí lineární regrese a pracovat s .csv soubory pomocí knihovny Pandas. Jak víte, než se dostaneme k neuronkám nám ještě chvíli potrvá :)

Lineární regrese

Určitě se mnozí z vás setkali s tímto vzorečkem:

Vzorec pro předpis lineární funkce - Neuronové sítě - Základy

Je to předpis lineární funkce. Tyto funkce jsou nám lidem velmi blízké a také jednoduché na pochopení.

Jablka

Představme si např. úlohu na sběr jablek v sadu. 1 farmář sebere 200 jablek za hodinu. x farmářů sebere y = ax jablek za hodinu, v našem případě se a = 200. Máme zde jednoduchý lineární vztah mezi x a y.

  • Koeficient a je sklon funkce, čím více jeden formář dokáže jablek sebrat, tím více nám s každým farmářem y povyroste.
  • b je tzv. bias (tento výraz rozebereme později u neuronových sítích) a dovoluje funkci posun, aby se lépe přizpůsobila datům. Můžeme např. říci, že ve skladu je již v základu b = 500 jablek a výsledek funkce bude vždy o 500 jablek vyšší, bez ohledu na hodnoty x a y.

Zlato

Přejděme na zajímavější komoditu. Řekněme, že programujeme jednoduchý předpovídač ceny zlata a historická data již máme.

Zlaté cihly - Neuronové sítě - Základy

Pro předpověď potřebujeme vytvořit přímku tak, aby prošla co nejvíce body v datasetu (jednoduše soubor dat, který chceme předpovídat) a tedy odpovídala co nejpřesněji tomu, jak cena zlata roste nebo klesá. Právě pomocí lineární regrese zjednodušíme velké množství bodů (cen zlata v daný okamžik) na pouhou přímku, čímž samozřejmě ztratíme určitou přesnost. Této metodě "osekání" nějaké složité funkce na podobnou jednodušší funkci se v matematice obecně říká aproximace.

Abychom lineární funkci přizpůsobili, potřebujeme ji takzvaně "optimalizovat". To se týká proměnných a a b, jelikož x je vstup (v tomto případě čas). Ukážeme si 2 způsoby, jak můžeme funkci optimalizovat:

  • Dopočítání z dat - Spočítáme sklon a a následně b
  • Gradientní metoda - U této metody vybereme a a b náhodně a postupně je podle námi definované chybové funkce optimalizujeme, dokud není chyba co nejmenší

Výpočet ceny zlata v Pythonu

Nyní již známe vzorec pro lineární funkci a můžeme si tedy ukázat jednoduchý příklad v Pythonu. Spusťme si prostředí, které jsme si představili v minulé lekci, a dle potřeby si vytvořme nový notebook.

Import knihoven

Nejdříve je potřeba importovat knihovny s kterými budeme pracovat:

from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

Zjednodušený příklad

Než se vrhneme na reálné ceny zlata, začneme jednodušším příkladem.

Vstupní a výstupní data

Pro ukázku si definujeme jednoduchý příklad: Chceme výstup o 2 větší než vstup. V tomto případě chceme sklon a = 1 a bias b = 2.

Funkci můžeme rychle ověřit při vstupu 3:

  • y = 1 * 3 + 2
  • y = 5

V kódu pro tyto hodnoty definujeme vstupní a výstupní data, čímž nasimulujeme podobný případ jako se zlatem - máme hodnoty před a po změně, ale nevíme vzoreček, jakým změny předpovídat. Budeme se tedy snažit uhádnout naši lineární funkci:

# 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

Data jsou připravena, nyní si můžeme vytvořit Regressor neboli lineární funkci a optimalizovat ji na naše data:

# Vytvoříme regressor neboli lineární funkci
reg = LinearRegression()
# Optimalizujeme
reg.fit(x, y)

Metodě fit() jednoduše předáme vstupní a výstupní data a ona zjistí vztah mezi nimi. Jak si funkce vede ověříme pomocí metody score().

reg.score(x, y)

Výsledek:

1

Metoda vrátila výsledek 1, což znamená, že mezi x a y je vysoká korelace neboli vztah. Když x stoupá, y také stoupá, přesněji o 2. Zjednodušeně to znamená, že naše funkce protíná všechny body, jak i uvidíte dále v grafu.

Vytvoříme si tedy graf pro vizualizaci funkce, kterou zjišťujeme, a bodů, které již máme z dat:

# 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ární regrese v Pythonu - Neuronové sítě - Základy

Vidíme, že metoda predict() nám zobrazila přímku odpovídající změně našich dat. Metoda scatter() na ni pak dále vykreslila body, v našem případě jen dva.

Zobrazíme si sklon a bias funkce a ověříme si tak, že jsme měli pravdu:

a = reg.coef_
b = reg.intercept_
print("Sklon je {} a bias je {}".format(a, b))

Výsledkem jsou opravdu koeficienty lineární funkce, podle které jsme data vytvořili:

Sklon je [[1.]] a bias je [2.]

Zlato!

Už umíme předpovídat data za pomoci knihovny scikit-learn, proto se vrhneme na příklad s reálnými daty o ceně zlata.

Příprava reálných dat

Ještě předtím než začneme, potřebujeme data. Ta můžeme stáhnout např. zde : https://pkgstore.datahub.io/…thly_csv.csv. Stažený .csv soubor přesuneme do složky s aktuálním .ipynb notebookem. Pokud nevíte, kde se nachází, přesuňte se na předchozí záložku v prohlížeči a tam bude běžící notebook označen zeleně:

Soubory našeho notebooku - Neuronové sítě - Základy

Výtečně, soubor monthly_csv.csv máme v naší pracovní složce a můžeme se tedy vrhnout na tvorbu předpovídače.

Importy

Importujeme si tedy ještě knihovnu Pandas pro čtení dat z .csv, naše prvotní importy ponecháme:

import pandas as pd

Čtení dat

Přečteme data ze souboru a zobrazíme si hlavičku neboli prvních 5 řádků .csv souboru:

data = pd.read_csv("monthly_csv.csv")
data.head()

Výsledek:

    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

Jak můžeme vidět, dataset obsahuje 2 vlastnosti: Datum a Cenu. Datum budeme reprezentovat jako počet měsíců od 1.1.1950, což je začátek datasetu. V den, kdy jsem tento článek psal, je maximální index 833, což je 1.6.2019.

Vstupy a výstupy

Připravíme si tedy opět 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()

Data ještě musíme převést do tvaru, který funkce fit() požaduje, což je (vzorek, vlastnosti). My zatím máme jen (hodnoty).

Představte si vzorek jako člověka a hodnoty jako nějaké jeho vlastnosti, jako např. výška a váha. Vstup by v tomto případě vypadal takto: [ [173, 71] ]. Pokud bychom chtěli více lidí, vypadal by vstup takto: [ [173, 71], [183, 86] ].

My tedy potřebujeme převést Cena a Datum na tento tvar, jelikož zatím mají tvar: [34.73, 34.73, 34.73, 34.73, 34.73] a [0, 1, 2, 3 4, 5]. Náš požadovaný tvar vypadá takto: [ [34.73], [34.73], [34.73], [34.73], [34.73] ] a [ [0], [1], [2], [3], [4], [5] ].

Jelikož je knihovna NumPy dělaná na práci s n-dimenzionálními poli, toto je jednodušší, než se zdá. Stačí použít funkci reshape() a zadat žádaný tvar. Funkci můžeme zadat tvar například (32, 2), pokud velikost pole sedí, tedy je 64 => 32 * 2 . Pokud funkci zadáme (-1, 2), automaticky si dopočítá chybějící dimenzi, takto lze použít pouze na jednu dimenzi.

Nejdříve si zobrazíme tvar x před změnou tvaru:

x.shape

Výsledek:

(834,)

Změní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ýsledek:

((834, 1), (834, 1))

Lineární regrese

Nyní pojďme zobecnit pohyb ceny zlata na jednoduchou lineární funkci. Data jsou připravená, vytvoříme si tedy LinearRegression() a optimalizujeme funkci pomocí metody fit():

reg = LinearRegression()
reg.fit(x, y)

Podíváme se, jak si funkce vede pomocí metody score().

reg.score(x, y)

Výsledek:

0.6859359867746044

Jak jsme asi tušili, tak jednoduché to nebude :) Funkce si nevede nějak dobře, to nám značí, že Cena není tak moc závislá na Datum. Vizualizujeme si vše v grafu, abychom se přesvědčili:

plt.plot(x, reg.predict(x))
plt.scatter(x, y, c="r")

Výsledek:

Lineární regrese vývoje ceny zlata v Pythonu - Neuronové sítě - Základy

I přesto, že funkce není ideální, bude zajímavé zjistit, jakou předpoví Cenu pro datum 1.7.2025 oproti dnešku. To je dle mých výpočtů index 906. Cena dnes je:

data["Price"][833]

Výsledek:

1358.4879999999998

A cena v roce 2025:

reg.predict([[906]]).item()

Výsledek:

1126.481982068847

Náš jednoduchý předpovídač předpovídá, že zlato rozhodně není vhodná investice. O tom zda je to pravda, se ještě dozvíme u polynomiální regrese, která si s tím dokáže poradit lépe. To vše se brzy dozvíte v následujících lekcích.

V následujícím kvízu, Kvíz - Základy neuronových sítí v Pythonu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 135x (59.61 kB)
Aplikace je včetně zdrojových kódů v jazyce Python

 

Předchozí článek
Neuronové sítě v Pythonu - Prostředí Jupyter
Všechny články v sekci
Neuronové sítě - Základy
Přeskočit článek
(nedoporučujeme)
Kvíz - Základy neuronových sítí v Pythonu
Článek pro vás napsal MQ .
Avatar
Uživatelské hodnocení:
52 hlasů
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity