- MultiSeasonal FTS
- Seasonal Indexers for Panda DataFrames - Indexed FLR's
This commit is contained in:
parent
71c71ca9d9
commit
bb42a6be07
@ -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],
|
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 = []
|
ret = []
|
||||||
errors = np.array([[0 for k in range(len(partitions))] for kk in range(len(orders))])
|
errors = np.array([[0 for k in range(len(partitions))] for kk in range(len(orders))])
|
||||||
forecasted_best = []
|
forecasted_best = []
|
||||||
@ -662,10 +663,13 @@ def simpleSearch_RMSE(train, test, model, partitions, orders, save=False, file=N
|
|||||||
sets = Grid.GridPartitionerTrimf(train, p)
|
sets = Grid.GridPartitionerTrimf(train, p)
|
||||||
for oc, o in enumerate(orders, start=0):
|
for oc, o in enumerate(orders, start=0):
|
||||||
fts = model("q = " + str(p) + " n = " + str(o))
|
fts = model("q = " + str(p) + " n = " + str(o))
|
||||||
fts.train(train, sets, o)
|
fts.train(train, sets, o,parameters=parameters)
|
||||||
if not intervals:
|
if not intervals:
|
||||||
forecasted = fts.forecast(test)
|
forecasted = fts.forecast(test)
|
||||||
|
if not fts.hasSeasonality:
|
||||||
error = Measures.rmse(np.array(test[o:]), np.array(forecasted[:-1]))
|
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):
|
for kk in range(o):
|
||||||
forecasted.insert(0, None)
|
forecasted.insert(0, None)
|
||||||
if plotforecasts: ax0.plot(forecasted, label=fts.name)
|
if plotforecasts: ax0.plot(forecasted, label=fts.name)
|
||||||
@ -683,15 +687,22 @@ def simpleSearch_RMSE(train, test, model, partitions, orders, save=False, file=N
|
|||||||
# handles0, labels0 = ax0.get_legend_handles_labels()
|
# handles0, labels0 = ax0.get_legend_handles_labels()
|
||||||
# ax0.legend(handles0, labels0)
|
# ax0.legend(handles0, labels0)
|
||||||
ax0.plot(test, label="Original", linewidth=3.0, color="black")
|
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)
|
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 = fig.add_axes([0.6, 0.5, 0.45, 0.45], projection='3d')
|
||||||
|
if _3d:
|
||||||
ax1.set_title('Error Surface')
|
ax1.set_title('Error Surface')
|
||||||
ax1.set_ylabel('Model order')
|
ax1.set_ylabel('Model order')
|
||||||
ax1.set_xlabel('Number of partitions')
|
ax1.set_xlabel('Number of partitions')
|
||||||
ax1.set_zlabel('RMSE')
|
ax1.set_zlabel('RMSE')
|
||||||
X, Y = np.meshgrid(partitions, orders)
|
X, Y = np.meshgrid(partitions, orders)
|
||||||
surf = ax1.plot_surface(X, Y, errors, rstride=1, cstride=1, antialiased=True)
|
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(best)
|
||||||
ret.append(forecasted_best)
|
ret.append(forecasted_best)
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
from pyFTS.common import FuzzySet
|
||||||
|
|
||||||
|
|
||||||
class FLR:
|
class FLR(object):
|
||||||
def __init__(self, LHS, RHS):
|
def __init__(self, LHS, RHS):
|
||||||
self.LHS = LHS
|
self.LHS = LHS
|
||||||
self.RHS = RHS
|
self.RHS = RHS
|
||||||
@ -10,6 +11,15 @@ class FLR:
|
|||||||
return self.LHS.name + " -> " + self.RHS.name
|
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):
|
def generateNonRecurrentFLRs(fuzzyData):
|
||||||
flrs = {}
|
flrs = {}
|
||||||
for i in range(2,len(fuzzyData)):
|
for i in range(2,len(fuzzyData)):
|
||||||
@ -18,8 +28,22 @@ def generateNonRecurrentFLRs(fuzzyData):
|
|||||||
ret = [value for key, value in flrs.items()]
|
ret = [value for key, value in flrs.items()]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def generateRecurrentFLRs(fuzzyData):
|
def generateRecurrentFLRs(fuzzyData):
|
||||||
flrs = []
|
flrs = []
|
||||||
for i in np.arange(1,len(fuzzyData)):
|
for i in np.arange(1,len(fuzzyData)):
|
||||||
flrs.append(FLR(fuzzyData[i-1],fuzzyData[i]))
|
flrs.append(FLR(fuzzyData[i-1],fuzzyData[i]))
|
||||||
return flrs
|
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
1
fts.py
@ -16,6 +16,7 @@ class FTS(object):
|
|||||||
self.hasPointForecasting = True
|
self.hasPointForecasting = True
|
||||||
self.hasIntervalForecasting = False
|
self.hasIntervalForecasting = False
|
||||||
self.hasDistributionForecasting = False
|
self.hasDistributionForecasting = False
|
||||||
|
self.isMultivariate = False
|
||||||
self.dump = False
|
self.dump = False
|
||||||
self.transformations = []
|
self.transformations = []
|
||||||
self.transformations_param = []
|
self.transformations_param = []
|
||||||
|
61
models/msfts.py
Normal file
61
models/msfts.py
Normal 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
|
102
models/seasonal/SeasonalIndexer.py
Normal file
102
models/seasonal/SeasonalIndexer.py
Normal 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
|
0
models/seasonal/__init__.py
Normal file
0
models/seasonal/__init__.py
Normal file
21
sfts.py
21
sfts.py
@ -1,7 +1,6 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from pyFTS.common import FuzzySet,FLR
|
from pyFTS.common import FuzzySet,FLR
|
||||||
import fts
|
from pyFTS import fts
|
||||||
|
|
||||||
|
|
||||||
class SeasonalFLRG(fts.FTS):
|
class SeasonalFLRG(fts.FTS):
|
||||||
def __init__(self, seasonality):
|
def __init__(self, seasonality):
|
||||||
@ -28,15 +27,19 @@ class SeasonalFTS(fts.FTS):
|
|||||||
self.detail = "Chen"
|
self.detail = "Chen"
|
||||||
self.seasonality = 1
|
self.seasonality = 1
|
||||||
self.hasSeasonality = True
|
self.hasSeasonality = True
|
||||||
|
self.hasPointForecasting = True
|
||||||
|
self.isHighOrder = False
|
||||||
|
|
||||||
def generateFLRG(self, flrs):
|
def generateFLRG(self, flrs):
|
||||||
flrgs = []
|
flrgs = []
|
||||||
season = 1
|
season = 1
|
||||||
for flr in flrs:
|
for flr in flrs:
|
||||||
|
|
||||||
if len(flrgs) < self.seasonality:
|
if len(flrgs) < self.seasonality:
|
||||||
flrgs.append(SeasonalFLRG(season))
|
flrgs.append(SeasonalFLRG(season))
|
||||||
|
|
||||||
flrgs[season].append(flr.RHS)
|
#print(season)
|
||||||
|
flrgs[season-1].append(flr.RHS)
|
||||||
|
|
||||||
season = (season + 1) % (self.seasonality + 1)
|
season = (season + 1) % (self.seasonality + 1)
|
||||||
|
|
||||||
@ -54,16 +57,20 @@ class SeasonalFTS(fts.FTS):
|
|||||||
|
|
||||||
def forecast(self, data):
|
def forecast(self, data):
|
||||||
|
|
||||||
data = np.array(data)
|
ndata = np.array(self.doTransformations(data))
|
||||||
|
|
||||||
ndata = self.doTransformations(data)
|
|
||||||
|
|
||||||
l = len(ndata)
|
l = len(ndata)
|
||||||
|
|
||||||
ret = []
|
ret = []
|
||||||
|
|
||||||
for k in np.arange(1, l):
|
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)
|
mp = self.getMidpoints(flrg)
|
||||||
|
|
||||||
|
55
tests/sfts.py
Normal file
55
tests/sfts.py
Normal 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)
|
Loading…
Reference in New Issue
Block a user