diff --git a/benchmarks/benchmarks.py b/benchmarks/benchmarks.py index f2b90da..423f8f0 100644 --- a/benchmarks/benchmarks.py +++ b/benchmarks/benchmarks.py @@ -72,15 +72,23 @@ def allPointForecasters(data_train, data_test, partitions, max_order=3, statisti intervals=False) -def getPointStatistics(data, models, externalmodels = None, externalforecasts = None): - ret = "Model & Order & RMSE & MAPE & Theil's U \\\\ \n" - for fts in models: - forecasts = fts.forecast(data) - ret += fts.shortname + " & " - ret += str(fts.order) + " & " - ret += str(round(Measures.rmse(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2)) + " & " - ret += str(round(Measures.smape(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2))+ " & " - ret += str(round(Measures.UStatistic(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2)) +def getPointStatistics(data, models, externalmodels = None, externalforecasts = None, indexers=None): + ret = "Model & Order & RMSE & SMAPE & Theil's U \\\\ \n" + for count,model in enumerate(models,start=0): + if indexers is not None: + ndata = np.array(indexers[count].get_data(data[model.order:])) + else: + ndata = np.array(data[model.order:]) + forecasts = model.forecast(data) + if model.hasSeasonality: + nforecasts = np.array(forecasts) + else: + nforecasts = np.array(forecasts[:-1]) + ret += model.shortname + " & " + ret += str(model.order) + " & " + ret += str(round(Measures.rmse(ndata, nforecasts), 2)) + " & " + ret += str(round(Measures.smape(ndata, nforecasts), 2))+ " & " + ret += str(round(Measures.UStatistic(ndata, nforecasts), 2)) #ret += str(round(Measures.TheilsInequality(np.array(data[fts.order:]), np.array(forecasts[:-1])), 4)) ret += " \\\\ \n" if externalmodels is not None: @@ -88,9 +96,9 @@ def getPointStatistics(data, models, externalmodels = None, externalforecasts = for k in np.arange(0,l): ret += externalmodels[k] + " & " ret += " 1 & " - ret += str(round(Measures.rmse(data[fts.order:], externalforecasts[k][:-1]), 2)) + " & " - ret += str(round(Measures.smape(data[fts.order:], externalforecasts[k][:-1]), 2))+ " & " - ret += str(round(Measures.UStatistic(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2)) + ret += str(round(Measures.rmse(data, externalforecasts[k][:-1]), 2)) + " & " + ret += str(round(Measures.smape(data, externalforecasts[k][:-1]), 2))+ " & " + ret += str(round(Measures.UStatistic(np.array(data), np.array(forecasts[:-1])), 2)) ret += " \\\\ \n" return ret diff --git a/chen.py b/chen.py index b58e3a5..529f2d3 100644 --- a/chen.py +++ b/chen.py @@ -34,7 +34,7 @@ class ConventionalFTS(fts.FTS): if flr.LHS.name in flrgs: flrgs[flr.LHS.name].append(flr.RHS) else: - flrgs[flr.LHS.name] = ConventionalFLRG(flr.LHS); + flrgs[flr.LHS.name] = ConventionalFLRG(flr.LHS) flrgs[flr.LHS.name].append(flr.RHS) return (flrgs) diff --git a/models/cmsfts.py b/models/cmsfts.py new file mode 100644 index 0000000..bde1bfa --- /dev/null +++ b/models/cmsfts.py @@ -0,0 +1,95 @@ +import numpy as np +from pyFTS.common import FuzzySet,FLR +from pyFTS import fts, sfts, chen + + +class ContextualSeasonalFLRG(object): + def __init__(self, seasonality): + super(ContextualSeasonalFLRG, self).__init__(None,None) + self.season = seasonality + self.flrgs = {} + + def append(self, flr): + if flr.LHS.name in self.flrgs: + self.flrgs[flr.LHS.name].append(flr.RHS) + else: + self.flrgs[flr.LHS.name] = chen.ConventionalFLRG(flr.LHS) + self.flrgs[flr.LHS.name].append(flr.RHS) + + def __str__(self): + tmp = str(self.season) + ": \n " + tmp2 = "\t" + for r in sorted(self.flrgs): + tmp2 += str(self.flrgs[r]) + "\n\t" + return tmp + tmp2 + "\n" + + +class ContextualMultiSeasonalFTS(sfts.SeasonalFTS): + def __init__(self, name, indexer): + super(ContextualMultiSeasonalFTS, self).__init__("CMSFTS") + self.name = "Contextual Multi Seasonal FTS" + self.shortname = "CMSFTS " + name + self.detail = "" + self.seasonality = 1 + self.hasSeasonality = True + self.hasPointForecasting = True + self.isHighOrder = True + self.isMultivariate = True + self.indexer = indexer + self.flrgs = {} + + def generateFLRG(self, flrs): + flrgs = {} + + for flr in flrs: + + if str(flr.index) not in self.flrgs: + flrgs[str(flr.index)] = ContextualSeasonalFLRG(flr.index) + + flrgs[str(flr.index)].append(flr) + + return (flrgs) + + def train(self, data, sets, order=1, parameters=None): + self.sets = sets + self.seasonality = parameters + flrs = FLR.generateIndexedFLRs(self.sets, self.indexer, data) + self.flrgs = self.generateFLRG(flrs) + + def getMidpoints(self, flrg, data): + ret = np.array([s.centroid for s in flrg.flrgs[data].RHS]) + return ret + + def forecast(self, data): + + ret = [] + + index = self.indexer.get_season_of_data(data) + ndata = self.indexer.get_data(data) + + for k in np.arange(1, len(data)): + + flrg = self.flrgs[str(index[k])] + + d = FuzzySet.getMaxMembershipFuzzySet(ndata[k], self.sets) + + mp = self.getMidpoints(flrg, d) + + ret.append(sum(mp) / len(mp)) + + ret = self.doInverseTransformations(ret, params=[ndata[self.order - 1:]]) + + return ret + + def forecastAhead(self, data, steps): + ret = [] + for i in steps: + flrg = self.flrgs[str(i)] + + mp = self.getMidpoints(flrg) + + ret.append(sum(mp) / len(mp)) + + ret = self.doInverseTransformations(ret, params=data) + + return ret diff --git a/models/msfts.py b/models/msfts.py index 1d3c6a1..c24487f 100644 --- a/models/msfts.py +++ b/models/msfts.py @@ -7,6 +7,7 @@ class MultiSeasonalFTS(sfts.SeasonalFTS): def __init__(self, name, indexer): super(MultiSeasonalFTS, self).__init__("MSFTS") self.name = "Multi Seasonal FTS" + self.shortname = "MSFTS " + name self.detail = "" self.seasonality = 1 self.hasSeasonality = True diff --git a/sfts.py b/sfts.py index 3cbfb16..c49cf30 100644 --- a/sfts.py +++ b/sfts.py @@ -2,8 +2,10 @@ import numpy as np from pyFTS.common import FuzzySet,FLR from pyFTS import fts -class SeasonalFLRG(fts.FTS): + +class SeasonalFLRG(FLR.FLR): def __init__(self, seasonality): + super(SeasonalFLRG, self).__init__(None,None) self.LHS = seasonality self.RHS = [] diff --git a/tests/sfts.py b/tests/sfts.py index 44716dd..5645b20 100644 --- a/tests/sfts.py +++ b/tests/sfts.py @@ -28,27 +28,6 @@ sonda = sonda[:][527041:] sonda.index = np.arange(0,len(sonda.index)) -#data = [] - -#for i in sonda.index: - - #inst = [] - - #year = int( sonda["year"][i] ) - #day_of_year = int( sonda["day"][i] ) - #minute = int (sonda["min"][i] ) - - #glo_avg = sonda["glo_avg"][i] - - #inst.append( datetime.datetime(year, 1, 1) + datetime.timedelta(day_of_year - 1, minutes=minute) ) - - #inst.append( glo_avg ) - - #data.append(inst) - -#nov = pd.DataFrame(data,columns=["data","glo_avg"]) - -#nov.to_csv("DataSets/SONDA_BSB_MOD.csv", sep=";") sonda_treino = sonda[:1051200] sonda_teste = sonda[1051201:] @@ -63,42 +42,23 @@ from pyFTS.models.seasonal import SeasonalIndexer from pyFTS.models import msfts from pyFTS.common import FLR -ix = SeasonalIndexer.DateTimeSeasonalIndexer('data',[SeasonalIndexer.DateTime.month, - SeasonalIndexer.DateTime.hour, SeasonalIndexer.DateTime.minute], - [None, None,15],'glo_avg') +partitions = ['grid','entropy'] + +indexers = ['m15','Mh','Mhm15'] + +models = [] +ixs = [] + +sample = sonda_teste[0:4300] -tmp = ix.get_data(sonda_treino) 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 - fs1 = Grid.GridPartitionerTrimf(tmp,max_part) + models.append(model) + ixs.append(ix) - Util.persist_obj(fs1,"models/sonda_fs_grid_" + str(max_part) + ".pkl") - - fs2 = FCM.FCMPartitionerTrimf(tmp, max_part) - - Util.persist_obj(fs2, "models/sonda_fs_fcm_" + str(max_part) + ".pkl") - - fs3 = Entropy.EntropyPartitionerTrimf(tmp, max_part) - - Util.persist_obj(fs3, "models/sonda_fs_entropy_" + str(max_part) + ".pkl") - - -#fs = Util.load_obj("models/sonda_fs_grid_50.pkl") - -#for f in fs: -# print(f) - -#mfts = msfts.MultiSeasonalFTS("",ix) - -#mfts.train(sonda_treino,fs) - -#print(str(mfts)) - -#plt.plot(mfts.forecast(sonda_teste)) - -#[10, 508] - -#flrs = FLR.generateIndexedFLRs(fs, ix, sonda_treino[110000:111450]) - -#for i in mfts.forecast(sonda_teste): -# print(i) \ No newline at end of file +print(bchmk.getPointStatistics(sample, models, indexers=ixs)) \ No newline at end of file