117 lines
3.9 KiB
Python
117 lines
3.9 KiB
Python
"""
|
|
Meta model that wraps another FTS method and continously retrain it using a data window with
|
|
the most recent data
|
|
"""
|
|
|
|
import numpy as np
|
|
from pyFTS.common import FuzzySet, FLR, fts, flrg
|
|
from pyFTS.partitioners import Grid
|
|
|
|
|
|
class Retrainer(fts.FTS):
|
|
"""
|
|
Meta model for incremental/online learning that retrain its internal model after
|
|
data windows controlled by the parameter 'batch_size', using as the training data a
|
|
window of recent lags, whose size is controlled by the parameter 'window_length'.
|
|
"""
|
|
def __init__(self, **kwargs):
|
|
super(Retrainer, self).__init__(**kwargs)
|
|
|
|
self.partitioner_method = kwargs.get('partitioner_method', Grid.GridPartitioner)
|
|
"""The partitioner method to be called when a new model is build"""
|
|
self.partitioner_params = kwargs.get('partitioner_params', {'npart': 10})
|
|
"""The partitioner method parameters"""
|
|
self.partitioner = None
|
|
"""The most recent trained partitioner"""
|
|
|
|
self.fts_method = kwargs.get('fts_method', None)
|
|
"""The FTS method to be called when a new model is build"""
|
|
self.fts_params = kwargs.get('fts_params', {})
|
|
"""The FTS method specific parameters"""
|
|
self.model = None
|
|
"""The most recent trained model"""
|
|
|
|
self.window_length = kwargs.get('window_length',100)
|
|
"""The memory window length"""
|
|
self.auto_update = False
|
|
"""If true the model is updated at each time and not recreated"""
|
|
self.batch_size = kwargs.get('batch_size', 10)
|
|
"""The batch interval between each retraining"""
|
|
self.is_high_order = True
|
|
self.is_time_variant = True
|
|
self.uod_clip = False
|
|
self.max_lag = self.window_length + self.order
|
|
self.is_wrapper = True
|
|
|
|
def train(self, data, **kwargs):
|
|
self.partitioner = self.partitioner_method(data=data, **self.partitioner_params)
|
|
self.model = self.fts_method(partitioner=self.partitioner, **self.fts_params)
|
|
if self.model.is_high_order:
|
|
self.model.order = self.model = self.fts_method(partitioner=self.partitioner,
|
|
order=self.order, **self.fts_params)
|
|
self.model.fit(data, **kwargs)
|
|
self.shortname = "TimeVariant - " + self.model.shortname
|
|
|
|
def forecast(self, data, **kwargs):
|
|
l = len(data)
|
|
|
|
no_update = kwargs.get('no_update',False)
|
|
|
|
if no_update:
|
|
return self.model.predict(data, **kwargs)
|
|
|
|
horizon = self.window_length + self.order
|
|
|
|
ret = []
|
|
|
|
for k in np.arange(horizon, l+1):
|
|
_train = data[k - horizon: k - self.order]
|
|
_test = data[k - self.order: k]
|
|
|
|
if k % self.batch_size == 0 or self.model is None:
|
|
if self.auto_update:
|
|
self.model.train(_train)
|
|
else:
|
|
self.train(_train, **kwargs)
|
|
|
|
ret.extend(self.model.predict(_test, **kwargs))
|
|
|
|
return ret
|
|
|
|
def forecast_ahead(self, data, steps, **kwargs):
|
|
if len(data) < self.order:
|
|
return data
|
|
|
|
if isinstance(data, np.ndarray):
|
|
data = data.tolist()
|
|
|
|
start = kwargs.get('start_at',0)
|
|
|
|
ret = data[:start+self.order]
|
|
for k in np.arange(start+self.order, steps+start+self.order):
|
|
tmp = self.forecast(ret[k-self.order:k], no_update=True, **kwargs)
|
|
|
|
if isinstance(tmp,(list, np.ndarray)):
|
|
tmp = tmp[-1]
|
|
|
|
ret.append(tmp)
|
|
data.append(tmp)
|
|
|
|
return ret[-steps:]
|
|
|
|
def offset(self):
|
|
return self.max_lag
|
|
|
|
def __str__(self):
|
|
"""String representation of the model"""
|
|
|
|
return str(self.model)
|
|
|
|
def __len__(self):
|
|
"""
|
|
The length (number of rules) of the model
|
|
|
|
:return: number of rules
|
|
"""
|
|
return len(self.model)
|