From 0d033c3ac2d5dcb95b8aae6505d0a5e7ee9ac2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=C3=B4nio=20C=C3=A2ndido?= Date: Tue, 11 Dec 2018 22:21:19 -0200 Subject: [PATCH] Improvements on cmvfts and pwfts for multivariate forecasting --- pyFTS/common/flrg.py | 4 ++++ pyFTS/common/fts.py | 14 ++++++++++++++ pyFTS/models/multivariate/cmvfts.py | 10 +++++++--- pyFTS/models/multivariate/common.py | 6 ++++++ pyFTS/models/multivariate/grid.py | 2 +- pyFTS/models/pwfts.py | 18 +++++++++--------- pyFTS/tests/multivariate.py | 16 +++++++++++++--- 7 files changed, 54 insertions(+), 16 deletions(-) diff --git a/pyFTS/common/flrg.py b/pyFTS/common/flrg.py index 3cc4d2e..3c9786e 100644 --- a/pyFTS/common/flrg.py +++ b/pyFTS/common/flrg.py @@ -106,5 +106,9 @@ class FLRG(object): def __len__(self): return len(self.RHS) + def reset_calculated_values(self): + self.midpoint = None + self.upper = None + self.lower = None diff --git a/pyFTS/common/fts.py b/pyFTS/common/fts.py index 188053c..ad6f039 100644 --- a/pyFTS/common/fts.py +++ b/pyFTS/common/fts.py @@ -507,8 +507,22 @@ class FTS(object): return len(self.flrgs) def len_total(self): + """ + Total length of the model, adding the number of terms in all rules + + :return: + """ return sum([len(k) for k in self.flrgs]) + def reset_calculated_values(self): + """ + Reset all pre-calculated values on the FLRG's + + :return: + """ + + for flrg in self.flrgs.keys(): + self.flrgs[flrg].reset_calculated_values() diff --git a/pyFTS/models/multivariate/cmvfts.py b/pyFTS/models/multivariate/cmvfts.py index e9db220..ca31204 100644 --- a/pyFTS/models/multivariate/cmvfts.py +++ b/pyFTS/models/multivariate/cmvfts.py @@ -82,11 +82,15 @@ class ClusteredMVFTS(mvfts.MVFTS): ret = {} for var in self.explanatory_variables: - self.cluster.change_target_variable(var) + if self.target_variable.name != var.name: + self.target_variable = var + self.cluster.change_target_variable(var) + self.model.partitioner = self.cluster + self.reset_calculated_values() + ret[var.name] = self.model.forecast(ndata, fuzzyfied=self.pre_fuzzyfy, **kwargs) - columns = ret.keys() - return pd.DataFrame(ret, columns=columns) + return pd.DataFrame(ret, columns=ret.keys()) def __str__(self): """String representation of the model""" diff --git a/pyFTS/models/multivariate/common.py b/pyFTS/models/multivariate/common.py index 43d3bbc..0f1868f 100644 --- a/pyFTS/models/multivariate/common.py +++ b/pyFTS/models/multivariate/common.py @@ -28,6 +28,12 @@ class MultivariateFuzzySet(Composite.FuzzySet): if variable == self.target_variable.name: self.centroid = set.centroid + def set_target_variable(self, variable): + #print(self.target_variable, variable) + self.target_variable = variable + #print(self.centroid,self.sets[variable.name].centroid) + self.centroid = self.sets[variable.name].centroid + def membership(self, x): mv = [] for var in self.sets.keys(): diff --git a/pyFTS/models/multivariate/grid.py b/pyFTS/models/multivariate/grid.py index caafbc3..0831b53 100644 --- a/pyFTS/models/multivariate/grid.py +++ b/pyFTS/models/multivariate/grid.py @@ -108,4 +108,4 @@ class GridCluster(partitioner.Partitioner): def change_target_variable(self, variable): for fset in self.sets: - self.sets[fset].target_variable = variable + self.sets[fset].set_target_variable(variable) diff --git a/pyFTS/models/pwfts.py b/pyFTS/models/pwfts.py index 53da7f6..e0248bd 100644 --- a/pyFTS/models/pwfts.py +++ b/pyFTS/models/pwfts.py @@ -202,18 +202,18 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): #return self.flrg_lhs_unconditional_probability(flrg) def flrg_lhs_conditional_probability(self, x, flrg): - mv = flrg.get_membership(x, self.sets) + mv = flrg.get_membership(x, self.partitioner.sets) pb = self.flrg_lhs_unconditional_probability(flrg) return mv * pb def get_midpoint(self, flrg): if flrg.get_key() in self.flrgs: tmp = self.flrgs[flrg.get_key()] - ret = tmp.get_midpoint(self.sets) #sum(np.array([tmp.rhs_unconditional_probability(s) * self.setsDict[s].centroid for s in tmp.RHS])) + ret = tmp.get_midpoint(self.partitioner.sets) #sum(np.array([tmp.rhs_unconditional_probability(s) * self.setsDict[s].centroid for s in tmp.RHS])) else: if len(flrg.LHS) > 0: pi = 1 / len(flrg.LHS) - ret = sum(np.array([pi * self.sets[s].centroid for s in flrg.LHS])) + ret = sum(np.array([pi * self.partitioner.sets[s].centroid for s in flrg.LHS])) else: ret = np.nan return ret @@ -224,19 +224,19 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): _flrg = self.flrgs[flrg.get_key()] cond = [] for s in _flrg.RHS.keys(): - _set = self.sets[s] + _set = self.partitioner.sets[s] tmp = _flrg.rhs_unconditional_probability(s) * (_set.membership(x) / _set.partition_function(uod=self.get_UoD())) cond.append(tmp) ret = sum(np.array(cond)) else: pi = 1 / len(flrg.LHS) - ret = sum(np.array([pi * self.sets[s].membership(x) for s in flrg.LHS])) + ret = sum(np.array([pi * self.partitioner.sets[s].membership(x) for s in flrg.LHS])) return ret def get_upper(self, flrg): if flrg.get_key() in self.flrgs: tmp = self.flrgs[flrg.get_key()] - ret = tmp.get_upper(self.sets) + ret = tmp.get_upper(self.partitioner.sets) else: ret = 0 return ret @@ -244,7 +244,7 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): def get_lower(self, flrg): if flrg.get_key() in self.flrgs: tmp = self.flrgs[flrg.get_key()] - ret = tmp.get_lower(self.sets) + ret = tmp.get_lower(self.partitioner.sets) else: ret = 0 return ret @@ -398,8 +398,8 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): for s in flrgs: if s.get_key() in self.flrgs: flrg = self.flrgs[s.get_key()] - pk = flrg.lhs_conditional_probability(sample, self.sets, self.global_frequency_count, uod, nbins) - wi = flrg.rhs_conditional_probability(bin, self.sets, uod, nbins) + pk = flrg.lhs_conditional_probability(sample, self.partitioner.sets, self.global_frequency_count, uod, nbins) + wi = flrg.rhs_conditional_probability(bin, self.partitioner.sets, uod, nbins) num.append(wi * pk) den.append(pk) else: diff --git a/pyFTS/tests/multivariate.py b/pyFTS/tests/multivariate.py index 6960ba5..f832ed8 100644 --- a/pyFTS/tests/multivariate.py +++ b/pyFTS/tests/multivariate.py @@ -26,13 +26,23 @@ from pyFTS.models.multivariate import variable, cmvfts vx = variable.Variable("x", data_label="x", partitioner=Grid.GridPartitioner, npart=15, data=df) vy = variable.Variable("y", data_label="y", partitioner=Grid.GridPartitioner, npart=15, data=df) -model = cmvfts.ClusteredMVFTS(pre_fuzzyfy=False, knn=3, fts_method=pwfts.ProbabilisticWeightedFTS) +model = cmvfts.ClusteredMVFTS(pre_fuzzyfy=False, knn=3, order=2, fts_method=pwfts.ProbabilisticWeightedFTS) model.append_variable(vx) model.append_variable(vy) model.target_variable = vx model.fit(df.iloc[:800]) -df = model.predict(df.iloc[800:], type='multivariate') +test = df.iloc[800:] -print(df) \ No newline at end of file +forecasts = model.predict(test, type='multivariate') + +fig, ax = plt.subplots(nrows=2, ncols=2, figsize=[15,7]) +ax[0][0].plot(test['x'].values) +ax[0][0].plot(forecasts['x'].values) +ax[0][1].scatter(test['x'].values,test['y'].values) +ax[0][1].scatter(forecasts['x'].values,forecasts['y'].values) +ax[1][0].scatter(test['y'].values,test['x'].values) +ax[1][0].scatter(forecasts['y'].values,forecasts['x'].values) +ax[1][1].plot(test['y'].values) +ax[1][1].plot(forecasts['y'].values) \ No newline at end of file