reconnect moved files to git repo
This commit is contained in:
@ -0,0 +1,17 @@
|
||||
from statsmodels.tsa.holtwinters.model import (
|
||||
PY_SMOOTHERS,
|
||||
SMOOTHERS,
|
||||
ExponentialSmoothing,
|
||||
Holt,
|
||||
SimpleExpSmoothing,
|
||||
)
|
||||
from statsmodels.tsa.holtwinters.results import HoltWintersResults
|
||||
|
||||
__all__ = [
|
||||
"ExponentialSmoothing",
|
||||
"SimpleExpSmoothing",
|
||||
"Holt",
|
||||
"HoltWintersResults",
|
||||
"SMOOTHERS",
|
||||
"PY_SMOOTHERS",
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,412 @@
|
||||
import numpy as np
|
||||
|
||||
LOWER_BOUND = np.sqrt(np.finfo(float).eps)
|
||||
|
||||
|
||||
class HoltWintersArgs:
|
||||
def __init__(self, xi, p, bounds, y, m, n, transform=False):
|
||||
self._xi = xi
|
||||
self._p = p
|
||||
self._bounds = bounds
|
||||
self._y = y
|
||||
self._lvl = np.empty(n)
|
||||
self._b = np.empty(n)
|
||||
self._s = np.empty(n + m - 1)
|
||||
self._m = m
|
||||
self._n = n
|
||||
self._transform = transform
|
||||
|
||||
@property
|
||||
def xi(self):
|
||||
return self._xi
|
||||
|
||||
@xi.setter
|
||||
def xi(self, value):
|
||||
self._xi = value
|
||||
|
||||
@property
|
||||
def p(self):
|
||||
return self._p
|
||||
|
||||
@property
|
||||
def bounds(self):
|
||||
return self._bounds
|
||||
|
||||
@property
|
||||
def y(self):
|
||||
return self._y
|
||||
|
||||
@property
|
||||
def lvl(self):
|
||||
return self._lvl
|
||||
|
||||
@property
|
||||
def b(self):
|
||||
return self._b
|
||||
|
||||
@property
|
||||
def s(self):
|
||||
return self._s
|
||||
|
||||
@property
|
||||
def m(self):
|
||||
return self._m
|
||||
|
||||
@property
|
||||
def n(self):
|
||||
return self._n
|
||||
|
||||
@property
|
||||
def transform(self):
|
||||
return self._transform
|
||||
|
||||
@transform.setter
|
||||
def transform(self, value):
|
||||
self._transform = value
|
||||
|
||||
|
||||
def to_restricted(p, sel, bounds):
|
||||
"""
|
||||
Transform parameters from the unrestricted [0,1] space
|
||||
to satisfy both the bounds and the 2 constraints
|
||||
beta <= alpha and gamma <= (1-alpha)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
p : ndarray
|
||||
The parameters to transform
|
||||
sel : ndarray
|
||||
Array indicating whether a parameter is being estimated. If not
|
||||
estimated, not transformed.
|
||||
bounds : ndarray
|
||||
2-d array of bounds where bound for element i is in row i
|
||||
and stored as [lb, ub]
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
"""
|
||||
a, b, g = p[:3]
|
||||
|
||||
if sel[0]:
|
||||
lb = max(LOWER_BOUND, bounds[0, 0])
|
||||
ub = min(1 - LOWER_BOUND, bounds[0, 1])
|
||||
a = lb + a * (ub - lb)
|
||||
if sel[1]:
|
||||
lb = bounds[1, 0]
|
||||
ub = min(a, bounds[1, 1])
|
||||
b = lb + b * (ub - lb)
|
||||
if sel[2]:
|
||||
lb = bounds[2, 0]
|
||||
ub = min(1.0 - a, bounds[2, 1])
|
||||
g = lb + g * (ub - lb)
|
||||
|
||||
return a, b, g
|
||||
|
||||
|
||||
def to_unrestricted(p, sel, bounds):
|
||||
"""
|
||||
Transform parameters to the unrestricted [0,1] space
|
||||
|
||||
Parameters
|
||||
----------
|
||||
p : ndarray
|
||||
Parameters that strictly satisfy the constraints
|
||||
|
||||
Returns
|
||||
-------
|
||||
ndarray
|
||||
Parameters all in (0,1)
|
||||
"""
|
||||
# eps < a < 1 - eps
|
||||
# eps < b <= a
|
||||
# eps < g <= 1 - a
|
||||
|
||||
a, b, g = p[:3]
|
||||
|
||||
if sel[0]:
|
||||
lb = max(LOWER_BOUND, bounds[0, 0])
|
||||
ub = min(1 - LOWER_BOUND, bounds[0, 1])
|
||||
a = (a - lb) / (ub - lb)
|
||||
if sel[1]:
|
||||
lb = bounds[1, 0]
|
||||
ub = min(p[0], bounds[1, 1])
|
||||
b = (b - lb) / (ub - lb)
|
||||
if sel[2]:
|
||||
lb = bounds[2, 0]
|
||||
ub = min(1.0 - p[0], bounds[2, 1])
|
||||
g = (g - lb) / (ub - lb)
|
||||
|
||||
return a, b, g
|
||||
|
||||
|
||||
def holt_init(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Initialization for the Holt Models
|
||||
"""
|
||||
# Map back to the full set of parameters
|
||||
hw_args.p[hw_args.xi.astype(bool)] = x
|
||||
|
||||
# Ensure alpha and beta satisfy the requirements
|
||||
if hw_args.transform:
|
||||
alpha, beta, _ = to_restricted(hw_args.p, hw_args.xi, hw_args.bounds)
|
||||
else:
|
||||
alpha, beta = hw_args.p[:2]
|
||||
# Level, trend and dampening
|
||||
l0, b0, phi = hw_args.p[3:6]
|
||||
# Save repeated calculations
|
||||
alphac = 1 - alpha
|
||||
betac = 1 - beta
|
||||
# Setup alpha * y
|
||||
y_alpha = alpha * hw_args.y
|
||||
# In-place operations
|
||||
hw_args.lvl[0] = l0
|
||||
hw_args.b[0] = b0
|
||||
|
||||
return alpha, beta, phi, alphac, betac, y_alpha
|
||||
|
||||
|
||||
def holt__(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Simple Exponential Smoothing
|
||||
Minimization Function
|
||||
(,)
|
||||
"""
|
||||
_, _, _, alphac, _, y_alpha = holt_init(x, hw_args)
|
||||
n = hw_args.n
|
||||
lvl = hw_args.lvl
|
||||
for i in range(1, n):
|
||||
lvl[i] = (y_alpha[i - 1]) + (alphac * (lvl[i - 1]))
|
||||
return hw_args.y - lvl
|
||||
|
||||
|
||||
def holt_mul_dam(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Multiplicative and Multiplicative Damped
|
||||
Minimization Function
|
||||
(M,) & (Md,)
|
||||
"""
|
||||
_, beta, phi, alphac, betac, y_alpha = holt_init(x, hw_args)
|
||||
lvl = hw_args.lvl
|
||||
b = hw_args.b
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (y_alpha[i - 1]) + (alphac * (lvl[i - 1] * b[i - 1] ** phi))
|
||||
b[i] = (beta * (lvl[i] / lvl[i - 1])) + (betac * b[i - 1] ** phi)
|
||||
return hw_args.y - lvl * b**phi
|
||||
|
||||
|
||||
def holt_add_dam(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Additive and Additive Damped
|
||||
Minimization Function
|
||||
(A,) & (Ad,)
|
||||
"""
|
||||
_, beta, phi, alphac, betac, y_alpha = holt_init(x, hw_args)
|
||||
lvl = hw_args.lvl
|
||||
b = hw_args.b
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (y_alpha[i - 1]) + (alphac * (lvl[i - 1] + phi * b[i - 1]))
|
||||
b[i] = (beta * (lvl[i] - lvl[i - 1])) + (betac * phi * b[i - 1])
|
||||
return hw_args.y - (lvl + phi * b)
|
||||
|
||||
|
||||
def holt_win_init(x, hw_args: HoltWintersArgs):
|
||||
"""Initialization for the Holt Winters Seasonal Models"""
|
||||
hw_args.p[hw_args.xi.astype(bool)] = x
|
||||
if hw_args.transform:
|
||||
alpha, beta, gamma = to_restricted(
|
||||
hw_args.p, hw_args.xi, hw_args.bounds
|
||||
)
|
||||
else:
|
||||
alpha, beta, gamma = hw_args.p[:3]
|
||||
|
||||
l0, b0, phi = hw_args.p[3:6]
|
||||
s0 = hw_args.p[6:]
|
||||
alphac = 1 - alpha
|
||||
betac = 1 - beta
|
||||
gammac = 1 - gamma
|
||||
y_alpha = alpha * hw_args.y
|
||||
y_gamma = gamma * hw_args.y
|
||||
hw_args.lvl[:] = 0
|
||||
hw_args.b[:] = 0
|
||||
hw_args.s[:] = 0
|
||||
hw_args.lvl[0] = l0
|
||||
hw_args.b[0] = b0
|
||||
hw_args.s[: hw_args.m] = s0
|
||||
return alpha, beta, gamma, phi, alphac, betac, gammac, y_alpha, y_gamma
|
||||
|
||||
|
||||
def holt_win__mul(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Multiplicative Seasonal
|
||||
Minimization Function
|
||||
(,M)
|
||||
"""
|
||||
(_, _, _, _, alphac, _, gammac, y_alpha, y_gamma) = holt_win_init(
|
||||
x, hw_args
|
||||
)
|
||||
lvl = hw_args.lvl
|
||||
s = hw_args.s
|
||||
m = hw_args.m
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (y_alpha[i - 1] / s[i - 1]) + (alphac * (lvl[i - 1]))
|
||||
s[i + m - 1] = (y_gamma[i - 1] / (lvl[i - 1])) + (gammac * s[i - 1])
|
||||
return hw_args.y - lvl * s[: -(m - 1)]
|
||||
|
||||
|
||||
def holt_win__add(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Additive Seasonal
|
||||
Minimization Function
|
||||
(,A)
|
||||
"""
|
||||
(alpha, _, gamma, _, alphac, _, gammac, y_alpha, y_gamma) = holt_win_init(
|
||||
x, hw_args
|
||||
)
|
||||
lvl = hw_args.lvl
|
||||
s = hw_args.s
|
||||
m = hw_args.m
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (
|
||||
(y_alpha[i - 1]) - (alpha * s[i - 1]) + (alphac * (lvl[i - 1]))
|
||||
)
|
||||
s[i + m - 1] = (
|
||||
y_gamma[i - 1] - (gamma * (lvl[i - 1])) + (gammac * s[i - 1])
|
||||
)
|
||||
return hw_args.y - lvl - s[: -(m - 1)]
|
||||
|
||||
|
||||
def holt_win_add_mul_dam(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Additive and Additive Damped with Multiplicative Seasonal
|
||||
Minimization Function
|
||||
(A,M) & (Ad,M)
|
||||
"""
|
||||
(
|
||||
_,
|
||||
beta,
|
||||
_,
|
||||
phi,
|
||||
alphac,
|
||||
betac,
|
||||
gammac,
|
||||
y_alpha,
|
||||
y_gamma,
|
||||
) = holt_win_init(x, hw_args)
|
||||
lvl = hw_args.lvl
|
||||
b = hw_args.b
|
||||
s = hw_args.s
|
||||
m = hw_args.m
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (y_alpha[i - 1] / s[i - 1]) + (
|
||||
alphac * (lvl[i - 1] + phi * b[i - 1])
|
||||
)
|
||||
b[i] = (beta * (lvl[i] - lvl[i - 1])) + (betac * phi * b[i - 1])
|
||||
s[i + m - 1] = (y_gamma[i - 1] / (lvl[i - 1] + phi * b[i - 1])) + (
|
||||
gammac * s[i - 1]
|
||||
)
|
||||
return hw_args.y - (lvl + phi * b) * s[: -(m - 1)]
|
||||
|
||||
|
||||
def holt_win_mul_mul_dam(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Multiplicative and Multiplicative Damped with Multiplicative Seasonal
|
||||
Minimization Function
|
||||
(M,M) & (Md,M)
|
||||
"""
|
||||
(
|
||||
_,
|
||||
beta,
|
||||
_,
|
||||
phi,
|
||||
alphac,
|
||||
betac,
|
||||
gammac,
|
||||
y_alpha,
|
||||
y_gamma,
|
||||
) = holt_win_init(x, hw_args)
|
||||
lvl = hw_args.lvl
|
||||
s = hw_args.s
|
||||
b = hw_args.b
|
||||
m = hw_args.m
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (y_alpha[i - 1] / s[i - 1]) + (
|
||||
alphac * (lvl[i - 1] * b[i - 1] ** phi)
|
||||
)
|
||||
b[i] = (beta * (lvl[i] / lvl[i - 1])) + (betac * b[i - 1] ** phi)
|
||||
s[i + m - 1] = (y_gamma[i - 1] / (lvl[i - 1] * b[i - 1] ** phi)) + (
|
||||
gammac * s[i - 1]
|
||||
)
|
||||
return hw_args.y - (lvl * b**phi) * s[: -(m - 1)]
|
||||
|
||||
|
||||
def holt_win_add_add_dam(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Additive and Additive Damped with Additive Seasonal
|
||||
Minimization Function
|
||||
(A,A) & (Ad,A)
|
||||
"""
|
||||
(
|
||||
alpha,
|
||||
beta,
|
||||
gamma,
|
||||
phi,
|
||||
alphac,
|
||||
betac,
|
||||
gammac,
|
||||
y_alpha,
|
||||
y_gamma,
|
||||
) = holt_win_init(x, hw_args)
|
||||
lvl = hw_args.lvl
|
||||
s = hw_args.s
|
||||
b = hw_args.b
|
||||
m = hw_args.m
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (
|
||||
(y_alpha[i - 1])
|
||||
- (alpha * s[i - 1])
|
||||
+ (alphac * (lvl[i - 1] + phi * b[i - 1]))
|
||||
)
|
||||
b[i] = (beta * (lvl[i] - lvl[i - 1])) + (betac * phi * b[i - 1])
|
||||
s[i + m - 1] = (
|
||||
y_gamma[i - 1]
|
||||
- (gamma * (lvl[i - 1] + phi * b[i - 1]))
|
||||
+ (gammac * s[i - 1])
|
||||
)
|
||||
return hw_args.y - ((lvl + phi * b) + s[: -(m - 1)])
|
||||
|
||||
|
||||
def holt_win_mul_add_dam(x, hw_args: HoltWintersArgs):
|
||||
"""
|
||||
Multiplicative and Multiplicative Damped with Additive Seasonal
|
||||
Minimization Function
|
||||
(M,A) & (M,Ad)
|
||||
"""
|
||||
(
|
||||
alpha,
|
||||
beta,
|
||||
gamma,
|
||||
phi,
|
||||
alphac,
|
||||
betac,
|
||||
gammac,
|
||||
y_alpha,
|
||||
y_gamma,
|
||||
) = holt_win_init(x, hw_args)
|
||||
lvl = hw_args.lvl
|
||||
s = hw_args.s
|
||||
b = hw_args.b
|
||||
m = hw_args.m
|
||||
for i in range(1, hw_args.n):
|
||||
lvl[i] = (
|
||||
(y_alpha[i - 1])
|
||||
- (alpha * s[i - 1])
|
||||
+ (alphac * (lvl[i - 1] * b[i - 1] ** phi))
|
||||
)
|
||||
b[i] = (beta * (lvl[i] / lvl[i - 1])) + (betac * b[i - 1] ** phi)
|
||||
s[i + m - 1] = (
|
||||
y_gamma[i - 1]
|
||||
- (gamma * (lvl[i - 1] * b[i - 1] ** phi))
|
||||
+ (gammac * s[i - 1])
|
||||
)
|
||||
return hw_args.y - ((lvl * phi * b) + s[: -(m - 1)])
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,766 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from scipy.special import inv_boxcox
|
||||
from scipy.stats import (
|
||||
boxcox,
|
||||
rv_continuous,
|
||||
rv_discrete,
|
||||
)
|
||||
from scipy.stats.distributions import rv_frozen
|
||||
|
||||
from statsmodels.base.data import PandasData
|
||||
from statsmodels.base.model import Results
|
||||
from statsmodels.base.wrapper import (
|
||||
ResultsWrapper,
|
||||
populate_wrapper,
|
||||
union_dicts,
|
||||
)
|
||||
|
||||
|
||||
class HoltWintersResults(Results):
|
||||
"""
|
||||
Results from fitting Exponential Smoothing models.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
model : ExponentialSmoothing instance
|
||||
The fitted model instance.
|
||||
params : dict
|
||||
All the parameters for the Exponential Smoothing model.
|
||||
sse : float
|
||||
The sum of squared errors.
|
||||
aic : float
|
||||
The Akaike information criterion.
|
||||
aicc : float
|
||||
AIC with a correction for finite sample sizes.
|
||||
bic : float
|
||||
The Bayesian information criterion.
|
||||
optimized : bool
|
||||
Flag indicating whether the model parameters were optimized to fit
|
||||
the data.
|
||||
level : ndarray
|
||||
An array of the levels values that make up the fitted values.
|
||||
trend : ndarray
|
||||
An array of the trend values that make up the fitted values.
|
||||
season : ndarray
|
||||
An array of the seasonal values that make up the fitted values.
|
||||
params_formatted : pd.DataFrame
|
||||
DataFrame containing all parameters, their short names and a flag
|
||||
indicating whether the parameter's value was optimized to fit the data.
|
||||
resid : ndarray
|
||||
An array of the residuals of the fittedvalues and actual values.
|
||||
k : int
|
||||
The k parameter used to remove the bias in AIC, BIC etc.
|
||||
fittedvalues : ndarray
|
||||
An array of the fitted values. Fitted by the Exponential Smoothing
|
||||
model.
|
||||
fittedfcast : ndarray
|
||||
An array of both the fitted values and forecast values.
|
||||
fcastvalues : ndarray
|
||||
An array of the forecast values forecast by the Exponential Smoothing
|
||||
model.
|
||||
mle_retvals : {None, scipy.optimize.optimize.OptimizeResult}
|
||||
Optimization results if the parameters were optimized to fit the data.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
model,
|
||||
params,
|
||||
sse,
|
||||
aic,
|
||||
aicc,
|
||||
bic,
|
||||
optimized,
|
||||
level,
|
||||
trend,
|
||||
season,
|
||||
params_formatted,
|
||||
resid,
|
||||
k,
|
||||
fittedvalues,
|
||||
fittedfcast,
|
||||
fcastvalues,
|
||||
mle_retvals=None,
|
||||
):
|
||||
self.data = model.data
|
||||
super().__init__(model, params)
|
||||
self._model = model
|
||||
self._sse = sse
|
||||
self._aic = aic
|
||||
self._aicc = aicc
|
||||
self._bic = bic
|
||||
self._optimized = optimized
|
||||
self._level = level
|
||||
self._trend = trend
|
||||
self._season = season
|
||||
self._params_formatted = params_formatted
|
||||
self._fittedvalues = fittedvalues
|
||||
self._fittedfcast = fittedfcast
|
||||
self._fcastvalues = fcastvalues
|
||||
self._resid = resid
|
||||
self._k = k
|
||||
self._mle_retvals = mle_retvals
|
||||
|
||||
@property
|
||||
def aic(self):
|
||||
"""
|
||||
The Akaike information criterion.
|
||||
"""
|
||||
return self._aic
|
||||
|
||||
@property
|
||||
def aicc(self):
|
||||
"""
|
||||
AIC with a correction for finite sample sizes.
|
||||
"""
|
||||
return self._aicc
|
||||
|
||||
@property
|
||||
def bic(self):
|
||||
"""
|
||||
The Bayesian information criterion.
|
||||
"""
|
||||
return self._bic
|
||||
|
||||
@property
|
||||
def sse(self):
|
||||
"""
|
||||
The sum of squared errors between the data and the fittted value.
|
||||
"""
|
||||
return self._sse
|
||||
|
||||
@property
|
||||
def model(self):
|
||||
"""
|
||||
The model used to produce the results instance.
|
||||
"""
|
||||
return self._model
|
||||
|
||||
@model.setter
|
||||
def model(self, value):
|
||||
self._model = value
|
||||
|
||||
@property
|
||||
def level(self):
|
||||
"""
|
||||
An array of the levels values that make up the fitted values.
|
||||
"""
|
||||
return self._level
|
||||
|
||||
@property
|
||||
def optimized(self):
|
||||
"""
|
||||
Flag indicating if model parameters were optimized to fit the data.
|
||||
"""
|
||||
return self._optimized
|
||||
|
||||
@property
|
||||
def trend(self):
|
||||
"""
|
||||
An array of the trend values that make up the fitted values.
|
||||
"""
|
||||
return self._trend
|
||||
|
||||
@property
|
||||
def season(self):
|
||||
"""
|
||||
An array of the seasonal values that make up the fitted values.
|
||||
"""
|
||||
return self._season
|
||||
|
||||
@property
|
||||
def params_formatted(self):
|
||||
"""
|
||||
DataFrame containing all parameters
|
||||
|
||||
Contains short names and a flag indicating whether the parameter's
|
||||
value was optimized to fit the data.
|
||||
"""
|
||||
return self._params_formatted
|
||||
|
||||
@property
|
||||
def fittedvalues(self):
|
||||
"""
|
||||
An array of the fitted values
|
||||
"""
|
||||
return self._fittedvalues
|
||||
|
||||
@property
|
||||
def fittedfcast(self):
|
||||
"""
|
||||
An array of both the fitted values and forecast values.
|
||||
"""
|
||||
return self._fittedfcast
|
||||
|
||||
@property
|
||||
def fcastvalues(self):
|
||||
"""
|
||||
An array of the forecast values
|
||||
"""
|
||||
return self._fcastvalues
|
||||
|
||||
@property
|
||||
def resid(self):
|
||||
"""
|
||||
An array of the residuals of the fittedvalues and actual values.
|
||||
"""
|
||||
return self._resid
|
||||
|
||||
@property
|
||||
def k(self):
|
||||
"""
|
||||
The k parameter used to remove the bias in AIC, BIC etc.
|
||||
"""
|
||||
return self._k
|
||||
|
||||
@property
|
||||
def mle_retvals(self):
|
||||
"""
|
||||
Optimization results if the parameters were optimized to fit the data.
|
||||
"""
|
||||
return self._mle_retvals
|
||||
|
||||
@mle_retvals.setter
|
||||
def mle_retvals(self, value):
|
||||
self._mle_retvals = value
|
||||
|
||||
def predict(self, start=None, end=None):
|
||||
"""
|
||||
In-sample prediction and out-of-sample forecasting
|
||||
|
||||
Parameters
|
||||
----------
|
||||
start : int, str, or datetime, optional
|
||||
Zero-indexed observation number at which to start forecasting, ie.,
|
||||
the first forecast is start. Can also be a date string to
|
||||
parse or a datetime type. Default is the the zeroth observation.
|
||||
end : int, str, or datetime, optional
|
||||
Zero-indexed observation number at which to end forecasting, ie.,
|
||||
the first forecast is start. Can also be a date string to
|
||||
parse or a datetime type. However, if the dates index does not
|
||||
have a fixed frequency, end must be an integer index if you
|
||||
want out of sample prediction. Default is the last observation in
|
||||
the sample.
|
||||
|
||||
Returns
|
||||
-------
|
||||
forecast : ndarray
|
||||
Array of out of sample forecasts.
|
||||
"""
|
||||
return self.model.predict(self.params, start, end)
|
||||
|
||||
def forecast(self, steps=1):
|
||||
"""
|
||||
Out-of-sample forecasts
|
||||
|
||||
Parameters
|
||||
----------
|
||||
steps : int
|
||||
The number of out of sample forecasts from the end of the
|
||||
sample.
|
||||
|
||||
Returns
|
||||
-------
|
||||
forecast : ndarray
|
||||
Array of out of sample forecasts
|
||||
"""
|
||||
try:
|
||||
freq = getattr(self.model._index, "freq", 1)
|
||||
if not isinstance(freq, int) and isinstance(
|
||||
self.model._index, (pd.DatetimeIndex, pd.PeriodIndex)
|
||||
):
|
||||
start = self.model._index[-1] + freq
|
||||
end = self.model._index[-1] + steps * freq
|
||||
else:
|
||||
start = self.model._index.shape[0]
|
||||
end = start + steps - 1
|
||||
return self.model.predict(self.params, start=start, end=end)
|
||||
except AttributeError:
|
||||
# May occur when the index does not have a freq
|
||||
return self.model._predict(h=steps, **self.params).fcastvalues
|
||||
|
||||
def summary(self):
|
||||
"""
|
||||
Summarize the fitted Model
|
||||
|
||||
Returns
|
||||
-------
|
||||
smry : Summary instance
|
||||
This holds the summary table and text, which can be printed or
|
||||
converted to various output formats.
|
||||
|
||||
See Also
|
||||
--------
|
||||
statsmodels.iolib.summary.Summary
|
||||
"""
|
||||
from statsmodels.iolib.summary import Summary
|
||||
from statsmodels.iolib.table import SimpleTable
|
||||
|
||||
model = self.model
|
||||
title = model.__class__.__name__ + " Model Results"
|
||||
|
||||
dep_variable = "endog"
|
||||
orig_endog = self.model.data.orig_endog
|
||||
if isinstance(orig_endog, pd.DataFrame):
|
||||
dep_variable = orig_endog.columns[0]
|
||||
elif isinstance(orig_endog, pd.Series):
|
||||
dep_variable = orig_endog.name
|
||||
seasonal_periods = (
|
||||
None
|
||||
if self.model.seasonal is None
|
||||
else self.model.seasonal_periods
|
||||
)
|
||||
lookup = {
|
||||
"add": "Additive",
|
||||
"additive": "Additive",
|
||||
"mul": "Multiplicative",
|
||||
"multiplicative": "Multiplicative",
|
||||
None: "None",
|
||||
}
|
||||
transform = self.params["use_boxcox"]
|
||||
box_cox_transform = True if transform else False
|
||||
box_cox_coeff = (
|
||||
transform if isinstance(transform, str) else self.params["lamda"]
|
||||
)
|
||||
if isinstance(box_cox_coeff, float):
|
||||
box_cox_coeff = f"{box_cox_coeff:>10.5f}"
|
||||
top_left = [
|
||||
("Dep. Variable:", [dep_variable]),
|
||||
("Model:", [model.__class__.__name__]),
|
||||
("Optimized:", [str(np.any(self.optimized))]),
|
||||
("Trend:", [lookup[self.model.trend]]),
|
||||
("Seasonal:", [lookup[self.model.seasonal]]),
|
||||
("Seasonal Periods:", [str(seasonal_periods)]),
|
||||
("Box-Cox:", [str(box_cox_transform)]),
|
||||
("Box-Cox Coeff.:", [str(box_cox_coeff)]),
|
||||
]
|
||||
|
||||
top_right = [
|
||||
("No. Observations:", [str(len(self.model.endog))]),
|
||||
("SSE", [f"{self.sse:5.3f}"]),
|
||||
("AIC", [f"{self.aic:5.3f}"]),
|
||||
("BIC", [f"{self.bic:5.3f}"]),
|
||||
("AICC", [f"{self.aicc:5.3f}"]),
|
||||
("Date:", None),
|
||||
("Time:", None),
|
||||
]
|
||||
|
||||
smry = Summary()
|
||||
smry.add_table_2cols(
|
||||
self, gleft=top_left, gright=top_right, title=title
|
||||
)
|
||||
formatted = self.params_formatted # type: pd.DataFrame
|
||||
|
||||
def _fmt(x):
|
||||
abs_x = np.abs(x)
|
||||
scale = 1
|
||||
if np.isnan(x):
|
||||
return f"{str(x):>20}"
|
||||
if abs_x != 0:
|
||||
scale = int(np.log10(abs_x))
|
||||
if scale > 4 or scale < -3:
|
||||
return f"{x:>20.5g}"
|
||||
dec = min(7 - scale, 7)
|
||||
fmt = f"{{:>20.{dec}f}}"
|
||||
return fmt.format(x)
|
||||
|
||||
tab = []
|
||||
for _, vals in formatted.iterrows():
|
||||
tab.append(
|
||||
[
|
||||
_fmt(vals.iloc[1]),
|
||||
f"{vals.iloc[0]:>20}",
|
||||
f"{str(bool(vals.iloc[2])):>20}",
|
||||
]
|
||||
)
|
||||
params_table = SimpleTable(
|
||||
tab,
|
||||
headers=["coeff", "code", "optimized"],
|
||||
title="",
|
||||
stubs=list(formatted.index),
|
||||
)
|
||||
|
||||
smry.tables.append(params_table)
|
||||
|
||||
return smry
|
||||
|
||||
def simulate(
|
||||
self,
|
||||
nsimulations,
|
||||
anchor=None,
|
||||
repetitions=1,
|
||||
error="add",
|
||||
random_errors=None,
|
||||
random_state=None,
|
||||
):
|
||||
r"""
|
||||
Random simulations using the state space formulation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nsimulations : int
|
||||
The number of simulation steps.
|
||||
anchor : int, str, or datetime, optional
|
||||
First period for simulation. The simulation will be conditional on
|
||||
all existing datapoints prior to the `anchor`. Type depends on the
|
||||
index of the given `endog` in the model. Two special cases are the
|
||||
strings 'start' and 'end'. `start` refers to beginning the
|
||||
simulation at the first period of the sample, and `end` refers to
|
||||
beginning the simulation at the first period after the sample.
|
||||
Integer values can run from 0 to `nobs`, or can be negative to
|
||||
apply negative indexing. Finally, if a date/time index was provided
|
||||
to the model, then this argument can be a date string to parse or a
|
||||
datetime type. Default is 'end'.
|
||||
repetitions : int, optional
|
||||
Number of simulated paths to generate. Default is 1 simulated path.
|
||||
error : {"add", "mul", "additive", "multiplicative"}, optional
|
||||
Error model for state space formulation. Default is ``"add"``.
|
||||
random_errors : optional
|
||||
Specifies how the random errors should be obtained. Can be one of
|
||||
the following:
|
||||
|
||||
* ``None``: Random normally distributed values with variance
|
||||
estimated from the fit errors drawn from numpy's standard
|
||||
RNG (can be seeded with the `random_state` argument). This is the
|
||||
default option.
|
||||
* A distribution function from ``scipy.stats``, e.g.
|
||||
``scipy.stats.norm``: Fits the distribution function to the fit
|
||||
errors and draws from the fitted distribution.
|
||||
Note the difference between ``scipy.stats.norm`` and
|
||||
``scipy.stats.norm()``, the latter one is a frozen distribution
|
||||
function.
|
||||
* A frozen distribution function from ``scipy.stats``, e.g.
|
||||
``scipy.stats.norm(scale=2)``: Draws from the frozen distribution
|
||||
function.
|
||||
* A ``np.ndarray`` with shape (`nsimulations`, `repetitions`): Uses
|
||||
the given values as random errors.
|
||||
* ``"bootstrap"``: Samples the random errors from the fit errors.
|
||||
|
||||
random_state : int or np.random.RandomState, optional
|
||||
A seed for the random number generator or a
|
||||
``np.random.RandomState`` object. Only used if `random_errors` is
|
||||
``None``. Default is ``None``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
sim : pd.Series, pd.DataFrame or np.ndarray
|
||||
An ``np.ndarray``, ``pd.Series``, or ``pd.DataFrame`` of simulated
|
||||
values.
|
||||
If the original data was a ``pd.Series`` or ``pd.DataFrame``, `sim`
|
||||
will be a ``pd.Series`` if `repetitions` is 1, and a
|
||||
``pd.DataFrame`` of shape (`nsimulations`, `repetitions`) else.
|
||||
Otherwise, if `repetitions` is 1, a ``np.ndarray`` of shape
|
||||
(`nsimulations`,) is returned, and if `repetitions` is not 1 a
|
||||
``np.ndarray`` of shape (`nsimulations`, `repetitions`) is
|
||||
returned.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The simulation is based on the state space model of the Holt-Winter's
|
||||
methods. The state space model assumes that the true value at time
|
||||
:math:`t` is randomly distributed around the prediction value.
|
||||
If using the additive error model, this means:
|
||||
|
||||
.. math::
|
||||
|
||||
y_t &= \hat{y}_{t|t-1} + e_t\\
|
||||
e_t &\sim \mathcal{N}(0, \sigma^2)
|
||||
|
||||
Using the multiplicative error model:
|
||||
|
||||
.. math::
|
||||
|
||||
y_t &= \hat{y}_{t|t-1} \cdot (1 + e_t)\\
|
||||
e_t &\sim \mathcal{N}(0, \sigma^2)
|
||||
|
||||
Inserting these equations into the smoothing equation formulation leads
|
||||
to the state space equations. The notation used here follows
|
||||
[1]_.
|
||||
|
||||
Additionally,
|
||||
|
||||
.. math::
|
||||
|
||||
B_t &= b_{t-1} \circ_d \phi\\
|
||||
L_t &= l_{t-1} \circ_b B_t\\
|
||||
S_t &= s_{t-m}\\
|
||||
Y_t &= L_t \circ_s S_t,
|
||||
|
||||
where :math:`\circ_d` is the operation linking trend and damping
|
||||
parameter (multiplication if the trend is additive, power if the trend
|
||||
is multiplicative), :math:`\circ_b` is the operation linking level and
|
||||
trend (addition if the trend is additive, multiplication if the trend
|
||||
is multiplicative), and :math:`\circ_s` is the operation linking
|
||||
seasonality to the rest.
|
||||
|
||||
The state space equations can then be formulated as
|
||||
|
||||
.. math::
|
||||
|
||||
y_t &= Y_t + \eta \cdot e_t\\
|
||||
l_t &= L_t + \alpha \cdot (M_e \cdot L_t + \kappa_l) \cdot e_t\\
|
||||
b_t &= B_t + \beta \cdot (M_e \cdot B_t + \kappa_b) \cdot e_t\\
|
||||
s_t &= S_t + \gamma \cdot (M_e \cdot S_t + \kappa_s) \cdot e_t\\
|
||||
|
||||
with
|
||||
|
||||
.. math::
|
||||
|
||||
\eta &= \begin{cases}
|
||||
Y_t\quad\text{if error is multiplicative}\\
|
||||
1\quad\text{else}
|
||||
\end{cases}\\
|
||||
M_e &= \begin{cases}
|
||||
1\quad\text{if error is multiplicative}\\
|
||||
0\quad\text{else}
|
||||
\end{cases}\\
|
||||
|
||||
and, when using the additive error model,
|
||||
|
||||
.. math::
|
||||
|
||||
\kappa_l &= \begin{cases}
|
||||
\frac{1}{S_t}\quad
|
||||
\text{if seasonality is multiplicative}\\
|
||||
1\quad\text{else}
|
||||
\end{cases}\\
|
||||
\kappa_b &= \begin{cases}
|
||||
\frac{\kappa_l}{l_{t-1}}\quad
|
||||
\text{if trend is multiplicative}\\
|
||||
\kappa_l\quad\text{else}
|
||||
\end{cases}\\
|
||||
\kappa_s &= \begin{cases}
|
||||
\frac{1}{L_t}\quad\text{if seasonality is
|
||||
multiplicative}\\
|
||||
1\quad\text{else}
|
||||
\end{cases}
|
||||
|
||||
When using the multiplicative error model
|
||||
|
||||
.. math::
|
||||
|
||||
\kappa_l &= \begin{cases}
|
||||
0\quad
|
||||
\text{if seasonality is multiplicative}\\
|
||||
S_t\quad\text{else}
|
||||
\end{cases}\\
|
||||
\kappa_b &= \begin{cases}
|
||||
\frac{\kappa_l}{l_{t-1}}\quad
|
||||
\text{if trend is multiplicative}\\
|
||||
\kappa_l + l_{t-1}\quad\text{else}
|
||||
\end{cases}\\
|
||||
\kappa_s &= \begin{cases}
|
||||
0\quad\text{if seasonality is multiplicative}\\
|
||||
L_t\quad\text{else}
|
||||
\end{cases}
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Hyndman, R.J., & Athanasopoulos, G. (2018) *Forecasting:
|
||||
principles and practice*, 2nd edition, OTexts: Melbourne,
|
||||
Australia. OTexts.com/fpp2. Accessed on February 28th 2020.
|
||||
"""
|
||||
|
||||
# check inputs
|
||||
if error in ["additive", "multiplicative"]:
|
||||
error = {"additive": "add", "multiplicative": "mul"}[error]
|
||||
if error not in ["add", "mul"]:
|
||||
raise ValueError("error must be 'add' or 'mul'!")
|
||||
|
||||
# Get the starting location
|
||||
if anchor is None or anchor == "end":
|
||||
start_idx = self.model.nobs
|
||||
elif anchor == "start":
|
||||
start_idx = 0
|
||||
else:
|
||||
start_idx, _, _ = self.model._get_index_loc(anchor)
|
||||
if isinstance(start_idx, slice):
|
||||
start_idx = start_idx.start
|
||||
if start_idx < 0:
|
||||
start_idx += self.model.nobs
|
||||
if start_idx > self.model.nobs:
|
||||
raise ValueError("Cannot anchor simulation outside of the sample.")
|
||||
|
||||
# get Holt-Winters settings and parameters
|
||||
trend = self.model.trend
|
||||
damped = self.model.damped_trend
|
||||
seasonal = self.model.seasonal
|
||||
use_boxcox = self.params["use_boxcox"]
|
||||
lamda = self.params["lamda"]
|
||||
alpha = self.params["smoothing_level"]
|
||||
beta = self.params["smoothing_trend"]
|
||||
gamma = self.params["smoothing_seasonal"]
|
||||
phi = self.params["damping_trend"]
|
||||
# if model has no seasonal component, use 1 as period length
|
||||
m = max(self.model.seasonal_periods, 1)
|
||||
n_params = (
|
||||
2
|
||||
+ 2 * self.model.has_trend
|
||||
+ (m + 1) * self.model.has_seasonal
|
||||
+ damped
|
||||
)
|
||||
mul_seasonal = seasonal == "mul"
|
||||
mul_trend = trend == "mul"
|
||||
mul_error = error == "mul"
|
||||
|
||||
# define trend, damping and seasonality operations
|
||||
if mul_trend:
|
||||
op_b = np.multiply
|
||||
op_d = np.power
|
||||
neutral_b = 1
|
||||
else:
|
||||
op_b = np.add
|
||||
op_d = np.multiply
|
||||
neutral_b = 0
|
||||
if mul_seasonal:
|
||||
op_s = np.multiply
|
||||
neutral_s = 1
|
||||
else:
|
||||
op_s = np.add
|
||||
neutral_s = 0
|
||||
|
||||
# set initial values
|
||||
level = self.level
|
||||
_trend = self.trend
|
||||
season = self.season
|
||||
# (notation as in https://otexts.com/fpp2/ets.html)
|
||||
y = np.empty((nsimulations, repetitions))
|
||||
# lvl instead of l because of E741
|
||||
lvl = np.empty((nsimulations + 1, repetitions))
|
||||
b = np.empty((nsimulations + 1, repetitions))
|
||||
s = np.empty((nsimulations + m, repetitions))
|
||||
# the following uses python's index wrapping
|
||||
if start_idx == 0:
|
||||
lvl[-1, :] = self.params["initial_level"]
|
||||
b[-1, :] = self.params["initial_trend"]
|
||||
else:
|
||||
lvl[-1, :] = level[start_idx - 1]
|
||||
b[-1, :] = _trend[start_idx - 1]
|
||||
if 0 <= start_idx and start_idx <= m:
|
||||
initial_seasons = self.params["initial_seasons"]
|
||||
_s = np.concatenate(
|
||||
(initial_seasons[start_idx:], season[:start_idx])
|
||||
)
|
||||
s[-m:, :] = np.tile(_s, (repetitions, 1)).T
|
||||
else:
|
||||
s[-m:, :] = np.tile(
|
||||
season[start_idx - m : start_idx], (repetitions, 1)
|
||||
).T
|
||||
|
||||
# set neutral values for unused features
|
||||
if trend is None:
|
||||
b[:, :] = neutral_b
|
||||
phi = 1
|
||||
beta = 0
|
||||
if seasonal is None:
|
||||
s[:, :] = neutral_s
|
||||
gamma = 0
|
||||
if not damped:
|
||||
phi = 1
|
||||
|
||||
# calculate residuals for error covariance estimation
|
||||
if use_boxcox:
|
||||
fitted = boxcox(self.fittedvalues, lamda)
|
||||
else:
|
||||
fitted = self.fittedvalues
|
||||
if error == "add":
|
||||
resid = self.model._y - fitted
|
||||
else:
|
||||
resid = (self.model._y - fitted) / fitted
|
||||
sigma = np.sqrt(np.sum(resid**2) / (len(resid) - n_params))
|
||||
|
||||
# get random error eps
|
||||
if isinstance(random_errors, np.ndarray):
|
||||
if random_errors.shape != (nsimulations, repetitions):
|
||||
raise ValueError(
|
||||
"If random_errors is an ndarray, it must have shape "
|
||||
"(nsimulations, repetitions)"
|
||||
)
|
||||
eps = random_errors
|
||||
elif random_errors == "bootstrap":
|
||||
eps = np.random.choice(
|
||||
resid, size=(nsimulations, repetitions), replace=True
|
||||
)
|
||||
elif random_errors is None:
|
||||
if random_state is None:
|
||||
eps = np.random.randn(nsimulations, repetitions) * sigma
|
||||
elif isinstance(random_state, int):
|
||||
rng = np.random.RandomState(random_state)
|
||||
eps = rng.randn(nsimulations, repetitions) * sigma
|
||||
elif isinstance(random_state, np.random.RandomState):
|
||||
eps = random_state.randn(nsimulations, repetitions) * sigma
|
||||
else:
|
||||
raise ValueError(
|
||||
"Argument random_state must be None, an integer, "
|
||||
"or an instance of np.random.RandomState"
|
||||
)
|
||||
elif isinstance(random_errors, (rv_continuous, rv_discrete)):
|
||||
params = random_errors.fit(resid)
|
||||
eps = random_errors.rvs(*params, size=(nsimulations, repetitions))
|
||||
elif isinstance(random_errors, rv_frozen):
|
||||
eps = random_errors.rvs(size=(nsimulations, repetitions))
|
||||
else:
|
||||
raise ValueError("Argument random_errors has unexpected value!")
|
||||
|
||||
for t in range(nsimulations):
|
||||
b0 = op_d(b[t - 1, :], phi)
|
||||
l0 = op_b(lvl[t - 1, :], b0)
|
||||
s0 = s[t - m, :]
|
||||
y0 = op_s(l0, s0)
|
||||
if error == "add":
|
||||
eta = 1
|
||||
kappa_l = 1 / s0 if mul_seasonal else 1
|
||||
kappa_b = kappa_l / lvl[t - 1, :] if mul_trend else kappa_l
|
||||
kappa_s = 1 / l0 if mul_seasonal else 1
|
||||
else:
|
||||
eta = y0
|
||||
kappa_l = 0 if mul_seasonal else s0
|
||||
kappa_b = (
|
||||
kappa_l / lvl[t - 1, :]
|
||||
if mul_trend
|
||||
else kappa_l + lvl[t - 1, :]
|
||||
)
|
||||
kappa_s = 0 if mul_seasonal else l0
|
||||
|
||||
y[t, :] = y0 + eta * eps[t, :]
|
||||
lvl[t, :] = l0 + alpha * (mul_error * l0 + kappa_l) * eps[t, :]
|
||||
b[t, :] = b0 + beta * (mul_error * b0 + kappa_b) * eps[t, :]
|
||||
s[t, :] = s0 + gamma * (mul_error * s0 + kappa_s) * eps[t, :]
|
||||
|
||||
if use_boxcox:
|
||||
y = inv_boxcox(y, lamda)
|
||||
|
||||
sim = np.atleast_1d(np.squeeze(y))
|
||||
if y.shape[0] == 1 and y.size > 1:
|
||||
sim = sim[None, :]
|
||||
# Wrap data / squeeze where appropriate
|
||||
if not isinstance(self.model.data, PandasData):
|
||||
return sim
|
||||
|
||||
_, _, _, index = self.model._get_prediction_index(
|
||||
start_idx, start_idx + nsimulations - 1
|
||||
)
|
||||
if repetitions == 1:
|
||||
sim = pd.Series(sim, index=index, name=self.model.endog_names)
|
||||
else:
|
||||
sim = pd.DataFrame(sim, index=index)
|
||||
|
||||
return sim
|
||||
|
||||
|
||||
class HoltWintersResultsWrapper(ResultsWrapper):
|
||||
_attrs = {
|
||||
"fittedvalues": "rows",
|
||||
"level": "rows",
|
||||
"resid": "rows",
|
||||
"season": "rows",
|
||||
"trend": "rows",
|
||||
"slope": "rows",
|
||||
}
|
||||
_wrap_attrs = union_dicts(ResultsWrapper._wrap_attrs, _attrs)
|
||||
_methods = {"predict": "dates", "forecast": "dates"}
|
||||
_wrap_methods = union_dicts(ResultsWrapper._wrap_methods, _methods)
|
||||
|
||||
|
||||
populate_wrapper(HoltWintersResultsWrapper, HoltWintersResults)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,715 @@
|
||||
DATE,HOUSTNSA
|
||||
1959-01-01,96.2
|
||||
1959-02-01,99.0
|
||||
1959-03-01,127.7
|
||||
1959-04-01,150.8
|
||||
1959-05-01,152.5
|
||||
1959-06-01,147.8
|
||||
1959-07-01,148.1
|
||||
1959-08-01,138.2
|
||||
1959-09-01,136.4
|
||||
1959-10-01,120.0
|
||||
1959-11-01,104.7
|
||||
1959-12-01,95.6
|
||||
1960-01-01,86.0
|
||||
1960-02-01,90.7
|
||||
1960-03-01,90.5
|
||||
1960-04-01,123.0
|
||||
1960-05-01,130.2
|
||||
1960-06-01,122.8
|
||||
1960-07-01,114.3
|
||||
1960-08-01,130.3
|
||||
1960-09-01,96.9
|
||||
1960-10-01,110.4
|
||||
1960-11-01,92.8
|
||||
1960-12-01,64.2
|
||||
1961-01-01,70.4
|
||||
1961-02-01,74.1
|
||||
1961-03-01,104.2
|
||||
1961-04-01,112.8
|
||||
1961-05-01,127.6
|
||||
1961-06-01,134.8
|
||||
1961-07-01,126.6
|
||||
1961-08-01,127.1
|
||||
1961-09-01,125.4
|
||||
1961-10-01,124.8
|
||||
1961-11-01,103.0
|
||||
1961-12-01,82.2
|
||||
1962-01-01,81.2
|
||||
1962-02-01,77.1
|
||||
1962-03-01,116.2
|
||||
1962-04-01,147.8
|
||||
1962-05-01,155.2
|
||||
1962-06-01,136.8
|
||||
1962-07-01,136.5
|
||||
1962-08-01,147.7
|
||||
1962-09-01,114.3
|
||||
1962-10-01,135.2
|
||||
1962-11-01,120.9
|
||||
1962-12-01,93.9
|
||||
1963-01-01,79.0
|
||||
1963-02-01,89.6
|
||||
1963-03-01,124.8
|
||||
1963-04-01,164.2
|
||||
1963-05-01,172.7
|
||||
1963-06-01,154.2
|
||||
1963-07-01,151.3
|
||||
1963-08-01,144.0
|
||||
1963-09-01,143.7
|
||||
1963-10-01,165.3
|
||||
1963-11-01,119.3
|
||||
1963-12-01,95.0
|
||||
1964-01-01,97.9
|
||||
1964-02-01,101.3
|
||||
1964-03-01,129.1
|
||||
1964-04-01,147.1
|
||||
1964-05-01,152.8
|
||||
1964-06-01,157.2
|
||||
1964-07-01,140.6
|
||||
1964-08-01,138.3
|
||||
1964-09-01,119.8
|
||||
1964-10-01,141.2
|
||||
1964-11-01,110.6
|
||||
1964-12-01,93.0
|
||||
1965-01-01,81.7
|
||||
1965-02-01,80.9
|
||||
1965-03-01,119.9
|
||||
1965-04-01,148.6
|
||||
1965-05-01,153.3
|
||||
1965-06-01,151.8
|
||||
1965-07-01,139.1
|
||||
1965-08-01,128.3
|
||||
1965-09-01,124.6
|
||||
1965-10-01,133.1
|
||||
1965-11-01,110.5
|
||||
1965-12-01,101.1
|
||||
1966-01-01,79.4
|
||||
1966-02-01,76.2
|
||||
1966-03-01,118.1
|
||||
1966-04-01,140.9
|
||||
1966-05-01,130.0
|
||||
1966-06-01,120.6
|
||||
1966-07-01,99.2
|
||||
1966-08-01,101.8
|
||||
1966-09-01,89.1
|
||||
1966-10-01,76.6
|
||||
1966-11-01,72.8
|
||||
1966-12-01,60.2
|
||||
1967-01-01,59.1
|
||||
1967-02-01,61.4
|
||||
1967-03-01,91.5
|
||||
1967-04-01,113.7
|
||||
1967-05-01,132.0
|
||||
1967-06-01,125.4
|
||||
1967-07-01,125.3
|
||||
1967-08-01,127.4
|
||||
1967-09-01,121.9
|
||||
1967-10-01,135.4
|
||||
1967-11-01,118.4
|
||||
1967-12-01,80.1
|
||||
1968-01-01,80.5
|
||||
1968-02-01,84.6
|
||||
1968-03-01,126.6
|
||||
1968-04-01,162.0
|
||||
1968-05-01,140.9
|
||||
1968-06-01,137.9
|
||||
1968-07-01,139.8
|
||||
1968-08-01,136.6
|
||||
1968-09-01,134.2
|
||||
1968-10-01,140.8
|
||||
1968-11-01,127.1
|
||||
1968-12-01,96.4
|
||||
1969-01-01,101.5
|
||||
1969-02-01,90.1
|
||||
1969-03-01,131.9
|
||||
1969-04-01,159.0
|
||||
1969-05-01,155.5
|
||||
1969-06-01,147.3
|
||||
1969-07-01,125.2
|
||||
1969-08-01,124.9
|
||||
1969-09-01,129.3
|
||||
1969-10-01,123.4
|
||||
1969-11-01,94.6
|
||||
1969-12-01,84.1
|
||||
1970-01-01,66.4
|
||||
1970-02-01,74.3
|
||||
1970-03-01,114.7
|
||||
1970-04-01,128.4
|
||||
1970-05-01,125.0
|
||||
1970-06-01,135.2
|
||||
1970-07-01,140.8
|
||||
1970-08-01,128.7
|
||||
1970-09-01,130.9
|
||||
1970-10-01,140.9
|
||||
1970-11-01,126.9
|
||||
1970-12-01,121.4
|
||||
1971-01-01,110.6
|
||||
1971-02-01,102.2
|
||||
1971-03-01,167.9
|
||||
1971-04-01,201.1
|
||||
1971-05-01,198.5
|
||||
1971-06-01,193.8
|
||||
1971-07-01,194.3
|
||||
1971-08-01,204.5
|
||||
1971-09-01,173.8
|
||||
1971-10-01,179.7
|
||||
1971-11-01,173.7
|
||||
1971-12-01,152.1
|
||||
1972-01-01,149.1
|
||||
1972-02-01,152.2
|
||||
1972-03-01,203.9
|
||||
1972-04-01,211.6
|
||||
1972-05-01,225.8
|
||||
1972-06-01,223.1
|
||||
1972-07-01,206.5
|
||||
1972-08-01,228.6
|
||||
1972-09-01,203.0
|
||||
1972-10-01,216.5
|
||||
1972-11-01,185.7
|
||||
1972-12-01,150.5
|
||||
1973-01-01,146.6
|
||||
1973-02-01,138.0
|
||||
1973-03-01,200.0
|
||||
1973-04-01,205.0
|
||||
1973-05-01,234.0
|
||||
1973-06-01,202.6
|
||||
1973-07-01,202.6
|
||||
1973-08-01,197.2
|
||||
1973-09-01,148.4
|
||||
1973-10-01,147.1
|
||||
1973-11-01,133.3
|
||||
1973-12-01,90.4
|
||||
1974-01-01,84.5
|
||||
1974-02-01,109.4
|
||||
1974-03-01,124.8
|
||||
1974-04-01,159.5
|
||||
1974-05-01,149.0
|
||||
1974-06-01,147.6
|
||||
1974-07-01,126.6
|
||||
1974-08-01,111.1
|
||||
1974-09-01,98.3
|
||||
1974-10-01,96.7
|
||||
1974-11-01,75.1
|
||||
1974-12-01,55.1
|
||||
1975-01-01,56.1
|
||||
1975-02-01,54.7
|
||||
1975-03-01,80.2
|
||||
1975-04-01,97.9
|
||||
1975-05-01,116.1
|
||||
1975-06-01,110.3
|
||||
1975-07-01,119.3
|
||||
1975-08-01,117.3
|
||||
1975-09-01,111.9
|
||||
1975-10-01,123.6
|
||||
1975-11-01,96.9
|
||||
1975-12-01,76.1
|
||||
1976-01-01,72.5
|
||||
1976-02-01,89.9
|
||||
1976-03-01,118.4
|
||||
1976-04-01,137.2
|
||||
1976-05-01,147.9
|
||||
1976-06-01,154.2
|
||||
1976-07-01,136.6
|
||||
1976-08-01,145.9
|
||||
1976-09-01,151.8
|
||||
1976-10-01,148.4
|
||||
1976-11-01,127.1
|
||||
1976-12-01,107.4
|
||||
1977-01-01,81.3
|
||||
1977-02-01,112.5
|
||||
1977-03-01,173.6
|
||||
1977-04-01,182.2
|
||||
1977-05-01,201.3
|
||||
1977-06-01,197.6
|
||||
1977-07-01,189.8
|
||||
1977-08-01,194.0
|
||||
1977-09-01,177.7
|
||||
1977-10-01,193.1
|
||||
1977-11-01,154.8
|
||||
1977-12-01,129.2
|
||||
1978-01-01,88.6
|
||||
1978-02-01,101.3
|
||||
1978-03-01,172.1
|
||||
1978-04-01,197.5
|
||||
1978-05-01,211.0
|
||||
1978-06-01,216.0
|
||||
1978-07-01,192.2
|
||||
1978-08-01,190.9
|
||||
1978-09-01,180.5
|
||||
1978-10-01,192.1
|
||||
1978-11-01,158.6
|
||||
1978-12-01,119.5
|
||||
1979-01-01,88.2
|
||||
1979-02-01,84.5
|
||||
1979-03-01,152.9
|
||||
1979-04-01,161.0
|
||||
1979-05-01,189.1
|
||||
1979-06-01,191.8
|
||||
1979-07-01,164.2
|
||||
1979-08-01,170.3
|
||||
1979-09-01,163.7
|
||||
1979-10-01,169.0
|
||||
1979-11-01,118.7
|
||||
1979-12-01,91.6
|
||||
1980-01-01,73.1
|
||||
1980-02-01,79.9
|
||||
1980-03-01,85.1
|
||||
1980-04-01,96.2
|
||||
1980-05-01,91.7
|
||||
1980-06-01,116.4
|
||||
1980-07-01,120.1
|
||||
1980-08-01,129.9
|
||||
1980-09-01,138.3
|
||||
1980-10-01,152.7
|
||||
1980-11-01,112.9
|
||||
1980-12-01,95.9
|
||||
1981-01-01,84.5
|
||||
1981-02-01,71.9
|
||||
1981-03-01,107.8
|
||||
1981-04-01,123.0
|
||||
1981-05-01,109.9
|
||||
1981-06-01,105.8
|
||||
1981-07-01,99.9
|
||||
1981-08-01,86.3
|
||||
1981-09-01,84.1
|
||||
1981-10-01,87.2
|
||||
1981-11-01,64.6
|
||||
1981-12-01,59.1
|
||||
1982-01-01,47.2
|
||||
1982-02-01,51.3
|
||||
1982-03-01,78.2
|
||||
1982-04-01,84.1
|
||||
1982-05-01,98.8
|
||||
1982-06-01,91.1
|
||||
1982-07-01,106.8
|
||||
1982-08-01,96.0
|
||||
1982-09-01,106.4
|
||||
1982-10-01,110.5
|
||||
1982-11-01,108.9
|
||||
1982-12-01,82.9
|
||||
1983-01-01,91.3
|
||||
1983-02-01,96.3
|
||||
1983-03-01,134.6
|
||||
1983-04-01,135.8
|
||||
1983-05-01,174.9
|
||||
1983-06-01,173.2
|
||||
1983-07-01,161.6
|
||||
1983-08-01,176.8
|
||||
1983-09-01,154.9
|
||||
1983-10-01,159.3
|
||||
1983-11-01,136.0
|
||||
1983-12-01,108.3
|
||||
1984-01-01,109.1
|
||||
1984-02-01,130.0
|
||||
1984-03-01,137.5
|
||||
1984-04-01,172.7
|
||||
1984-05-01,180.7
|
||||
1984-06-01,184.0
|
||||
1984-07-01,162.1
|
||||
1984-08-01,147.4
|
||||
1984-09-01,148.5
|
||||
1984-10-01,152.3
|
||||
1984-11-01,126.2
|
||||
1984-12-01,98.9
|
||||
1985-01-01,105.4
|
||||
1985-02-01,95.4
|
||||
1985-03-01,145.0
|
||||
1985-04-01,175.8
|
||||
1985-05-01,170.2
|
||||
1985-06-01,163.2
|
||||
1985-07-01,160.7
|
||||
1985-08-01,160.7
|
||||
1985-09-01,147.7
|
||||
1985-10-01,173.0
|
||||
1985-11-01,124.1
|
||||
1985-12-01,120.5
|
||||
1986-01-01,115.6
|
||||
1986-02-01,107.2
|
||||
1986-03-01,151.0
|
||||
1986-04-01,188.2
|
||||
1986-05-01,186.6
|
||||
1986-06-01,183.6
|
||||
1986-07-01,172.0
|
||||
1986-08-01,163.8
|
||||
1986-09-01,154.0
|
||||
1986-10-01,154.8
|
||||
1986-11-01,115.6
|
||||
1986-12-01,113.0
|
||||
1987-01-01,105.1
|
||||
1987-02-01,102.8
|
||||
1987-03-01,141.2
|
||||
1987-04-01,159.3
|
||||
1987-05-01,158.0
|
||||
1987-06-01,162.9
|
||||
1987-07-01,152.4
|
||||
1987-08-01,143.6
|
||||
1987-09-01,152.0
|
||||
1987-10-01,139.1
|
||||
1987-11-01,118.8
|
||||
1987-12-01,85.4
|
||||
1988-01-01,78.2
|
||||
1988-02-01,90.2
|
||||
1988-03-01,128.8
|
||||
1988-04-01,153.2
|
||||
1988-05-01,140.2
|
||||
1988-06-01,150.2
|
||||
1988-07-01,137.0
|
||||
1988-08-01,136.8
|
||||
1988-09-01,131.1
|
||||
1988-10-01,135.1
|
||||
1988-11-01,113.0
|
||||
1988-12-01,94.2
|
||||
1989-01-01,100.1
|
||||
1989-02-01,85.8
|
||||
1989-03-01,117.8
|
||||
1989-04-01,129.4
|
||||
1989-05-01,131.7
|
||||
1989-06-01,143.2
|
||||
1989-07-01,134.7
|
||||
1989-08-01,122.4
|
||||
1989-09-01,109.3
|
||||
1989-10-01,130.1
|
||||
1989-11-01,96.6
|
||||
1989-12-01,75.0
|
||||
1990-01-01,99.2
|
||||
1990-02-01,86.9
|
||||
1990-03-01,108.5
|
||||
1990-04-01,119.0
|
||||
1990-05-01,121.1
|
||||
1990-06-01,117.8
|
||||
1990-07-01,111.2
|
||||
1990-08-01,102.8
|
||||
1990-09-01,93.1
|
||||
1990-10-01,94.2
|
||||
1990-11-01,81.4
|
||||
1990-12-01,57.4
|
||||
1991-01-01,52.5
|
||||
1991-02-01,59.1
|
||||
1991-03-01,73.8
|
||||
1991-04-01,99.7
|
||||
1991-05-01,97.7
|
||||
1991-06-01,103.4
|
||||
1991-07-01,103.5
|
||||
1991-08-01,94.7
|
||||
1991-09-01,86.6
|
||||
1991-10-01,101.8
|
||||
1991-11-01,75.6
|
||||
1991-12-01,65.6
|
||||
1992-01-01,71.6
|
||||
1992-02-01,78.8
|
||||
1992-03-01,111.6
|
||||
1992-04-01,107.6
|
||||
1992-05-01,115.2
|
||||
1992-06-01,117.8
|
||||
1992-07-01,106.2
|
||||
1992-08-01,109.9
|
||||
1992-09-01,106.0
|
||||
1992-10-01,111.8
|
||||
1992-11-01,84.5
|
||||
1992-12-01,78.6
|
||||
1993-01-01,70.5
|
||||
1993-02-01,74.6
|
||||
1993-03-01,95.5
|
||||
1993-04-01,117.8
|
||||
1993-05-01,120.9
|
||||
1993-06-01,128.5
|
||||
1993-07-01,115.3
|
||||
1993-08-01,121.8
|
||||
1993-09-01,118.5
|
||||
1993-10-01,123.3
|
||||
1993-11-01,102.3
|
||||
1993-12-01,98.7
|
||||
1994-01-01,76.2
|
||||
1994-02-01,83.5
|
||||
1994-03-01,134.3
|
||||
1994-04-01,137.6
|
||||
1994-05-01,148.8
|
||||
1994-06-01,136.4
|
||||
1994-07-01,127.8
|
||||
1994-08-01,139.8
|
||||
1994-09-01,130.1
|
||||
1994-10-01,130.6
|
||||
1994-11-01,113.4
|
||||
1994-12-01,98.5
|
||||
1995-01-01,84.5
|
||||
1995-02-01,81.6
|
||||
1995-03-01,103.8
|
||||
1995-04-01,116.9
|
||||
1995-05-01,130.5
|
||||
1995-06-01,123.4
|
||||
1995-07-01,129.1
|
||||
1995-08-01,135.8
|
||||
1995-09-01,122.4
|
||||
1995-10-01,126.2
|
||||
1995-11-01,107.2
|
||||
1995-12-01,92.8
|
||||
1996-01-01,90.7
|
||||
1996-02-01,95.9
|
||||
1996-03-01,116.0
|
||||
1996-04-01,146.6
|
||||
1996-05-01,143.9
|
||||
1996-06-01,138.0
|
||||
1996-07-01,137.5
|
||||
1996-08-01,144.2
|
||||
1996-09-01,128.7
|
||||
1996-10-01,130.8
|
||||
1996-11-01,111.5
|
||||
1996-12-01,93.1
|
||||
1997-01-01,82.2
|
||||
1997-02-01,94.7
|
||||
1997-03-01,120.4
|
||||
1997-04-01,142.3
|
||||
1997-05-01,136.3
|
||||
1997-06-01,140.4
|
||||
1997-07-01,134.6
|
||||
1997-08-01,126.5
|
||||
1997-09-01,139.2
|
||||
1997-10-01,139.0
|
||||
1997-11-01,112.4
|
||||
1997-12-01,106.0
|
||||
1998-01-01,91.2
|
||||
1998-02-01,101.1
|
||||
1998-03-01,132.6
|
||||
1998-04-01,144.9
|
||||
1998-05-01,143.3
|
||||
1998-06-01,159.6
|
||||
1998-07-01,156.0
|
||||
1998-08-01,147.5
|
||||
1998-09-01,141.5
|
||||
1998-10-01,155.5
|
||||
1998-11-01,124.2
|
||||
1998-12-01,119.6
|
||||
1999-01-01,106.8
|
||||
1999-02-01,110.2
|
||||
1999-03-01,147.3
|
||||
1999-04-01,144.6
|
||||
1999-05-01,153.2
|
||||
1999-06-01,149.4
|
||||
1999-07-01,152.6
|
||||
1999-08-01,152.9
|
||||
1999-09-01,140.3
|
||||
1999-10-01,142.9
|
||||
1999-11-01,127.4
|
||||
1999-12-01,113.6
|
||||
2000-01-01,104.0
|
||||
2000-02-01,119.7
|
||||
2000-03-01,133.4
|
||||
2000-04-01,149.5
|
||||
2000-05-01,152.9
|
||||
2000-06-01,146.3
|
||||
2000-07-01,135.0
|
||||
2000-08-01,141.4
|
||||
2000-09-01,128.9
|
||||
2000-10-01,139.7
|
||||
2000-11-01,117.1
|
||||
2000-12-01,100.7
|
||||
2001-01-01,106.4
|
||||
2001-02-01,108.2
|
||||
2001-03-01,133.2
|
||||
2001-04-01,151.3
|
||||
2001-05-01,154.0
|
||||
2001-06-01,155.2
|
||||
2001-07-01,154.6
|
||||
2001-08-01,141.5
|
||||
2001-09-01,133.1
|
||||
2001-10-01,139.8
|
||||
2001-11-01,121.0
|
||||
2001-12-01,104.6
|
||||
2002-01-01,110.4
|
||||
2002-02-01,120.4
|
||||
2002-03-01,138.2
|
||||
2002-04-01,148.8
|
||||
2002-05-01,165.5
|
||||
2002-06-01,160.3
|
||||
2002-07-01,155.9
|
||||
2002-08-01,147.0
|
||||
2002-09-01,155.6
|
||||
2002-10-01,146.8
|
||||
2002-11-01,133.0
|
||||
2002-12-01,123.1
|
||||
2003-01-01,117.8
|
||||
2003-02-01,109.7
|
||||
2003-03-01,147.2
|
||||
2003-04-01,151.2
|
||||
2003-05-01,165.0
|
||||
2003-06-01,174.5
|
||||
2003-07-01,175.8
|
||||
2003-08-01,163.8
|
||||
2003-09-01,171.3
|
||||
2003-10-01,173.5
|
||||
2003-11-01,153.7
|
||||
2003-12-01,144.2
|
||||
2004-01-01,124.5
|
||||
2004-02-01,126.4
|
||||
2004-03-01,173.8
|
||||
2004-04-01,179.5
|
||||
2004-05-01,187.6
|
||||
2004-06-01,172.3
|
||||
2004-07-01,182.0
|
||||
2004-08-01,185.9
|
||||
2004-09-01,164.0
|
||||
2004-10-01,181.3
|
||||
2004-11-01,138.1
|
||||
2004-12-01,140.2
|
||||
2005-01-01,142.9
|
||||
2005-02-01,149.1
|
||||
2005-03-01,156.2
|
||||
2005-04-01,184.6
|
||||
2005-05-01,197.9
|
||||
2005-06-01,192.8
|
||||
2005-07-01,187.6
|
||||
2005-08-01,192.0
|
||||
2005-09-01,187.9
|
||||
2005-10-01,180.4
|
||||
2005-11-01,160.7
|
||||
2005-12-01,136.0
|
||||
2006-01-01,153.0
|
||||
2006-02-01,145.1
|
||||
2006-03-01,165.9
|
||||
2006-04-01,160.5
|
||||
2006-05-01,190.2
|
||||
2006-06-01,170.2
|
||||
2006-07-01,160.9
|
||||
2006-08-01,146.8
|
||||
2006-09-01,150.1
|
||||
2006-10-01,130.6
|
||||
2006-11-01,115.2
|
||||
2006-12-01,112.4
|
||||
2007-01-01,95.0
|
||||
2007-02-01,103.1
|
||||
2007-03-01,123.8
|
||||
2007-04-01,135.6
|
||||
2007-05-01,136.5
|
||||
2007-06-01,137.8
|
||||
2007-07-01,127.9
|
||||
2007-08-01,121.2
|
||||
2007-09-01,101.5
|
||||
2007-10-01,115.0
|
||||
2007-11-01,88.8
|
||||
2007-12-01,68.9
|
||||
2008-01-01,70.8
|
||||
2008-02-01,78.4
|
||||
2008-03-01,82.2
|
||||
2008-04-01,89.5
|
||||
2008-05-01,91.7
|
||||
2008-06-01,102.5
|
||||
2008-07-01,86.7
|
||||
2008-08-01,76.4
|
||||
2008-09-01,73.9
|
||||
2008-10-01,68.2
|
||||
2008-11-01,47.5
|
||||
2008-12-01,37.7
|
||||
2009-01-01,31.9
|
||||
2009-02-01,39.8
|
||||
2009-03-01,42.7
|
||||
2009-04-01,42.5
|
||||
2009-05-01,52.2
|
||||
2009-06-01,59.1
|
||||
2009-07-01,56.8
|
||||
2009-08-01,52.9
|
||||
2009-09-01,52.6
|
||||
2009-10-01,44.5
|
||||
2009-11-01,42.3
|
||||
2009-12-01,36.6
|
||||
2010-01-01,38.9
|
||||
2010-02-01,40.7
|
||||
2010-03-01,54.7
|
||||
2010-04-01,62.0
|
||||
2010-05-01,56.2
|
||||
2010-06-01,53.8
|
||||
2010-07-01,51.5
|
||||
2010-08-01,56.3
|
||||
2010-09-01,53.0
|
||||
2010-10-01,45.4
|
||||
2010-11-01,40.6
|
||||
2010-12-01,33.8
|
||||
2011-01-01,40.2
|
||||
2011-02-01,35.4
|
||||
2011-03-01,49.9
|
||||
2011-04-01,49.0
|
||||
2011-05-01,54.0
|
||||
2011-06-01,60.5
|
||||
2011-07-01,57.6
|
||||
2011-08-01,54.5
|
||||
2011-09-01,58.8
|
||||
2011-10-01,53.2
|
||||
2011-11-01,53.0
|
||||
2011-12-01,42.7
|
||||
2012-01-01,47.2
|
||||
2012-02-01,49.7
|
||||
2012-03-01,58.0
|
||||
2012-04-01,66.8
|
||||
2012-05-01,67.8
|
||||
2012-06-01,74.7
|
||||
2012-07-01,69.2
|
||||
2012-08-01,69.0
|
||||
2012-09-01,75.8
|
||||
2012-10-01,77.0
|
||||
2012-11-01,62.2
|
||||
2012-12-01,63.2
|
||||
2013-01-01,58.7
|
||||
2013-02-01,66.1
|
||||
2013-03-01,83.3
|
||||
2013-04-01,76.3
|
||||
2013-05-01,87.2
|
||||
2013-06-01,80.7
|
||||
2013-07-01,84.0
|
||||
2013-08-01,80.4
|
||||
2013-09-01,78.4
|
||||
2013-10-01,78.4
|
||||
2013-11-01,83.8
|
||||
2013-12-01,67.6
|
||||
2014-01-01,60.7
|
||||
2014-02-01,65.1
|
||||
2014-03-01,80.2
|
||||
2014-04-01,94.9
|
||||
2014-05-01,92.5
|
||||
2014-06-01,87.3
|
||||
2014-07-01,101.0
|
||||
2014-08-01,86.2
|
||||
2014-09-01,94.2
|
||||
2014-10-01,92.0
|
||||
2014-11-01,75.8
|
||||
2014-12-01,73.4
|
||||
2015-01-01,73.0
|
||||
2015-02-01,61.9
|
||||
2015-03-01,79.7
|
||||
2015-04-01,108.5
|
||||
2015-05-01,99.6
|
||||
2015-06-01,112.3
|
||||
2015-07-01,107.2
|
||||
2015-08-01,99.2
|
||||
2015-09-01,111.6
|
||||
2015-10-01,90.9
|
||||
2015-11-01,89.9
|
||||
2015-12-01,78.1
|
||||
2016-01-01,74.3
|
||||
2016-02-01,84.1
|
||||
2016-03-01,90.7
|
||||
2016-04-01,106.2
|
||||
2016-05-01,105.0
|
||||
2016-06-01,111.6
|
||||
2016-07-01,115.2
|
||||
2016-08-01,102.8
|
||||
2016-09-01,95.0
|
||||
2016-10-01,114.5
|
||||
2016-11-01,87.8
|
||||
2016-12-01,86.5
|
||||
2017-01-01,82.3
|
||||
2017-02-01,87.8
|
||||
2017-03-01,97.1
|
||||
2017-04-01,105.2
|
||||
2017-05-01,106.0
|
||||
2017-06-01,116.3
|
||||
2017-07-01,112.3
|
||||
2017-08-01,102.6
|
||||
2017-09-01,104.4
|
||||
2017-10-01,109.6
|
||||
2017-11-01,97.9
|
||||
2017-12-01,81.4
|
||||
2018-01-01,91.6
|
||||
2018-02-01,89.7
|
||||
2018-03-01,107.2
|
||||
2018-04-01,117.5
|
||||
2018-05-01,123.8
|
||||
2018-06-01,111.5
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user