Curs
Să zicem că faci prognoze pentru cererea lunară de electricitate. Ai un model ARIMA solid care surprinde autocorelația și tendința seriei. Apoi lovește un val de căldură și prognoza ta dă greș cu 15%. Seria nu s-a schimbat; vremea s-a schimbat. Exact pentru astfel de situații a fost creat ARIMAX: prognoza seriilor temporale când factorii externi explică la fel de multă variație ca istoria proprie a seriei.
Vom acoperi ce este ARIMAX, cum diferă de ARIMA și SARIMAX și când are sens să folosești unul sau altul. Vom parcurge și o implementare completă în Python, de la pregătirea datelor la potrivirea modelului, diagnostic și evaluarea prognozelor, ca să poți aplica ce ai învățat.
Ce este ARIMAX?
ARIMAX vine de la AutoRegressive Integrated Moving Average with eXogenous variables. Este un model ARIMA care acceptă și intrări externe, adică predictori din afara seriei-țintă. Exemple care îți vin în minte: cheltuieli de publicitate, temperatură, indicatori de promoție, rate ale dobânzii.
Notația generală este ARIMAX(p, d, q) cu unul sau mai mulți regresori exogeni. Parametrii p, d și q au același înțeles ca în ARIMA: ordinul autoregresiv, gradul de diferențiere și ordinul mediei mobile. „X” înseamnă că poți furniza coloane suplimentare despre care crezi că influențează ținta. Un aspect de semnalat: unele pachete software implementează ARIMAX ca regresie cu erori ARIMA, nu tratând variabilele externe ca intrări AR directe. Distincția e subtilă matematic, dar contează pentru interpretarea coeficienților. Vom reveni la asta când analizăm rezultatul din statsmodels.
Cum funcționează ARIMAX
ARIMAX combină două lucruri: memoria seriei însăși și puterea explicativă a variabilelor externe.
Componentelor AR, I și MA
Componenta AR (autoregresivă) folosește valorile decalate ale seriei-țintă pentru a prezice valoarea curentă. Dacă vânzările de luna trecută au fost mari, contează.
Componenta I (integrată) diferențiază seria pentru a elimina tendințele sau rădăcinile unitare, făcând-o staționară.
Componenta MA (medie mobilă) folosește erorile de prognoză trecute pentru a corecta greșelile sistematice pe care le face modelul.
Împreună, aceste trei elemente gestionează multe dintre cauzele tipice ale unei serii temporale: tendințe, cicluri și autocorelație în reziduuri.
Unde intervin variabilele exogene
Variabilele exogene aduc informații pe care istoria seriei nu le poate furniza. Dacă faci prognoza vânzărilor, vânzările trecute îți arată tiparele obișnuite. Dar o reducere de preț sau intrarea unui competitor pe piață reprezintă informații noi. Modelul estimează un coeficient pentru fiecare predictor extern în timp ce ține cont simultan de autocorelația din erori.
Iată interpretarea practică: dacă seria-țintă este bine explicată de propriile valori trecute și nu ai predictori externi de încredere, un ARIMA simplu este probabil suficient. Dar când știi că intervin factori externi și când vei avea efectiv valori viitoare ale acelor predictori disponibile, ARIMAX tinde să ofere prognoze mai precise.
ARIMA vs. ARIMAX vs. SARIMAX
SARIMAX construiește pe baza SARIMA adăugând variabile exogene. În practică, majoritatea implementărilor ARIMAX în Python folosesc SARIMAX() din statsmodels, cu ordinul sezonier setat la zero.
Nu e un artificiu. E abordarea standard. SARIMAX este o primă alegere bună când seria ta are un tipar sezonier clar sau când ai nevoie de regresori externi; gestionează ambele situații elegant. Un avertisment: „ARIMAX” și „SARIMAX” nu sunt interschimbabile în toate bibliotecile. În unele pachete, SARIMAX fără termeni sezonieri și ARIMAX sunt identice funcțional. În altele, diferă prin modul în care variabilele exogene intră în verosimilitate. Verifică documentația instrumentului pe care îl folosești.
Când să folosești ARIMAX
De obicei totul se reduce la un lucru: ai predictori externi care probabil influențează ținta și vei avea valorile lor viitoare la momentul prognozei?
Situații în care ARIMAX aduce valoare
Cazuri bune includ prognoza vânzărilor cu indicatori de promoție sau schimbări de preț, cererea de energie cu intrări de temperatură, traficul pe site cu cheltuieli de campanie și indicatori economici alături de date despre ratele dobânzii. În fiecare caz, variabila externă oferă informații pe care seria nu le poate genera singură.
Un ARIMA simplu poate fi suficient când predictorii externi nu sunt disponibili, nu sunt fiabili sau pur și simplu nu îmbunătățesc acuratețea out-of-sample. Adăugarea de predictori care introduc zgomot fără semnal nu ajută. Mai multe intrări nu garantează prognoze mai bune. Evaluează orice predictor propus pe date separate înainte de a te baza pe el.
Un cuvânt despre cauzalitate
O relație între un predictor și țintă nu stabilește cauzalitatea. ARIMAX este un cadru de prognoză; estimează asocieri. Dacă cheltuielile de publicitate corelează cu vânzările pentru că ambele cresc în decembrie, modelul poate surprinde asta, dar nu îți va spune că publicitatea a cauzat creșterea. Distincția contează dacă folosești prognozele pentru a lua decizii, nu doar pentru a prezice rezultate. Merită să fii explicit despre asta când prezinți rezultatele.
Cum să construiești un model ARIMAX în Python
Să trecem la implementare.
Vom folosi un exemplu reproductibil: vânzări lunare de înghețată (unități vândute) cu temperatura (°C) și un indicator de promoție ca predictori exogeni. Setul de date acoperă 48 de luni, împărțite în 36 pentru antrenare și 12 pentru evaluare.
Pregătește datele
Începe prin a încărca sau construi un DataFrame cu un index de date lunar consistent. Identifică variabila-țintă și coloanele exogene, apoi aliniază totul după dată. Gestionează valorile lipsă înainte de împărțire. Nu imputa peste granița train/test, deoarece introduce scurgeri de informație.
Regula de reținut de la început: orice valori exogene furnizezi în antrenare, vei avea nevoie de echivalentele lor viitoare la momentul prognozei. Dacă nu poți obține prognoze de temperatură viitoare, nu poți folosi temperatura ca predictor. Nu e un detaliu minor; descalifică mulți candidați.
import pandas as pd
import numpy as np
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.tsa.stattools import adfuller
from sklearn.metrics import mean_absolute_error
# Construct a sample monthly dataset
np.random.seed(42)
dates = pd.date_range(start="2020-01", periods=48, freq="MS")
temperature = 15 + 10 * np.sin(np.linspace(0, 4 * np.pi, 48)) + np.random.normal(0, 1, 48)
promotion = np.where((np.arange(48) % 6 == 0), 1, 0)
sales = (
500
+ 8 * temperature
+ 150 * promotion
+ np.cumsum(np.random.normal(0, 10, 48))
)
df = pd.DataFrame({"sales": sales, "temperature": temperature, "promotion": promotion}, index=dates)
# Train/test split
train = df.iloc[:36]
test = df.iloc[36:]
Scalarea nu este de obicei necesară pentru estimarea în statsmodels, dar ajută la stabilitatea numerică atunci când predictorii sunt pe scări foarte diferite. Dacă să scalezi sau nu ține de judecata ta.
Verifică seria și predictorii
Înainte de a alege parametrii, inspectează vizual seria-țintă și rulează un test de staționaritate. Testul Augmented Dickey-Fuller (ADF) este standard. Un p-value sub 0,05 sugerează că seria e staționară și probabil nu necesită diferențiere (d=0). Dacă seria are o tendință clară, de obicei setezi d=1. Testele sunt un input; contează și cunoașterea domeniului și inspecția vizuală.
Verifică și predictorii: sunt aliniați cu ținta? Există vreo șansă ca un predictor să fie măsurat după data prognozei? Un indicator de promoție setat înainte de începutul lunii e în regulă. Venitul din acea lună nu.
Alege parametrii candidați și potrivește modelul
Graficele ACF și PACF ajută la sugerarea valorilor candidate pentru p și q. Un vârf semnificativ la lagul 1 în PACF cu ACF în descreștere sugerează adesea AR(1); inversul sugerează MA(1). Compară un set mic de candidați folosind AIC sau BIC pe datele de antrenare și păstrează setul de test doar pentru evaluarea finală.
# Fit ARIMAX(1,1,1) via SARIMAX with no seasonal order
exog_train = train[["temperature", "promotion"]]
exog_test = test[["temperature", "promotion"]]
model = SARIMAX(
train["sales"],
exog=exog_train,
order=(1, 1, 1),
seasonal_order=(0, 0, 0, 0),
trend="n"
)
result = model.fit(disp=False)
print(result.summary())
Ieșirea summary() arată coeficienții ARIMA alături de coeficienții variabilelor exogene. Coeficientul pentru temperatură îți spune cu cât este asociată o creștere de un grad în temperatură cu o schimbare în nivelul vânzărilor, după ce structura autoregresivă ține cont de inerția seriei. Un lucru util: statsmodels folosește o formulare de tip regresie cu erori ARIMA, ceea ce înseamnă că diferențierea (d=1) se aplică procesului de eroare, nu ecuației de regresie. Coeficientul reprezintă efectul asupra nivelului vânzărilor indiferent de d. Într-o formulare ARIMAX de tip funcție de transfer (folosită de unele alte pachete), d=1 ar însemna că coeficienții reflectă efecte asupra schimbărilor, nu asupra nivelurilor. Această distincție creează confuzii, așa că merită verificată documentația instrumentului folosit.
Verifică reziduurile și evaluează prognozele
Reziduurile ar trebui să arate ca un zgomot alb. Verifică graficul ACF al reziduurilor pentru orice autocorelație rămasă. Vârfurile semnificative înseamnă că modelul ratează structură. Dacă vezi tipare sistematice la laguri sezoniere, treci la SARIMAX cu un ordin sezonier.
# Generate out-of-sample predictions
predictions = result.forecast(steps=12, exog=exog_test)
# Evaluate
mae = mean_absolute_error(test["sales"], predictions)
# Naive baseline: forecast each period using the previous period's actual value
naive_forecast = np.concatenate([[train["sales"].iloc[-1]], test["sales"].values[:-1]])
naive_mae = mean_absolute_error(test["sales"], naive_forecast)
print(f"ARIMAX MAE: {mae:.1f}")
print(f"Naive MAE: {naive_mae:.1f}")
Compară MAE-ul ARIMAX cu un punct de referință naiv (folosind valoarea perioadei anterioare ca prognoză). Dacă ARIMAX nu depășește modelul naiv pe setul tău de test, e un rezultat semnificativ. Complexitatea adăugată nu se justifică. Am văzut asta întâmplându-se mai des decât te-ai aștepta, mai ales când predictorii exogeni sunt mai zgomotoși decât par în eșantion.
Prognozează valori viitoare
Prognozarea dincolo de perioada de antrenare funcționează la fel ca evaluarea out-of-sample: furnizezi valori exogene viitoare împreună cu apelul forecast(). Pentru indicatorii de promoție, de obicei e simplu, deoarece cunoști dinainte calendarul promoțional. Pentru temperatură, de regulă folosești o prognoză meteo sau medii sezoniere istorice.
Clarificare: intervalele de încredere returnate de statsmodels sunt condiționate de valorile predictorilor pe care le furnizezi. Ele nu iau în calcul incertitudinea acelor predictori. Dacă prognoza ta de temperatură este incertă, incertitudinea reală a prognozei este mai mare decât sugerează intervalele. Merită comunicat dacă prezinți rezultate cuiva care ar putea acționa pe baza lor.
Provocări și limitări comune
Implementarea de mai sus acoperă scenariul fericit. Iată unde lucrurile tind să se complice.
- Predictorii viitori pot fi necunoscuți: Acesta este cel mai comun obstacol practic. Dacă nu poți obține în mod fiabil valori viitoare ale variabilelor exogene, nu le poți folosi. Prognozarea cererii de energie cu temperatura de mâine necesită o prognoză a temperaturii, nu pe cea de ieri.
- Predictorii pot scurge informații: O variabilă măsurată după data prognozei poate face ca evaluarea in-sample să arate mult mai bine decât este în realitate. Fii atent la ce mărci temporale corespund de fapt predictorilor tăi.
- Relațiile se pot schimba: Coeficienții estimați pe date istorice pot să nu se mențină pe viitor. O elasticitate a prețului stabilă timp de doi ani se poate schimba după un șoc de piață, iar 2024 și 2025 au produs destule astfel de șocuri ca să nu mai pară teoretic. Re-estimarea periodică a modelului este o practică bună.
- Predictorii corelați complică interpretarea: Intrările puternic coliniare pot face estimările coeficienților individuali instabile. Asta nu strică întotdeauna acuratețea prognozei, dar îngreunează identificarea predictorului care „muncește”.
- Mai multe intrări nu garantează prognoze mai bune: Evaluează fiecare predictor propus față de un baseline pe date ținute deoparte. Unele caracteristici care par informative in-sample adaugă zgomot out-of-sample.
- Sezonalitatea are nevoie de termeni sezonieri: Dacă seria ta are un tipar sezonier consistent, cum ar fi vânzări lunare cu un vârf în decembrie, SARIMAX cu un ordin sezonier este alegerea corectă. ARIMAX singur nu îl va surprinde.
- Cauzalitatea nu este stabilită: Merită repetat: ARIMAX este un cadru de prognoză, nu o metodă de inferență cauzală. Nu folosi semnele coeficienților pentru a susține afirmații cauzale fără analize suplimentare.
Concluzie
ARIMAX își câștigă locul când ai factori externi care chiar influențează ținta și poți furniza valorile lor viitoare la momentul prognozei. Este o extensie firească a ARIMA, nu un înlocuitor. Dacă seria ta este bine comportată și nu ai predictori de încredere, ARIMA simplu este de obicei punctul de pornire mai bun. Adăugarea de variabile dă impresia de progres. Uneori nu este.
Fluxul de lucru se reduce la patru lucruri făcute bine:
- aliniază corect predictorii,
- verifică scurgerile înainte de evaluare,
- validează pe date cu adevărat ținute deoparte și
- compară întotdeauna cu un baseline simplu.
Un model ARIMAX care abia îl depășește pe cel naiv nu e mai bun decât un model naiv. Doar e mai scump.
Dacă vrei să aprofundezi fundamentele seriilor temporale, cursul nostru Time Series Analysis in Python acoperă în detaliu ARIMA, staționaritatea și diagnosticele. Pentru partea de statsmodels, cursul nostru Introduction to Regression with statsmodels in Python construiește intuiția statistică de care ai nevoie când interpretezi sumarizările modelului și verifici reziduurile.
Vinod Chugani și-a început cariera la Tokyo ca cel mai tânăr șef al desk-ului de vânzări pentru fonduri speculative al JPMorgan, iar ulterior a stabilit un record individual de vânzări la Lehman Brothers, apoi a construit o afacere de distribuție de electronice în 30 de țări care a depășit SG$100 de milioane în venituri, înainte de a se orienta către date. Absolvent de Economie la Duke și alumn al NYC Data Science Academy, a fost unul dintre cei trei beneficiari ai bursei din peste 100 de candidați pentru cursul lui Hugo Bowne-Anderson, Building AI Applications, pe Maven. Astăzi, scrie pentru DataCamp, KDnuggets, Machine Learning Mastery și Statology despre subiecte de la statistică la IA agențială și îndrumă profesioniști în domeniul datelor la NYC Data Science Academy, cu peste 1.000 de sesiuni unu-la-unu la activ.
Întrebări frecvente
Care este diferența dintre ARIMAX și ARIMA?
ARIMA face prognoze pentru o serie-țintă folosind doar propriile valori trecute și erorile de prognoză trecute. ARIMAX extinde acest lucru prin încorporarea variabilelor exogene — intrări externe precum temperatura, promoțiile sau ratele dobânzii — despre care se crede că influențează ținta. Dacă acești factori externi chiar determină variația în seria ta și poți furniza valorile lor viitoare, ARIMAX va produce de obicei prognoze mai bune decât ARIMA singur.
Cum diferă ARIMAX de SARIMAX?
ARIMAX gestionează variabile externe, dar nu tipare sezoniere. SARIMAX adaugă termeni sezonieri AR, diferențiere și MA peste ARIMAX, fiind alegerea corectă când seria ta are o structură sezonieră recurentă. În statsmodels pentru Python, ARIMAX este de obicei implementat prin SARIMAX() cu ordinul sezonier setat la (0, 0, 0, 0). Funcțional, sunt același model în acea configurație.
Trebuie să furnizez valori viitoare ale variabilelor exogene pentru a face prognoze cu ARIMAX?
Da — aceasta este una dintre cele mai importante constrângeri practice. Când generezi prognoze dincolo de perioada de antrenare, trebuie să furnizezi valori pentru fiecare variabilă exogenă la fiecare pas de timp viitor. Pentru indicatori de promoții sau sărbători, de obicei e simplu. Pentru variabile precum temperatura sau prețurile mărfurilor, vei avea nevoie de valori prognozate sau de presupuneri rezonabile, ceea ce introduce incertitudine suplimentară.
Cum aleg p, d și q pentru un model ARIMAX?
Începe cu graficele ACF și PACF ale seriei (diferențiate). Un vârf semnificativ la lagul 1 în PACF și un ACF în decădere sugerează adesea AR(1); tiparul invers sugerează MA(1). Folosește cunoștințele de domeniu și testul ADF pentru a determina d. Apoi compară un set mic de combinații candidate (p, d, q) folosind AIC sau BIC pe datele de antrenare. Evită folosirea setului de test în această etapă — el trebuie folosit doar pentru evaluarea finală.
Ce înseamnă coeficientul unei variabile exogene într-un model ARIMAX?
Coeficientul reprezintă schimbarea estimată în nivelul seriei-țintă asociată cu o creștere de o unitate a acelui predictor, după ce se ține cont de structura autoregresivă. În statsmodels, acest lucru e valabil chiar și când d=1, deoarece diferențierea se aplică procesului de eroare, nu ecuației de regresie (formulare de tip regresie cu erori ARIMA). Unele alte pachete folosesc o formulare de tip funcție de transfer, unde d=1 ar face ca coeficienții să reflecte efecte asupra schimbărilor, nu asupra nivelurilor, așa că verifică documentația instrumentului tău. Interpretarea poate deveni dificilă și când predictorii sunt pe scări diferite sau corelați între ei, deci merită să standardizezi intrările atunci când vrei să compari coeficienții.
Cum detectez și gestionez multicoliniaritatea în predictorii exogeni?
Calculează Variance Inflation Factor (VIF) pentru fiecare predictor înainte de potrivire. Valori peste 10 sugerează coliniaritate problematică. Dacă o găsești, încearcă să elimini predictorul cel mai puțin justificat teoretic sau combină variabilele corelate într-un compozit. Coliniaritatea ridicată nu va afecta neapărat acuratețea prognozei, dar face coeficienții individuali nesiguri și greu de interpretat.
Cum ar trebui să evaluez dacă ARIMAX chiar adaugă valoare?
Compară întotdeauna cu un baseline simplu — o prognoză naivă (folosind valoarea perioadei anterioare) este un punct de pornire bun. Dacă ARIMAX nu o depășește pe date de test ținute deoparte, modelul nu își justifică complexitatea. MAE și RMSE sunt ambele metrici rezonabile; MAE este mai ușor de explicat stakeholderilor. Rulează comparația pe un set de test adecvat, care nu a fost folosit niciodată pentru selectarea parametrilor.
Când ar trebui să folosesc SARIMAX în loc de ARIMAX?
Folosește SARIMAX când seria ta arată un tipar sezonier consistent — vânzări lunare cu un vârf în decembrie, trafic web săptămânal cu un vârf lunea și așa mai departe. SARIMAX adaugă componente sezoniere AR, diferențiere și MA pe care ARIMAX nu le are. Din moment ce statsmodels pentru Python implementează oricum ARIMAX prin SARIMAX(), întrebarea practică este doar dacă să setezi un ordin sezonier diferit de zero. Dacă reziduurile arată autocorelație semnificativă la laguri sezoniere după potrivirea ARIMAX, e un semnal să adaugi termeni sezonieri.
