پیشبینی سری زمانی چیست؟ آموزش عملی با Python، SARIMA و Prophet
پیشبینی فروش یا تعداد درخواستهای روزانه را از کجا شروع کنیم؟ در این آموزش، سری زمانی، روند و فصلمندی را میشناسید و با Python سه روش پیشبینی فصلی ساده، SARIMA و Prophet را روی داده مستقل مقایسه میکنید.
یک فروشگاه میخواهد بداند هفته آینده روزانه چند سفارش دریافت میکند. یک تیم پشتیبانی میخواهد تعداد درخواستهای ماه آینده را تخمین بزند. یک سرویس آنلاین نیز باید برای افزایش مصرف در روزهای خاص آماده باشد.
وجه مشترک این مسائل، ترتیب زمانی دادهها است. مقدار امروز ممکن است با دیروز، همان روز هفته قبل، تعطیلات و تغییرات بلندمدت مرتبط باشد. اگر هنگام آموزش و ارزیابی این ترتیب را نادیده بگیریم، ممکن است مدلی بسازیم که روی کاغذ خوب عمل میکند اما در پیشبینی آینده قابل اتکا نیست.
Time Series Forecasting یا پیشبینی سری زمانی یعنی استفاده از مشاهدات گذشته و اطلاعاتی که در زمان پیشبینی واقعاً در دسترساند، برای تخمین مقدارهای آینده.
در این مقاله، ابتدا مفاهیم و شیوه ارزیابی را بررسی میکنیم. سپس با یک مثال کامل در Python، سه روش را روی دادهای یکسان مقایسه میکنیم:
- پیشبینی فصلی ساده یا Seasonal Naive
- مدل آماری SARIMA
- کتابخانه Prophet
در پایان، بر اساس داده اعتبارسنجی مدل را انتخاب میکنیم و عملکرد آن را روی بازه آزمون مستقل میسنجیم.
سری زمانی چیست؟
سری زمانی مجموعهای از اندازهگیریهاست که به ترتیب زمان ثبت شدهاند. برای مثال:
| تاریخ | تعداد درخواست پشتیبانی |
|---|---|
| شنبه | ۱۳۸ |
| یکشنبه | ۱۵۱ |
| دوشنبه | ۱۴۶ |
| سهشنبه | ۱۴۲ |
داده میتواند در فاصلههای زمانی متفاوت ثبت شود:
- هر دقیقه: تعداد درخواستAPI
- هر ساعت: مصرف برق
- هر روز: تعداد سفارش
- هر هفته: درخواستهای پشتیبانی
- هر ماه: فروش یک محصول
قبل از مدلسازی باید بدانید هر ردیف دقیقاً نماینده چه بازهای است و عدد هدف در چه زمانی نهایی میشود.
برای نمونه، اگر تعداد سفارش روزانه تا پایان روز تغییر میکند، ساعت ۱۰ صبح نمیتوانید «تعداد نهایی سفارش همان روز» را بهعنوان ورودی قطعی در اختیار مدل بگذارید.
اجزای مهم یک سری زمانی
سطح یاLevel
سطح، مقدار معمول داده در یک بازه است. اگر تعداد درخواستها بیشتر روزها حدود ۱۰۰ باشد، میتوان گفت سری در آن دوره سطحی نزدیک به ۱۰۰ دارد.
روند یاTrend
روند، تغییر تدریجی سطح در طول زمان است. رشد تعداد کاربران ممکن است میانگین درخواستهای روزانه را در چند ماه افزایش دهد.
روند همیشه صعودی یا خطی نیست. ممکن است پس از یک تغییر محصول، سطح داده ناگهان جابهجا شود.
فصلمندی یاSeasonality
فصلمندی به الگویی گفته میشود که با دورهای نسبتاً منظم تکرار میشود. مثالها:
- تفاوت روزهای هفته
- تغییرات هر ساعت شبانهروز
- تفاوت ماههای سال
- افزایش ترافیک در مناسبتهای تکرارشونده
«فصلی» در این اصطلاح فقط به چهار فصل سال اشاره ندارد. الگویی که هر هفت روز تکرار شود نیز فصلمندی محسوب میشود.
رویدادهای خاص
تعطیلات، کمپینهای فروش، تغییر قیمت، اختلال سرویس یا عرضه محصول جدید میتوانند مقدار سری را تغییر دهند. برخی از این رویدادها از قبل معلوماند و برخی تنها پس از وقوع شناخته میشوند.
نویز
بخشی از تغییرات داده ممکن است با اطلاعات موجود قابل توضیح یا پیشبینی نباشد. انتظار حذف کامل این بخش از خطا واقعبینانه نیست.
پیشبینی یکمرحلهای و چندمرحلهای
پیش از انتخاب مدل، افق پیشبینی را مشخص کنید:
- پیشبینی فردا
- پیشبینی هفت روز آینده
- پیشبینی سی روز آینده
- پیشبینی مقدار هر ساعت در ۴۸ ساعت بعد
پیشبینی فردا و پیشبینی یک ماه آینده یک مسئله یکسان نیستند. هرچه افق بلندتر شود، معمولاً عدم قطعیت بیشتری وارد پیشبینی میشود.
همچنین باید مشخص کنید آیا قرار است هر روز مدل را با داده تازه بهروزرسانی کنید، یا امروز یکباره همه سی روز آینده را پیشبینی کنید. روش ارزیابی باید همین شرایط عملیاتی را بازنمایی کند.
چرا تقسیم تصادفی Train و Test برای سری زمانی مناسب نیست؟
در بسیاری از مسائل یادگیری ماشین، ردیفها بهصورت تصادفی میان Train و Test تقسیم میشوند. برای پیشبینی آینده، این کار میتواند باعث شود مدل از دادههای بعدی برای پیشبینی دادههای قبلی استفاده کند.
تقسیم مناسبتر معمولاً چنین است:
| بخش | ترتیب زمانی | کاربرد |
|---|---|---|
| Train | دوره قدیمیتر | آموزش مدل |
| Validation | دوره بعد از Train | مقایسه روشها و تنظیمات |
| Test | جدیدترین دوره کنارگذاشتهشده | ارزیابی نهایی |
برای نمونه، اگر داده تا پایان شهریور در اختیار دارید، میتوانید روی ماههای قدیمیتر آموزش دهید، روی مرداد روشها را مقایسه کنید و شهریور را برای آزمون نهایی نگه دارید؛ البته مرز دقیق به حجم داده، فصلمندی و هدف استفاده وابسته است.
ابزار TimeSeriesSplit در scikit-learn نیز برای اعتبارسنجی دادههای مرتبشده زمانی طراحی شده است تا آموزش روی آینده و آزمون روی گذشته رخ ندهد. scikit-learn.org
پیش از مدل پیچیده، یک مبنای ساده بسازید
اگر داده شما الگوی هفتگی دارد، یک مبنای اولیه این است:
مقدار دوشنبه آینده را برابر مقدار آخرین دوشنبه مشاهدهشده پیشبینی کنید.
به این روش Seasonal Naive یا پیشبینی فصلی ساده میگویند.
این روش روند رشد و رویدادهای تازه را بهخوبی مدل نمیکند، اما مزیت بزرگی دارد: نشان میدهد مدل پیچیدهتر واقعاً نسبت به یک راهحل بسیار ساده چه بهبودی ایجاد میکند.
کتاب Forecasting: Principles and Practice نیز پیشبینی فصلی ساده را یکی از روشهای پایه برای دادههای دارای فصلمندی معرفی میکند. otexts.com
ARIMA و SARIMAچیست؟
ARIMA خانوادهای از مدلهای آماری برای پیشبینی سری زمانی است. این مدل از رابطه مقدارهای گذشته، تغییرات سری و خطاهای پیشبینی قبلی استفاده میکند.
وقتی الگوی فصلی تکرارشونده نیز وارد مدل شود، با شکل فصلی آن یعنی SARIMA روبهرو هستیم. برای مثال، در داده روزانهای که تفاوت روزهای هفته مهم است، دوره فصلی میتواند هفت روز باشد.
در Python میتوان از کلاس SARIMAX کتابخانه statsmodels برای ساخت این مدل استفاده کرد. این کلاس علاوه بر مؤلفههای فصلی، امکان استفاده از بعضی متغیرهای بیرونی را نیز فراهم میکند. مستندات رسمی آن پارامتر seasonal_order را برای تعیین ساختار فصلی معرفی میکند. statsmodels.org
انتخاب تنظیمات SARIMA باید بر اساس داده و ارزیابی زمانی انجام شود. هیچ ترکیبی از تنظیمات برای همه سریهای زمانی بهترین نیست.
Prophetچیست؟
Prophet ابزار متنبازی برای پیشبینی سری زمانی است که امکان مدلسازی روند، فصلمندی و برخی اثرهای تقویمی را فراهم میکند.
در رابط Python آن، داده آموزش معمولاً شامل دو ستون است:
ds: تاریخ یا زمانy: مقدار مشاهدهشده
پس از آموزش، متد predict برای تاریخهای موردنظر خروجیای شامل مقدار پیشبینیشده yhat برمیگرداند. این ساختار در راهنمای رسمی Prophet توضیح داده شده است. Prophet
Prophet میتواند گزینهای مناسب برای آزمایش باشد، اما نام ابزار یا سهولت استفاده تضمین نمیکند از مبنای ساده یا SARIMAدقیقتر باشد. مقایسه باید روی بازههای زمانی مستقل انجام شود.
آموزش عملی پیشبینی سری زمانی باPython
برای اجرای مثال بدون دریافت فایل بیرونی، یک سری روزانه ساختگی میسازیم. داده دارای سه بخش است:
- روند تدریجی
- الگوی هفتگی
- تغییرات کوتاهتر و نویز
این داده صرفاً برای آموزش کد و روش ارزیابی است. نتیجه آن نشاندهنده عملکرد مدلها روی فروش یا ترافیک واقعی نیست.
نصب کتابخانهها
pip install numpy pandas matplotlib scikit-learn statsmodels prophetنصب Prophet ممکن است بسته به سیستمعامل و محیط Python به وابستگیهای بیشتری نیاز داشته باشد. در صورت خطای نصب، راهنمای رسمی همان کتابخانه را برای نسخه محیط خود بررسی کنید.
ساخت سری زمانی
import numpy as npimport pandas as pdimport matplotlib.pyplot as pltRANDOM_STATE = 42rng = np.random.default_rng( RANDOM_STATE)number_of_days = 480dates = pd.date_range( start="2025-01-01", periods=number_of_days, freq="D",)day_number = np.arange( number_of_days)trend = ( 100 + 0.04 * day_number)weekly_pattern = ( 15 * np.sin( 2 * np.pi * day_number / 7 )فرمولها فقط داخل کد آمدهاند تا مثال قابلاجرا باشد. برای دنبالکردن مقاله نیازی به محاسبه دستی آنها ندارید.
مشاهده داده
plt.figure( figsize=(12, 4))plt.plot( series.index, series.values,)plt.title( "Daily observed volume")plt.xlabel("Date")plt.ylabel("Volume")plt.tight_layout()plt.show()در نمودار به موارد زیر توجه کنید:
- آیا سطح داده در طول زمان تغییر میکند؟
- آیا الگوی تکراری دیده میشود؟
- آیا پرش ناگهانی یا دورههای غیرعادی وجود دارد؟
- آیا بعضی روزها داده ثبت نشده است؟
در داده واقعی، پاسخ به این پرسشها پیش از انتخاب مدل اهمیت زیادی دارد.
تفکیک زمانی Train، Validation وTest
در این مثال:
- ۳۶۰ روز نخست برای آموزش
- ۶۰ روز بعد برای اعتبارسنجی
- ۶۰ روز پایانی برای آزمون نهایی
استفاده میشود.
train = series.iloc[:360]validation = series.iloc[ 360:420]test = series.iloc[ 420:]print( "Train:", train.index.min(), "to", train.index.max(),)print( "Validation:", validation.index.min(), "to", validation.index.max(),)print( "Test:", test.index.min(), "to", test.index.max(),)مرزهای این تقسیم برای آموزش انتخاب شدهاند. در کاربرد واقعی، طول هر بخش باید با دورههای فصلی، افق پیشبینی و تعداد دورههایی که میخواهید ارزیابی کنید هماهنگ باشد.
روش اول: پیشبینی فصلی ساده
برای پیشبینی هر روز آینده، مقدار همان موقعیت در آخرین چرخه هفتروزه مشاهدهشده را تکرار میکنیم.
def seasonal_naive_forecast( history: pd.Series, future_index: pd.DatetimeIndex, season_length: int = 7,) -> pd.Series: if len(history) < season_length: raise ValueError( "History is shorter " "than one seasonal cycle." ) last_cycle = ( history .iloc[ -season_length: ] .to_numpy() ) predictions = np.resize( last_cycle, len(future_index), ) return pd.Series( predictions, index=future_index, name="seasonal_naive", )naive_validation = ( seasonal_naive_forecast( train, validation.index, season_length=7,چون train درست پیش از validation پایان مییابد و فاصلهها روزانه و منظماند، تکرار آخرین هفت مشاهده با روزهای متناظر هفته آینده همتراز میشود.
اگر در داده واقعی روزهای ثبتنشده دارید، پیش از استفاده از این کد باید تقویم و فاصلههای زمانی را بررسی کنید.
روش دوم: SARIMA باstatsmodels
اکنون یک مدل SARIMA با دوره فصلی هفتروزه میسازیم:
from statsmodels.tsa.statespace.sarimax import ( SARIMAX,)def sarima_forecast( history: pd.Series, future_index: pd.DatetimeIndex,) -> pd.Series: fitted = SARIMAX( history, order=(1, 1, 1), seasonal_order=( 1, 0, 0, 7, ), enforce_stationarity=False, enforce_invertibility=False, ).fit( disp=False ) predictions = ( fitted.forecast( steps=len( future_index ) ) ) return pd.Series( np.asarray( predictions ),این تنظیمات فقط یک نقطه شروع آموزشی هستند. برای داده واقعی باید ساختار روند و فصلمندی، رفتار باقیماندهها، پایداری مدل و عملکرد روی چند بازه اعتبارسنجی بررسی شود.
مستندات پیشبینی statsmodels نیز استفاده از روشهای forecast و get_forecast را برای پیشبینی بیرون از بازه آموزش توضیح میدهد. statsmodels 0.15.1 (+81)
روش سوم:Prophet
برای Prophet، داده را به قالب ds و y تبدیل میکنیم. چون هدف مثال بررسی الگوی هفتگی است، فصلمندی هفتگی را فعال و فصلمندی سالانه را غیرفعال میکنیم.
from prophet import Prophetdef prophet_forecast( history: pd.Series, future_index: pd.DatetimeIndex,) -> pd.Series: training_frame = ( history .rename_axis("ds") .reset_index( name="y" ) ) model = Prophet( weekly_seasonality=True, yearly_seasonality=False, daily_seasonality=False, ) model.fit( training_frame ) future_frame = pd.DataFrame( { "ds": future_index } ) prediction_frame = ( model.predict( future_frame ) )در این مثال، هر سه روش تمام ۶۰ روز Validation را از انتهای Train پیشبینی میکنند. در طول این افق، مقدارهای واقعی Validation برای بهروزرسانی پیشبینی در اختیار هیچیک قرار نمیگیرد. یکسان بودن این شرایط برای مقایسه منصفانه مهم است.
اگر در محصول هر روز مقدار جدید را دریافت و پیشبینی را بهروزرسانی میکنید، باید یک ارزیابی جداگانه برای آن سناریوی «پیشبینیِ بهروزشونده» طراحی کنید.
ارزیابی با MAE وRMSE
برای سنجش خطا از دو معیار استفاده میکنیم:
- MAE: میانگین بزرگی خطاها در واحد خود داده؛ برای گزارش عملی معمولاً قابلفهم است.
- RMSE: به خطاهای بزرگ حساسیت بیشتری دارد.
برای یک سری زمانی واحد، این معیارها امکان مقایسه روشها روی همان بازه و همان واحد را فراهم میکنند. کتاب Forecasting: Principles and Practice نیز ویژگیها و محدودیتهای معیارهای رایج دقت پیشبینی را بررسی میکند. Forecasting: Principles and Practice (3rd ed)
from sklearn.metrics import ( mean_absolute_error, mean_squared_error,)def evaluate_forecast( actual: pd.Series, predicted: pd.Series,) -> dict: if not actual.index.equals( predicted.index ): raise ValueError( "Actual and forecast " "dates do not match." ) mae = mean_absolute_error( actual, predicted, ) rmse = np.sqrt( mean_squared_error( actual, predicted, ) ) return { "MAE": float(mae), "RMSE": float(rmse), }عددهای خروجی را از اجرای خودتان به دست آورید. پیشاپیش فرض نکنید Prophet یا SARIMA از پیشبینی فصلی ساده بهتر است؛ همین مقایسه هدف آزمایش است.
چرا از MAPE استفاده نکردیم؟
MAPEخطا را بهصورت درصدی گزارش میکند، اما وقتی مقدار واقعی صفر یا نزدیک صفر باشد، تفسیر آن دشوار یا ناپایدار میشود.
اگر شمارش درخواستها ممکن است در بعضی روزها صفر باشد، MAE معمولاً برای شروع انتخاب سادهتری است. برای مقایسه چند سری با مقیاسهای متفاوت، معیارهای مقیاسزداییشده مانند MASE نیز قابل بررسیاند؛ البته باید مبنای مقایسه و نحوه محاسبه آن روشن باشد. Forecasting: Principles and Practice (3rd ed)
نمایش پیشبینیهایValidation
plt.figure(
figsize=(13, 5)
)
plt.plot(
train.index[-45:],
train.iloc[-45:],
label="Recent training data",
)
plt.plot(
validation.index,
validation.values,
label="Observed validation",
linewidth=2,
)
for name, forecast in (
validation_forecasts.items()
):
plt.plot(
forecast.index,
forecast.values,
label=name,
alpha=0.85,
)
plt.title(
"Forecast comparison "
"on validation period"
)
plt.xlabel("Date")
plt.ylabel("Volume")
plt.legend()
plt.tight_layout()
plt.show()نمودار را فقط برای انتخاب «زیباترین خط» استفاده نکنید. به شکل خطاها توجه کنید:
- آیا مدل در روزهای خاص هفته بیشتر اشتباه میکند؟
- آیا خطا با دورشدن از انتهای Train بیشتر میشود؟
- آیا روند رشد را جا میاندازد؟
- آیا جهشهای کوتاهمدت را بیش از حد دنبال میکند؟
انتخاب مدل رویValidation
مدلی را که کمترین MAE روی Validation دارد انتخاب میکنیم:
best_name = min( validation_results, key=lambda name: ( validation_results[ name ]["MAE"] ),)print( "Selected method:", best_name,)در اینجا معیار انتخاب از ابتدا مشخص است. اگر هدف عملی شما به خطاهای بزرگ حساستر است، میتوانید RMSE یا معیار متناسبتری را پیش از مشاهده نتیجه انتخاب کنید.
اختلاف بسیار کوچک میان دو روش روی یک بازه ۶۰ روزه ممکن است پایدار نباشد. برای تصمیم مهم، بهتر است روشها را روی چند مبدأ پیشبینی و چند بازه زمانی نیز مقایسه کنید.
ارزیابی نهایی رویTest
پس از انتخاب روش، Train و Validation را بهعنوان تاریخچه موجود تا آغاز Test کنار هم قرار میدهیم. سپس روش انتخابشده را دوباره روی این تاریخچه آموزش میدهیم و ۶۰ روز Test را یکباره پیشبینی میکنیم.
history_before_test = ( pd.concat( [ train, validation, ] ))if best_name == "Seasonal Naive": test_forecast = ( seasonal_naive_forecast( history_before_test, test.index, season_length=7, ) )elif best_name == "SARIMA": test_forecast = ( sarima_forecast( history_before_test, test.index, ) )elif best_name == "Prophet": test_forecast = ( prophet_forecast( history_before_test, test.index, ) )else:این ارزیابی مستقل است، چون:
- روش را با Validation انتخاب کردیم.
- هنگام انتخاب، مقدارهای Test را ندیدیم.
- پیشبینی Test فقط از دادههای پیش از آغاز Test استفاده میکند.
پس از دیدن نتیجه Test نباید بارها روشها را تغییر دهیم و همچنان همان Test را آزمون مستقل بنامیم.
نمایش نتیجه نهایی
plt.figure(
figsize=(12, 5)
)
plt.plot(
history_before_test.index[-60:],
history_before_test.iloc[-60:],
label="Observed history",
)
plt.plot(
test.index,
test.values,
label="Observed test",
linewidth=2,
)
plt.plot(
test_forecast.index,
test_forecast.values,
label=(
f"Forecast: {best_name}"
),
)
plt.title(
"Final forecast "
"on independent test period"
)
plt.xlabel("Date")
plt.ylabel("Volume")
plt.legend()
plt.tight_layout()
plt.show()اگر مدل در روزهای نخست خوب و در هفتههای بعد ضعیف است، ممکن است افق ۶۰ روزه برای روش انتخابشده طولانی باشد. آن را جدا از خطای میانگین بررسی کنید.
اعتبارسنجی با چند مبدأ پیشبینی
یک Validation ثابت، فقط رفتار مدل را در یک دوره نشان میدهد. در پروژه واقعی بهتر است چند بار شرایط استفاده را شبیهسازی کنید:
- تا یک تاریخ مشخص آموزش دهید.
- بازه بعدی را پیشبینی کنید.
- مبدأ را جلو ببرید.
- آموزش و پیشبینی را تکرار کنید.
- خطا را در همه بازهها گزارش کنید.
به این روش معمولاً Backtesting یا ارزیابی با مبدأهای پیشبینی متحرک گفته میشود. کتاب Forecasting: Principles and Practice این رویکرد را برای ارزیابی سریهای زمانی توضیح میدهد. Forecasting: Principles and Practice (3rd ed)
در طراحی Backtesting دو حالت مهم وجود دارد:
- پنجره گسترشیابنده: همه دادههای قدیمی تا مبدأ جدید در آموزش باقی میمانند.
- پنجره لغزان: فقط یک دوره اخیر از داده برای آموزش استفاده میشود.
اگر رفتار سامانه در زمان تغییر میکند، پنجره لغزان ممکن است ارزش بررسی داشته باشد. انتخاب آن باید با آزمایش انجام شود.
نشت داده در پیشبینی سری زمانی
در مقاله نشت داده در یادگیری ماشین دیدیم که ارزیابی چگونه میتواند از اطلاعات نامجاز تأثیر بگیرد. در سری زمانی، این خطر بهخصوص مهم است.
نمونههای رایج عبارتاند از:
- محاسبه میانگین متحرک با استفاده از روزهای پس از زمان پیشبینی
- جایگزینی داده گمشده با آماری محاسبهشده از کل دوره، شامل آینده
- تنظیم مقیاس روی Train و Test با هم
- ساخت متغیر «فروش نهایی ماه» برای پیشبینی فروش روزهای میانی همان ماه
- تقسیم تصادفی دادههایی که قرار است آینده را پیشبینی کنند
- استفاده از مقدار واقعی روزهای Test برای پیشبینی روزهای بعدی Test، در حالی که سناریوی عملی اجازه آن را نمیدهد
یک قاعده مفید این است که برای هر ویژگی بنویسید در لحظه صدور پیشبینی چه زمانی واقعاً قابل دسترسی میشود.
داده گمشده و روزهای بدون مشاهده
«ثبتنشدن مقدار» و «واقعاً صفر بودن مقدار» یکسان نیستند.
اگر در یک روز هیچ درخواست پشتیبانی ثبت نشده باشد، مقدار میتواند صفر باشد. اما اگر سامانه ثبت داده از کار افتاده باشد، مقدار واقعی نامعلوم است. تبدیل خودکار هر مقدار گمشده به صفر میتواند الگوهای ساختگی بسازد.
پیش از مدلسازی بررسی کنید:
- آیا همه تاریخهای مورد انتظار حضور دارند؟
- آیا زمانها در یک منطقه زمانی ثبت شدهاند؟
- تغییر ساعت یا تبدیل منطقه زمانی چه اثری بر داده ساعتی دارد؟
- آیا داده دیرهنگام اصلاح میشود؟
- روزهای بدون رویداد باید صفر باشند یا مقدار گمشده؟
در داده روزانه مربوط به ایران نیز باید مراقب باشید تاریخ عملیاتی کسبوکار، تقویم گزارشگیری و تاریخ ذخیرهشده در پایگاه داده با هم هماهنگ باشند.
تعطیلات و مناسبتها در پیشبینی داده ایران
تعطیلات رسمی، مناسبتهای متغیر و الگوی روزهای کاری میتوانند روی سفارشها، تماسها و ترافیک اثر بگذارند. اگر این اثر برای مسئله شما مهم است، تقویم رویدادها را از منبع معتبر و متناسب با سال مورد بررسی تهیه کنید.
دو نکته اجرایی اهمیت دارند:
- تاریخ رویداد باید برای روز آینده مورد پیشبینی از قبل معلوم باشد.
- تبدیل تاریخ شمسی و میلادی باید دقیق و در کل مسیر داده یکسان باشد.
مدل Prophet امکان تعریف تعطیلات و فصلمندیهای سفارشی را دارد، اما کیفیت پیشبینی به درستی داده تقویمی و ارزیابی مستقل وابسته است. Prophet
برای تعطیلات متغیر، تاریخ سال قبل را بدون بررسی به سال بعد تعمیم ندهید.
متغیرهای بیرونی یاExogenous Features
گاهی گذشته خود سری برای پیشبینی کافی نیست. اطلاعاتی مانند موارد زیر ممکن است مفید باشد:
- برنامه قطعی کمپینهای آینده
- تقویم تعطیلات
- قیمت برنامهریزیشده
- تعداد شعب فعال طبق برنامه
- اطلاعات آبوهوایی پیشبینیشده
اما باید تفاوت میان مقدار واقعی آینده و اطلاعاتی که امروز درباره آینده داریم روشن باشد.
برای مثال، اگر مقدار واقعی دمای فردا را فقط پسفردا میدانید، استفاده از آن در آزمایش امروز نشت اطلاعات است. در عمل باید از پیشبینی دمایی استفاده کنید که در زمان صدور پیشبینی در اختیار بوده است و خطای همان پیشبینی را هم بپذیرید.
بازه عدم قطعیت پیشبینی
یک عدد مانند «فردا ۱۵۰ درخواست» تمام داستان نیست. برای برنامهریزی ظرفیت ممکن است لازم باشد بدانید چه دامنهای از مقادیر محتمل است.
برخی ابزارها بازه پیشبینی ارائه میکنند، اما این بازهها به فرضهای مدل وابستهاند. بازه Prophet نیز مطابق مستندات رسمی، با فرضهایی درباره عدم قطعیت روند، فصلمندی و نویز ساخته میشود. Prophet
بازه را فقط به دلیل نمایش توسط کتابخانه معتبر ندانید. روی داده مستقل بررسی کنید چه سهمی از مقدارهای واقعی داخل بازه قرار میگیرند و آیا پهنای آن برای تصمیم عملی مفید است.
SARIMA یا Prophet؛ کدام را انتخاب کنیم؟
| پرسش | SARIMA | Prophet |
|---|---|---|
| تمرکز اصلی | ساختار آماری سری و وابستگیهای زمانی | روند، فصلمندی و رویدادهای تقویمی |
| فصلمندی | با تنظیم دوره و ساختار فصلی | با فصلمندیهای داخلی یا سفارشی |
| تنظیمات | انتخاب ساختار مدل مهم است | تنظیم روند، فصلمندی و رویدادها مهم است |
| متغیر بیرونی | در SARIMAX قابل استفاده است | امکان افزودن متغیر کمکی دارد |
| معیار نهایی انتخاب | عملکرد روی چند بازه مستقل | عملکرد روی چند بازه مستقل |
در برخی دادهها یک مبنای ساده از هر دو بهتر عمل میکند. روش انتخاب باید از هزینه خطا و ارزیابی واقعی شروع شود، نه از شهرت ابزار.
آیا مدلهای یادگیری ماشین و یادگیری عمیق بهترند؟
مدلهای دیگری نیز برای سری زمانی استفاده میشوند:
- رگرسیون با ویژگیهای تأخیری
- Random Forest و Gradient Boosting
- XGBoost و LightGBM
- شبکههای بازگشتی
- Transformerهای ویژه سری زمانی
برخی از این روشها وقتی چندین سری مرتبط، ویژگی بیرونی معتبر یا داده فراوان دارید ارزش بررسی پیدا میکنند. اما پیچیدگی بیشتر لزوماً خطای کمتر ایجاد نمیکند.
برای مقایسه منصفانه، همه مدلها باید:
- یک افق پیشبینی داشته باشند.
- به اطلاعات یکسان در لحظه پیشبینی دسترسی داشته باشند.
- روی بازههای زمانی یکسان ارزیابی شوند.
- با همان معیارهای از پیش تعیینشده سنجیده شوند.
اشتباهات رایج در پیشبینی سری زمانی
مقایسه مدلها بدونBaseline
اگر مدل پیچیده از تکرار مقدار هفته قبل بهتر نیست، ابتدا باید فهمید چرا. شاید داده کافی نیست، ویژگیهای مهم موجود نیستند یا افق پیشبینی بیش از حد بلند است.
تقسیم تصادفی تاریخها
چنین تقسیمی ممکن است شرایط واقعی «آموزش روی گذشته، پیشبینی آینده» را نقض کند.
مقایسه افقهای متفاوت
خطای پیشبینی فردا را با خطای پیشبینی کل ماه آینده مقایسه نکنید، مگر تعریف دقیق مسئله و روش ارزیابی یکسان باشد.
نادیده گرفتن تغییر ساختاری
افت ناگهانی پس از تغییر محصول یا قیمت ممکن است با تنظیم جزئی مدل حل نشود. ابتدا خود تغییر فرایند تولید داده را بررسی کنید.
استفاده از متغیر آیندهای که واقعاً معلوم نیست
داشتن آن ستون در دیتاست تاریخی به معنای در دسترس بودنش در لحظه پیشبینی نیست.
فرض ثابت بودن تقویم
در بسیاری از کسبوکارها، تفاوت روزهای کاری، تعطیلات و کمپینها بخش مهمی از الگوی سری است.
تفسیر بیش از حد یک بازه آزمون
ممکن است یک روش در یک ماه بهتر و در ماه دیگر ضعیفتر باشد. چند مبدأ پیشبینی را ارزیابی کنید.
گزارش فقط خطای میانگین
خطای میانگین ممکن است شکست مدل در روزهای پرترافیک یا رویدادهای مهم را پنهان کند.
پرسشهای متداول
پیشبینی سری زمانی چیست؟
استفاده از مشاهدههای گذشته و اطلاعات مجاز در زمان پیشبینی برای تخمین مقدارهای آینده یک متغیر است.
تفاوت ARIMA و SARIMA چیست؟
SARIMA شکل فصلی خانواده ARIMAاست و برای مدلسازی الگوهای تکرارشونده با دوره مشخص استفاده میشود.
Prophetچیست؟
Prophetکتابخانهای برای پیشبینی سری زمانی است که ابزارهایی برای مدلسازی روند، فصلمندی و رویدادهای تقویمی ارائه میدهد.
آیا Prophet همیشه از ARIMA بهتر است؟
خیر. برتری هر روش به داده، افق پیشبینی، تنظیمات و معیار ارزیابی وابسته است. هر دو را با روش پایه روی بازههای زمانی مستقل مقایسه کنید.
چرا باید از Seasonal Naive شروع کنیم؟
چون مبنایی ساده و قابلفهم میدهد. مدل پیچیده باید نشان دهد نسبت به تکرار آخرین الگوی فصلی بهبود معناداری دارد.
بهترین معیار ارزیابی سری زمانی چیست؟
یک معیار جهانی وجود ندارد. MAE برای فهم میانگین خطا در واحد اصلی مفید است؛ RMSE به خطاهای بزرگ حساستر است. معیار را متناسب با پیامد عملی اشتباه انتخاب کنید.
برای پیشبینی روزانه به چند ماه داده نیاز داریم؟
به دورههای تکرارشوندهای بستگی دارد که میخواهید مدل یاد بگیرد. برای ارزیابی اثر سالانه، چند هفته داده کافی نیست. مهمتر از یک عدد ثابت، داشتن تاریخچهای است که الگوهای مورد انتظار و چند بازه ارزیابی مستقل را پوشش دهد.
آیا مدل میتواند تعطیلات ایران را در نظر بگیرد؟
بله، اگر تاریخ درست رویدادها و شیوه اثرگذاری آنها در مدل تعریف شود. تقویم سال موردنظر و تبدیل تاریخها را باید با دقت بررسی کرد.
آیا سری زمانی با مدل زبانی پیشبینی میشود؟
مدل زبانی میتواند در توضیح گزارشها و تولید متن تحلیلی کمک کند، اما برای پیشبینی عددی باید کیفیت آن را در کنار روشهای تخصصی و مبناهای ساده روی داده مستقل ارزیابی کرد.
جمعبندی
پیشبینی سری زمانی از تعریف دقیق مسئله آغاز میشود: چه مقداری، برای چه افقی و با چه اطلاعاتی در لحظه پیشبینی باید تخمین زده شود؟
در مثال عملی، ابتدا یک سری روزانه ساختیم و داده را به ترتیب زمان به Train، Validation و Test تقسیم کردیم. سپس پیشبینی فصلی ساده، SARIMA و Prophet را روی افق یکسان مقایسه کردیم. انتخاب روش با Validation انجام شد و Test برای ارزیابی نهایی باقی ماند.
در پروژه واقعی، کیفیت داده، تقویم، نشت اطلاعات آینده، تغییرات ساختاری و عملکرد روی چند بازه زمانی به اندازه انتخاب نام مدل اهمیت دارند. یک روش پیچیده تنها وقتی ارزش عملی دارد که نسبت به مبنای ساده، بهبود قابل اتکا و متناسب با هزینه اجرا ایجاد کند.
از پیشبینی عددی تا گزارش قابل استفاده
خروجی یک مدل پیشبینی زمانی مفید میشود که تیم بتواند بر اساس آن تصمیم بگیرد: چه ظرفیتی آماده کند، کدام روزها را دقیقتر پایش کند و چه زمانی پیشبینی نیازمند بازبینی انسان است.
اگر در کنار مدل پیشبینی، به ابزارهای هوش مصنوعی برای توضیح گزارشها، ساخت رابط پرسشوپاسخ یا توسعه قابلیتهای هوشمند محصول نیاز دارید، خدمات و زیرساخت درواره را در darvareh.ir بررسی کنید.
مقالات مرتبط
- نشت داده در یادگیری ماشین و پیشگیری باPipeline
- اعتبارسنجی متقاطع و K-Fold درPython
- تحلیل داده باPandas
- آموزش scikit-learn باPython
- مهندسی ویژگی و انتخاب ویژگی
- بیشبرازش و کمبرازش در یادگیری ماشین
- ارزیابی مدل هوش مصنوعی وEvals
- MLOps و LLMOpsچیست؟
منابع
- Forecasting: Principles and Practice —روشهای ساده پیشبینی otexts.com
- Forecasting: Principles and Practice —ارزیابی دقت پیشبینی Forecasting: Principles and Practice (3rd ed)
- Forecasting: Principles and Practice —اعتبارسنجی سری زمانی Forecasting: Principles and Practice (3rd ed)
- مستندات statsmodels برایSARIMAX statsmodels.org
- مستندات statsmodels درباره پیشبینی خارج از نمونه statsmodels 0.15.1 (+81)
- راهنمای شروع رسمیProphet Prophet
- مستندات TimeSeriesSplit درscikit-learn scikit-learn.org
این مقاله صرفاً با هدف آموزش و اطلاعرسانی تهیه شده است. پیش از استفاده عملی، مستندات رسمی ابزارها و صفحه سلب مسئولیت درواره را مطالعه کنید.