From 88d22a44824ae118a6b0c964f70b24b0aece16f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=C3=B4nio=20C=C3=A2ndido?= Date: Fri, 22 Jun 2018 23:40:19 -0300 Subject: [PATCH] bugfixes for seasonal FTS --- pyFTS/benchmarks/Measures.py | 2 +- pyFTS/common/fts.py | 2 +- pyFTS/models/chen.py | 4 +-- pyFTS/models/seasonal/SeasonalIndexer.py | 4 +-- pyFTS/models/seasonal/cmsfts.py | 24 +++++++------- pyFTS/models/seasonal/sfts.py | 25 +++++++++------ pyFTS/tests/sfts.py | 41 ++++++++---------------- 7 files changed, 48 insertions(+), 54 deletions(-) diff --git a/pyFTS/benchmarks/Measures.py b/pyFTS/benchmarks/Measures.py index 63593ad..b4cce36 100644 --- a/pyFTS/benchmarks/Measures.py +++ b/pyFTS/benchmarks/Measures.py @@ -169,7 +169,7 @@ def sharpness(forecasts): def resolution(forecasts): """Resolution - Standard deviation of the intervals""" shp = sharpness(forecasts) - tmp = [abs((i[1] - i[0]) - shp) for i in forecasts] + tmp = [abs((i[1] - i[0]) - shp) for i in forecasts] return np.mean(tmp) diff --git a/pyFTS/common/fts.py b/pyFTS/common/fts.py index 4b11206..e5d81fc 100644 --- a/pyFTS/common/fts.py +++ b/pyFTS/common/fts.py @@ -37,7 +37,7 @@ class FTS(object): self.sets = self.partitioner.sets self.auto_update = False self.benchmark_only = False - self.indexer = None + self.indexer = kwargs.get("indexer", None) self.uod_clip = kwargs.get("uod_clip", True) def fuzzy(self, data): diff --git a/pyFTS/models/chen.py b/pyFTS/models/chen.py index ebba22b..fc53678 100644 --- a/pyFTS/models/chen.py +++ b/pyFTS/models/chen.py @@ -22,12 +22,12 @@ class ConventionalFLRG(flrg.FLRG): self.RHS.add(c) def __str__(self): - tmp = self.LHS + " -> " + tmp = str(self.LHS) + " -> " tmp2 = "" for c in sorted(self.RHS, key=lambda s: s): if len(tmp2) > 0: tmp2 = tmp2 + "," - tmp2 = tmp2 + c + tmp2 = tmp2 + str(c) return tmp + tmp2 diff --git a/pyFTS/models/seasonal/SeasonalIndexer.py b/pyFTS/models/seasonal/SeasonalIndexer.py index a498ba5..d97878b 100644 --- a/pyFTS/models/seasonal/SeasonalIndexer.py +++ b/pyFTS/models/seasonal/SeasonalIndexer.py @@ -31,7 +31,7 @@ class SeasonalIndexer(object): class LinearSeasonalIndexer(SeasonalIndexer): - def __init__(self,seasons,units,ignore=None, **kwargs): + def __init__(self, seasons, units, ignore=None, **kwargs): super(LinearSeasonalIndexer, self).__init__(len(seasons), **kwargs) self.seasons = seasons self.units = units @@ -40,7 +40,7 @@ class LinearSeasonalIndexer(SeasonalIndexer): def get_season_of_data(self,data): return self.get_season_by_index(np.arange(0, len(data)).tolist()) - def get_season_by_index(self,index): + def get_season_by_index(self, index): ret = [] if not isinstance(index, (list, np.ndarray)): if self.num_seasons == 1: diff --git a/pyFTS/models/seasonal/cmsfts.py b/pyFTS/models/seasonal/cmsfts.py index b0722d9..7d68bb6 100644 --- a/pyFTS/models/seasonal/cmsfts.py +++ b/pyFTS/models/seasonal/cmsfts.py @@ -13,11 +13,11 @@ class ContextualSeasonalFLRG(sfts.SeasonalFLRG): self.RHS = {} def append_rhs(self, flr, **kwargs): - if flr.LHS in self.RHS: - self.RHS[flr.LHS].append_rhs(flr.RHS) + if flr.LHS.name in self.RHS: + self.RHS[flr.LHS.name].append_rhs(flr.RHS.name) else: - self.RHS[flr.LHS] = chen.ConventionalFLRG(flr.LHS) - self.RHS[flr.LHS].append_rhs(flr.RHS) + self.RHS[flr.LHS.name] = chen.ConventionalFLRG(flr.LHS.name) + self.RHS[flr.LHS.name].append_rhs(flr.RHS.name) def __str__(self): tmp = str(self.LHS) + ": \n " @@ -31,17 +31,17 @@ class ContextualMultiSeasonalFTS(sfts.SeasonalFTS): """ Contextual Multi-Seasonal Fuzzy Time Series """ - def __init__(self, name, indexer, **kwargs): - super(ContextualMultiSeasonalFTS, self).__init__("CMSFTS") + def __init__(self, **kwargs): + super(ContextualMultiSeasonalFTS, self).__init__(**kwargs) self.name = "Contextual Multi Seasonal FTS" - self.shortname = "CMSFTS " + name + self.shortname = "CMSFTS " self.detail = "" self.seasonality = 1 self.has_seasonality = True self.has_point_forecasting = True self.is_high_order = True self.is_multivariate = True - self.indexer = indexer + self.order = 1 self.flrgs = {} def generate_flrg(self, flrs): @@ -61,11 +61,11 @@ class ContextualMultiSeasonalFTS(sfts.SeasonalFTS): self.generate_flrg(flrs) def get_midpoints(self, flrg, data): - if data in flrg.flrgs: - ret = np.array([self.sets[s].centroid for s in flrg.flrgs[data.name].RHS]) + if data.name in flrg.RHS: + ret = np.array([self.sets[s].centroid for s in flrg.RHS[data.name].RHS]) return ret else: - return np.array([self.sets[data].centroid]) + return np.array([self.sets[data.name].centroid]) def forecast(self, data, **kwargs): ordered_sets = FuzzySet.set_ordered(self.sets) @@ -97,3 +97,5 @@ class ContextualMultiSeasonalFTS(sfts.SeasonalFTS): ret.append(sum(mp) / len(mp)) return ret + + diff --git a/pyFTS/models/seasonal/sfts.py b/pyFTS/models/seasonal/sfts.py index 77fe694..0747ae3 100644 --- a/pyFTS/models/seasonal/sfts.py +++ b/pyFTS/models/seasonal/sfts.py @@ -7,13 +7,13 @@ S.-M. Chen, “Forecasting enrollments based on fuzzy time series,” Fuzzy Sets """ import numpy as np -from pyFTS.common import FuzzySet, FLR, fts +from pyFTS.common import FuzzySet, FLR, flrg, fts -class SeasonalFLRG(FLR.FLRG): +class SeasonalFLRG(flrg.FLRG): """First Order Seasonal Fuzzy Logical Relationship Group""" def __init__(self, seasonality): - super(SeasonalFLRG, self).__init__(None,None) + super(SeasonalFLRG, self).__init__(1) self.LHS = seasonality self.RHS = [] @@ -26,10 +26,10 @@ class SeasonalFLRG(FLR.FLRG): def __str__(self): tmp = str(self.LHS) + " -> " tmp2 = "" - for c in sorted(self.RHS, key=lambda s: s.name): + for c in sorted(self.RHS, key=lambda s: str(s)): if len(tmp2) > 0: tmp2 = tmp2 + "," - tmp2 = tmp2 + c.name + tmp2 = tmp2 + str(c) return tmp + tmp2 def __len__(self): @@ -38,10 +38,11 @@ class SeasonalFLRG(FLR.FLRG): class SeasonalFTS(fts.FTS): """First Order Seasonal Fuzzy Time Series""" - def __init__(self, name, **kwargs): - super(SeasonalFTS, self).__init__(1, "SFTS", **kwargs) + def __init__(self, **kwargs): + super(SeasonalFTS, self).__init__(**kwargs) self.name = "Seasonal FTS" - self.detail = "Chen" + self.shortname = "SFTS" + self.order = 1 self.seasonality = 1 self.has_seasonality = True self.has_point_forecasting = True @@ -62,11 +63,15 @@ class SeasonalFTS(fts.FTS): #print(season) self.flrgs[ss].append_rhs(flr.RHS) + def get_midpoints(self, flrg): + ret = np.array([self.sets[s].centroid for s in flrg.RHS]) + return ret + def train(self, data, **kwargs): if kwargs.get('sets', None) is not None: self.sets = kwargs.get('sets', None) tmpdata = FuzzySet.fuzzyfy_series_old(data, self.sets) - flrs = FLR.generate_recurrent_flrs(tmpdata) + flrs = FLR.generate_non_recurrent_flrs(tmpdata) self.generate_flrg(flrs) def forecast(self, data, **kwargs): @@ -81,7 +86,7 @@ class SeasonalFTS(fts.FTS): flrg = self.flrgs[str(season)] - mp = self.getMidpoints(flrg) + mp = self.get_midpoints(flrg) ret.append(np.percentile(mp, 50)) diff --git a/pyFTS/tests/sfts.py b/pyFTS/tests/sfts.py index 2c74f9a..855e403 100644 --- a/pyFTS/tests/sfts.py +++ b/pyFTS/tests/sfts.py @@ -8,43 +8,30 @@ import pandas as pd from pyFTS.common import Util from pyFTS.benchmarks import benchmarks as bchmk -os.chdir("/home/petronio/dados/Dropbox/Doutorado/Codigos/") +os.chdir("/home/petronio/Downloads") -sonda = pd.read_csv("DataSets/SONDA_BSB_MOD.csv", sep=";") +data = pd.read_csv("dress_data.csv", sep=",") -sonda['data'] = pd.to_datetime(sonda['data']) +#sonda['data'] = pd.to_datetime(sonda['data']) -sonda = sonda[:][527041:] +#data.index = np.arange(0,len(data.index)) -sonda.index = np.arange(0,len(sonda.index)) +data = data["a"].tolist() -sonda_treino = sonda[:1051200] -sonda_teste = sonda[1051201:] +from pyFTS.models.seasonal import sfts, cmsfts, SeasonalIndexer +ix = SeasonalIndexer.LinearSeasonalIndexer([7],[1]) -#res = bchmk.simpleSearch_RMSE(sonda_treino, sonda_teste, -# sfts.SeasonalFTS,np.arange(3,30),[1],parameters=1440, -# tam=[15,8], plotforecasts=False,elev=45, azim=40, -# save=False,file="pictures/sonda_sfts_error_surface", intervals=False) +from pyFTS.partitioners import Grid -partitions = ['grid','entropy'] +fs = Grid.GridPartitioner(data=data,npart=10) -indexers = ['m15','Mh','Mhm15'] +model = sfts.SeasonalFTS(indexer=ix, partitioner=fs) +#model = cmsfts.ContextualMultiSeasonalFTS(indexer=ix, partitioner=fs) -models = [] -ixs = [] +model.fit(data) -sample = sonda_teste[0:4300] +print(model) -for max_part in [10, 20, 30, 40, 50]: - for part in partitions: - for ind in indexers: - ix = Util.load_obj("models/sonda_ix_" + ind + ".pkl") - model = Util.load_obj("models/sonda_msfts_" + part + "_" + str(max_part) + "_" + ind + ".pkl") - model.shortname = part + "_" + str(max_part) + "_" + ind - - models.append(model) - ixs.append(ix) - -print(bchmk.print_point_statistics(sample, models, indexers=ixs)) \ No newline at end of file +print(model.predict(data)) \ No newline at end of file