آمار، داده کاوی ۲۷۰۳ بازدید

در طبیعت و دنیای اطراف ما، پدیده‌هایی وجود دارند که با طول زمان دچار تغییر می‌شوند. این تغییرات می‌تواند به عوامل مختلفی وابسته باشد. گاهی ممکن است یک روند صعودی (یا نزولی) در تغییرات مربوط به ویژگی‌های یک پدیده مشاهده شود یا تغییرات فصلی باعث پدید آمدن تفاوت و اختلاف شود. هدف تحلیل سری زمانی، تشخیص یا ایجاد یک مدل سری زمانی است که در آن، بخش تصادفی و بخش غیرتصادفی از یکدیگر جدا شده و قابل تشخیص شوند، بطوری که بتوان آینده آن پدیده تصادفی را به طور کلی مشخص کرد. از شیوه‌های جداسازی بخش تصادفی از غیرتصادفی، می‌توان به هموارسازی نمایی سری زمانی (Smoothing) اشاره کرد. هموارسازی نمایی سری زمانی تکنیکی است که به کمک آن هموارسازی صورت گرفته و داده‌های مربوط به گذشته، رفته رفته نقش کمتری در محاسبه میانگین خواهند داشت. این سیر نزولی به صورت نمایی تغییر کرده و در نتیجه به آن هموارسازی نمایی می‌گویند.

برای آشنایی بیشتر با مدل‌های سری زمانی و مفاهیم اولیه آن بهتر است نوشتار سری زمانی در علم داده — از صفر تا صد و تحلیل سری زمانی — تعریف و مفاهیم اولیه را مطالعه کنید. همچنین خواندن نوشتار سری زمانی در SPSS — راهنمای کاربردی و تحلیل سری زمانی با پایتون — معرفی انواع مدل ها نیز خالی از لطف نیست.

هموارسازی نمایی سری زمانی

به منظور مشخص کردن وضعیت داده‌های سری زمانی باید بخش تصادفی را از بخش غیرتصادفی جدا کرد. به این منظور باید مدل را ایستا (Stationary) نمود به این معنی که روند و تغییرات دیگری که ماهیت تصادفی ندارند را از داده‌ها خارج کرد. چنین عملی را هموارسازی (Smoothing) می‌نامند.

هموارسازی نمایی سری زمانی با میانگین متحرک (Exponentially Weighted Moving Average) یا EWMA، یک روش برای محاسبه میانگین از مقادیر، به طور پیوسته است. به این معنی که با ورود یک متغیر جدید، میانگین نیز تغییر خواهد یافت. اثر تغییری که مقدار جدید به میانگین وارد می‌کند به صورت «تابع نمایی کاهشی» (Decreasing Exponentially) از زمان است. به این معنی که اثر داده‌های دورتر روی میانگین متحرک کمتر و اثر داده‌های اخیر روی میانگین متحرک بیشتر است و این اثر به صورت نمایی تغییر می‌کند.

از مزایای استفاده از هموارسازی نمایی سری زمانی با میانگین متحرک می‌توان به سادگی و سرعت انجام محاسبات اشاره کرد.

در الگوریتم‌های EWMA از یک فاکتور کاهنده (Decay Factor) استفاده می‌شود که با علامت $$\alpha$$‌ مشخص می‌شود. هر چه $$\alpha$$ بزرگتر باشد، اهمیت و نقش داده‌های اخیر در تعیین و پیش‌بینی مقدارهای آینده بیشتر شده و اثر داده‌های گذشته کمرنگ‌تر می‌شود. این فاکتور مقداری در بازه $$(0,1)$$ دارد.

الگوریتم محاسباتی برای EWMA به شکل زیر خواهد بود.

  1. مقدار $$x_t$$ را در مقدار $$\alpha$$ ضرب کنید.
  2. مقدار میانگین متحرک در زمان $$t-1$$ را در $$(1-\alpha)$$ ضرب کنید.
  3. حاصل جمع مرحله ۱ و ۲ را به عنوان مقدار زمان سری زمانی هموار شده در $$t$$ در نظر بگیرید.
  4. عملیات را از مرحله ۱ تکرار نمایید.

فرض کنید که یک سری زمانی با ۵ مشاهده دارید که برحسب زمان در نمودار زیر ترسیم شده‌اند.

step one EWMA

فرض کنید مقدار $$\alpha$$ برابر با $$0.5$$ در نظر گرفته شده است. می‌خواهیم مراحل هموارسازی میانگین متحرک را روی این داده‌ها اجرا کنیم.

در گام اول مشخص است که میانگین متحرک، همان مقدار اول است زیرا مشاهداتی قبل از آن وجود ندارد.

step one EWMA

با گرفتن میانگین وزنی با وزن $$\alpha$$ بین مقدار مربوط به مشاهده اول و دوم، دومین نقطه هموارسازی ایجاد می‌شود.

step two EWMA

ارتفاع ستون جدید در نمودار، مقدار هموار شده را نشان می‌دهد. از آنجایی که سهم مشاهده اول و دوم در محاسبه این میانگین یکسان است، ارتفاع این مستطیل به طور مساوی بین دو رنگ قرمز پررنگ و کم‌رنگ تقسیم شده است.

حال نقطه سوم الی آخر را برای مقادیر هموار شده محاسبه و در نمودار ترسیم می‌کنیم. رنگ هر قسمت در ستون مربوط به نقاط هموار شده بیانگر سهم آن نقطه در محاسبه میانگین متحرک است.

steps of EWMA

همانطور که مشخص است، سهم مشاهده اول که با رنگ قرمز پررنگ مشخص شده، در محاسبه نقاط هموار شده با روش هموارسازی نمایی میانگین متحرک به صورت نمایی رو به کاهش است. از طرفی در نقطه آخر، سهم مشاهده پنجم، نصف سهم بقیه نقاط است.

در تصویر زیر این تغییر نمایی برای وزن یا اثر مشاهده اول روی مشاهدات دیگر مشخص شده است.

Plot of EWMA

در ادامه به رابطه‌ای که برای محاسبه هموارسازی نمایی میانگین متحرک احتیاج داریم، اشاره خواهیم کرد. همچنین مشخصات داده‌هایی که می‌توانیم برایشان مدل‌سازی انجام دهیم، مورد بحث قرار خواهد گرفت. در این بین با نمودارهایی کار خواهیم کرد که مربوط به تعداد وظایف CPU برحسب زمان در یک سیستم رایانه‌ای است. تصویر زیر این تغییرات را در نمودار مربوطه نشان داده است. فرض کنید محور افقی زمان برحسب ثانیه است و محور عمودی نیز تعداد عملیات (Task) را نشان می‌دهد.

Plot_of_cpu
تصویر ۱: سری زمانی تعداد وظایف CPU

با توجه به این نمودار، مشخص است که تعداد وظیفه‌هایی که CPU در زمان انجام می‌دهد، دارای نوسانات زیادی است ولی در کل به نظر می‌رسد که حول یک مقدار ثابت (مثلا میانگین با مقدار ۱۳۰) تغییرات پایدار هستند. به چنین داده‌ها و فرآیند سری زمانی، ایستا (Stationary) می‌گویند. به این ترتیب اگر بخواهیم مقداری را برای آینده تعداد وظایف پیش‌بینی کنیم، باید مقداری حدود ۱۳۰ باشد. البته ممکن است مقدار ۱۳۰، پیش‌بینی خیلی خوبی نباشد ولی به راحتی و سادگی بدست آمده است و البته پیش‌بینی چندان بدی هم نیست.

هموارسازی نمایی در سری زمانی با میانگین متحرک

منظور از «هموارسازی نمایی» (Exponential Smoothing)، استفاده از عملگر میانگین متحرک (Moving Average) با وزن‌هایی است که به صورت نمایی از نقطه شروع کاهش پیدا می‌کنند. چنین شیوه هموارسازی را «هموارسازی نمایی سری زمانی میانگین متحرک» (Exponentially Weighted Moving Average) یا EWMA می‌نامند.

فرض کنید روی سری زمانی $$x_t$$ هموارسازی صورت گرفته و یک سری زمانی جدید با نام $$s_t$$ ساخته شده است. شیوه هموارسازی میانگین متحرک نمایی، در این حالت به شکل زیر بیان شده است.

$$\large s_t=\alpha x_t+(1-\alpha)s_{t-1}$$

رابطه ۱

در نتیجه به نظر می‌رسد که هموارسازی روی داده مربوط به زمان $$t$$، حاصل میانگین وزنی $$x_t$$ و $$s_{t-1}$$ است که با وزن‌های $$\alpha$$ و $$1-\alpha$$ انجام شده است. تصویر زیر نتیجه این هموارسازی را به ازاء $$\alpha=0.5$$ و $$\alpha=0.05$$ نشان می‌دهد.

stationary_time_series
تصویر ۲: سری زمانی ایستا و هموارسازی نمایی

مشخص است که با در نظر گرفتن $$\alpha=0.5$$ منحنی خیلی هموار به نظر نمی‌رسد، زیرا سهم $$x_t$$، با نوسانات زیاد، با سهم داده‌های هموار شده زمان قبل $$s_{t-1}$$ در مدل برابر است. ولی زمانی که $$\alpha=0.05$$ است، هموارسازی بیشتر صورت گرفته و سهم مقادیر $$s_{t-1}$$ در میانگین‌گیری بیشتر است.

نکته: از آنجایی که صحبت از میانگین وزنی می‌کنیم، مشخص است که وزن‌ها باید در بازه $$(0,1)$$ باشند. از طرفی جمع وزن‌ها نیز برای نقاط با واحد (یک) برابر است.

فرض کنید قرار است براساس داده‌های سری زمانی تا زمان $$t$$ (یعنی $$x_t$$)، مقدار $$x_{t+1}$$ را پیش‌بینی کنید. اگر مقدار وزن $$\alpha$$ را در مدل ۱ کم کنید، نقش مقدار قبلی $$x_t$$ را کم کرده و در عوض نقش $$s_{t}$$ را افزایش داده‌اید. همانطور که در نمودار بالا نیز دیده شد، در مجموع، هموارسازی می‌تواند پیش‌بینی ساده و نسبتا مناسبی ارائه کند. در نتیجه $$s_t$$ برآوردگر $$x_t$$ خواهد بود.

انتخاب مقدار وزن ($$\alpha$$) در هموارسازی نمایی سری زمانی

فرض کنید که در یک سری زمانی می‌خواهیم میانگین متحرک با وزن یکسان برای همه مشاهدات داشته باشیم. اگر میانگین متحرک براساس $$n$$‌ مشاهده، بدست آید، متوسط طول عمر هر مشاهده در محاسبه میانگین متحرک چقدر است؟

با کمی دقت متوجه خواهید شد که این طول عمر برابر با حدودا $$\dfrac{n+1}{2}$$ است. به تصویر زیر دقت کنید.

average age of points in EWMA

در اینجا ۵ نقطه در نظر گرفته شده و میانگین متحرک براساس سه مشاهده صورت گرفته. در نتیجه متوسط عمر نقاط برابر با $$2.6$$ است که به $$2.4$$ بسیار نزدیک است. با افزایش تعداد نمونه‌ها، به تقریب مناسبی از $$\dfrac{n+1}{2}$$ خواهیم رسید.

حال فرض کنید که می‌خواهید یک هموارسازی نمایی میانگین متحرک با وزن‌های برابر برای مشاهده ایجاد کنید. به این ترتیب کافی است که از عکس متوسط طول عمر استفاده کنید و $$\alpha=\dfrac{2}{n+1}$$ قرار بگیرد.

برای مثال فرض کنید قرار است که یک سری زمانی بر اساس نمونه‌هایی که هر ثانیه یک‌بار گرفته می‌شوند، توسط هموارسازی نمایی میانگین متحرک، پیش‌بینی شود. داده‌های مربوط به یک دقیقه جمع‌آوری شده‌اند. اگر میانگین متحرک برای زمان $$t$$ وابسته به $$t-1$$ باشد آنگاه مقدار $$\alpha$$ برابر با $$0.03278$$ خواهد بود.

$$\large \alpha= \dfrac{2}{61}= 0.032786885$$

موضوع مهم هنگام استفاده از برآورد حاصل از هموارسازی به این شکل، ایستا بودن فرآیند سری زمانی است، به این معنی که میانگین آن ثابت بوده و فرآیند دارای روند نیست. سوال مهم در اینجا این است که زمانی که نوسانات ایستا نبوده و تغییرات به صورت روند (Trend) یا فصلی (Seasonality) در سری زمانی وجود داشته باشد، به چه طریق باید عمل کرد؟

ایستایی، روند و تغییرات فصلی در هموارسازی نمایی سری زمانی

ویژگی‌های متعددی برای یک سری زمانی وجود دارد ولی در اینجا فقط به سه خاصیت اصلی یعنی ایستایی، روند و تغییرات فصلی اشاره خواهیم داشت.

  • ایستایی (Stationary): به ثابت بودن میانگین تغییرات یک سری زمانی، ایستایی می‌گویند. به این ترتیب روند صعودی یا نزولی در نمودار ترسیم شده یک سری زمانی وجود نداشته و به نظر می‌رسد که تغییرات در داده‌های سری زمانی به صورت تصادفی و حول یک نقطه رخ می‌دهد. معمولا در بررسی چنین سری زمانی، از هموارسازی «میانگین متحرک وزنی نمایی» (EWMA) استفاده می‌شود.
  • روند (Trend): به تغییرات طولانی مدت در یک سری زمانی که طبق یک الگوی مشخص ظاهر می‌شود، روند گفته می‌شود. برای مثال روند صعودی یا نزولی نشان می‌دهد که مقدارهای مربوط به یک سری زمانی در کل افزایش دارند یا رو به کاهش هستند. معمولا تغییرات کلی که توسط روند مشخص می‌شود، به صورت معادله یا رابطه یک خط راست است. در تصویر زیر یک سری زمانی با روند صعودی را مشاهده می‌کنید.
ewma-trend-time-series2
تصویر ۳: سری زمانی با روند خطی

نکته: اگر روند به صورت درجه ۲ باشد، هموارسازی به شکل یک مخروط خواهد بود. در زیر، مدل هموارسازی نمایی دیده می‌شود که با سه پارامتر $$\alpha, \beta , \gamma$$ مشخص شده است.

$$\large s_t=\alpha\dfrac{x_t}{g_{t-L}}+(1-\alpha)(s_{t-1}+b_{t-1})\\ \large b_t=\beta(s_t-s_{t-1})+(1-\beta)b_{t-1})\\ \large g_t=\gamma\dfrac{x_t}{s_t}+(1-\gamma)g_{t-L}$$

رابطه ۲

  • تغییرات فصلی: گاهی تغییرات تناوبی در سری زمانی، مرتبط با تغییرات فصلی است. به این معنی که تقریبا در مقاطع مشخصی از زمان، رفتار سری زمانی تکرار می‌شود. به عنوان یک مثال مناسب می‌توان به تغییرات دمایی در طول سال‌ها اشاره کرد که به صورت تناوبی تغییر می‌کند.
seasonality-time-series
تصویر ۴: سری زمانی با تغییرات فصلی

نتیجه اعمال هموارسازی نمایی سری زمانی (میانگین متحرک وزنی نمایی) روی این گونه سری‌های زمانی در تصویر زیر دیده می‌شود.

seasonality-time-series2
تصویر ۵: سری زمانی با تغییرات فصلی و نمودار هموار شده آن

ممکن است در یک سری زمانی، هم اثر تغییرات فصلی (تناوبی) و هم روند دیده شود. در تصویر زیر تغییرات میزان گازکربنیک در اتمسفر در سال‌های مختلف ترسیم شده که نشان می‌دهد روند و تغییرات فصلی در سری زمانی تاثیرگذار هستند و از طرفی یک روند افزایشی سریع، در سال‌های ۱۹۸۰ به بعد رخ داده است.

concentration_time_series
تصویر ۶: سری زمانی تراکم گازکربنیک در اتمسفر همراه با روند و تغییرات فصلی

هموارسازی نمایی سری زمانی مضاعف و درجه سه

در سال ۱۹۵۰، چارلز هولت (Charles Holt) متوجه شد که مدل هموارسازی نمایی، برای مدل‌بندی سری‌های زمانی همراه با روند، دچار مشکل می‌شود. او مدل هموارسازی نمایی ساده (طبق رابطه ۱) را تغییر داد و نتیجه کار او به نام روش هموارسازی هولت معروف شد. در روش هموارسازی هولت، دوبار هموارسازی صورت می‌گیرد. در گام اول هموارسازی براساس مقدار واقعی سری زمانی است و در گام بعدی نتایج هموارسازی، دوباره هموار می‌شوند.

$$\large s_t=\alpha x_t+(1-\alpha)(s_{t-1}+b_t)\\ \large b_t=\beta(s_t-s_{t-1})+(1-\beta)b_{t-1}$$

رابطه ۳

Double_exponential_smoothing
تصویر ۷: هموارسازی نمایی مضاعف

البته برای محاسبه مقدار پیش‌بینی طبق این الگو، باید احتیاط کرد. همانطور که دیده می‌شود در هر مرحله، یک رابطه خطی بین مقدار هموار شده در زمان $$t$$ و $$t-1$$ ایجاد شده است که $$\beta$$ شیب این خط است که باید در محاسبات پیش‌بینی به کار رود. فرض کنید که می‌خواهید مقدار سری زمانی را برای $$m$$‌ واحد زمانی بعد از $$t$$ بدست آورید. به این ترتیب می‌نویسیم:

$$\large F_{t+m}=s_t+mb_t$$

رابطه 4

همانطور که مشخص است رابطه ۴، معادله یک خط راست است، که براساس رابطه ۳ ساخته می‌شود.

نکته: اگر بخواهید مقدار سری زمانی را در زمان $$t+1$$ مشخص کنید، کافی است مقدار $$m$$ را ۱ انتخاب کنید.

زمانی که علاوه بر روند، تغییرات فصلی نیز در داده‌های سری زمانی وجود داشته باشد، استفاده از هموارسازی نمایی در سری زمانی مرتبه ۳، مناسب است. پیتر وینترز (Peter Winters) که دانشجوی هولت بود، روش استادش را گسترش داد و مدل دیگری را برای هموارسازی توسعه داد. او با دخالت دادن عامل تغییرات فصلی مدل جدیدی معرفی کرد که براساس پارامتر $$L$$‌ که وابسته به تغییرات فصلی است، هموارسازی را انجام می‌دهد.

به این ترتیب مدل پیش‌گو برای مقدار سری زمانی در فاصله $$m$$ از زمان $$t$$ به شکل زیر خواهد بود.

$$\large F_{t+m} = (s_t+mb_t)g_{t-L+m}$$

رابطه ۵

مقدار $$g_{t-L+m}$$ و $$b_t$$ باید براساس رابطه ۲ صورت گیرد.

triple_exponential_smoothing
تصویر 8: سری زمانی با هموارسازی نمایی مرتبه ۳

نمونه هموارسازی و پیش‌بینی سری زمانی، توسط روش هموارسازی نمایی مرتبه ۳ در تصویر ۸ دیده می‌شود. همانطور که مشخص است این مدل به خوبی از عهده پیش‌بینی مقادیر قبلی برآمده و مدلی قابل اعتماد برای داده‌های سری زمانی با روند و تغییرات فصلی به نظر می‌رسد.

هموارسازی نمایی در سری زمانی برای از بین بردن اثر داده‌های دورافتاده

زمانی که با داده‌های جریانی (Streaming Data) مواجه هستیم، باید به سرعت،‌ مشاهدات پرت (Outlier) یا نامتعارف (Abnormal) شناسایی شده و کنار گذاشته شوند.

متاسفانه ذات داده‌های جریانی، این امکان را برای شناسایی داده‌های پرت فراهم نمی‌کند در نتیجه باید نقش آن‌ها را در پیش‌بینی‌ها کاهش دهیم. راه مناسب برای بررسی داده‌های جریان و حذف اثر داده‌های نامتعارف، استفاده از هموارسازی است، بخصوص که هموارسازی نمایی میانگین متحرک با توجه به وزن‌دهی به مشاهدات، این کار را به بهترین وجهی انجام می‌دهد. پیاده‌سازی الگوریتم و نحوه محاسبات برای هموارسازی نمایی میانگین متحرک برای داده‌های ساختگی توسط کدهای زیر که با زبان Go‌ نوشته شده‌اند، صورت پذیرفته است.

// Package ewma implements exponentially weighted moving averages.
package ewma

// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
// Please see the LICENSE file for applicable license terms.

const (
	// By default, we average over a one-minute period, which means the average
	// age of the metrics in the period is 30 seconds.
	AVG_METRIC_AGE float64 = 30.0

	// The formula for computing the decay factor from the average age comes
	// from "Production and Operations Analysis" by Steven Nahmias.
	DECAY float64 = 2 / (float64(AVG_METRIC_AGE) + 1)

	// For best results, the moving average should not be initialized to the
	// samples it sees immediately. The book "Production and Operations
	// Analysis" by Steven Nahmias suggests initializing the moving average to
	// the mean of the first 10 samples. Until the VariableEwma has seen this
	// many samples, it is not "ready" to be queried for the value of the
	// moving average. This adds some memory cost.
	WARMUP_SAMPLES uint8 = 10
)

// MovingAverage is the interface that computes a moving average over a time-
// series stream of numbers. The average may be over a window or exponentially
// decaying.
type MovingAverage interface {
	Add(float64)
	Value() float64
	Set(float64)
}

// NewMovingAverage constructs a MovingAverage that computes an average with the
// desired characteristics in the moving window or exponential decay. If no
// age is given, it constructs a default exponentially weighted implementation
// that consumes minimal memory. The age is related to the decay factor alpha
// by the formula given for the DECAY constant. It signifies the average age
// of the samples as time goes to infinity.
func NewMovingAverage(age ...float64) MovingAverage {
	if len(age) == 0 || age[0] == AVG_METRIC_AGE {
		return new(SimpleEWMA)
	}
	return &VariableEWMA{
		decay: 2 / (age[0] + 1),
	}
}

// A SimpleEWMA represents the exponentially weighted moving average of a
// series of numbers. It WILL have different behavior than the VariableEWMA
// for multiple reasons. It has no warm-up period and it uses a constant
// decay.  These properties let it use less memory.  It will also behave
// differently when it's equal to zero, which is assumed to mean
// uninitialized, so if a value is likely to actually become zero over time,
// then any non-zero value will cause a sharp jump instead of a small change.
// However, note that this takes a long time, and the value may just
// decays to a stable value that's close to zero, but which won't be mistaken
// for uninitialized. See http://play.golang.org/p/litxBDr_RC for example.
type SimpleEWMA struct {
	// The current value of the average. After adding with Add(), this is
	// updated to reflect the average of all values seen thus far.
	value float64
}

// Add adds a value to the series and updates the moving average.
func (e *SimpleEWMA) Add(value float64) {
	if e.value == 0 { // this is a proxy for "uninitialized"
		e.value = value
	} else {
		e.value = (value * DECAY) + (e.value * (1 - DECAY))
	}
}

// Value returns the current value of the moving average.
func (e *SimpleEWMA) Value() float64 {
	return e.value
}

// Set sets the EWMA's value.
func (e *SimpleEWMA) Set(value float64) {
	e.value = value
}

// VariableEWMA represents the exponentially weighted moving average of a series of
// numbers. Unlike SimpleEWMA, it supports a custom age, and thus uses more memory.
type VariableEWMA struct {
	// The multiplier factor by which the previous samples decay.
	decay float64
	// The current value of the average.
	value float64
	// The number of samples added to this instance.
	count uint8
}

// Add adds a value to the series and updates the moving average.
func (e *VariableEWMA) Add(value float64) {
	switch {
	case e.count < WARMUP_SAMPLES:
		e.count++
		e.value += value
	case e.count == WARMUP_SAMPLES:
		e.count++
		e.value = e.value / float64(WARMUP_SAMPLES)
		e.value = (value * e.decay) + (e.value * (1 - e.decay))
	default:
		e.value = (value * e.decay) + (e.value * (1 - e.decay))
	}
}

// Value returns the current value of the average, or 0.0 if the series hasn't
// warmed up yet.
func (e *VariableEWMA) Value() float64 {
	if e.count <= WARMUP_SAMPLES {
		return 0.0
	}

	return e.value
}

// Set sets the EWMA's value.
func (e *VariableEWMA) Set(value float64) {
	e.value = value
	if e.count <= WARMUP_SAMPLES {
		e.count = WARMUP_SAMPLES + 1
	}
}

همچنین برای آزمایش این کدها و عملکرد آن‌ها روی یک مجموعه داده فرضی بهتر است برنامه زیر را اجرا کنید.

package ewma

// Copyright (c) 2013 VividCortex, Inc. All rights reserved.
// Please see the LICENSE file for applicable license terms.

import "testing"

var samples = [100]float64{
	4599, 5711, 4746, 4621, 5037, 4218, 4925, 4281, 5207, 5203, 5594, 5149,
	4948, 4994, 6056, 4417, 4973, 4714, 4964, 5280, 5074, 4913, 4119, 4522,
	4631, 4341, 4909, 4750, 4663, 5167, 3683, 4964, 5151, 4892, 4171, 5097,
	3546, 4144, 4551, 6557, 4234, 5026, 5220, 4144, 5547, 4747, 4732, 5327,
	5442, 4176, 4907, 3570, 4684, 4161, 5206, 4952, 4317, 4819, 4668, 4603,
	4885, 4645, 4401, 4362, 5035, 3954, 4738, 4545, 5433, 6326, 5927, 4983,
	5364, 4598, 5071, 5231, 5250, 4621, 4269, 3953, 3308, 3623, 5264, 5322,
	5395, 4753, 4936, 5315, 5243, 5060, 4989, 4921, 4480, 3426, 3687, 4220,
	3197, 5139, 6101, 5279,
}

func TestSimpleEWMA(t *testing.T) {
	var e SimpleEWMA
	for _, f := range samples {
		e.Add(f)
	}
	if e.Value() != 4734.500946466118 {
		t.Errorf("e.Value() is %v, wanted %v", e.Value(), 4734.500946466118)
	}
	e.Set(1.0)
	if e.Value() != 1.0 {
		t.Errorf("e.Value() is %d", e.Value())
	}
}

func TestVariableEWMA(t *testing.T) {
	e := NewMovingAverage(30)
	for _, f := range samples {
		e.Add(f)
	}
	if e.Value() != 4734.500946466118 {
		t.Errorf("e.Value() is %v, wanted %v", e.Value(), 4734.500946466118)
	}
	e.Set(1.0)
	if e.Value() != 1.0 {
		t.Errorf("e.Value() is %d", e.Value())
	}
}

func TestVariableEWMA2(t *testing.T) {
	e := NewMovingAverage(5)
	for _, f := range samples {
		e.Add(f)
	}
	if e.Value() != 5015.397367486725 {
		t.Errorf("e.Value() is %v, wanted %v", e.Value(), 5015.397367486725)
	}
}

func TestVariableEWMAWarmup(t *testing.T) {
	e := NewMovingAverage(5)
	for i, f := range samples {
		e.Add(f)

		// all values returned during warmup should be 0.0
		if uint8(i) < WARMUP_SAMPLES {
			if e.Value() != 0.0 {
				t.Errorf("e.Value() is %v, expected %v", e.Value(), 0.0)
			}
		}
	}
	e = NewMovingAverage(5)
	e.Set(5)
	e.Add(1)
	if e.Value() >= 5 {
		t.Errorf("e.Value() is %d, expected it to decay towards 0", e.Value())
	}
}

func TestVariableEWMAWarmup2(t *testing.T) {
	e := NewMovingAverage(5)
	testSamples := [12]float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10000, 1}
	for i, f := range testSamples {
		e.Add(f)

		// all values returned during warmup should be 0.0
		if uint8(i) < WARMUP_SAMPLES {
			if e.Value() != 0.0 {
				t.Errorf("e.Value() is %v, expected %v", e.Value(), 0.0)
			}
		}
	}
	if val := e.Value(); val == 1.0 {
		t.Errorf("e.Value() is expected to be greater than %v", 1.0)
	}
}

خلاصه و جمع‌بندی

تشخیص ناهنجاری‌ها و مقابله با آن در زمان واقعی (Real Time) یکی از مشکلاتی است که در پیش‌بینی‌ها باید مورد بررسی قرار گیرد. زیرا در سری زمانی نمی‌دانید در آینده چه داده‌ای ظاهر خواهد شد و همیشه براساس گذشته فرآیند تصادفی مدل را ساخته‌اید.

به همین دلیل پیش‌بینی و مدل‌سازی براساس داده‌های سری زمانی می‌تواند واقعاً پیچیده باشد، اما بسیاری از تکنیک‌ها و روش‌های ساده و کارآمد مانند EWMA یا (Exponentially Weighted Moving Average) با اضافه کردن کمی زمان و هزینه، می‌توانند بهترین نتیجه را بوجود آورند.

البته استفاده از  تکنیک‌های پیچیده‌تر برای موارد بسیار خاص مناسب بوده و پیش‌بینی را با دقت بیشتری انجام می‌دهند ولی به پیچیدگی مدل و هزینه‌های محاسباتی نیز می‌افزایند. در این نوشتار با هموارسازی هولت وینترز آشنا شدیم و براساس نمودارها و روابطی که معرفی کردیم، ساختار آن را آموزش دادیم.

اگر علاقه‌مند به یادگیری مباحث مشابه مطلب سری زمانی هستید، آموزش‌هایی که در ادامه آمده‌اند نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۳ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.

«آرمان ری‌بد» دکتری آمار در شاخه آمار ریاضی دارد. از علاقمندی‌های او، یادگیری ماشین، خوشه‌بندی و داده‌کاوی است و در حال حاضر نوشتارهای مربوط به آمار و یادگیری ماشین را در مجله فرادرس تهیه می‌کند.