Improvements on generators for multi step ahead forecasting at MVFTS

This commit is contained in:
Petrônio Cândido 2019-02-16 09:08:13 -02:00
parent cef00bd71a
commit ff951546e1
5 changed files with 39 additions and 30 deletions

Binary file not shown.

View File

@ -101,7 +101,8 @@ class FTS(object):
:keyword explain: try to explain, step by step, the one-step-ahead point forecasting result given the input data. :keyword explain: try to explain, step by step, the one-step-ahead point forecasting result given the input data.
:keyword generators: for multivariate methods on multi step ahead forecasting, generators is a dict where the keys :keyword generators: for multivariate methods on multi step ahead forecasting, generators is a dict where the keys
are the variables names (except the target_variable) and the values are lambda functions that are the variables names (except the target_variable) and the values are lambda functions that
accept one value (the actual value of the variable) and return the next value. accept one value (the actual value of the variable) and return the next value or trained FTS
models that accept the actual values and forecast new ones.
:return: a numpy array with the forecasted data :return: a numpy array with the forecasted data
""" """

View File

@ -2,6 +2,7 @@ from pyFTS.common import fts, FuzzySet, FLR, Membership
from pyFTS.partitioners import Grid from pyFTS.partitioners import Grid
from pyFTS.models.multivariate import FLR as MVFLR, common, flrg as mvflrg from pyFTS.models.multivariate import FLR as MVFLR, common, flrg as mvflrg
from itertools import product from itertools import product
from types import LambdaType
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -52,11 +53,15 @@ class MVFTS(fts.FTS):
def apply_transformations(self, data, params=None, updateUoD=False, **kwargs): def apply_transformations(self, data, params=None, updateUoD=False, **kwargs):
ndata = data.copy(deep=True) ndata = data.copy(deep=True)
for var in self.explanatory_variables: for var in self.explanatory_variables:
try:
values = ndata[var.data_label].values #if isinstance(ndata, pd.DataFrame) else ndata[var.data_label]
if self.uod_clip and var.partitioner.type == 'common': if self.uod_clip and var.partitioner.type == 'common':
ndata[var.data_label] = np.clip(ndata[var.data_label].values, ndata[var.data_label] = np.clip(values,
var.partitioner.min, var.partitioner.max) var.partitioner.min, var.partitioner.max)
ndata[var.data_label] = var.apply_transformations(ndata[var.data_label].values) ndata[var.data_label] = var.apply_transformations(values)
except:
pass
return ndata return ndata
@ -120,7 +125,7 @@ class MVFTS(fts.FTS):
ret = [] ret = []
ndata = self.apply_transformations(data) ndata = self.apply_transformations(data)
c = 0 c = 0
for index, row in ndata.iterrows(): for index, row in ndata.iterrows() if isinstance(ndata, pd.DataFrame) else enumerate(ndata):
data_point = self.format_data(row) data_point = self.format_data(row)
flrs = self.generate_lhs_flrs(data_point) flrs = self.generate_lhs_flrs(data_point)
mvs = [] mvs = []
@ -159,7 +164,8 @@ class MVFTS(fts.FTS):
raise Exception('You must provide parameter \'generators\'! generators is a dict where the keys' + raise Exception('You must provide parameter \'generators\'! generators is a dict where the keys' +
' are the variables names (except the target_variable) and the values are ' + ' are the variables names (except the target_variable) and the values are ' +
'lambda functions that accept one value (the actual value of the variable) ' 'lambda functions that accept one value (the actual value of the variable) '
' and return the next value.') ' and return the next value or trained FTS models that accept the actual values and '
'forecast new ones.')
ndata = self.apply_transformations(data) ndata = self.apply_transformations(data)
@ -174,13 +180,20 @@ class MVFTS(fts.FTS):
ret.append(tmp) ret.append(tmp)
last_data_point = sample.loc[sample.index[-1]]
new_data_point = {} new_data_point = {}
for var in self.explanatory_variables: for var in self.explanatory_variables:
if var.name != self.target_variable.name: if var.name != self.target_variable.name:
if isinstance(generators[var.name], LambdaType):
last_data_point = ndata.loc[sample.index[-1]]
new_data_point[var.data_label] = generators[var.name](last_data_point[var.data_label]) new_data_point[var.data_label] = generators[var.name](last_data_point[var.data_label])
elif isinstance(generators[var.name], fts.FTS):
model = generators[var.name]
last_data_point = ndata.loc[[sample.index[-model.order]]]
if not model.is_multivariate:
last_data_point = last_data_point[var.data_label].values
new_data_point[var.data_label] = model.forecast(last_data_point)[0]
new_data_point[self.target_variable.data_label] = tmp new_data_point[self.target_variable.data_label] = tmp

View File

@ -30,9 +30,13 @@ class Variable:
self.mask = kwargs.get('mask', None) self.mask = kwargs.get('mask', None)
"""The mask for format the data column on Pandas Dataframe""" """The mask for format the data column on Pandas Dataframe"""
self.transformation = kwargs.get('transformation', None) self.transformation = kwargs.get('transformation', None)
"""Pre processing transformation for the variable"""
self.transformation_params = kwargs.get('transformation_params', None) self.transformation_params = kwargs.get('transformation_params', None)
self.partitioner = None self.partitioner = None
"""UoD partitioner for the variable data"""
self.alpha_cut = kwargs.get('alpha_cut', 0.0) self.alpha_cut = kwargs.get('alpha_cut', 0.0)
"""Minimal membership value to be considered on fuzzyfication process"""
if kwargs.get('data', None) is not None: if kwargs.get('data', None) is not None:
self.build(**kwargs) self.build(**kwargs)

View File

@ -128,30 +128,21 @@ vtemp = variable.Variable("Temperature", data_label="temperature", alias='temper
from pyFTS.models.multivariate import mvfts, wmvfts, cmvfts, grid from pyFTS.models.multivariate import mvfts, wmvfts, cmvfts, grid
vars = [vhour, vday, vload] from pyFTS.models.multivariate import mvfts, wmvfts, cmvfts, grid
#fs = grid.GridCluster(explanatory_variables=vars, target_variable=vload) mtemp = wmvfts.WeightedMVFTS(explanatory_variables=[vhour, vmonth, vtemp], target_variable=vtemp)
mtemp.fit(train_mv)
#model = mvfts.MVFTS(explanatory_variables=vars, target_variable=vload) from pyFTS.models.multivariate import mvfts, wmvfts, cmvfts, grid
model = wmvfts.WeightedMVFTS(explanatory_variables=vars, target_variable=vload)
#model = cmvfts.ClusteredMVFTS(explanatory_variables=vars, target_variable=vload,order=2, knn=3, partitioner=fs)
model.fit(train_mv)
print(model.shortname)
Util.persist_obj(model, model.shortname)
#'''
#model = Util.load_obj('MVFTS') mload = wmvfts.WeightedMVFTS(explanatory_variables=[vhour, vday, vtemp, vload], target_variable=vload)
mload.fit(train_mv)
with open("rules.txt","w") as file:
file.write(str(model))
forecasts = model.predict(test_mv.iloc[:100]) time_generator = lambda x : pd.to_datetime(x) + pd.to_timedelta(1, unit='h')
forecasts.insert(0,None) temp_generator = mtemp
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[15,3])
ax.plot(test_mv['load'].values[:100],label='Original')
ax.plot(forecasts, label='predicted')
handles, labels = ax.get_legend_handles_labels()
lgd = ax.legend(handles, labels, loc=2, bbox_to_anchor=(1, 1))
Util.show_and_save_image(fig, model.shortname, True) forecasts = mload.predict(test_mv.iloc[:1], steps_ahead=48, generators={'Hour': time_generator,
'DayOfWeek': time_generator,
"Temperature": mtemp})