- Sliding Window benchmark
- Refactoring of partitioners for OO design
This commit is contained in:
parent
c708430313
commit
84e6e1abbf
@ -23,13 +23,106 @@ styles = ['-','--','-.',':','.']
|
|||||||
|
|
||||||
nsty = len(styles)
|
nsty = len(styles)
|
||||||
|
|
||||||
|
def get_point_methods():
|
||||||
|
return [naive.Naive, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS,
|
||||||
|
sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, pwfts.ProbabilisticWeightedFTS]
|
||||||
|
|
||||||
|
|
||||||
|
def sliding_window(data, windowsize, train=0.8,models=None,partitioners=[Grid.GridPartitioner],
|
||||||
|
partitions=[10], max_order=3,transformation=None,indexer=None):
|
||||||
|
if models is None:
|
||||||
|
models = get_point_methods()
|
||||||
|
|
||||||
|
objs = {}
|
||||||
|
lcolors = {}
|
||||||
|
rmse = {}
|
||||||
|
smape = {}
|
||||||
|
u = {}
|
||||||
|
|
||||||
|
for train,test in Util.sliding_window(data, windowsize, train):
|
||||||
|
for partition in partitions:
|
||||||
|
for partitioner in partitioners:
|
||||||
|
pttr = str(partitioner.__module__).split('.')[-1]
|
||||||
|
if transformation is not None:
|
||||||
|
data_train_fs = partitioner(transformation.apply(train), partition)
|
||||||
|
else:
|
||||||
|
data_train_fs = partitioner(train, partition)
|
||||||
|
|
||||||
|
for count, model in enumerate(models, start=0):
|
||||||
|
|
||||||
|
mfts = model("")
|
||||||
|
_key = mfts.shortname + " " + pttr+ " q = " +str(partition)
|
||||||
|
|
||||||
|
mfts.partitioner = data_train_fs
|
||||||
|
if not mfts.isHighOrder:
|
||||||
|
|
||||||
|
if _key not in objs:
|
||||||
|
objs[_key] = mfts
|
||||||
|
lcolors[_key] = colors[count % ncol]
|
||||||
|
rmse[_key] = []
|
||||||
|
smape[_key] = []
|
||||||
|
u[_key] = []
|
||||||
|
|
||||||
|
if transformation is not None:
|
||||||
|
mfts.appendTransformation(transformation)
|
||||||
|
|
||||||
|
mfts.train(train, data_train_fs.sets)
|
||||||
|
|
||||||
|
_rmse, _smape, _u = get_point_statistics(test, mfts, indexer)
|
||||||
|
rmse[_key].append(_rmse)
|
||||||
|
smape[_key].append(_smape)
|
||||||
|
u[_key].append(_u)
|
||||||
|
|
||||||
|
else:
|
||||||
|
for order in np.arange(1, max_order + 1):
|
||||||
|
if order >= mfts.minOrder:
|
||||||
|
mfts = model("")
|
||||||
|
_key = mfts.shortname + " n = " + str(order) + " " + pttr + " q = " + str(partition)
|
||||||
|
mfts.partitioner = data_train_fs
|
||||||
|
|
||||||
|
if _key not in objs:
|
||||||
|
objs[_key] = mfts
|
||||||
|
lcolors[_key] = colors[count % ncol]
|
||||||
|
rmse[_key] = []
|
||||||
|
smape[_key] = []
|
||||||
|
u[_key] = []
|
||||||
|
|
||||||
|
if transformation is not None:
|
||||||
|
mfts.appendTransformation(transformation)
|
||||||
|
|
||||||
|
mfts.train(train, data_train_fs.sets, order=order)
|
||||||
|
|
||||||
|
_rmse, _smape, _u = get_point_statistics(test, mfts, indexer)
|
||||||
|
rmse[_key].append(_rmse)
|
||||||
|
smape[_key].append(_smape)
|
||||||
|
u[_key].append(_u)
|
||||||
|
|
||||||
|
ret = "Model\t&Order\t&Scheme\t&Partitions\t&RMSE AVG\t&RMSE STD\t& SMAPE AVG\t& SMAPE STD\t& U AVG\t& U STD \\\\ \n"
|
||||||
|
for k in sorted(objs.keys()):
|
||||||
|
mfts = objs[k]
|
||||||
|
ret += mfts.shortname + "\t &"
|
||||||
|
ret += str( mfts.order ) + "\t &"
|
||||||
|
ret += mfts.partitioner.name + "\t &"
|
||||||
|
ret += str(mfts.partitioner.partitions) + "\t &"
|
||||||
|
ret += str(round(np.mean(rmse[k]),2)) + "\t &"
|
||||||
|
ret += str(round(np.std(rmse[k]), 2)) + "\t &"
|
||||||
|
ret += str(round(np.mean(smape[k]), 2)) + "\t &"
|
||||||
|
ret += str(round(np.std(smape[k]), 2)) + "\t &"
|
||||||
|
ret += str(round(np.mean(u[k]), 2)) + "\t &"
|
||||||
|
ret += str(round(np.std(u[k]), 2)) + "\t &"
|
||||||
|
ret += str(len(mfts)) + "\\\\ \n"
|
||||||
|
|
||||||
|
print(ret)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def allPointForecasters(data_train, data_test, partitions, max_order=3, statistics=True, residuals=True,
|
def allPointForecasters(data_train, data_test, partitions, max_order=3, statistics=True, residuals=True,
|
||||||
series=True, save=False, file=None, tam=[20, 5], models=None, transformation=None,
|
series=True, save=False, file=None, tam=[20, 5], models=None, transformation=None,
|
||||||
distributions=False):
|
distributions=False):
|
||||||
|
|
||||||
if models is None:
|
if models is None:
|
||||||
models = [naive.Naive, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS,
|
models = get_point_methods()
|
||||||
sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, pwfts.ProbabilisticWeightedFTS]
|
|
||||||
|
|
||||||
objs = []
|
objs = []
|
||||||
|
|
||||||
@ -62,7 +155,7 @@ def allPointForecasters(data_train, data_test, partitions, max_order=3, statisti
|
|||||||
lcolors.append(colors[(count + order) % ncol])
|
lcolors.append(colors[(count + order) % ncol])
|
||||||
|
|
||||||
if statistics:
|
if statistics:
|
||||||
print(getPointStatistics(data_test, objs))
|
print(print_point_statistics(data_test, objs))
|
||||||
|
|
||||||
if residuals:
|
if residuals:
|
||||||
print(ResidualAnalysis.compareResiduals(data_test, objs))
|
print(ResidualAnalysis.compareResiduals(data_test, objs))
|
||||||
@ -87,29 +180,38 @@ def allPointForecasters(data_train, data_test, partitions, max_order=3, statisti
|
|||||||
|
|
||||||
plotProbabilityDistributions(pmfs, lcolors,tam=tam)
|
plotProbabilityDistributions(pmfs, lcolors,tam=tam)
|
||||||
|
|
||||||
|
def get_point_statistics(data, model, indexer=None):
|
||||||
def getPointStatistics(data, models, externalmodels = None, externalforecasts = None, indexers=None):
|
if indexer is not None:
|
||||||
ret = "Model & Order & RMSE & SMAPE & Theil's U \\\\ \n"
|
ndata = np.array(indexer.get_data(data[model.order:]))
|
||||||
for count,model in enumerate(models,start=0):
|
|
||||||
if indexers is not None and indexers[count] is not None:
|
|
||||||
ndata = np.array(indexers[count].get_data(data[model.order:]))
|
|
||||||
else:
|
else:
|
||||||
ndata = np.array(data[model.order:])
|
ndata = np.array(data[model.order:])
|
||||||
|
|
||||||
if model.isMultivariate or indexers is None:
|
if model.isMultivariate or indexer is None:
|
||||||
forecasts = model.forecast(data)
|
forecasts = model.forecast(data)
|
||||||
elif not model.isMultivariate and indexers is not None:
|
elif not model.isMultivariate and indexer is not None:
|
||||||
forecasts = model.forecast( indexers[count].get_data(data) )
|
forecasts = model.forecast(indexer.get_data(data))
|
||||||
|
|
||||||
if model.hasSeasonality:
|
if model.hasSeasonality:
|
||||||
nforecasts = np.array(forecasts)
|
nforecasts = np.array(forecasts)
|
||||||
else:
|
else:
|
||||||
nforecasts = np.array(forecasts[:-1])
|
nforecasts = np.array(forecasts[:-1])
|
||||||
|
ret = list()
|
||||||
|
ret.append(np.round(Measures.rmse(ndata, nforecasts), 2))
|
||||||
|
ret.append(np.round(Measures.smape(ndata, nforecasts), 2))
|
||||||
|
ret.append(np.round(Measures.UStatistic(ndata, nforecasts), 2))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def print_point_statistics(data, models, externalmodels = None, externalforecasts = None, indexers=None):
|
||||||
|
ret = "Model & Order & RMSE & SMAPE & Theil's U \\\\ \n"
|
||||||
|
for count,model in enumerate(models,start=0):
|
||||||
|
_rmse, _smape, _u = get_point_statistics(data, model, indexers[count])
|
||||||
ret += model.shortname + " & "
|
ret += model.shortname + " & "
|
||||||
ret += str(model.order) + " & "
|
ret += str(model.order) + " & "
|
||||||
ret += str(round(Measures.rmse(ndata, nforecasts), 2)) + " & "
|
ret += str(_rmse) + " & "
|
||||||
ret += str(round(Measures.smape(ndata, nforecasts), 2))+ " & "
|
ret += str(_smape)+ " & "
|
||||||
ret += str(round(Measures.UStatistic(ndata, nforecasts), 2))
|
ret += str(_u)
|
||||||
#ret += str(round(Measures.TheilsInequality(np.array(data[fts.order:]), np.array(forecasts[:-1])), 4))
|
#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:
|
||||||
@ -194,7 +296,7 @@ def plotDistribution(dist):
|
|||||||
|
|
||||||
|
|
||||||
def plotComparedSeries(original, models, colors, typeonlegend=False, save=False, file=None, tam=[20, 5],
|
def plotComparedSeries(original, models, colors, typeonlegend=False, save=False, file=None, tam=[20, 5],
|
||||||
intervals=True):
|
points=True, intervals=True, linewidth=1.5):
|
||||||
fig = plt.figure(figsize=tam)
|
fig = plt.figure(figsize=tam)
|
||||||
ax = fig.add_subplot(111)
|
ax = fig.add_subplot(111)
|
||||||
|
|
||||||
@ -203,10 +305,10 @@ def plotComparedSeries(original, models, colors, typeonlegend=False, save=False,
|
|||||||
|
|
||||||
legends = []
|
legends = []
|
||||||
|
|
||||||
ax.plot(original, color='black', label="Original", linewidth=1.5)
|
ax.plot(original, color='black', label="Original", linewidth=linewidth*1.5)
|
||||||
|
|
||||||
for count, fts in enumerate(models, start=0):
|
for count, fts in enumerate(models, start=0):
|
||||||
if fts.hasPointForecasting and not intervals:
|
if fts.hasPointForecasting and points:
|
||||||
forecasted = fts.forecast(original)
|
forecasted = fts.forecast(original)
|
||||||
mi.append(min(forecasted) * 0.95)
|
mi.append(min(forecasted) * 0.95)
|
||||||
ma.append(max(forecasted) * 1.05)
|
ma.append(max(forecasted) * 1.05)
|
||||||
@ -214,7 +316,7 @@ def plotComparedSeries(original, models, colors, typeonlegend=False, save=False,
|
|||||||
forecasted.insert(0, None)
|
forecasted.insert(0, None)
|
||||||
lbl = fts.shortname
|
lbl = fts.shortname
|
||||||
if typeonlegend: lbl += " (Point)"
|
if typeonlegend: lbl += " (Point)"
|
||||||
ax.plot(forecasted, color=colors[count], label=lbl, ls="-")
|
ax.plot(forecasted, color=colors[count], label=lbl, ls="-",linewidth=linewidth)
|
||||||
|
|
||||||
if fts.hasIntervalForecasting and intervals:
|
if fts.hasIntervalForecasting and intervals:
|
||||||
forecasted = fts.forecastInterval(original)
|
forecasted = fts.forecastInterval(original)
|
||||||
@ -227,8 +329,8 @@ def plotComparedSeries(original, models, colors, typeonlegend=False, save=False,
|
|||||||
upper.insert(0, None)
|
upper.insert(0, None)
|
||||||
lbl = fts.shortname
|
lbl = fts.shortname
|
||||||
if typeonlegend: lbl += " (Interval)"
|
if typeonlegend: lbl += " (Interval)"
|
||||||
ax.plot(lower, color=colors[count], label=lbl, ls="-")
|
ax.plot(lower, color=colors[count], label=lbl, ls="--",linewidth=linewidth)
|
||||||
ax.plot(upper, color=colors[count], ls="-")
|
ax.plot(upper, color=colors[count], ls="--",linewidth=linewidth)
|
||||||
|
|
||||||
handles0, labels0 = ax.get_legend_handles_labels()
|
handles0, labels0 = ax.get_legend_handles_labels()
|
||||||
lgd = ax.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))
|
lgd = ax.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))
|
||||||
|
@ -6,7 +6,7 @@ from pyFTS import fts
|
|||||||
|
|
||||||
class Naive(fts.FTS):
|
class Naive(fts.FTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(Naive, self).__init__(1, "Naïve" + name)
|
super(Naive, self).__init__(1, "Naïve " + name)
|
||||||
self.name = "Naïve Model"
|
self.name = "Naïve Model"
|
||||||
self.detail = "Naïve Model"
|
self.detail = "Naïve Model"
|
||||||
|
|
||||||
|
5
chen.py
5
chen.py
@ -20,10 +20,13 @@ class ConventionalFLRG(object):
|
|||||||
tmp2 = tmp2 + c.name
|
tmp2 = tmp2 + c.name
|
||||||
return tmp + tmp2
|
return tmp + tmp2
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.RHS)
|
||||||
|
|
||||||
|
|
||||||
class ConventionalFTS(fts.FTS):
|
class ConventionalFTS(fts.FTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(ConventionalFTS, self).__init__(1, "CFTS")
|
super(ConventionalFTS, self).__init__(1, "CFTS " + name)
|
||||||
self.name = "Conventional FTS"
|
self.name = "Conventional FTS"
|
||||||
self.detail = "Chen"
|
self.detail = "Chen"
|
||||||
self.flrgs = {}
|
self.flrgs = {}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import time
|
import time
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import dill
|
import dill
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
current_milli_time = lambda: int(round(time.time() * 1000))
|
current_milli_time = lambda: int(round(time.time() * 1000))
|
||||||
@ -29,6 +30,12 @@ def enumerate2(xs, start=0, step=1):
|
|||||||
yield (start, x)
|
yield (start, x)
|
||||||
start += step
|
start += step
|
||||||
|
|
||||||
|
def sliding_window(data, windowsize, train=0.8):
|
||||||
|
l = len(data)
|
||||||
|
ttrain = int(round(windowsize * train, 0))
|
||||||
|
for count in np.arange(0,l,windowsize):
|
||||||
|
yield ( data[count : count + ttrain], data[count + ttrain : count + windowsize] )
|
||||||
|
|
||||||
|
|
||||||
def persist_obj(obj, file):
|
def persist_obj(obj, file):
|
||||||
with open(file, 'wb') as _file:
|
with open(file, 'wb') as _file:
|
||||||
|
10
fts.py
10
fts.py
@ -25,6 +25,7 @@ class FTS(object):
|
|||||||
self.transformations_param = []
|
self.transformations_param = []
|
||||||
self.original_max = 0
|
self.original_max = 0
|
||||||
self.original_min = 0
|
self.original_min = 0
|
||||||
|
self.partitioner = None
|
||||||
|
|
||||||
def fuzzy(self, data):
|
def fuzzy(self, data):
|
||||||
best = {"fuzzyset": "", "membership": 0.0}
|
best = {"fuzzyset": "", "membership": 0.0}
|
||||||
@ -55,7 +56,7 @@ class FTS(object):
|
|||||||
def forecastAheadDistribution(self, data, steps):
|
def forecastAheadDistribution(self, data, steps):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def train(self, data, sets,order=1, parameters=None):
|
def train(self, data, sets, order=1, parameters=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def getMidpoints(self, flrg):
|
def getMidpoints(self, flrg):
|
||||||
@ -104,6 +105,12 @@ class FTS(object):
|
|||||||
tmp = tmp + str(self.flrgs[r]) + "\n"
|
tmp = tmp + str(self.flrgs[r]) + "\n"
|
||||||
return tmp
|
return tmp
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.flrgs)
|
||||||
|
|
||||||
|
def len_total(self):
|
||||||
|
return sum([len(k) for k in self.flrgs])
|
||||||
|
|
||||||
def buildTreeWithoutOrder(self, node, lags, level):
|
def buildTreeWithoutOrder(self, node, lags, level):
|
||||||
|
|
||||||
if level not in lags:
|
if level not in lags:
|
||||||
@ -168,3 +175,4 @@ class FTS(object):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
6
hofts.py
6
hofts.py
@ -3,7 +3,7 @@ from pyFTS.common import FuzzySet,FLR
|
|||||||
from pyFTS import fts
|
from pyFTS import fts
|
||||||
|
|
||||||
|
|
||||||
class HighOrderFLRG:
|
class HighOrderFLRG(object):
|
||||||
def __init__(self, order):
|
def __init__(self, order):
|
||||||
self.LHS = []
|
self.LHS = []
|
||||||
self.RHS = {}
|
self.RHS = {}
|
||||||
@ -34,6 +34,10 @@ class HighOrderFLRG:
|
|||||||
return self.strLHS() + " -> " + tmp
|
return self.strLHS() + " -> " + tmp
|
||||||
|
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.RHS)
|
||||||
|
|
||||||
|
|
||||||
class HighOrderFTS(fts.FTS):
|
class HighOrderFTS(fts.FTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(HighOrderFTS, self).__init__(1, "HOFTS" + name)
|
super(HighOrderFTS, self).__init__(1, "HOFTS" + name)
|
||||||
|
@ -3,7 +3,7 @@ from pyFTS.common import FuzzySet,FLR
|
|||||||
from pyFTS import fts
|
from pyFTS import fts
|
||||||
|
|
||||||
|
|
||||||
class ImprovedWeightedFLRG:
|
class ImprovedWeightedFLRG(object):
|
||||||
def __init__(self, LHS):
|
def __init__(self, LHS):
|
||||||
self.LHS = LHS
|
self.LHS = LHS
|
||||||
self.RHS = {}
|
self.RHS = {}
|
||||||
@ -28,10 +28,13 @@ class ImprovedWeightedFLRG:
|
|||||||
tmp2 = tmp2 + c + "(" + str(round(self.RHS[c] / self.count, 3)) + ")"
|
tmp2 = tmp2 + c + "(" + str(round(self.RHS[c] / self.count, 3)) + ")"
|
||||||
return tmp + tmp2
|
return tmp + tmp2
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.RHS)
|
||||||
|
|
||||||
|
|
||||||
class ImprovedWeightedFTS(fts.FTS):
|
class ImprovedWeightedFTS(fts.FTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(ImprovedWeightedFTS, self).__init__(1, "IWFTS")
|
super(ImprovedWeightedFTS, self).__init__(1, "IWFTS " + name)
|
||||||
self.name = "Improved Weighted FTS"
|
self.name = "Improved Weighted FTS"
|
||||||
self.detail = "Ismail & Efendi"
|
self.detail = "Ismail & Efendi"
|
||||||
self.setsDict = {}
|
self.setsDict = {}
|
||||||
|
@ -3,6 +3,7 @@ import math
|
|||||||
import random as rnd
|
import random as rnd
|
||||||
import functools, operator
|
import functools, operator
|
||||||
from pyFTS.common import FuzzySet, Membership
|
from pyFTS.common import FuzzySet, Membership
|
||||||
|
from pyFTS.partitioners import partitioner
|
||||||
|
|
||||||
|
|
||||||
def distancia(x, y):
|
def distancia(x, y):
|
||||||
@ -75,20 +76,23 @@ def c_means(k, dados, tam):
|
|||||||
|
|
||||||
return centroides
|
return centroides
|
||||||
|
|
||||||
|
class CMeansPartitioner(partitioner.Partitioner):
|
||||||
|
def __init__(self, npart,data,func = Membership.trimf):
|
||||||
|
super(CMeansPartitioner, self).__init__("CMeans ",data,npart,func)
|
||||||
|
|
||||||
def CMeansPartitionerTrimf(data, npart, names=None, prefix="A"):
|
def build(self, data):
|
||||||
sets = []
|
sets = []
|
||||||
dmax = max(data)
|
dmax = max(data)
|
||||||
dmax += dmax * 0.10
|
dmax += dmax * 0.10
|
||||||
dmin = min(data)
|
dmin = min(data)
|
||||||
dmin -= dmin * 0.10
|
dmin -= dmin * 0.10
|
||||||
centroides = c_means(npart, data, 1)
|
centroides = c_means(self.partitions, data, 1)
|
||||||
centroides.append(dmax)
|
centroides.append(dmax)
|
||||||
centroides.append(dmin)
|
centroides.append(dmin)
|
||||||
centroides = list(set(centroides))
|
centroides = list(set(centroides))
|
||||||
centroides.sort()
|
centroides.sort()
|
||||||
for c in np.arange(1, len(centroides) - 1):
|
for c in np.arange(1, len(centroides) - 1):
|
||||||
sets.append(FuzzySet.FuzzySet(prefix + str(c), Membership.trimf,
|
sets.append(FuzzySet.FuzzySet(self.prefix + str(c), Membership.trimf,
|
||||||
[round(centroides[c - 1], 3), round(centroides[c], 3), round(centroides[c + 1], 3)],
|
[round(centroides[c - 1], 3), round(centroides[c], 3), round(centroides[c + 1], 3)],
|
||||||
round(centroides[c], 3)))
|
round(centroides[c], 3)))
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import math
|
|||||||
import random as rnd
|
import random as rnd
|
||||||
import functools, operator
|
import functools, operator
|
||||||
from pyFTS.common import FuzzySet, Membership
|
from pyFTS.common import FuzzySet, Membership
|
||||||
|
from pyFTS.partitioners import partitioner
|
||||||
|
|
||||||
# C. H. Cheng, R. J. Chang, and C. A. Yeh, “Entropy-based and trapezoidal fuzzification-based fuzzy time series approach for forecasting IT project cost,”
|
# C. H. Cheng, R. J. Chang, and C. A. Yeh, “Entropy-based and trapezoidal fuzzification-based fuzzy time series approach for forecasting IT project cost,”
|
||||||
# Technol. Forecast. Social Change, vol. 73, no. 5, pp. 524–542, Jun. 2006.
|
# Technol. Forecast. Social Change, vol. 73, no. 5, pp. 524–542, Jun. 2006.
|
||||||
@ -76,21 +76,24 @@ def bestSplit(data, npart):
|
|||||||
else:
|
else:
|
||||||
return [threshold]
|
return [threshold]
|
||||||
|
|
||||||
|
class EntropyPartitioner(partitioner.Partitioner):
|
||||||
|
def __init__(self, data,npart,func = Membership.trimf):
|
||||||
|
super(EntropyPartitioner, self).__init__("Entropy" ,data,npart,func)
|
||||||
|
|
||||||
def EntropyPartitionerTrimf(data, npart, prefix="A"):
|
def build(self, data):
|
||||||
sets = []
|
sets = []
|
||||||
dmax = max(data)
|
dmax = max(data)
|
||||||
dmax += dmax * 0.10
|
dmax += dmax * 0.10
|
||||||
dmin = min(data)
|
dmin = min(data)
|
||||||
dmin -= dmin * 0.10
|
dmin -= dmin * 0.10
|
||||||
|
|
||||||
partitions = bestSplit(data, npart)
|
partitions = bestSplit(data, self.partitions)
|
||||||
partitions.append(dmin)
|
partitions.append(dmin)
|
||||||
partitions.append(dmax)
|
partitions.append(dmax)
|
||||||
partitions = list(set(partitions))
|
partitions = list(set(partitions))
|
||||||
partitions.sort()
|
partitions.sort()
|
||||||
for c in np.arange(1, len(partitions) - 1):
|
for c in np.arange(1, len(partitions) - 1):
|
||||||
sets.append(FuzzySet.FuzzySet(prefix + str(c), Membership.trimf,
|
sets.append(FuzzySet.FuzzySet(self.prefix + str(c), Membership.trimf,
|
||||||
[partitions[c - 1], partitions[c], partitions[c + 1]],partitions[c]))
|
[partitions[c - 1], partitions[c], partitions[c + 1]],partitions[c]))
|
||||||
|
|
||||||
return sets
|
return sets
|
||||||
|
@ -3,19 +3,20 @@ import math
|
|||||||
import random as rnd
|
import random as rnd
|
||||||
import functools,operator
|
import functools,operator
|
||||||
from pyFTS.common import FuzzySet,Membership
|
from pyFTS.common import FuzzySet,Membership
|
||||||
|
from pyFTS.partitioners import partitioner
|
||||||
#import CMeans
|
#import CMeans
|
||||||
|
|
||||||
# S. T. Li, Y. C. Cheng, and S. Y. Lin, “A FCM-based deterministic forecasting model for fuzzy time series,”
|
# S. T. Li, Y. C. Cheng, and S. Y. Lin, “A FCM-based deterministic forecasting model for fuzzy time series,”
|
||||||
# Comput. Math. Appl., vol. 56, no. 12, pp. 3052–3063, Dec. 2008. DOI: 10.1016/j.camwa.2008.07.033.
|
# Comput. Math. Appl., vol. 56, no. 12, pp. 3052–3063, Dec. 2008. DOI: 10.1016/j.camwa.2008.07.033.
|
||||||
|
|
||||||
def distancia(x,y):
|
def fuzzy_distance(x, y):
|
||||||
if isinstance(x, list):
|
if isinstance(x, list):
|
||||||
tmp = functools.reduce(operator.add, [(x[k] - y[k])**2 for k in range(0,len(x))])
|
tmp = functools.reduce(operator.add, [(x[k] - y[k])**2 for k in range(0,len(x))])
|
||||||
else:
|
else:
|
||||||
tmp = (x - y) ** 2
|
tmp = (x - y) ** 2
|
||||||
return math.sqrt(tmp)
|
return math.sqrt(tmp)
|
||||||
|
|
||||||
def pert(val, vals):
|
def membership(val, vals):
|
||||||
soma = 0
|
soma = 0
|
||||||
for k in vals:
|
for k in vals:
|
||||||
if k == 0:
|
if k == 0:
|
||||||
@ -55,7 +56,7 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
|
|||||||
|
|
||||||
grupo_count = 0
|
grupo_count = 0
|
||||||
for grupo in centroides:
|
for grupo in centroides:
|
||||||
dist_grupos[grupo_count] = distancia(grupo, instancia)
|
dist_grupos[grupo_count] = fuzzy_distance(grupo, instancia)
|
||||||
grupo_count = grupo_count + 1
|
grupo_count = grupo_count + 1
|
||||||
|
|
||||||
dist_grupos_total = functools.reduce(operator.add, [xk for xk in dist_grupos])
|
dist_grupos_total = functools.reduce(operator.add, [xk for xk in dist_grupos])
|
||||||
@ -64,7 +65,7 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
|
|||||||
if dist_grupos[grp] == 0:
|
if dist_grupos[grp] == 0:
|
||||||
grupos[inst_count][grp] = 1
|
grupos[inst_count][grp] = 1
|
||||||
else:
|
else:
|
||||||
grupos[inst_count][grp] = 1 / pert(dist_grupos[grp], dist_grupos)
|
grupos[inst_count][grp] = 1 / membership(dist_grupos[grp], dist_grupos)
|
||||||
# grupos[inst_count][grp] = 1/(dist_grupos[grp] / dist_grupos_total)
|
# grupos[inst_count][grp] = 1/(dist_grupos[grp] / dist_grupos_total)
|
||||||
# grupos[inst_count][grp] = (1/(dist_grupos[grp]**2))**m_exp / (1/(dist_grupos_total**2))**m_exp
|
# grupos[inst_count][grp] = (1/(dist_grupos[grp]**2))**m_exp / (1/(dist_grupos_total**2))**m_exp
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
|
|||||||
norm = functools.reduce(operator.add, [grupos[xk][grupo_count] for xk in range(0, tam_dados)])
|
norm = functools.reduce(operator.add, [grupos[xk][grupo_count] for xk in range(0, tam_dados)])
|
||||||
centroides[grupo_count] = soma / norm
|
centroides[grupo_count] = soma / norm
|
||||||
|
|
||||||
alteracaomedia = alteracaomedia + distancia(oldgrp, grupo)
|
alteracaomedia = alteracaomedia + fuzzy_distance(oldgrp, grupo)
|
||||||
grupo_count = grupo_count + 1
|
grupo_count = grupo_count + 1
|
||||||
|
|
||||||
alteracaomedia = alteracaomedia / k
|
alteracaomedia = alteracaomedia / k
|
||||||
@ -98,18 +99,23 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
|
|||||||
|
|
||||||
return centroides
|
return centroides
|
||||||
|
|
||||||
def FCMPartitionerTrimf(data,npart,names = None,prefix = "A"):
|
|
||||||
|
class FCMPartitioner(partitioner.Partitioner):
|
||||||
|
def __init__(self, data,npart,func = Membership.trimf):
|
||||||
|
super(FCMPartitioner, self).__init__("FCM ",data,npart,func)
|
||||||
|
|
||||||
|
def build(self,data):
|
||||||
sets = []
|
sets = []
|
||||||
dmax = max(data)
|
dmax = max(data)
|
||||||
dmax = dmax + dmax*0.10
|
dmax = dmax + dmax*0.10
|
||||||
dmin = min(data)
|
dmin = min(data)
|
||||||
dmin = dmin - dmin*0.10
|
dmin = dmin - dmin*0.10
|
||||||
centroides = fuzzy_cmeans(npart, data, 1, 2)
|
centroides = fuzzy_cmeans(self.partitions, data, 1, 2)
|
||||||
centroides.append(dmax)
|
centroides.append(dmax)
|
||||||
centroides.append(dmin)
|
centroides.append(dmin)
|
||||||
centroides = list(set(centroides))
|
centroides = list(set(centroides))
|
||||||
centroides.sort()
|
centroides.sort()
|
||||||
for c in np.arange(1,len(centroides)-1):
|
for c in np.arange(1,len(centroides)-1):
|
||||||
sets.append(FuzzySet.FuzzySet(prefix+str(c),Membership.trimf,[round(centroides[c-1],3), round(centroides[c],3), round(centroides[c+1],3)], round(centroides[c],3) ) )
|
sets.append(FuzzySet.FuzzySet(self.prefix+str(c),Membership.trimf,[round(centroides[c-1],3), round(centroides[c],3), round(centroides[c+1],3)], round(centroides[c],3) ) )
|
||||||
|
|
||||||
return sets
|
return sets
|
@ -3,11 +3,14 @@ import math
|
|||||||
import random as rnd
|
import random as rnd
|
||||||
import functools, operator
|
import functools, operator
|
||||||
from pyFTS.common import FuzzySet, Membership
|
from pyFTS.common import FuzzySet, Membership
|
||||||
|
from pyFTS.partitioners import partitioner
|
||||||
|
|
||||||
|
|
||||||
# print(common.__dict__)
|
class GridPartitioner(partitioner.Partitioner):
|
||||||
|
def __init__(self, data,npart,func = Membership.trimf):
|
||||||
|
super(GridPartitioner, self).__init__("Grid",data,npart,func)
|
||||||
|
|
||||||
def GridPartitionerTrimf(data, npart, names=None, prefix="A"):
|
def build(self, data):
|
||||||
sets = []
|
sets = []
|
||||||
_min = min(data)
|
_min = min(data)
|
||||||
if _min < 0:
|
if _min < 0:
|
||||||
@ -22,30 +25,17 @@ def GridPartitionerTrimf(data, npart, names=None, prefix="A"):
|
|||||||
dmax = _max * 0.9
|
dmax = _max * 0.9
|
||||||
|
|
||||||
dlen = dmax - dmin
|
dlen = dmax - dmin
|
||||||
partlen = dlen / npart
|
partlen = dlen / self.partitions
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
for c in np.arange(dmin, dmax, partlen):
|
for c in np.arange(dmin, dmax, partlen):
|
||||||
|
if self.membership_function == Membership.trimf:
|
||||||
sets.append(
|
sets.append(
|
||||||
FuzzySet.FuzzySet(prefix + str(count), Membership.trimf, [c - partlen, c, c + partlen],c))
|
FuzzySet.FuzzySet(self.prefix + str(count), Membership.trimf, [c - partlen, c, c + partlen],c))
|
||||||
|
elif self.membership_function == Membership.gaussmf:
|
||||||
|
sets.append(
|
||||||
|
FuzzySet.FuzzySet(self.prefix + str(count), Membership.gaussmf, [c, partlen / 3], c))
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
return sets
|
|
||||||
|
|
||||||
|
|
||||||
def GridPartitionerGaussmf(data, npart, names=None, prefix="A"):
|
|
||||||
sets = []
|
|
||||||
dmax = max(data)
|
|
||||||
dmax += dmax * 0.10
|
|
||||||
dmin = min(data)
|
|
||||||
dmin -= dmin * 0.10
|
|
||||||
dlen = dmax - dmin
|
|
||||||
partlen = math.ceil(dlen / npart)
|
|
||||||
partition = math.ceil(dmin)
|
|
||||||
for c in range(npart):
|
|
||||||
sets.append(
|
|
||||||
FuzzySet.FuzzySet(prefix + str(c), Membership.gaussmf, [partition, partlen/3],
|
|
||||||
partition))
|
|
||||||
partition += partlen
|
|
||||||
|
|
||||||
return sets
|
return sets
|
||||||
|
@ -7,8 +7,14 @@ from pyFTS.common import FuzzySet, Membership, Transformations
|
|||||||
|
|
||||||
# K. H. Huarng, “Effective lengths of intervals to improve forecasting in fuzzy time series,”
|
# K. H. Huarng, “Effective lengths of intervals to improve forecasting in fuzzy time series,”
|
||||||
# Fuzzy Sets Syst., vol. 123, no. 3, pp. 387–394, Nov. 2001.
|
# Fuzzy Sets Syst., vol. 123, no. 3, pp. 387–394, Nov. 2001.
|
||||||
|
from pyFTS.partitioners import partitioner
|
||||||
|
|
||||||
def GridPartitionerTrimf(data, prefix="A"):
|
|
||||||
|
class HuarngPartitioner(partitioner.Partitioner):
|
||||||
|
def __init__(self, npart,data,func = Membership.trimf):
|
||||||
|
super(HuarngPartitioner, self).__init__("Huarng",data,npart,func)
|
||||||
|
|
||||||
|
def build(self, data):
|
||||||
data2 = Transformations.differential(data)
|
data2 = Transformations.differential(data)
|
||||||
davg = np.abs( np.mean(data2) / 2 )
|
davg = np.abs( np.mean(data2) / 2 )
|
||||||
|
|
||||||
@ -31,7 +37,7 @@ def GridPartitionerTrimf(data, prefix="A"):
|
|||||||
partition = math.ceil(dmin)
|
partition = math.ceil(dmin)
|
||||||
for c in range(npart):
|
for c in range(npart):
|
||||||
sets.append(
|
sets.append(
|
||||||
FuzzySet.FuzzySet(prefix + str(c), Membership.trimf, [partition - base, partition, partition + base], partition))
|
FuzzySet.FuzzySet(self.prefix + str(c), Membership.trimf, [partition - base, partition, partition + base], partition))
|
||||||
partition += base
|
partition += base
|
||||||
|
|
||||||
return sets
|
return sets
|
||||||
|
38
partitioners/partitioner.py
Normal file
38
partitioners/partitioner.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
from pyFTS.common import FuzzySet, Membership
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class Partitioner(object):
|
||||||
|
def __init__(self,name,data,npart,func = Membership.trimf, names=None, prefix="A"):
|
||||||
|
self.name = name
|
||||||
|
self.partitions = npart
|
||||||
|
self.sets = []
|
||||||
|
self.membership_function = func
|
||||||
|
self.setnames = names
|
||||||
|
self.prefix = prefix
|
||||||
|
_min = min(data)
|
||||||
|
if _min < 0:
|
||||||
|
self.min = _min * 1.1
|
||||||
|
else:
|
||||||
|
self.min = _min * 0.9
|
||||||
|
|
||||||
|
_max = max(data)
|
||||||
|
if _max > 0:
|
||||||
|
self.max = _max * 1.1
|
||||||
|
else:
|
||||||
|
self.max = _max * 0.9
|
||||||
|
self.sets = self.build(data)
|
||||||
|
|
||||||
|
def build(self,data):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def plot(self,ax):
|
||||||
|
ax.set_title(self.name)
|
||||||
|
ax.set_ylim([0, 1])
|
||||||
|
ax.set_xlim([self.min, self.max])
|
||||||
|
for s in self.sets:
|
||||||
|
if s.mf == Membership.trimf:
|
||||||
|
ax.plot([s.parameters[0], s.parameters[1], s.parameters[2]], [0, 1, 0])
|
||||||
|
elif s.mf == Membership.gaussmf:
|
||||||
|
tmpx = [kk for kk in np.arange(s.lower, s.upper)]
|
||||||
|
tmpy = [s.membership(kk) for kk in np.arange(s.lower, s.upper)]
|
||||||
|
ax.plot(tmpx, tmpy)
|
4
pwfts.py
4
pwfts.py
@ -43,8 +43,8 @@ class ProbabilisticWeightedFLRG(hofts.HighOrderFLRG):
|
|||||||
|
|
||||||
class ProbabilisticWeightedFTS(ifts.IntervalFTS):
|
class ProbabilisticWeightedFTS(ifts.IntervalFTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(ProbabilisticWeightedFTS, self).__init__("PFTS")
|
super(ProbabilisticWeightedFTS, self).__init__("PWFTS")
|
||||||
self.shortname = "PFTS " + name
|
self.shortname = "PWFTS " + name
|
||||||
self.name = "Probabilistic FTS"
|
self.name = "Probabilistic FTS"
|
||||||
self.detail = "Silva, P.; Guimarães, F.; Sadaei, H."
|
self.detail = "Silva, P.; Guimarães, F.; Sadaei, H."
|
||||||
self.flrgs = {}
|
self.flrgs = {}
|
||||||
|
@ -2,7 +2,7 @@ import numpy as np
|
|||||||
from pyFTS.common import FuzzySet,FLR
|
from pyFTS.common import FuzzySet,FLR
|
||||||
from pyFTS import fts
|
from pyFTS import fts
|
||||||
|
|
||||||
class ExponentialyWeightedFLRG:
|
class ExponentialyWeightedFLRG(object):
|
||||||
def __init__(self, LHS, c):
|
def __init__(self, LHS, c):
|
||||||
self.LHS = LHS
|
self.LHS = LHS
|
||||||
self.RHS = []
|
self.RHS = []
|
||||||
@ -31,6 +31,9 @@ class ExponentialyWeightedFLRG:
|
|||||||
cc = cc + 1
|
cc = cc + 1
|
||||||
return tmp + tmp2
|
return tmp + tmp2
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.RHS)
|
||||||
|
|
||||||
|
|
||||||
class ExponentialyWeightedFTS(fts.FTS):
|
class ExponentialyWeightedFTS(fts.FTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
|
3
sfts.py
3
sfts.py
@ -21,6 +21,9 @@ class SeasonalFLRG(FLR.FLR):
|
|||||||
tmp2 = tmp2 + c.name
|
tmp2 = tmp2 + c.name
|
||||||
return tmp + tmp2
|
return tmp + tmp2
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.RHS)
|
||||||
|
|
||||||
|
|
||||||
class SeasonalFTS(fts.FTS):
|
class SeasonalFTS(fts.FTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
|
31
tests/general.py
Normal file
31
tests/general.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#!/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, Entropy, FCM
|
||||||
|
from pyFTS.common import FLR,FuzzySet,Membership,Transformations
|
||||||
|
from pyFTS import fts,hofts,ifts,pwfts,tree, chen
|
||||||
|
from pyFTS.benchmarks import benchmarks as bchmk
|
||||||
|
from pyFTS.benchmarks import Measures
|
||||||
|
from numpy import random
|
||||||
|
|
||||||
|
#print(FCM.FCMPartitionerTrimf.__module__)
|
||||||
|
|
||||||
|
gauss = random.normal(0,1.0,2000)
|
||||||
|
#gauss_teste = random.normal(0,1.0,400)
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir("/home/petronio/dados/Dropbox/Doutorado/Disciplinas/AdvancedFuzzyTimeSeriesModels/")
|
||||||
|
|
||||||
|
#from pyFTS.common import Util
|
||||||
|
|
||||||
|
|
||||||
|
bchmk.sliding_window(gauss,500,train=0.7,partitioners=[Grid.GridPartitioner, FCM.FCMPartitioner, Entropy.EntropyPartitioner])
|
||||||
|
|
@ -61,4 +61,4 @@ for max_part in [10, 20, 30, 40, 50]:
|
|||||||
models.append(model)
|
models.append(model)
|
||||||
ixs.append(ix)
|
ixs.append(ix)
|
||||||
|
|
||||||
print(bchmk.getPointStatistics(sample, models, indexers=ixs))
|
print(bchmk.print_point_statistics(sample, models, indexers=ixs))
|
2
yu.py
2
yu.py
@ -32,7 +32,7 @@ class WeightedFLRG(fts.FTS):
|
|||||||
|
|
||||||
class WeightedFTS(fts.FTS):
|
class WeightedFTS(fts.FTS):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
super(WeightedFTS, self).__init__(1, "WFTS")
|
super(WeightedFTS, self).__init__(1, "WFTS " + name)
|
||||||
self.name = "Weighted FTS"
|
self.name = "Weighted FTS"
|
||||||
self.detail = "Yu"
|
self.detail = "Yu"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user