Correções de bugs e pequenas otimizações diversas:

- Otimização do GridPartitioner
 - Correção na geração de PFLRG's em PFTS
 - Métodos de __str__ mais intuitivos
This commit is contained in:
Petrônio Cândido de Lima e Silva 2017-01-10 18:05:51 -02:00
parent dba1919a18
commit ba1b4fbae6
10 changed files with 506 additions and 465 deletions

View File

@ -5,10 +5,11 @@ import matplotlib.colors as pltcolors
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d import Axes3D
from sklearn.cross_validation import KFold from sklearn.cross_validation import KFold
import Measures from pyFTS.benchmarks import Measures
from pyFTS.partitioners import Grid from pyFTS.partitioners import Grid
from pyFTS.common import Membership, FuzzySet, FLR, Transformations from pyFTS.common import Membership, FuzzySet, FLR, Transformations
def getIntervalStatistics(original, models): def getIntervalStatistics(original, models):
ret = "Model & RMSE & MAPE & Sharpness & Resolution & Coverage \\ \n" ret = "Model & RMSE & MAPE & Sharpness & Resolution & Coverage \\ \n"
for fts in models: for fts in models:
@ -21,15 +22,18 @@ def getIntervalStatistics(original,models):
ret = ret + str(round(Measures.coverage(original[fts.order - 1:], forecasts), 2)) + " \\ \n" ret = ret + str(round(Measures.coverage(original[fts.order - 1:], forecasts), 2)) + " \\ \n"
return ret return ret
def plotDistribution(dist): def plotDistribution(dist):
for k in dist.index: for k in dist.index:
alpha = np.array([dist[x][k] for x in dist]) * 100 alpha = np.array([dist[x][k] for x in dist]) * 100
x = [k for x in np.arange(0, len(alpha))] x = [k for x in np.arange(0, len(alpha))]
y = dist.columns y = dist.columns
plt.scatter(x,y,c=alpha,marker='s',linewidths=0,cmap='Oranges',norm=pltcolors.Normalize(vmin=0,vmax=1),vmin=0,vmax=1,edgecolors=None) plt.scatter(x, y, c=alpha, marker='s', linewidths=0, cmap='Oranges', norm=pltcolors.Normalize(vmin=0, vmax=1),
vmin=0, vmax=1, edgecolors=None)
def plotComparedSeries(original, models, colors): def plotComparedSeries(original, models, colors):
fig = plt.figure(figsize=[25,10]) fig = plt.figure(figsize=[15, 5])
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
mi = [] mi = []
@ -38,9 +42,16 @@ def plotComparedSeries(original,models, colors):
ax.plot(original, color='black', label="Original") ax.plot(original, color='black', label="Original")
count = 0 count = 0
for fts in models: for fts in models:
if fts.hasPointForecasting:
forecasted = fts.forecast(original) forecasted = fts.forecast(original)
mi.append(min(forecasted))
ma.append(max(forecasted))
for k in np.arange(0, fts.order):
forecasted.insert(0, None)
ax.plot(forecasted, color=colors[count], label=fts.shortname, ls="-")
if fts.isInterval: if fts.hasIntervalForecasting:
forecasted = fts.forecastInterval(original)
lower = [kk[0] for kk in forecasted] lower = [kk[0] for kk in forecasted]
upper = [kk[1] for kk in forecasted] upper = [kk[1] for kk in forecasted]
mi.append(min(lower)) mi.append(min(lower))
@ -48,17 +59,11 @@ def plotComparedSeries(original,models, colors):
for k in np.arange(0, fts.order): for k in np.arange(0, fts.order):
lower.insert(0, None) lower.insert(0, None)
upper.insert(0, None) upper.insert(0, None)
ax.plot(lower,color=colors[count],label=fts.shortname) ax.plot(lower, color=colors[count], label=fts.shortname,ls="--")
ax.plot(upper,color=colors[count]) ax.plot(upper, color=colors[count],ls="--")
else:
mi.append(min(forecasted))
ma.append(max(forecasted))
forecasted.insert(0,None)
ax.plot(forecasted,color=colors[count],label=fts.shortname)
handles0, labels0 = ax.get_legend_handles_labels() handles0, labels0 = ax.get_legend_handles_labels()
ax.legend(handles0,labels0) ax.legend(handles0, labels0, loc=2)
count = count + 1 count = count + 1
# ax.set_title(fts.name) # ax.set_title(fts.name)
ax.set_ylim([min(mi), max(ma)]) ax.set_ylim([min(mi), max(ma)])
@ -76,7 +81,7 @@ def plotComparedIntervalsAhead(original,models, colors, distributions, time_from
count = 0 count = 0
for fts in models: for fts in models:
if fts.isDensity and distributions[count]: if fts.hasDistributionForecasting and distributions[count]:
density = fts.forecastDistributionAhead(original[:time_from], time_to, 25) density = fts.forecastDistributionAhead(original[:time_from], time_to, 25)
for k in density.index: for k in density.index:
alpha = np.array([density[x][k] for x in density]) * 100 alpha = np.array([density[x][k] for x in density]) * 100
@ -85,7 +90,7 @@ def plotComparedIntervalsAhead(original,models, colors, distributions, time_from
ax.scatter(x, y, c=alpha, marker='s', linewidths=0, cmap='Oranges', ax.scatter(x, y, c=alpha, marker='s', linewidths=0, cmap='Oranges',
norm=pltcolors.Normalize(vmin=0, vmax=1), vmin=0, vmax=1, edgecolors=None) norm=pltcolors.Normalize(vmin=0, vmax=1), vmin=0, vmax=1, edgecolors=None)
if fts.isInterval: if fts.hasIntervalForecasting:
forecasts = fts.forecastAhead(original[:time_from], time_to) forecasts = fts.forecastAhead(original[:time_from], time_to)
lower = [kk[0] for kk in forecasts] lower = [kk[0] for kk in forecasts]
upper = [kk[1] for kk in forecasts] upper = [kk[1] for kk in forecasts]
@ -130,6 +135,7 @@ def plotCompared(original,forecasts,labels,title):
ax.set_xlim([0, len(original)]) ax.set_xlim([0, len(original)])
ax.set_ylim([min(original), max(original)]) ax.set_ylim([min(original), max(original)])
def SelecaoKFold_MenorRMSE(original, parameters, modelo): def SelecaoKFold_MenorRMSE(original, parameters, modelo):
nfolds = 5 nfolds = 5
ret = [] ret = []
@ -250,6 +256,7 @@ def SelecaoKFold_MenorRMSE(original,parameters,modelo):
ret.append(forecasted_best) ret.append(forecasted_best)
return ret return ret
def SelecaoSimples_MenorRMSE(original, parameters, modelo): def SelecaoSimples_MenorRMSE(original, parameters, modelo):
ret = [] ret = []
errors = [] errors = []
@ -332,6 +339,7 @@ def SelecaoSimples_MenorRMSE(original,parameters,modelo):
ret.append(forecastedd_best) ret.append(forecastedd_best)
return ret return ret
def compareModelsPlot(original, models_fo, models_ho): def compareModelsPlot(original, models_fo, models_ho):
fig = plt.figure(figsize=[13, 6]) fig = plt.figure(figsize=[13, 6])
fig.suptitle("Comparação de modelos ") fig.suptitle("Comparação de modelos ")
@ -346,6 +354,7 @@ def compareModelsPlot(original,models_fo,models_ho):
handles0, labels0 = ax0.get_legend_handles_labels() handles0, labels0 = ax0.get_legend_handles_labels()
ax0.legend(handles0, labels0) ax0.legend(handles0, labels0)
def compareModelsTable(original, models_fo, models_ho): def compareModelsTable(original, models_fo, models_ho):
fig = plt.figure(figsize=[12, 4]) fig = plt.figure(figsize=[12, 4])
fig.suptitle("Comparação de modelos ") fig.suptitle("Comparação de modelos ")
@ -392,8 +401,10 @@ def compareModelsTable(original,models_fo,models_ho):
return sup + header + body + "\\end{tabular}" return sup + header + body + "\\end{tabular}"
from pyFTS import hwang from pyFTS import hwang
def HOSelecaoSimples_MenorRMSE(original, parameters, orders): def HOSelecaoSimples_MenorRMSE(original, parameters, orders):
ret = [] ret = []
errors = np.array([[0 for k in range(len(parameters))] for kk in range(len(orders))]) errors = np.array([[0 for k in range(len(parameters))] for kk in range(len(orders))])

View File

@ -1,10 +1,14 @@
import numpy as np
class FLR: class FLR:
def __init__(self, LHS, RHS): def __init__(self, LHS, RHS):
self.LHS = LHS self.LHS = LHS
self.RHS = RHS self.RHS = RHS
def __str__(self): def __str__(self):
return str(self.LHS) + " -> " + str(self.RHS) return self.LHS.name + " -> " + self.RHS.name
def generateNonRecurrentFLRs(fuzzyData): def generateNonRecurrentFLRs(fuzzyData):
flrs = {} flrs = {}

View File

@ -20,7 +20,7 @@ class FuzzySet:
return self.mf(x, self.parameters) return self.mf(x, self.parameters)
def __str__(self): def __str__(self):
return self.name + ": " + str(self.mf) + "(" + str(self.parameters) + ")" return self.name + ": " + str(self.mf.__name__) + "(" + str(self.parameters) + ")"
def fuzzyInstance(inst, fuzzySets): def fuzzyInstance(inst, fuzzySets):

23
fts.py
View File

@ -10,9 +10,11 @@ class FTS:
self.shortname = name self.shortname = name
self.name = name self.name = name
self.detail = name self.detail = name
self.isSeasonal = False self.hasSeasonality = False
self.isInterval = False self.hasPointForecasting = True
self.isDensity = False self.hasIntervalForecasting = False
self.hasDistributionForecasting = False
self.dump = False
def fuzzy(self, data): def fuzzy(self, data):
best = {"fuzzyset": "", "membership": 0.0} best = {"fuzzyset": "", "membership": 0.0}
@ -28,6 +30,21 @@ class FTS:
def forecast(self, data): def forecast(self, data):
pass pass
def forecastInterval(self, data):
pass
def forecastDistribution(self, data):
pass
def forecastAhead(self, data, steps):
pass
def forecastAheadInterval(self, data, steps):
pass
def forecastAheadDistribution(self, data, steps):
pass
def train(self, data, sets): def train(self, data, sets):
pass pass

View File

@ -1,6 +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 HighOrderFLRG: class HighOrderFLRG:
@ -18,7 +18,7 @@ class HighOrderFLRG:
if len(self.strlhs) == 0: if len(self.strlhs) == 0:
for c in self.LHS: for c in self.LHS:
if len(self.strlhs) > 0: if len(self.strlhs) > 0:
self.strlhs = self.strlhs + ", " self.strlhs += ", "
self.strlhs = self.strlhs + c.name self.strlhs = self.strlhs + c.name
return self.strlhs return self.strlhs
@ -63,7 +63,7 @@ class HighOrderFTS(fts.FTS):
self.sets = sets self.sets = sets
for s in self.sets: self.setsDict[s.name] = s for s in self.sets: self.setsDict[s.name] = s
tmpdata = FuzzySet.fuzzySeries(data, sets) tmpdata = FuzzySet.fuzzySeries(data, sets)
flrs = FuzzySet.generateRecurrentFLRs(tmpdata) flrs = FLR.generateRecurrentFLRs(tmpdata)
self.flrgs = self.generateFLRG(flrs) self.flrgs = self.generateFLRG(flrs)
def getMidpoints(self, flrg): def getMidpoints(self, flrg):

View File

@ -1,6 +1,6 @@
import numpy as np import numpy as np
from pyFTS.common import FuzzySet,FLR,Transformations from pyFTS.common import FuzzySet,FLR,Transformations
import fts from pyFTS import fts
class HighOrderFTS(fts.FTS): class HighOrderFTS(fts.FTS):

View File

@ -1,6 +1,6 @@
import numpy as np import numpy as np
from pyFTS.common import FuzzySet,FLR from pyFTS.common import FuzzySet,FLR
import hofts, fts, tree from pyFTS import hofts, fts, tree
class IntervalFTS(hofts.HighOrderFTS): class IntervalFTS(hofts.HighOrderFTS):
@ -10,7 +10,8 @@ class IntervalFTS(hofts.HighOrderFTS):
self.name = "Interval FTS" self.name = "Interval FTS"
self.detail = "Silva, P.; Guimarães, F.; Sadaei, H. (2016)" self.detail = "Silva, P.; Guimarães, F.; Sadaei, H. (2016)"
self.flrgs = {} self.flrgs = {}
self.isInterval = True self.hasPointForecasting = False
self.hasIntervalForecasting = True
def getUpper(self, flrg): def getUpper(self, flrg):
if flrg.strLHS() in self.flrgs: if flrg.strLHS() in self.flrgs:

View File

@ -10,17 +10,21 @@ from pyFTS.common import FuzzySet, Membership
def GridPartitionerTrimf(data, npart, names=None, prefix="A"): def GridPartitionerTrimf(data, npart, names=None, prefix="A"):
sets = [] sets = []
dmax = max(data) dmax = max(data)
dmax += dmax * 0.10 dmax += dmax * 0.1
print(dmax)
dmin = min(data) dmin = min(data)
dmin -= dmin * 0.10 dmin -= dmin * 0.1
print(dmin)
dlen = dmax - dmin dlen = dmax - dmin
partlen = math.ceil(dlen / npart) partlen = math.ceil(dlen / npart)
partition = math.ceil(dmin) #p2 = partlen / 2
for c in range(npart): #partition = dmin #+ partlen
count = 0
for c in np.arange(dmin, dmax, partlen):
sets.append( sets.append(
FuzzySet.FuzzySet(prefix + str(c), Membership.trimf, [round(partition - partlen, 3), partition, partition + partlen], FuzzySet.FuzzySet(prefix + str(count), Membership.trimf, [c - partlen, c, c + partlen],c))
partition)) count += 1
partition += partlen #partition += partlen
return sets return sets

28
pfts.py
View File

@ -2,21 +2,21 @@ import numpy as np
import pandas as pd import pandas as pd
import math import math
from pyFTS.common import FuzzySet, FLR from pyFTS.common import FuzzySet, FLR
import hofts, ifts, tree from pyFTS import hofts, ifts, tree
class ProbabilisticFLRG(hofts.HighOrderFLRG): class ProbabilisticFLRG(hofts.HighOrderFLRG):
def __init__(self, order): def __init__(self, order):
super(ProbabilisticFLRG, self).__init__(order) super(ProbabilisticFLRG, self).__init__(order)
self.RHS = {} self.RHS = {}
self.frequencyCount = 0 self.frequencyCount = 0.0
def appendRHS(self, c): def appendRHS(self, c):
self.frequencyCount = self.frequencyCount + 1 self.frequencyCount += 1
if c.name in self.RHS: if c.name in self.RHS:
self.RHS[c.name] = self.RHS[c.name] + 1 self.RHS[c.name] += 1
else: else:
self.RHS[c.name] = 1 self.RHS[c.name] = 1.0
def getProbability(self, c): def getProbability(self, c):
return self.RHS[c] / self.frequencyCount return self.RHS[c] / self.frequencyCount
@ -38,23 +38,27 @@ class ProbabilisticFTS(ifts.IntervalFTS):
self.detail = "Silva, P.; Guimarães, F.; Sadaei, H." self.detail = "Silva, P.; Guimarães, F.; Sadaei, H."
self.flrgs = {} self.flrgs = {}
self.globalFrequency = 0 self.globalFrequency = 0
self.isInterval = True self.hasPointForecasting = True
self.isDensity = True self.hasIntervalForecasting = True
self.hasDistributionForecasting = True
def generateFLRG(self, flrs): def generateFLRG(self, flrs):
flrgs = {} flrgs = {}
l = len(flrs) l = len(flrs)
for k in np.arange(self.order + 1, l): for k in np.arange(self.order, l+1):
if self.dump: print("FLR: " + str(k))
flrg = ProbabilisticFLRG(self.order) flrg = ProbabilisticFLRG(self.order)
for kk in np.arange(k - self.order, k): for kk in np.arange(k - self.order, k):
flrg.appendLHS(flrs[kk].LHS) flrg.appendLHS(flrs[kk].LHS)
if self.dump: print("LHS: " + str(flrs[kk]))
if flrg.strLHS() in flrgs: if flrg.strLHS() in flrgs:
flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) flrgs[flrg.strLHS()].appendRHS(flrs[k-1].RHS)
else: else:
flrgs[flrg.strLHS()] = flrg; flrgs[flrg.strLHS()] = flrg;
flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) flrgs[flrg.strLHS()].appendRHS(flrs[k-1].RHS)
if self.dump: print("RHS: " + str(flrs[k-1]))
self.globalFrequency = self.globalFrequency + 1 self.globalFrequency = self.globalFrequency + 1
return (flrgs) return (flrgs)
@ -68,9 +72,9 @@ class ProbabilisticFTS(ifts.IntervalFTS):
def getMidpoints(self, flrg): def getMidpoints(self, flrg):
if flrg.strLHS() in self.flrgs: if flrg.strLHS() in self.flrgs:
tmp = self.flrgs[flrg.strLHS()] tmp = self.flrgs[flrg.strLHS()]
ret = sum(np.array([tmp.getProbability(s) * self.setsDict[s].midpoint for s in tmp.RHS])) ret = sum(np.array([tmp.getProbability(s) * self.setsDict[s].centroid for s in tmp.RHS]))
else: else:
ret = sum(np.array([0.33 * s.midpoint for s in flrg.LHS])) ret = sum(np.array([0.33 * s.centroid for s in flrg.LHS]))
return ret return ret
def getUpper(self, flrg): def getUpper(self, flrg):

View File

@ -27,7 +27,7 @@ class SeasonalFTS(fts.FTS):
self.name = "Seasonal FTS" self.name = "Seasonal FTS"
self.detail = "Chen" self.detail = "Chen"
self.seasonality = 1 self.seasonality = 1
self.isSeasonal = True self.hasSeasonality = True
def generateFLRG(self, flrs): def generateFLRG(self, flrs):
flrgs = [] flrgs = []