From 3868bb1c48d1eb243a2a113ae5e4a4575b2895de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=C3=B4nio=20C=C3=A2ndido?= Date: Fri, 22 Mar 2019 15:07:44 -0300 Subject: [PATCH] Interval forecasting on MVFTS and WMVFTS --- pyFTS/models/hofts.py | 12 -------- pyFTS/models/multivariate/mvfts.py | 48 +++++++++++++++++++++++++++-- pyFTS/models/multivariate/wmvfts.py | 19 ++++++++++-- 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/pyFTS/models/hofts.py b/pyFTS/models/hofts.py index 40d21c2..9e395a9 100644 --- a/pyFTS/models/hofts.py +++ b/pyFTS/models/hofts.py @@ -73,24 +73,12 @@ class WeightedHighOrderFLRG(flrg.FLRG): return self.midpoint def get_lower(self, sets): - """ - Returns the lower bound value for the RHS fuzzy sets - - :param sets: fuzzy sets - :return: lower bound value - """ if self.lower is None: lw = np.array([sets[s].lower for s in self.RHS.keys()]) self.lower = lw.dot(self.weights()) return self.lower def get_upper(self, sets): - """ - Returns the upper bound value for the RHS fuzzy sets - - :param sets: fuzzy sets - :return: upper bound value - """ if self.upper is None: up = np.array([sets[s].upper for s in self.RHS.keys()]) self.upper = up.dot(self.weights()) diff --git a/pyFTS/models/multivariate/mvfts.py b/pyFTS/models/multivariate/mvfts.py index b94adab..5121f63 100644 --- a/pyFTS/models/multivariate/mvfts.py +++ b/pyFTS/models/multivariate/mvfts.py @@ -145,8 +145,9 @@ class MVFTS(fts.FTS): mvs.append(0.) mps.append(0.) else: - mvs.append(self.flrgs[flrg.get_key()].get_membership(data_point, self.explanatory_variables)) - mps.append(self.flrgs[flrg.get_key()].get_midpoint(self.target_variable.partitioner.sets)) + _flrg = self.flrgs[flrg.get_key()] + mvs.append(_flrg.get_membership(data_point, self.explanatory_variables)) + mps.append(_flrg.get_midpoint(self.target_variable.partitioner.sets)) mv = np.array(mvs) mp = np.array(mps) @@ -201,6 +202,49 @@ class MVFTS(fts.FTS): return ret + def forecast_interval(self, data, **kwargs): + ret = [] + ndata = self.apply_transformations(data) + c = 0 + for index, row in ndata.iterrows() if isinstance(ndata, pd.DataFrame) else enumerate(ndata): + data_point = self.format_data(row) + flrs = self.generate_lhs_flrs(data_point) + mvs = [] + ups = [] + los = [] + for flr in flrs: + flrg = mvflrg.FLRG(lhs=flr.LHS) + if flrg.get_key() not in self.flrgs: + #Naïve approach is applied when no rules were found + if self.target_variable.name in flrg.LHS: + fs = flrg.LHS[self.target_variable.name] + fset = self.target_variable.partitioner.sets[fs] + up = fset.upper + lo = fset.lower + mv = fset.membership(data_point[self.target_variable.name]) + mvs.append(mv) + ups.append(up) + los.append(lo) + else: + mvs.append(0.) + ups.append(0.) + los.append(0.) + else: + _flrg = self.flrgs[flrg.get_key()] + mvs.append(_flrg.get_membership(data_point, self.explanatory_variables)) + ups.append(_flrg.get_upper(self.target_variable.partitioner.sets)) + los.append(_flrg.get_lower(self.target_variable.partitioner.sets)) + + mv = np.array(mvs) + up = np.dot(mv, np.array(ups).T) / np.sum(mv) + lo = np.dot(mv, np.array(los).T) / np.sum(mv) + + ret.append([lo, up]) + + ret = self.target_variable.apply_inverse_transformations(ret, + params=data[self.target_variable.data_label].values) + return ret + def clone_parameters(self, model): super(MVFTS, self).clone_parameters(model) diff --git a/pyFTS/models/multivariate/wmvfts.py b/pyFTS/models/multivariate/wmvfts.py index 156fc5d..a969ef7 100644 --- a/pyFTS/models/multivariate/wmvfts.py +++ b/pyFTS/models/multivariate/wmvfts.py @@ -33,8 +33,23 @@ class WeightedFLRG(mvflrg.FLRG): return self.w def get_midpoint(self, sets): - mp = np.array([sets[c].centroid for c in self.RHS.keys()]) - return mp.dot(self.weights()) + if self.midpoint is None: + mp = np.array([sets[c].centroid for c in self.RHS.keys()]) + self.midpoint = mp.dot(self.weights()) + + return self.midpoint + + def get_lower(self, sets): + if self.lower is None: + lw = np.array([sets[s].lower for s in self.RHS.keys()]) + self.lower = lw.dot(self.weights()) + return self.lower + + def get_upper(self, sets): + if self.upper is None: + up = np.array([sets[s].upper for s in self.RHS.keys()]) + self.upper = up.dot(self.weights()) + return self.upper def __str__(self):