- 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,11 +42,21 @@ def UStatistic(targets, forecasts):
naive = []
y = []
for k in np.arange(0,l-1):
y.append(((forecasts[k+1] - targets[k+1])/targets[k]) ** 2)
naive.append(((targets[k + 1] - targets[k]) / targets[k]) ** 2)
y.append((forecasts[k ] - targets[k ]) ** 2)
naive.append((targets[k + 1] - targets[k]) ** 2)
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
def BoxPierceStatistic(data, h):
n = len(data)

View File

@ -19,7 +19,6 @@ def ChiSquared(q,h):
return p
def compareResiduals(data, models):
ret = "Model & Order & Mean & STD & Box-Pierce & Box-Ljung & P-value \\\\ \n"
for mfts in models:
@ -29,12 +28,12 @@ def compareResiduals(data, models):
sig = np.std(res)
ret += mfts.shortname + " & "
ret += str(mfts.order) + " & "
ret += str(mu) + " & "
ret += str(sig) + " & "
ret += str(round(mu,2)) + " & "
ret += str(round(sig,2)) + " & "
q1 = Measures.BoxPierceStatistic(res, 10)
ret += str(q1) + " & "
ret += str(round(q1,2)) + " & "
q2 = Measures.BoxLjungStatistic(res, 10)
ret += str(q2) + " & "
ret += str(round(q2,2)) + " & "
ret += str(ChiSquared(q2, 10))
ret += " \\\\ \n"
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
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,
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])
count += 10
if statistics:
print(getPointStatistics(data_test, objs))
if residuals:
print(ResidualAnalysis.compareResiduals(data_test, objs))
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]])
if series:
plotComparedSeries(data_test, objs, colors, typeonlegend=False, save=save, file=file, tam=tam, intervals=False)
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:
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.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"
if externalmodels is not None:
l = len(externalmodels)

View File

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

View File

@ -3,12 +3,41 @@ import math
from pyFTS import *
def differential(original, lags=1):
n = len(original)
diff = [original[t - lags] - original[t] for t in np.arange(lags, n)]
for t in np.arange(0, lags): diff.insert(0, 0)
class Transformation(object):
def __init__(self, parameters):
self.isInversible = True
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):
n = len(original)

27
fts.py
View File

@ -17,6 +17,8 @@ class FTS(object):
self.hasIntervalForecasting = False
self.hasDistributionForecasting = False
self.dump = False
self.transformations = []
self.transformations_param = []
def fuzzy(self, data):
best = {"fuzzyset": "", "membership": 0.0}
@ -54,6 +56,31 @@ class FTS(object):
ret = np.array([s.centroid for s in flrg.RHS])
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):
tmp = self.name + ":\n"
for r in sorted(self.flrgs):