- Several bugfixes;

-  class Transformation
- Inclusion of cascaded transformations in FTS
This commit is contained in:
Petrônio Cândido de Lima e Silva 2017-01-26 10:19:34 -02:00
parent 664fec513e
commit 15b4aa1137
6 changed files with 91 additions and 21 deletions

View File

@ -42,9 +42,19 @@ def UStatistic(targets, forecasts):
naive = [] naive = []
y = [] y = []
for k in np.arange(0,l-1): for k in np.arange(0,l-1):
y.append(((forecasts[k+1] - targets[k+1])/targets[k]) ** 2) y.append((forecasts[k ] - targets[k ]) ** 2)
naive.append(((targets[k + 1] - targets[k]) / targets[k]) ** 2) naive.append((targets[k + 1] - targets[k]) ** 2)
return np.sqrt(sum(y)/sum(naive)) return np.sqrt(sum(y) / sum(naive))
# Theils Inequality Coefficient
def TheilsInequality(targets, forecasts):
res = targets - forecasts
t = len(res)
us = np.sqrt(sum([u**2 for u in res]))
ys = np.sqrt(sum([y**2 for y in targets]))
fs = np.sqrt(sum([f**2 for f in forecasts]))
return us / (ys + fs)
# Q Statistic for Box-Pierce test # Q Statistic for Box-Pierce test

View File

@ -19,7 +19,6 @@ def ChiSquared(q,h):
return p return p
def compareResiduals(data, models): def compareResiduals(data, models):
ret = "Model & Order & Mean & STD & Box-Pierce & Box-Ljung & P-value \\\\ \n" ret = "Model & Order & Mean & STD & Box-Pierce & Box-Ljung & P-value \\\\ \n"
for mfts in models: for mfts in models:
@ -29,12 +28,12 @@ def compareResiduals(data, models):
sig = np.std(res) sig = np.std(res)
ret += mfts.shortname + " & " ret += mfts.shortname + " & "
ret += str(mfts.order) + " & " ret += str(mfts.order) + " & "
ret += str(mu) + " & " ret += str(round(mu,2)) + " & "
ret += str(sig) + " & " ret += str(round(sig,2)) + " & "
q1 = Measures.BoxPierceStatistic(res, 10) q1 = Measures.BoxPierceStatistic(res, 10)
ret += str(q1) + " & " ret += str(round(q1,2)) + " & "
q2 = Measures.BoxLjungStatistic(res, 10) q2 = Measures.BoxLjungStatistic(res, 10)
ret += str(q2) + " & " ret += str(round(q2,2)) + " & "
ret += str(ChiSquared(q2, 10)) ret += str(ChiSquared(q2, 10))
ret += " \\\\ \n" ret += " \\\\ \n"
return ret return ret

View File

@ -14,7 +14,8 @@ from pyFTS.common import Membership, FuzzySet, FLR, Transformations, Util
from pyFTS import fts, chen, yu, ismailefendi, sadaei, hofts, hwang, pfts, ifts from pyFTS import fts, chen, yu, ismailefendi, sadaei, hofts, hwang, pfts, ifts
def allPointForecasters(data_train, data_test, partitions, max_order=3,save=False, file=None, tam=[20, 5]): def allPointForecasters(data_train, data_test, partitions, max_order=3, statistics=True, residuals=True, series=True,
save=False, file=None, tam=[20, 5]):
models = [naive.Naive, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS, models = [naive.Naive, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS,
sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, pfts.ProbabilisticFTS] sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, pfts.ProbabilisticFTS]
@ -44,24 +45,27 @@ def allPointForecasters(data_train, data_test, partitions, max_order=3,save=Fals
colors.append(all_colors[count]) colors.append(all_colors[count])
count += 10 count += 10
print(getPointStatistics(data_test, objs)) if statistics:
print(getPointStatistics(data_test, objs))
print(ResidualAnalysis.compareResiduals(data_test, objs)) if residuals:
print(ResidualAnalysis.compareResiduals(data_test, objs))
ResidualAnalysis.plotResiduals(data_test, objs, save=save, file=file, tam=[tam[0], 5 * tam[1]])
plotComparedSeries(data_test, objs, colors, typeonlegend=False, save=save, file=file, tam=tam, intervals=False) if series:
plotComparedSeries(data_test, objs, colors, typeonlegend=False, save=save, file=file, tam=tam, intervals=False)
ResidualAnalysis.plotResiduals(data_test, objs, save=save, file=file, tam=[tam[0],5*tam[1]])
def getPointStatistics(data, models, externalmodels = None, externalforecasts = None): def getPointStatistics(data, models, externalmodels = None, externalforecasts = None):
ret = "Model & Order & RMSE & MAPE & Theil's U \\\\ \n" ret = "Model & Order & RMSE & MAPE & Theil's U & Theil's I \\\\ \n"
for fts in models: for fts in models:
forecasts = fts.forecast(data) forecasts = fts.forecast(data)
ret += fts.shortname + " & " ret += fts.shortname + " & "
ret += str(fts.order) + " & " ret += str(fts.order) + " & "
ret += str(round(Measures.rmse(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2)) + " & " ret += str(round(Measures.rmse(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2)) + " & "
ret += str(round(Measures.mape(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2))+ " & " ret += str(round(Measures.mape(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)) ret += str(round(Measures.UStatistic(np.array(data[fts.order:]), np.array(forecasts[:-1])), 2))+ " & "
ret += str(round(Measures.TheilsInequality(np.array(data[fts.order:]), np.array(forecasts[:-1])), 4))
ret += " \\\\ \n" ret += " \\\\ \n"
if externalmodels is not None: if externalmodels is not None:
l = len(externalmodels) l = len(externalmodels)

View File

@ -12,3 +12,4 @@ class Naive(fts.FTS):
def forecast(self, data): def forecast(self, data):
return [k for k in data] return [k for k in data]

View File

@ -3,11 +3,40 @@ import math
from pyFTS import * from pyFTS import *
def differential(original, lags=1): class Transformation(object):
n = len(original)
diff = [original[t - lags] - original[t] for t in np.arange(lags, n)] def __init__(self, parameters):
for t in np.arange(0, lags): diff.insert(0, 0) self.isInversible = True
return np.array(diff) self.parameters = parameters
def apply(self,data,param):
pass
def inverse(self,data, param):
pass
def __str__(self):
return self.__class__.__name__ + '(' + str(self.parameters) + ')'
class Differential(Transformation):
def __init__(self, parameters):
super(Differential, self).__init__(parameters)
self.lag = parameters
def apply(self, data, param=None):
if param is not None:
self.lag = param
n = len(data)
diff = [data[t - self.lag] - data[t] for t in np.arange(self.lag, n)]
for t in np.arange(0, self.lag): diff.insert(0, 0)
return np.array(diff)
def inverse(self,data, param):
n = len(data)
inc = [data[t] + param[t] for t in np.arange(1, n)]
return np.array(inc)
def boxcox(original, plambda): def boxcox(original, plambda):

27
fts.py
View File

@ -17,6 +17,8 @@ class FTS(object):
self.hasIntervalForecasting = False self.hasIntervalForecasting = False
self.hasDistributionForecasting = False self.hasDistributionForecasting = False
self.dump = False self.dump = False
self.transformations = []
self.transformations_param = []
def fuzzy(self, data): def fuzzy(self, data):
best = {"fuzzyset": "", "membership": 0.0} best = {"fuzzyset": "", "membership": 0.0}
@ -54,6 +56,31 @@ class FTS(object):
ret = np.array([s.centroid for s in flrg.RHS]) ret = np.array([s.centroid for s in flrg.RHS])
return ret return ret
def appendTransformation(self, transformation):
self.transformations.append(transformation)
def doTransformations(self,data,params=None):
ndata = data
if params is None:
params = [ None for k in self.transformations]
c = 0
for t in self.transformations:
ndata = t.apply(ndata,params[c])
c += 1
return ndata
def doInverseTransformations(self,data,params=None):
ndata = data
if params is None:
params = [None for k in self.transformations]
c = 0
for t in reversed(self.transformations):
ndata = t.inverse(ndata, params[c])
c += 1
return ndata
def __str__(self): def __str__(self):
tmp = self.name + ":\n" tmp = self.name + ":\n"
for r in sorted(self.flrgs): for r in sorted(self.flrgs):