- MultiSeasonal FTS

- Seasonal Indexers for Panda DataFrames
- Indexed FLR's
This commit is contained in:
Petrônio Cândido de Lima e Silva 2017-02-04 20:40:27 -02:00
parent 71c71ca9d9
commit bb42a6be07
8 changed files with 280 additions and 19 deletions

View File

@ -641,7 +641,8 @@ def compareModelsTable(original, models_fo, models_ho):
def simpleSearch_RMSE(train, test, model, partitions, orders, save=False, file=None, tam=[10, 15],
plotforecasts=False, elev=30, azim=144, intervals=False):
plotforecasts=False, elev=30, azim=144, intervals=False,parameters=None):
_3d = len(orders) > 1
ret = []
errors = np.array([[0 for k in range(len(partitions))] for kk in range(len(orders))])
forecasted_best = []
@ -662,13 +663,16 @@ def simpleSearch_RMSE(train, test, model, partitions, orders, save=False, file=N
sets = Grid.GridPartitionerTrimf(train, p)
for oc, o in enumerate(orders, start=0):
fts = model("q = " + str(p) + " n = " + str(o))
fts.train(train, sets, o)
fts.train(train, sets, o,parameters=parameters)
if not intervals:
forecasted = fts.forecast(test)
error = Measures.rmse(np.array(test[o:]), np.array(forecasted[:-1]))
if not fts.hasSeasonality:
error = Measures.rmse(np.array(test[o:]), np.array(forecasted[:-1]))
else:
error = Measures.rmse(np.array(test[o:]), np.array(forecasted))
for kk in range(o):
forecasted.insert(0, None)
if plotforecasts: ax0.plot(forecasted, label=fts.name)
if plotforecasts: ax0.plot(forecasted, label=fts.name)
else:
forecasted = fts.forecastInterval(test)
error = 1.0 - Measures.rmse_interval(np.array(test[o:]), np.array(forecasted[:-1]))
@ -683,15 +687,22 @@ def simpleSearch_RMSE(train, test, model, partitions, orders, save=False, file=N
# handles0, labels0 = ax0.get_legend_handles_labels()
# ax0.legend(handles0, labels0)
ax0.plot(test, label="Original", linewidth=3.0, color="black")
ax1 = Axes3D(fig, rect=[0, 1, 0.9, 0.9], elev=elev, azim=azim)
if _3d: ax1 = Axes3D(fig, rect=[0, 1, 0.9, 0.9], elev=elev, azim=azim)
if not plotforecasts: ax1 = Axes3D(fig, rect=[0, 1, 0.9, 0.9], elev=elev, azim=azim)
# ax1 = fig.add_axes([0.6, 0.5, 0.45, 0.45], projection='3d')
ax1.set_title('Error Surface')
ax1.set_ylabel('Model order')
ax1.set_xlabel('Number of partitions')
ax1.set_zlabel('RMSE')
X, Y = np.meshgrid(partitions, orders)
surf = ax1.plot_surface(X, Y, errors, rstride=1, cstride=1, antialiased=True)
if _3d:
ax1.set_title('Error Surface')
ax1.set_ylabel('Model order')
ax1.set_xlabel('Number of partitions')
ax1.set_zlabel('RMSE')
X, Y = np.meshgrid(partitions, orders)
surf = ax1.plot_surface(X, Y, errors, rstride=1, cstride=1, antialiased=True)
else:
ax1 = fig.add_axes([0, 1, 0.9, 0.9])
ax1.set_title('Error Curve')
ax1.set_ylabel('Number of partitions')
ax1.set_xlabel('RMSE')
ax0.plot(errors,partitions)
ret.append(best)
ret.append(forecasted_best)

View File

@ -1,7 +1,8 @@
import numpy as np
from pyFTS.common import FuzzySet
class FLR:
class FLR(object):
def __init__(self, LHS, RHS):
self.LHS = LHS
self.RHS = RHS
@ -10,6 +11,15 @@ class FLR:
return self.LHS.name + " -> " + self.RHS.name
class IndexedFLR(FLR):
def __init__(self, index, LHS, RHS):
super(IndexedFLR, self).__init__(LHS, RHS)
self.index = index
def __str__(self):
return str(self.index) + ": "+ self.LHS.name + " -> " + self.RHS.name
def generateNonRecurrentFLRs(fuzzyData):
flrs = {}
for i in range(2,len(fuzzyData)):
@ -18,8 +28,22 @@ def generateNonRecurrentFLRs(fuzzyData):
ret = [value for key, value in flrs.items()]
return ret
def generateRecurrentFLRs(fuzzyData):
flrs = []
for i in np.arange(1,len(fuzzyData)):
flrs.append(FLR(fuzzyData[i-1],fuzzyData[i]))
return flrs
def generateIndexedFLRs(sets, indexer, data):
flrs = []
index = indexer.get_season_of_data(data)
ndata = indexer.get_data(data)
for k in np.arange(0,len(data)-1):
lhs = FuzzySet.getMaxMembershipFuzzySet(ndata[k],sets)
rhs = FuzzySet.getMaxMembershipFuzzySet(ndata[k+1], sets)
season = index[k]
flr = IndexedFLR(season,lhs,rhs)
flrs.append(flr)
return flrs

1
fts.py
View File

@ -16,6 +16,7 @@ class FTS(object):
self.hasPointForecasting = True
self.hasIntervalForecasting = False
self.hasDistributionForecasting = False
self.isMultivariate = False
self.dump = False
self.transformations = []
self.transformations_param = []

61
models/msfts.py Normal file
View File

@ -0,0 +1,61 @@
import numpy as np
from pyFTS.common import FuzzySet,FLR
from pyFTS import fts, sfts
class MultiSeasonalFTS(sfts.SeasonalFTS):
def __init__(self, name, indexer):
super(MultiSeasonalFTS, self).__init__("MSFTS")
self.name = "Multi Seasonal FTS"
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 index, season in enumerate(self.indexer.get_season_of_data(flrs),start=0):
print(index)
print(season)
if str(season) not in self.flrgs:
flrgs[str(season)] = sfts.SeasonalFLRG(season)
flrgs[str(season)].append(flrs[index].RHS)
return (flrgs)
def train(self, data, sets, order=1, parameters=None):
self.sets = sets
self.seasonality = parameters
ndata = self.indexer.set_data(data,self.doTransformations(self.indexer.get_data(data)))
tmpdata = FuzzySet.fuzzySeries(ndata, sets)
flrs = FLR.generateRecurrentFLRs(tmpdata)
self.flrgs = self.generateFLRG(flrs)
def forecast(self, data):
ndata = np.array(self.doTransformations(self.indexer.get_data(data)))
l = len(ndata)
ret = []
for k in np.arange(1, l):
season = self.indexer.get_season_index(k)
flrg = self.flrgs[str(season)]
mp = self.getMidpoints(flrg)
ret.append(sum(mp) / len(mp))
ret = self.doInverseTransformations(ret, params=[data[self.order - 1:]])
return ret

View File

@ -0,0 +1,102 @@
import numpy as np
class SeasonalIndexer(object):
def __init__(self,num_seasons):
self.num_seasons = num_seasons
def get_season_of_data(self,data):
pass
def get_season_by_index(self,inde):
pass
def get_data_by_season(self, data, indexes):
pass
def get_index_by_season(self, indexes):
pass
def get_data(self, data):
pass
class LinearSeasonalIndexer(SeasonalIndexer):
def __init__(self,seasons):
super(LinearSeasonalIndexer, self).__init__(len(seasons))
self.seasons = seasons
def get_season_of_data(self,data):
return self.get_season_by_index(np.arange(0,len(data)))
def get_season_by_index(self,index):
ret = []
for ix in index:
if self.num_seasons == 1:
season = ix % self.seasons
else:
season = []
for seasonality in self.seasons:
print("S ", seasonality)
tmp = ix // seasonality
print("T ", tmp)
season.append(tmp)
#season.append(rest)
ret.append(season)
return ret
def get_index_by_season(self, indexes):
ix = 0;
for count,season in enumerate(self.seasons):
ix += season*(indexes[count])
#ix += indexes[-1]
return ix
def get_data(self, data):
return data
class DataFrameSeasonalIndexer(SeasonalIndexer):
def __init__(self,index_fields,index_seasons, data_fields):
super(DataFrameSeasonalIndexer, self).__init__(len(index_seasons))
self.fields = index_fields
self.seasons = index_seasons
self.data_fields = data_fields
def get_season_of_data(self,data):
ret = []
for ix in data.index:
season = []
for c, f in enumerate(self.fields, start=0):
if self.seasons[c] is None:
season.append(data[f][ix])
else:
season.append(data[f][ix] // self.seasons[c])
ret.append(season)
return ret
def get_season_by_index(self,index):
raise Exception("Operation not available!")
def get_data_by_season(self, data, indexes):
for season in indexes:
for c, f in enumerate(self.fields, start=0):
if self.seasons[c] is None:
data = data[data[f]== season[c]]
else:
data = data[(data[f] // self.seasons[c]) == season[c]]
return data[self.data_fields]
def get_index_by_season(self, indexes):
raise Exception("Operation not available!")
def get_data(self, data):
return data[self.data_fields].tolist()
def set_data(self, data, value):
data[self.data_fields] = value
return data

View File

21
sfts.py
View File

@ -1,7 +1,6 @@
import numpy as np
from pyFTS.common import FuzzySet,FLR
import fts
from pyFTS import fts
class SeasonalFLRG(fts.FTS):
def __init__(self, seasonality):
@ -28,15 +27,19 @@ class SeasonalFTS(fts.FTS):
self.detail = "Chen"
self.seasonality = 1
self.hasSeasonality = True
self.hasPointForecasting = True
self.isHighOrder = False
def generateFLRG(self, flrs):
flrgs = []
season = 1
for flr in flrs:
if len(flrgs) < self.seasonality:
flrgs.append(SeasonalFLRG(season))
flrgs[season].append(flr.RHS)
#print(season)
flrgs[season-1].append(flr.RHS)
season = (season + 1) % (self.seasonality + 1)
@ -54,16 +57,20 @@ class SeasonalFTS(fts.FTS):
def forecast(self, data):
data = np.array(data)
ndata = self.doTransformations(data)
ndata = np.array(self.doTransformations(data))
l = len(ndata)
ret = []
for k in np.arange(1, l):
flrg = self.flrgs[data[k]]
#flrg = self.flrgs[ndata[k]]
season = (k + 1) % (self.seasonality + 1)
#print(season)
flrg = self.flrgs[season-1]
mp = self.getMidpoints(flrg)

55
tests/sfts.py Normal file
View File

@ -0,0 +1,55 @@
#!/usr/bin/python
# -*- coding: utf8 -*-
import os
import numpy as np
import pandas as pd
import matplotlib as plt
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
from pyFTS.partitioners import Grid
from pyFTS.common import FLR,FuzzySet,Membership,Transformations
from pyFTS import fts,sfts
from pyFTS.models import msfts
from pyFTS.benchmarks import benchmarks as bchmk
from pyFTS.benchmarks import Measures
os.chdir("/home/petronio/dados/Dropbox/Doutorado/Disciplinas/AdvancedFuzzyTimeSeriesModels/")
sonda = pd.read_csv("DataSets/SONDA_BSB_CLEAN.csv", sep=";")
sonda = sonda[:][527041:]
sonda.index = np.arange(0,len(sonda.index))
sonda_treino = sonda[:1051200]
sonda_teste = sonda[1051201:]
#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.models.seasonal import SeasonalIndexer
from pyFTS.models import msfts
from pyFTS.common import FLR
ix = SeasonalIndexer.DataFrameSeasonalIndexer(['day','min'],[30, 60],'glo_avg')
fs = Grid.GridPartitionerTrimf(ix.get_data(sonda_treino),20)
#mfts = msfts.MultiSeasonalFTS("",ix)
#mfts.train(sonda_teste,fs)
#print(str(mfts))
#[10, 508]
flrs = FLR.generateIndexedFLRs(fs, ix, sonda_treino[110000:111450])
for i in flrs: #ix.get_data(sonda_treino[111430:111450]):
print(i)