|
|
<!--
|
|
|
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 модела
|
|
|
|
|
|
У претходној лекцији, научили сте нешто о прогнозирању временских серија и учитали скуп података који приказује флуктуације електричног оптерећења током одређеног временског периода.
|
|
|
|
|
|
[](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()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
Дакле, коришћење релативно малог временског прозора за обуку података требало би да буде довољно.
|
|
|
|
|
|
> Напомена: Пошто функција коју користимо за прилагођавање 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()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
> Оригинални подаци
|
|
|
|
|
|

|
|
|
|
|
|
> Скалирани подаци
|
|
|
|
|
|
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](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()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
🏆 Веома леп графикон, који приказује модел са добром тачношћу. Одличан посао!
|
|
|
|
|
|
---
|
|
|
|
|
|
## 🚀Изазов
|
|
|
|
|
|
Истражите начине за тестирање тачности модела временске серије. У овој лекцији смо се дотакли 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). Иако тежимо тачности, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на изворном језику треба сматрати ауторитативним извором. За критичне информације препоручује се професионални превод од стране људи. Не сносимо одговорност за било каква неспоразумевања или погрешна тумачења која могу произаћи из коришћења овог превода. |