Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/statsmodels/tsa/exponential_smoothing/initialization.py : 7%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Initialization methods for states of exponential smoothing models
3"""
5import numpy as np
6import pandas as pd
9def _initialization_simple(endog, trend=False, seasonal=False,
10 seasonal_periods=None):
11 # See Section 7.6 of Hyndman and Athanasopoulos
12 initial_trend = None
13 initial_seasonal = None
15 # Non-seasonal
16 if seasonal is None:
17 initial_level = endog[0]
18 if trend == 'add':
19 initial_trend = endog[1] - endog[0]
20 elif trend == 'mul':
21 initial_trend = endog[1] / endog[0]
22 # Seasonal
23 else:
24 initial_level = np.mean(endog[:seasonal_periods])
25 m = seasonal_periods
26 if trend is not None:
27 initial_trend = (pd.Series(endog).diff(m)[m:2 * m] / m).mean()
29 if seasonal == 'add':
30 initial_seasonal = endog[:m] - initial_level
31 elif seasonal == 'mul':
32 initial_seasonal = endog[:m] / initial_level
34 return initial_level, initial_trend, initial_seasonal
37def _initialization_heuristic(endog, trend=False, seasonal=False,
38 seasonal_periods=None):
39 # See Section 2.6 of Hyndman et al.
40 endog = endog.copy()
41 nobs = len(endog)
43 if nobs < 10:
44 raise ValueError('Cannot use heuristic method with less than 10'
45 ' observations.')
47 # Seasonal component
48 initial_seasonal = None
49 if seasonal is not None:
50 # Calculate the number of full cycles to use
51 if nobs < 2 * seasonal_periods:
52 raise ValueError('Cannot compute initial seasonals using'
53 ' heuristic method with less than two full'
54 ' seasonal cycles in the data.')
55 # We need at least 10 periods for the level initialization
56 # and we will lose self.seasonal_periods // 2 values at the
57 # beginning and end of the sample, so we need at least
58 # 10 + 2 * (self.seasonal_periods // 2) values
59 min_obs = 10 + 2 * (seasonal_periods // 2)
60 if nobs < min_obs:
61 raise ValueError('Cannot use heuristic method to compute'
62 ' initial seasonal and levels with less'
63 ' than 10 + 2 * (seasonal_periods // 2)'
64 ' datapoints.')
65 # In some datasets we may only have 2 full cycles (but this may
66 # still satisfy the above restriction that we will end up with
67 # 10 seasonally adjusted observations)
68 k_cycles = min(5, nobs // seasonal_periods)
69 # In other datasets, 3 full cycles may not be enough to end up
70 # with 10 seasonally adjusted observations
71 k_cycles = max(k_cycles, int(np.ceil(min_obs / seasonal_periods)))
73 # Compute the moving average
74 series = pd.Series(endog[:seasonal_periods * k_cycles])
75 initial_trend = series.rolling(seasonal_periods, center=True).mean()
76 if seasonal_periods % 2 == 0:
77 initial_trend = initial_trend.shift(-1).rolling(2).mean()
79 # Detrend
80 if seasonal == 'add':
81 detrended = series - initial_trend
82 elif seasonal == 'mul':
83 detrended = series / initial_trend
85 # Average seasonal effect
86 tmp = np.zeros(k_cycles * seasonal_periods) * np.nan
87 tmp[:len(detrended)] = detrended.values
88 initial_seasonal = np.nanmean(
89 tmp.reshape(k_cycles, seasonal_periods).T, axis=1)
91 # Normalize the seasonals
92 if seasonal == 'add':
93 initial_seasonal -= np.mean(initial_seasonal)
94 elif seasonal == 'mul':
95 initial_seasonal /= np.mean(initial_seasonal)
97 # Replace the data with the trend
98 endog = initial_trend.dropna().values
100 # Trend / Level
101 exog = np.c_[np.ones(10), np.arange(10) + 1]
102 beta = np.linalg.pinv(exog).dot(endog[:10])
103 initial_level = beta[0]
105 initial_trend = None
106 if trend == 'add':
107 initial_trend = beta[1]
108 elif trend == 'mul':
109 initial_trend = 1 + beta[1] / beta[0]
111 return initial_level, initial_trend, initial_seasonal