You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/sr/7-TimeSeries/2-ARIMA/README.md

405 lines
26 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "917dbf890db71a322f306050cb284749",
"translation_date": "2025-09-05T11:50:36+00:00",
"source_file": "7-TimeSeries/2-ARIMA/README.md",
"language_code": "sr"
}
-->
# Прогнозирање временских серија помоћу ARIMA модела
У претходној лекцији, научили сте нешто о прогнозирању временских серија и учитали скуп података који приказује флуктуације електричног оптерећења током одређеног временског периода.
[![Увод у ARIMA](https://img.youtube.com/vi/IUSk-YDau10/0.jpg)](https://youtu.be/IUSk-YDau10 "Увод у ARIMA")
> 🎥 Кликните на слику изнад за видео: Кратак увод у ARIMA моделе. Пример је урађен у R језику, али су концепти универзални.
## [Квиз пре предавања](https://ff-quizzes.netlify.app/en/ml/)
## Увод
У овој лекцији, открићете специфичан начин за изградњу модела помоћу [ARIMA: *A*uto*R*egressive *I*ntegrated *M*oving *A*verage](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average). ARIMA модели су посебно погодни за податке који показују [неконстантност](https://wikipedia.org/wiki/Stationary_process).
## Општи концепти
Да бисте могли да радите са ARIMA моделима, потребно је да разумете неке основне концепте:
- 🎓 **Стационарност**. У статистичком контексту, стационарност се односи на податке чија се дистрибуција не мења када се помери у времену. Неконстантни подаци показују флуктуације услед трендова који морају бити трансформисани како би се анализирали. На пример, сезоналност може унети флуктуације у податке и може се елиминисати процесом 'сезонског разликовања'.
- 🎓 **[Разликовање](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average#Differencing)**. Разликовање података, у статистичком контексту, односи се на процес трансформисања неконстантних података у константне уклањањем њиховог неконстантног тренда. "Разликовање уклања промене у нивоу временске серије, елиминише тренд и сезоналност и тиме стабилизује средњу вредност временске серије." [Рад Шиксионга и сарадника](https://arxiv.org/abs/1904.07632)
## ARIMA у контексту временских серија
Хајде да разложимо делове ARIMA модела како бисмо боље разумели како нам помаже у моделирању временских серија и прављењу предвиђања.
- **AR - АутоРегресивно**. Ауторегресивни модели, како и само име каже, гледају 'уназад' у времену како би анализирали претходне вредности у вашим подацима и направили претпоставке о њима. Те претходне вредности се називају 'закашњења'. Пример би били подаци који приказују месечну продају оловака. Укупна продаја сваког месеца би се сматрала 'променљивом која се развија' у скупу података. Овај модел се гради тако што се "променљива која нас занима регресира на своје закашњеле (тј. претходне) вредности." [википедија](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average)
- **I - Интегрисано**. За разлику од сличних 'ARMA' модела, 'I' у ARIMA се односи на његов *[интегрисани](https://wikipedia.org/wiki/Order_of_integration)* аспект. Подаци се 'интегришу' када се примењују кораци разликовања како би се елиминисала неконстантност.
- **MA - Покретни Просек**. Аспект [покретног просека](https://wikipedia.org/wiki/Moving-average_model) овог модела односи се на излазну променљиву која се одређује посматрањем тренутних и претходних вредности закашњења.
Суштина: ARIMA се користи за прављење модела који што боље одговара специфичном облику података временских серија.
## Вежба - изградња ARIMA модела
Отворите [_/working_](https://github.com/microsoft/ML-For-Beginners/tree/main/7-TimeSeries/2-ARIMA/working) фасциклу у овој лекцији и пронађите [_notebook.ipynb_](https://github.com/microsoft/ML-For-Beginners/blob/main/7-TimeSeries/2-ARIMA/working/notebook.ipynb) датотеку.
1. Покрените бележницу да учитате Python библиотеку `statsmodels`; биће вам потребна за ARIMA моделе.
1. Учитајте неопходне библиотеке.
1. Сада учитајте још неколико библиотека корисних за визуализацију података:
```python
import os
import warnings
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import datetime as dt
import math
from pandas.plotting import autocorrelation_plot
from statsmodels.tsa.statespace.sarimax import SARIMAX
from sklearn.preprocessing import MinMaxScaler
from common.utils import load_data, mape
from IPython.display import Image
%matplotlib inline
pd.options.display.float_format = '{:,.2f}'.format
np.set_printoptions(precision=2)
warnings.filterwarnings("ignore") # specify to ignore warning messages
```
1. Учитајте податке из `/data/energy.csv` датотеке у Pandas dataframe и погледајте их:
```python
energy = load_data('./data')[['load']]
energy.head(10)
```
1. Прикажите све доступне податке о енергији од јануара 2012. до децембра 2014. Не би требало да буде изненађења јер смо ове податке видели у претходној лекцији:
```python
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
plt.xlabel('timestamp', fontsize=12)
plt.ylabel('load', fontsize=12)
plt.show()
```
Сада, хајде да изградимо модел!
### Креирање скупова за обуку и тестирање
Сада када су ваши подаци учитани, можете их поделити на скупове за обуку и тестирање. Модел ћете обучавати на скупу за обуку. Као и обично, након што модел заврши обуку, проценићете његову тачност користећи скуп за тестирање. Морате осигурати да скуп за тестирање покрива каснији временски период у односу на скуп за обуку како бисте били сигурни да модел не добија информације из будућих временских периода.
1. Доделите двомесечни период од 1. септембра до 31. октобра 2014. скупу за обуку. Скуп за тестирање ће укључивати двомесечни период од 1. новембра до 31. децембра 2014:
```python
train_start_dt = '2014-11-01 00:00:00'
test_start_dt = '2014-12-30 00:00:00'
```
Пошто ови подаци одражавају дневну потрошњу енергије, постоји снажан сезонски образац, али је потрошња најсличнија потрошњи у последњим данима.
1. Визуелизујте разлике:
```python
energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \
.join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \
.plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)
plt.xlabel('timestamp', fontsize=12)
plt.ylabel('load', fontsize=12)
plt.show()
```
![подаци за обуку и тестирање](../../../../7-TimeSeries/2-ARIMA/images/train-test.png)
Дакле, коришћење релативно малог временског прозора за обуку података требало би да буде довољно.
> Напомена: Пошто функција коју користимо за прилагођавање ARIMA модела користи унутар-узорка валидацију током прилагођавања, изоставићемо валидационе податке.
### Припрема података за обуку
Сада треба да припремите податке за обуку тако што ћете извршити филтрирање и скалирање података. Филтрирајте свој скуп података тако да укључује само потребне временске периоде и колоне, а затим извршите скалирање како би подаци били у интервалу 0,1.
1. Филтрирајте оригинални скуп података тако да укључује само претходно наведене временске периоде по скупу и само потребну колону 'load' плус датум:
```python
train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]
test = energy.copy()[energy.index >= test_start_dt][['load']]
print('Training data shape: ', train.shape)
print('Test data shape: ', test.shape)
```
Можете видети облик података:
```output
Training data shape: (1416, 1)
Test data shape: (48, 1)
```
1. Скалирајте податке тако да буду у опсегу (0, 1).
```python
scaler = MinMaxScaler()
train['load'] = scaler.fit_transform(train)
train.head(10)
```
1. Визуелизујте оригиналне и скалиране податке:
```python
energy[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']].rename(columns={'load':'original load'}).plot.hist(bins=100, fontsize=12)
train.rename(columns={'load':'scaled load'}).plot.hist(bins=100, fontsize=12)
plt.show()
```
![оригинални](../../../../7-TimeSeries/2-ARIMA/images/original.png)
> Оригинални подаци
![скалирани](../../../../7-TimeSeries/2-ARIMA/images/scaled.png)
> Скалирани подаци
1. Сада када сте калибрисали скалиране податке, можете скалирати и тест податке:
```python
test['load'] = scaler.transform(test)
test.head()
```
### Имплементација ARIMA модела
Време је да имплементирате ARIMA модел! Сада ћете користити библиотеку `statsmodels` коју сте раније инсталирали.
Сада треба да следите неколико корака:
1. Дефинишите модел позивањем `SARIMAX()` и прослеђивањем параметара модела: p, d, и q параметара, као и P, D, и Q параметара.
2. Припремите модел за скуп података за обуку позивањем функције `fit()`.
3. Направите предвиђања позивањем функције `forecast()` и специфицирањем броја корака (хоризонта) за предвиђање.
> 🎓 Шта значе сви ови параметри? У ARIMA моделу постоје 3 параметра која се користе за моделирање главних аспеката временске серије: сезоналност, тренд и шум. Ови параметри су:
`p`: параметар повезан са ауторегресивним аспектом модела, који укључује *прошле* вредности.
`d`: параметар повезан са интегрисаним делом модела, који утиче на количину *разликовања* (🎓 сећате се разликовања 👆?) која се примењује на временску серију.
`q`: параметар повезан са делом модела који се односи на покретни просек.
> Напомена: Ако ваши подаци имају сезонски аспект - што је овде случај - користимо сезонски ARIMA модел (SARIMA). У том случају треба да користите још један сет параметара: `P`, `D`, и `Q` који описују исте асоцијације као `p`, `d`, и `q`, али се односе на сезонске компоненте модела.
1. Почните тако што ћете подесити вредност хоризонта. Пробајмо 3 сата:
```python
# Specify the number of steps to forecast ahead
HORIZON = 3
print('Forecasting horizon:', HORIZON, 'hours')
```
Одабир најбољих вредности за параметре ARIMA модела може бити изазован јер је донекле субјективан и временски захтеван. Можете размотрити коришћење функције `auto_arima()` из библиотеке [`pyramid`](https://alkaline-ml.com/pmdarima/0.9.0/modules/generated/pyramid.arima.auto_arima.html).
1. За сада пробајте неке ручне изборе како бисте пронашли добар модел.
```python
order = (4, 1, 0)
seasonal_order = (1, 1, 0, 24)
model = SARIMAX(endog=train, order=order, seasonal_order=seasonal_order)
results = model.fit()
print(results.summary())
```
Исписује се табела резултата.
Направили сте свој први модел! Сада треба да пронађемо начин да га евалуирамо.
### Евалуација вашег модела
Да бисте евалуирали свој модел, можете извршити такозвану `walk forward` валидацију. У пракси, модели временских серија се поново обучавају сваки пут када нови подаци постану доступни. Ово омогућава моделу да направи најбољу прогнозу у сваком временском кораку.
Почевши од почетка временске серије, користећи ову технику, обучите модел на скупу података за обуку. Затим направите предвиђање за следећи временски корак. Предвиђање се евалуира у односу на познату вредност. Скуп за обуку се затим проширује тако да укључује познату вредност и процес се понавља.
> Напомена: Требало би да задржите прозор скупа за обуку фиксним ради ефикасније обуке, тако да сваки пут када додате нову опсервацију у скуп за обуку, уклоните опсервацију са почетка скупа.
Овај процес пружа робуснију процену како ће модел функционисати у пракси. Међутим, долази са рачунарским трошковима креирања толико модела. Ово је прихватљиво ако су подаци мали или ако је модел једноставан, али може бити проблем на већем обиму.
`Walk-forward` валидација је златни стандард за евалуацију модела временских серија и препоручује се за ваше пројекте.
1. Прво, креирајте тестну тачку података за сваки корак ХОРИЗОНТА.
```python
test_shifted = test.copy()
for t in range(1, HORIZON+1):
test_shifted['load+'+str(t)] = test_shifted['load'].shift(-t, freq='H')
test_shifted = test_shifted.dropna(how='any')
test_shifted.head(5)
```
| | | load | load+1 | load+2 |
| ---------- | -------- | ---- | ------ | ------ |
| 2014-12-30 | 00:00:00 | 0.33 | 0.29 | 0.27 |
| 2014-12-30 | 01:00:00 | 0.29 | 0.27 | 0.27 |
| 2014-12-30 | 02:00:00 | 0.27 | 0.27 | 0.30 |
| 2014-12-30 | 03:00:00 | 0.27 | 0.30 | 0.41 |
| 2014-12-30 | 04:00:00 | 0.30 | 0.41 | 0.57 |
Подаци се померају хоризонтално у складу са тачком хоризонта.
1. Направите предвиђања за тест податке користећи овај приступ клизног прозора у петљи величине скупа тест података:
```python
%%time
training_window = 720 # dedicate 30 days (720 hours) for training
train_ts = train['load']
test_ts = test_shifted
history = [x for x in train_ts]
history = history[(-training_window):]
predictions = list()
order = (2, 1, 0)
seasonal_order = (1, 1, 0, 24)
for t in range(test_ts.shape[0]):
model = SARIMAX(endog=history, order=order, seasonal_order=seasonal_order)
model_fit = model.fit()
yhat = model_fit.forecast(steps = HORIZON)
predictions.append(yhat)
obs = list(test_ts.iloc[t])
# move the training window
history.append(obs[0])
history.pop(0)
print(test_ts.index[t])
print(t+1, ': predicted =', yhat, 'expected =', obs)
```
Можете пратити процес обуке:
```output
2014-12-30 00:00:00
1 : predicted = [0.32 0.29 0.28] expected = [0.32945389435989236, 0.2900626678603402, 0.2739480752014323]
2014-12-30 01:00:00
2 : predicted = [0.3 0.29 0.3 ] expected = [0.2900626678603402, 0.2739480752014323, 0.26812891674127126]
2014-12-30 02:00:00
3 : predicted = [0.27 0.28 0.32] expected = [0.2739480752014323, 0.26812891674127126, 0.3025962399283795]
```
1. Упоредите предвиђања са стварним оптерећењем:
```python
eval_df = pd.DataFrame(predictions, columns=['t+'+str(t) for t in range(1, HORIZON+1)])
eval_df['timestamp'] = test.index[0:len(test.index)-HORIZON+1]
eval_df = pd.melt(eval_df, id_vars='timestamp', value_name='prediction', var_name='h')
eval_df['actual'] = np.array(np.transpose(test_ts)).ravel()
eval_df[['prediction', 'actual']] = scaler.inverse_transform(eval_df[['prediction', 'actual']])
eval_df.head()
```
Излаз
| | | timestamp | h | prediction | actual |
| --- | ---------- | --------- | --- | ---------- | -------- |
| 0 | 2014-12-30 | 00:00:00 | t+1 | 3,008.74 | 3,023.00 |
| 1 | 2014-12-30 | 01:00:00 | t+1 | 2,955.53 | 2,935.00 |
| 2 | 2014-12-30 | 02:00:00 | t+1 | 2,900.17 | 2,899.00 |
| 3 | 2014-12-30 | 03:00:00 | t+1 | 2,917.69 | 2,886.00 |
| 4 | 2014-12-30 | 04:00:00 | t+1 | 2,946.99 | 2,963.00 |
Посматрајте предвиђања података на сатном нивоу у поређењу са стварним оптерећењем. Колико је тачно?
### Провера тачности модела
Проверите тачност вашег модела тестирањем његове средње апсолутне процентуалне грешке (MAPE) за сва предвиђања.
> **🧮 Покажите ми математику**
>
> ![MAPE](../../../../7-TimeSeries/2-ARIMA/images/mape.png)
>
> [MAPE](https://www.linkedin.com/pulse/what-mape-mad-msd-time-series-allameh-statistics/) се користи за приказивање тачности предвиђања као односа дефинисаног горњом формулом. Разлика између стварне и предвиђене вредности дели се са стварном вредношћу. "Апсолутна вредност у овом израчунавању се сабира за сваку предвиђену тачку у времену и дели са бројем прилагођених тачака n." [википедија](https://wikipedia.org/wiki/Mean_absolute_percentage_error)
1. Изразите једначину у коду:
```python
if(HORIZON > 1):
eval_df['APE'] = (eval_df['prediction'] - eval_df['actual']).abs() / eval_df['actual']
print(eval_df.groupby('h')['APE'].mean())
```
1. Израчунајте MAPE за један корак:
```python
print('One step forecast MAPE: ', (mape(eval_df[eval_df['h'] == 't+1']['prediction'], eval_df[eval_df['h'] == 't+1']['actual']))*100, '%')
```
MAPE за прогнозу једног корака: 0.5570581332313952 %
1. Испишите MAPE за прогнозу више корака:
```python
print('Multi-step forecast MAPE: ', mape(eval_df['prediction'], eval_df['actual'])*100, '%')
```
```output
Multi-step forecast MAPE: 1.1460048657704118 %
```
Добар низак број је најбољи: узмите у обзир да је прогноза са MAPE од 10 погрешна за 10%.
1. Али као и увек, лакше је видети овакву врсту мерења тачности визуелно, па хајде да то прикажемо графички:
```python
if(HORIZON == 1):
## Plotting single step forecast
eval_df.plot(x='timestamp', y=['actual', 'prediction'], style=['r', 'b'], figsize=(15, 8))
else:
## Plotting multi step forecast
plot_df = eval_df[(eval_df.h=='t+1')][['timestamp', 'actual']]
for t in range(1, HORIZON+1):
plot_df['t+'+str(t)] = eval_df[(eval_df.h=='t+'+str(t))]['prediction'].values
fig = plt.figure(figsize=(15, 8))
ax = plt.plot(plot_df['timestamp'], plot_df['actual'], color='red', linewidth=4.0)
ax = fig.add_subplot(111)
for t in range(1, HORIZON+1):
x = plot_df['timestamp'][(t-1):]
y = plot_df['t+'+str(t)][0:len(x)]
ax.plot(x, y, color='blue', linewidth=4*math.pow(.9,t), alpha=math.pow(0.8,t))
ax.legend(loc='best')
plt.xlabel('timestamp', fontsize=12)
plt.ylabel('load', fontsize=12)
plt.show()
```
![модел временске серије](../../../../7-TimeSeries/2-ARIMA/images/accuracy.png)
🏆 Веома леп графикон, који приказује модел са добром тачношћу. Одличан посао!
---
## 🚀Изазов
Истражите начине за тестирање тачности модела временске серије. У овој лекцији смо се дотакли MAPE-а, али да ли постоје други методи које бисте могли користити? Истражите их и додајте белешке. Корисни документ можете пронаћи [овде](https://otexts.com/fpp2/accuracy.html)
## [Квиз након предавања](https://ff-quizzes.netlify.app/en/ml/)
## Преглед и самостално учење
Ова лекција покрива само основе прогнозирања временских серија са ARIMA моделом. Одвојите време да продубите своје знање истражујући [овај репозиторијум](https://microsoft.github.io/forecasting/) и његове различите типове модела како бисте научили друге начине за креирање модела временских серија.
## Задатак
[Нови ARIMA модел](assignment.md)
---
**Одрицање од одговорности**:
Овај документ је преведен коришћењем услуге за превођење помоћу вештачке интелигенције [Co-op Translator](https://github.com/Azure/co-op-translator). Иако тежимо тачности, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не сносимо одговорност за било каква неспоразумевања или погрешна тумачења која могу произаћи из коришћења овог превода.