Модель Хольта

Модель Хольта

По сравнению с наивными методами прогноза модель Хольта несколько сложнее в реализации. Кроме того, у данной модели есть большой недостаток – она выдает прогноз лишь на один шаг вперед и не может спрогнозировать, например, 12 будущих часов.

Модель Хольта строится по следующим формулам:

f_n1

где L – прогноз, очищенный от тренда (по сути, представляет собой экспоненциальное сглаживание);
B – линейный тренд;
Y – функция прогноза;
α, β – коэффициенты чувствительности модели;
t – момент времени;
h – шаг прогноза.

Нулевые точки рассчитываются по отдельным формулам.

f_n2

Модель Хольта учитывает только линейный тренд, есть очень большая проблема с выбором оптимальных коэффициентов α и β. Для этого вводятся критерии и ограничения, описываемые формулами.

f_n3

Коэффициенты α и β подбираются с помощью генетического алгоритма, результатом работы которого стали значения α= β=0,95. Для произвольного дня по модели Хольта с подобранными коэффициентами: α= β=0,95 строится прогноз, результаты прогноза заносятся в таблицу.

Прогнозирование по модели Хольта с коэффициентами α= β=0,95

Часы Скорость Exp Тренд Прогноз Ошибка
0 1266 845 1 846 0,33
1 423 444 -380 64 0,85
2 351 337 -121 216 0,39
3 150 153 -180 -27 1,18
4 64 59 -98 -39 1,60
5 52 47 -16 31 0,40
6 76 74 24 98 0,29
7 187 183 105 287 0,54
8 526 514 320 834 0,59
9 1034 1024 500 1524 0,47
10 1969 1947 902 2848 0,45
11 3007 2999 1045 4044 0,34
12 3661 3680 699 4379 0,20
13 6081 5996 2235 8231 0,35
14 7376 7419 1463 8882 0,20
15 7639 7701 341 8043 0,05
16 5768 5882 -1711 4170 0,28
17 6629 6506 508 7014 0,06
18 8294 8230 1663 9893 0,19
19 10841 10794 2519 13312 0,23
20 15646 15529 4625 20154 0,29
21 20994 20952 5383 26335 0,25
22 21894 22116 1375 23491 0,07
23 11843 12425 -9137 3288 0,72
MAPE 43,03
Alpha 0,95
Beta 0,95

По результатам расчетов, представленных в таблице 10, строится график эталонной функции и прогноза, представленный на рис.

gr_n_2

gr_n_3

Оценка точности прогнозирования модели Хольта будет проведена на четырех днях из следующих типовых групп: рабочие дни, выходные дни, праздничные дни. Результаты эксперимента занесены в таблицу, построенные графики представлены на рис.

Время Замеры a b Прогноз Ошибка Ошибка %
Прогноз для группы «рабочие дни»
6 37,68 37,68 86,32 124,00
7 124 124,00 86,32 210,32 0,00 0,00
8 267,52 266,95 132,29 399,24 0,21 21,38
9 355,79 356,22 97,37 453,59 0,12 12,21
10 585,9 584,58 203,71 788,29 0,23 22,58
11 749,5 749,89 172,54 922,42 0,05 5,17
12 750,65 752,37 34,47 786,84 0,23 22,88
13 1098,63 1095,51 285,07 1380,58 0,28 28,38
14 1901,45 1896,24 703,71 2599,95 0,27 27,39
15 3638,37 3627,99 1538,33 5166,32 0,29 28,54
16 7904,3 7876,92 3738,96 11615,88 0,35 34,64
17 10946,2 10952,90 3200,71 14153,61 0,06 6,12
18 10342 10380,07 137,13 10517,19 0,37 36,86
19 11788,1 11775,39 1158,61 12934,00 0,11 10,78
20 15736,8 15708,77 3411,33 19120,10 0,18 17,81
Прогноз для группы «рабочие дни»
6 9,58 9,58 19,25 28,83
7 28,83 28,83 19,25 48,08 0,00 0,00
8 138,00 137,10 91,52 228,62 0,65 65,16
9 153,08 153,84 30,81 184,64 0,49 49,35
10 210,92 210,66 51,93 262,58 0,12 12,46
11 256,55 256,61 47,08 303,69 0,02 2,35
12 593,25 590,35 279,81 870,16 0,49 48,81
13 889,25 889,06 295,15 1184,21 0,02 2,15
14 1528,25 1524,81 571,67 2096,48 0,23 22,51
15 3346,67 3334,17 1576,50 4910,67 0,37 37,36
16 6872,92 6853,30 3153,64 10006,94 0,29 28,55
17 10547,50 10542,09 3588,11 14130,21 0,05 5,13
18 12915,45 12927,60 2611,76 15539,36 0,09 9,41
19 17267,08 17249,80 4000,40 21250,20 0,10 10,01
20 23777,17 23751,90 6031,43 29783,33 0,11 10,63
Прогноз для группы «выходные дни»
6 41,08 41,08 63,00 104,08
7 104,08 104,08 63,00 167,08 0,00 0,00
8 188,17 187,96 79,95 267,91 0,11 11,21
9 227,83 228,23 47,74 275,97 0,18 17,59
10 297,25 297,04 64,84 361,88 0,07 7,16
11 391,33 391,04 88,51 479,55 0,08 7,53
12 489,36 489,26 96,40 585,66 0,02 2,00
13 550,83 551,18 68,40 619,58 0,06 6,32
14 968,08 964,60 348,51 1313,10 0,36 36,00
15 1313,23 1313,23 348,61 1661,84 0,00 0,01
16 1835,17 1833,44 487,92 2321,36 0,09 9,44
17 2070 2072,51 285,90 2358,41 0,12 12,14
18 2421,23 2420,60 336,39 2756,99 0,03 2,59
19 2958,75 2956,73 498,55 3455,28 0,07 6,82
20 3411,42 3411,86 463,30 3875,15 0,01 1,29
Прогноз для группы «праздничные дни»
6 157,95 157,95 251,20 409,15 0,00
7 409,15 409,15 251,20 660,35 0,00 0,00
8 1005,95 1002,49 528,97 1531,47 0,34 34,36
9 2221,30 2214,40 1083,42 3297,82 0,31 31,06
10 3764,90 3760,23 1458,83 5219,06 0,12 12,41
11 5738,70 5733,50 1876,49 7609,99 0,09 9,06
12 8300,95 8294,04 2431,84 10725,88 0,08 8,32
13 9632,20 9643,14 1552,80 11195,94 0,11 11,35
14 11688,35 11683,43 1948,57 13632,00 0,04 4,21
15 10353,25 10386,04 -686,69 9699,35 0,32 31,67
16 9078,30 9084,51 -1185,85 7898,66 0,07 6,84
17 9122,40 9110,16 -202,28 8907,88 0,13 13,41
18 11234,20 11210,94 1667,47 12878,41 0,21 20,71
19 13878,89 13868,89 2471,60 16340,48 0,07 7,21
20 14028,33 14051,45 613,23 14664,68 0,16 16,48

 

MAPE 19,63 21,70 8,58 14,79
Точность прогноза 80,37 78,30 91,42 85,21

Программная реализация алгоритма,приведена ниже. Результаты работы реализованной программы представлены в таблице.

Время Скорость показов Динамика Сглаж. exp Тренд Прогноз Ошибка Абс. ошибка
6:00 110,4 + 110 41 151 0 0%
7:00 151,38 + 151 41 192 0 0%
8:00 265 + 257.64 88.63 346.27 73 28%
9:00 393,83 + 388.29 119.12 507.41 46.73 12%
10:00 717 + 695.86 255.87 951.73 209.59 29%
11:00 1038,3 + 1029.3 312.16 1341.46 86.27 8%
12:00 1167,35 + 1184.6 198.33 1382.93 -174.46 15%
13:00 1331,05 + 1336.24 164.45 1500.69 -51.93 4%
14:00 1245,67 1270.79 -2.38 1268.41 -255.69 21%

 

gr_n_1

Точность краткосрочного (часового) прогноза программы составляет в среднем 87%.

Из таблицы следует, что модель Хольта имеет достаточно высокую точность прогнозирования, однако часового прогноза недостаточно для применения этой модели в реальных системах. Такая модель отлично справится с прогнозом в системах, где явно выражена линейная связь между точками прогноза.

<?
  mysql_select_db(, $conn);
 
  $date_now = date('Y-m-d', time());
  //$date_now = '2014-03-18';
    /*
  $sql = "SELECT DATE_FORMAT(`time`, '%k') AS `t`, floor(minute(`time`)/10) AS `m`, ROUND(AVG(`impressions_sum`),2) AS `s` FROM `vk_stat` WHERE
  (DATE_FORMAT(`time`, '%Y-%m-%d') = '$date_now'
  AND DATE_FORMAT(`time`, '%k') > 2)
  GROUP BY hour(`time`), floor(minute(`time`)/10);";
  */
 
  $sql = "SELECT DATE_FORMAT(`time`, '%k') AS `t`, 0 AS `m`, replace(ROUND(AVG(`impressions_sum`),2),'.',',') AS `s` FROM `vk_stat` WHERE
  DATE_FORMAT(`time`, '%Y-%m-%d') = '$date_now'
  AND DATE_FORMAT(`time`, '%k') BETWEEN 6 AND 23
  GROUP BY hour(`time`)";
 
  $alpha = 0.89914;
  $beta = 0.72565;
 
  $sezon = array (
    0 => 0.17,
    2 => 2.33,
    3 => 0.38,
    4 => 0.73,
    5 => 1.18,
    6 => 1.42,
    7 => 2.05,
    8 => 1.34,
    9 => 1.60,
    10 => 1.36,
    11 => 1.33,
    12 => 1.20,
    13 => 1.29,
    14 => 1.68,
    15 => 1.59,
    16 => 1.45,
    17 => 1.23,
    18 => 1.25,
    19 => 1.26,
    20 => 1.22,
    21 => 1.17,
    22 => 0.88,
    23 => 0.69
  );
 
 
  $j = $pre_s = 0;
  $s_arr = $t_arr = $p_arr = $e_arr = $e_ab_arr = array();
  $result = mysql_query($sql);
  while ($row = mysql_fetch_array($result)){
    	$y_array[] = $row;
  }
  echo '
  <p><b>Рассчет краткосрочного прогноза:</b></p>
  <table border="1">
    <tr><td><b>Время</b></td><td><b>Скорость показов</b></td><td><b>Динамика</b></td><td><b>Сглаж. exp</b></td>
    <td><b>Тренд</b></td><td><b>Прогноз</b></td><td><b>Ошибка</b></td><td><b>Абс. ошибка</b></td></tr>';
    foreach ($y_array as $row){
      $speed = (float)$row['s'];
 
      if ($j == 0){
        $s_arr[$j] = $speed;
        $t_arr[$j] = $y_array[$j+1]['s']-$y_array[$j]['s'];
        $p_arr[$j] = $s_arr[$j]+$t_arr[$j];
        $e_arr[$j] = 0;
        $e_ab_arr[$j] = 0;
      } else {
        $s_arr[$j] = $alpha*$speed + (1-$alpha)*($s_arr[$j-1]+$t_arr[$j-1]);
        $t_arr[$j] = $beta*($s_arr[$j]-$s_arr[$j-1]) + (1-$beta)*$t_arr[$j-1];
        $p_arr[$j] = $s_arr[$j]+$t_arr[$j];
        $e_arr[$j] = $speed-$p_arr[$j-1];
        $e_ab_arr[$j] = $e_arr[$j]/$speed;
      }
 
      if ($pre_s <= $speed) {
        $d = '+';
        $c = '#CCFFE6';
      } else {
        $d = '-';
        $c = '#FFCACA';
      }
      echo '<tr><td>'.$row['t'].':'.($row['m']*10).'</td><td>'.$row['s'].'</td><td bgcolor="'.$c.'">'.$d.'</td>
      <td>'.round($s_arr[$j],2).'</td><td>'.round($t_arr[$j],2).'</td><td>'.round($p_arr[$j],2).'</td>
      <td>'.round($e_arr[$j],2).'</td><td>'.abs(round($e_ab_arr[$j],2)*100).'%</td></tr>';
      $i++; $j++;
      $pre_s = $speed;
    }
  echo '
  </table>';
  $e_ab_abs = 0; $i = 0;
  foreach ($e_ab_arr as $e_val){
    if ($i > 1)	$e_ab_abs += abs($e_val);
    $i++;
  }
  $error = 100-abs(($e_ab_abs/($i-2))*100);
 
  echo '<b>Точность краткосрочного прогноза:</b> '.round($error,2).'%<hr />';
  echo '<p><b>Рассчет суточного прогноза:</b></p>';
  echo '<table border="1">
    <tr><td><b>Время</b></td><td><b>Прогноз</b></td></tr>';
 
  $j = 0;
  $prognoz = array_pop($p_arr);
  for ($i=date('G', time())+1; $i<24; $i++){
    $m = (int)date('i', time());
        if ($j == 0){
        	$k = $sezon[$i-1] + (($sezon[$i]-$sezon[$i-1])/60)*$m;
      	$prognoz = $prognoz*$k;
        } else $prognoz = $prognoz*$sezon[$i];
    echo '<tr><td>'.$i.'</td><td>'.round($prognoz,2).'</td></tr>';
    $j++;
  }
  echo '<table>';
?>

Автор статьи: Чернядьев Леонид Валерьевич

Facebook Comments

Леонид Чернядьев

Увлекаюсь программированием, интернет маркетингом, прогнозированием, дизайном и версткой. Принимаю заказы на лидогенерацию. Связь через - https://www.facebook.com/lenid.chernyadyev