Improvements on EnsembleFTS and IncrementalEnsembleFTS
This commit is contained in:
parent
934c744139
commit
f7c1b4443e
@ -299,7 +299,7 @@ def white_noise(n=500):
|
|||||||
def random_walk(n=500, type='gaussian'):
|
def random_walk(n=500, type='gaussian'):
|
||||||
"""
|
"""
|
||||||
Simple random walk
|
Simple random walk
|
||||||
|
|
||||||
:param n: number of samples
|
:param n: number of samples
|
||||||
:param type: 'gaussian' or 'uniform'
|
:param type: 'gaussian' or 'uniform'
|
||||||
:return:
|
:return:
|
||||||
|
@ -43,10 +43,12 @@ class EnsembleFTS(fts.FTS):
|
|||||||
self.alpha = kwargs.get("alpha", 0.05)
|
self.alpha = kwargs.get("alpha", 0.05)
|
||||||
"""The quantiles """
|
"""The quantiles """
|
||||||
self.point_method = kwargs.get('point_method', 'mean')
|
self.point_method = kwargs.get('point_method', 'mean')
|
||||||
"""The method used to mix the several model's forecasts into a unique point forecast. Options: mean, median, quantile"""
|
"""The method used to mix the several model's forecasts into a unique point forecast. Options: mean, median, quantile, exponential"""
|
||||||
self.interval_method = kwargs.get('interval_method', 'quantile')
|
self.interval_method = kwargs.get('interval_method', 'quantile')
|
||||||
"""The method used to mix the several model's forecasts into a interval forecast. Options: quantile, extremum, normal"""
|
"""The method used to mix the several model's forecasts into a interval forecast. Options: quantile, extremum, normal"""
|
||||||
self.order = 1
|
#self.order = 1
|
||||||
|
self.exp_factor = kwargs.get('exp_factor', 0.5)
|
||||||
|
"""Multiplicative factor on exponential averaging of the models"""
|
||||||
|
|
||||||
def append_model(self, model):
|
def append_model(self, model):
|
||||||
"""
|
"""
|
||||||
@ -80,9 +82,9 @@ class EnsembleFTS(fts.FTS):
|
|||||||
data = self.indexer.get_data(data)
|
data = self.indexer.get_data(data)
|
||||||
|
|
||||||
sample = data[-model.order:]
|
sample = data[-model.order:]
|
||||||
forecast = model.forecast(sample)
|
forecast = model.predict(sample)
|
||||||
if isinstance(forecast, (list,np.ndarray)) and len(forecast) > 0:
|
if isinstance(forecast, (list,np.ndarray)) and len(forecast) > 0:
|
||||||
forecast = int(forecast[-1])
|
forecast = forecast[-1]
|
||||||
elif isinstance(forecast, (list,np.ndarray)) and len(forecast) == 0:
|
elif isinstance(forecast, (list,np.ndarray)) and len(forecast) == 0:
|
||||||
forecast = np.nan
|
forecast = np.nan
|
||||||
if isinstance(forecast, list):
|
if isinstance(forecast, list):
|
||||||
@ -99,6 +101,11 @@ class EnsembleFTS(fts.FTS):
|
|||||||
elif self.point_method == 'quantile':
|
elif self.point_method == 'quantile':
|
||||||
alpha = kwargs.get("alpha",0.05)
|
alpha = kwargs.get("alpha",0.05)
|
||||||
ret = np.percentile(forecasts, alpha*100)
|
ret = np.percentile(forecasts, alpha*100)
|
||||||
|
elif self.point_method == 'exponential':
|
||||||
|
l = len(self.models)
|
||||||
|
if l == 1:
|
||||||
|
return forecasts
|
||||||
|
ret = np.nansum([np.exp(-(self.exp_factor * (l - k))) * forecasts[k] for k in range(l)])
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -38,6 +38,11 @@ class IncrementalEnsembleFTS(ensemble.EnsembleFTS):
|
|||||||
self.batch_size = kwargs.get('batch_size', 10)
|
self.batch_size = kwargs.get('batch_size', 10)
|
||||||
"""The batch interval between each retraining"""
|
"""The batch interval between each retraining"""
|
||||||
|
|
||||||
|
self.num_models = kwargs.get('num_models', 5)
|
||||||
|
"""The number of models to hold in the ensemble"""
|
||||||
|
|
||||||
|
self.point_method = kwargs.get('point_method', 'exponential')
|
||||||
|
|
||||||
self.is_high_order = True
|
self.is_high_order = True
|
||||||
self.uod_clip = False
|
self.uod_clip = False
|
||||||
#self.max_lag = self.window_length + self.max_lag
|
#self.max_lag = self.window_length + self.max_lag
|
||||||
@ -49,16 +54,9 @@ class IncrementalEnsembleFTS(ensemble.EnsembleFTS):
|
|||||||
if model.is_high_order:
|
if model.is_high_order:
|
||||||
model = self.fts_method(partitioner=partitioner, order=self.order, **self.fts_params)
|
model = self.fts_method(partitioner=partitioner, order=self.order, **self.fts_params)
|
||||||
model.fit(data, **kwargs)
|
model.fit(data, **kwargs)
|
||||||
if len(self.models) > 0:
|
self.append_model(model)
|
||||||
|
if len(self.models) > self.num_models:
|
||||||
self.models.pop(0)
|
self.models.pop(0)
|
||||||
self.models.append(model)
|
|
||||||
|
|
||||||
def _point_smoothing(self, forecasts):
|
|
||||||
l = len(self.models)
|
|
||||||
|
|
||||||
ret = np.nansum([np.exp(-(l-k)) * forecasts[k] for k in range(l)])
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def forecast(self, data, **kwargs):
|
def forecast(self, data, **kwargs):
|
||||||
l = len(data)
|
l = len(data)
|
||||||
@ -79,7 +77,7 @@ class IncrementalEnsembleFTS(ensemble.EnsembleFTS):
|
|||||||
|
|
||||||
sample = data[k - self.max_lag: k]
|
sample = data[k - self.max_lag: k]
|
||||||
tmp = self.get_models_forecasts(sample)
|
tmp = self.get_models_forecasts(sample)
|
||||||
point = self._point_smoothing(tmp)
|
point = self.get_point(tmp)
|
||||||
ret.append(point)
|
ret.append(point)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
Loading…
Reference in New Issue
Block a user