- Improvements and refactorings on HOFTS, IFTS and PWFTS;

- Complete version of NSFTS
This commit is contained in:
Petrônio Cândido 2017-10-11 22:51:50 -03:00
parent ce71dc20cb
commit 6f455f3215
15 changed files with 402 additions and 134 deletions

View File

@ -35,6 +35,10 @@ def rmse(targets, forecasts):
:param forecasts:
:return:
"""
if isinstance(targets, list):
targets = np.array(targets)
if isinstance(forecasts, list):
forecasts = np.array(forecasts)
return np.sqrt(np.nanmean((targets - forecasts) ** 2))
@ -56,6 +60,10 @@ def mape(targets, forecasts):
:param forecasts:
:return:
"""
if isinstance(targets, list):
targets = np.array(targets)
if isinstance(forecasts, list):
forecasts = np.array(forecasts)
return np.mean(np.abs(targets - forecasts) / targets) * 100
@ -67,6 +75,10 @@ def smape(targets, forecasts, type=2):
:param type:
:return:
"""
if isinstance(targets, list):
targets = np.array(targets)
if isinstance(forecasts, list):
forecasts = np.array(forecasts)
if type == 1:
return np.mean(np.abs(forecasts - targets) / ((forecasts + targets)/2))
elif type == 2:
@ -88,6 +100,11 @@ def UStatistic(targets, forecasts):
:return:
"""
l = len(targets)
if isinstance(targets, list):
targets = np.array(targets)
if isinstance(forecasts, list):
forecasts = np.array(forecasts)
naive = []
y = []
for k in np.arange(0,l-1):

View File

@ -128,3 +128,29 @@ def plot_residuals(targets, models, tam=[8, 8], save=False, file=None):
plt.tight_layout()
Util.showAndSaveImage(fig, file, save)
def single_plot_residuals(targets, forecasts, order, tam=[8, 8], save=False, file=None):
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=tam)
ax = axes
res = residuals(targets, forecasts, order)
ax[0].set_title("Residuals", size='large')
ax[0].set_ylabel("Model", size='large')
ax[0].set_xlabel(' ')
ax[0].plot(res)
ax[1].set_title("Residuals Autocorrelation", size='large')
ax[1].set_ylabel('ACS')
ax[1].set_xlabel('Lag')
ax[1].acorr(res)
ax[2].set_title("Residuals Histogram", size='large')
ax[2].set_ylabel('Freq')
ax[2].set_xlabel('Bins')
ax[2].hist(res)
plt.tight_layout()
Util.showAndSaveImage(fig, file, save)

View File

@ -35,6 +35,25 @@ class IndexedFLR(FLR):
def __str__(self):
return str(self.index) + ": "+ self.LHS.name + " -> " + self.RHS.name
def generate_high_order_recurrent_flr(fuzzyData):
"""
Create a ordered FLR set from a list of fuzzy sets with recurrence
:param fuzzyData: ordered list of fuzzy sets
:return: ordered list of FLR
"""
flrs = []
for i in np.arange(1,len(fuzzyData)):
lhs = fuzzyData[i - 1]
rhs = fuzzyData[i]
if isinstance(lhs, list) and isinstance(rhs, list):
for l in lhs:
for r in rhs:
tmp = FLR(l, r)
flrs.append(tmp)
else:
tmp = FLR(lhs,rhs)
flrs.append(tmp)
return flrs
def generateRecurrentFLRs(fuzzyData):
"""

View File

@ -27,6 +27,7 @@ class FuzzySet(object):
elif self.mf == Membership.gaussmf:
self.lower = parameters[0] - parameters[1]*3
self.upper = parameters[0] + parameters[1]*3
self.metadata = {}
def membership(self, x):
"""
@ -89,6 +90,7 @@ def getMaxMembershipFuzzySet(inst, fuzzySets):
mv = fuzzyInstance(inst, fuzzySets)
return fuzzySets[np.argwhere(mv == max(mv))[0, 0]]
def getMaxMembershipFuzzySetIndex(inst, fuzzySets):
"""
Fuzzify a data point, returning the fuzzy set with maximum membership value

View File

@ -11,6 +11,16 @@ class FLRG(object):
self.lower = None
self.upper = None
def get_membership(self, data):
ret = 0.0
if isinstance(self.LHS, (list, set)):
assert len(self.LHS) == len(data)
ret = min([self.LHS[ct].membership(dat) for ct, dat in enumerate(data)])
else:
ret = self.LHS.membership(data)
return ret
def get_midpoint(self):
if self.midpoint is None:
self.midpoint = sum(self.get_midpoints())/len(self.RHS)

View File

@ -7,7 +7,7 @@ Fuzzy Sets Syst., vol. 81, no. 3, pp. 311319, 1996.
import numpy as np
from pyFTS.common import FuzzySet,FLR
from pyFTS import fts, flrg
from pyFTS import fts, flrg, tree
class HighOrderFLRG(flrg.FLRG):
@ -57,6 +57,27 @@ class HighOrderFTS(fts.FTS):
self.setsDict = {}
self.is_high_order = True
def build_tree(self, node, lags, level):
if level >= self.order:
return
for s in lags[level]:
node.appendChild(tree.FLRGTreeNode(s))
for child in node.getChildren():
self.build_tree(child, lags, level + 1)
def build_tree_without_order(self, node, lags, level):
if level not in lags:
return
for s in lags[level]:
node.appendChild(tree.FLRGTreeNode(s))
for child in node.getChildren():
self.build_tree_without_order(child, lags, level + 1)
def generateFLRG(self, flrs):
flrgs = {}
l = len(flrs)
@ -73,6 +94,43 @@ class HighOrderFTS(fts.FTS):
flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS)
return (flrgs)
def generate_flrg(self, data):
flrgs = {}
l = len(data)
for k in np.arange(self.order, l):
if self.dump: print("FLR: " + str(k))
sample = data[k - self.order: k]
rhs = [set for set in self.sets if set.membership(data[k]) > 0.0]
lags = {}
for o in np.arange(0, self.order):
lhs = [set for set in self.sets if set.membership(sample[o]) > 0.0]
lags[o] = lhs
root = tree.FLRGTreeNode(None)
self.build_tree_without_order(root, lags, 0)
# Trace the possible paths
for p in root.paths():
flrg = HighOrderFLRG(self.order)
path = list(reversed(list(filter(None.__ne__, p))))
for lhs in enumerate(path, start=0):
flrg.appendLHS(lhs)
if flrg.strLHS() not in flrgs:
flrgs[flrg.strLHS()] = flrg;
for st in rhs:
flrgs[flrg.strLHS()].appendRHS(st)
return flrgs
def train(self, data, sets, order=1,parameters=None):
data = self.doTransformations(data, updateUoD=True)
@ -80,9 +138,7 @@ class HighOrderFTS(fts.FTS):
self.order = order
self.sets = sets
for s in self.sets: self.setsDict[s.name] = s
tmpdata = FuzzySet.fuzzySeries(data, sets)
flrs = FLR.generateRecurrentFLRs(tmpdata)
self.flrgs = self.generateFLRG(flrs)
self.flrgs = self.generate_flrg(data)
def forecast(self, data, **kwargs):

View File

@ -43,16 +43,6 @@ class IntervalFTS(hofts.HighOrderFTS):
mb = [fuzzySets[k].membership(data[k]) for k in np.arange(0, len(data))]
return mb
def build_tree(self, node, lags, level):
if level >= self.order:
return
for s in lags[level]:
node.appendChild(tree.FLRGTreeNode(s))
for child in node.getChildren():
self.build_tree(child, lags, level + 1)
def forecastInterval(self, data, **kwargs):
ndata = np.array(self.doTransformations(data))

View File

@ -172,14 +172,15 @@ class FuzzySet(FS.FuzzySet):
def __str__(self):
tmp = ""
if self.location is not None:
tmp += "Loc. Pert.: "
tmp += "Location: "
for ct, f in enumerate(self.location):
tmp += str(f.__name__) + "(" + str(self.location_params[ct]) + ") "
tmp += str(f.__name__) + "(" + str(["{0:.2f}".format(p) for p in self.location_params[ct]]) + ") "
if self.width is not None:
tmp += "Wid. Pert.: "
tmp += "Width: "
for ct, f in enumerate(self.width):
tmp += str(f.__name__) + "(" + str(self.width_params[ct]) + ") "
return self.name + ": " + str(self.mf.__name__) + "(" + str(self.parameters) + ") " + tmp
tmp += str(f.__name__) + "(" + str(["{0:.2f}".format(p) for p in self.width_params[ct]]) + ") "
tmp = "(" + str(["{0:.2f}".format(p) for p in self.parameters]) + ") " + tmp
return self.name + ": " + str(self.mf.__name__) + tmp
class PolynomialNonStationaryPartitioner(partitioner.Partitioner):
@ -218,6 +219,14 @@ class PolynomialNonStationaryPartitioner(partitioner.Partitioner):
tmp = np.polyfit(rng, diff, deg=deg)
return tmp
def scale_up(self,x,pct):
if x > 0: return x*(1+pct)
else: return x*pct
def scale_down(self,x,pct):
if x > 0: return x*pct
else: return x*(1+pct)
def get_polynomial_perturbations(self, data, **kwargs):
w = kwargs.get("window_size", int(len(data) / 5))
deg = kwargs.get("degree", 2)
@ -225,8 +234,7 @@ class PolynomialNonStationaryPartitioner(partitioner.Partitioner):
tmax = [0]
xmin = [data[0]]
tmin = [0]
lengs = [0]
tlengs = [0]
l = len(data)
for i in np.arange(0, l, w):
@ -237,15 +245,9 @@ class PolynomialNonStationaryPartitioner(partitioner.Partitioner):
tn = min(sample)
xmin.append(tn)
tmin.append(np.ravel(np.argwhere(data == tn)).tolist()[0])
lengs.append((tx - tn)/self.partitions)
tlengs.append(i)
cmax = np.polyfit(tmax, xmax, deg=deg)
#cmax = cmax.tolist()
cmin = np.polyfit(tmin, xmin, deg=deg)
#cmin = cmin.tolist()
cmed = []
@ -297,12 +299,37 @@ def fuzzify(inst, t, fuzzySets):
return ret
def fuzzySeries(data, fuzzySets):
def fuzzySeries(data, fuzzySets, window_size=1, method='fuzzy'):
fts = []
for t, i in enumerate(data):
mv = np.array([fs.membership(i, t) for fs in fuzzySets])
tdisp = window_index(t, window_size)
mv = np.array([fs.membership(i, tdisp) for fs in fuzzySets])
if len(mv) == 0:
sets = [check_bounds(i, fuzzySets, tdisp)]
else:
if method == 'fuzzy':
ix = np.ravel(np.argwhere(mv > 0.0))
elif method == 'maximum':
mx = max(mv)
ix = np.ravel(np.argwhere(mv == mx))
sets = [fuzzySets[i] for i in ix]
fts.append(sets)
return fts
def window_index(t, window_size):
return t - (t % window_size)
def check_bounds(data, sets, t):
if data < sets[0].get_lower(t):
return sets[0]
elif data > sets[-1].get_upper(t):
return sets[-1]
def check_bounds_index(data, sets, t):
if data < sets[0].get_lower(t):
return 0
elif data > sets[-1].get_upper(t):
return len(sets) -1

View File

@ -1,5 +1,6 @@
from pyFTS import flrg
from pyFTS.nonstationary import common
class NonStationaryFLRG(flrg.FLRG):
@ -9,18 +10,41 @@ class NonStationaryFLRG(flrg.FLRG):
self.LHS = LHS
self.RHS = set()
def get_midpoint(self, t):
if self.midpoint is None:
tmp = [r.get_midpoint(t) for r in self.RHS]
self.midpoint = sum(tmp) / len(tmp)
return self.midpoint
def get_membership(self, data, t, window_size=1):
ret = 0.0
if isinstance(self.LHS, (list, set)):
assert len(self.LHS) == len(data)
def get_lower(self, t):
ret = min([self.LHS[ct].membership(dat, common.window_index(t - (self.order - ct), window_size))
for ct, dat in enumerate(data)])
else:
ret = self.LHS.membership(data, common.window_index(t, window_size))
return ret
def get_midpoint(self, t, window_size=1):
if len(self.RHS) > 0:
if isinstance(self.RHS, (list,set)):
tmp = [r.get_midpoint(common.window_index(t, window_size)) for r in self.RHS]
elif isinstance(self.RHS, dict):
tmp = [self.RHS[r].get_midpoint(common.window_index(t, window_size)) for r in self.RHS.keys()]
return sum(tmp) / len(tmp)
else:
return self.LHS[-1].get_midpoint(common.window_index(t, window_size))
def get_lower(self, t, window_size=1):
if self.lower is None:
self.lower = min([r.get_lower(t) for r in self.RHS])
if len(self.RHS) > 0:
self.lower = min([r.get_lower(common.window_index(t, window_size)) for r in self.RHS])
else:
self.lower = self.LHS[-1].get_lower(common.window_index(t, window_size))
return self.lower
def get_upper(self, t):
def get_upper(self, t, window_size=1):
if self.upper is None:
self.upper = min([r.get_upper(t) for r in self.RHS])
if len(self.RHS) > 0:
self.upper = min([r.get_upper(common.window_index(t, window_size)) for r in self.RHS])
else:
self.upper = self.LHS[-1].get_upper(common.window_index(t, window_size))
return self.upper

View File

@ -2,6 +2,7 @@ import numpy as np
from pyFTS.common import FuzzySet, FLR
from pyFTS import fts, hofts
from pyFTS.nonstationary import common, flrg
from pyFTS import tree
class HighOrderNonStationaryFLRG(flrg.NonStationaryFLRG):
@ -37,31 +38,64 @@ class HighOrderNonStationaryFLRG(flrg.NonStationaryFLRG):
return self.strLHS() + " -> " + tmp
class HighOrderNonStationaryFTS(hofts.HighOrderFLRG):
class HighOrderNonStationaryFTS(hofts.HighOrderFTS):
"""NonStationaryFTS Fuzzy Time Series"""
def __init__(self, name, **kwargs):
super(HighOrderNonStationaryFTS, self).__init__(1, "HONSFTS " + name, **kwargs)
super(HighOrderNonStationaryFTS, self).__init__("HONSFTS " + name, **kwargs)
self.name = "High Order Non Stationary FTS"
self.detail = ""
self.flrgs = {}
def generateFLRG(self, flrs):
def generate_flrg(self, data, **kwargs):
flrgs = {}
l = len(flrs)
for k in np.arange(self.order + 1, l):
l = len(data)
window_size = kwargs.get("window_size", 1)
for k in np.arange(self.order, l):
if self.dump: print("FLR: " + str(k))
sample = data[k - self.order: k]
disp = common.window_index(k, window_size)
rhs = [set for set in self.sets if set.membership(data[k], disp) > 0.0]
if len(rhs) == 0:
rhs = [common.check_bounds(data[k], self.sets, disp)]
lags = {}
for o in np.arange(0, self.order):
tdisp = common.window_index(k - (self.order - o), window_size)
lhs = [set for set in self.sets if set.membership(sample[o], tdisp) > 0.0]
if len(lhs) == 0:
lhs = [common.check_bounds(sample[o], self.sets, tdisp)]
lags[o] = lhs
root = tree.FLRGTreeNode(None)
self.build_tree_without_order(root, lags, 0)
# Trace the possible paths
for p in root.paths():
flrg = HighOrderNonStationaryFLRG(self.order)
path = list(reversed(list(filter(None.__ne__, p))))
for kk in np.arange(k - self.order, k):
flrg.appendLHS(flrs[kk].LHS)
for c, e in enumerate(path, start=0):
flrg.appendLHS(e)
if flrg.strLHS() in flrgs:
flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS)
else:
if flrg.strLHS() not in flrgs:
flrgs[flrg.strLHS()] = flrg;
flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS)
return (flrgs)
def train(self, data, sets=None,order=1,parameters=None):
for st in rhs:
flrgs[flrg.strLHS()].appendRHS(st)
return flrgs
def train(self, data, sets=None, order=2, parameters=None):
self.order = order
if sets is not None:
self.sets = sets
@ -69,43 +103,72 @@ class HighOrderNonStationaryFTS(hofts.HighOrderFLRG):
self.sets = self.partitioner.sets
ndata = self.doTransformations(data)
tmpdata = common.fuzzySeries(ndata, self.sets)
flrs = FLR.generateNonRecurrentFLRs(tmpdata)
self.flrgs = self.generateFLRG(flrs)
#tmpdata = common.fuzzySeries(ndata, self.sets)
#flrs = FLR.generateRecurrentFLRs(ndata)
window_size = parameters if parameters is not None else 1
self.flrgs = self.generate_flrg(ndata, window_size=window_size)
def forecast(self, data, **kwargs):
time_displacement = kwargs.get("time_displacement",0)
window_size = kwargs.get("window_size", 1)
ndata = np.array(self.doTransformations(data))
l = len(ndata)
ret = []
for k in np.arange(0, l):
for k in np.arange(self.order, l+1):
#print("input: " + str(ndata[k]))
tdisp = k + time_displacement
disp = common.window_index(k + time_displacement, window_size)
affected_sets = [ [set, set.membership(ndata[k], tdisp)]
for set in self.sets if set.membership(ndata[k], tdisp) > 0.0]
affected_flrgs = []
affected_flrgs_memberships = []
if len(affected_sets) == 0:
if self.sets[0].get_lower(tdisp) > ndata[k]:
affected_sets.append([self.sets[0], 1.0])
elif self.sets[-1].get_upper(tdisp) < ndata[k]:
affected_sets.append([self.sets[-1], 1.0])
lags = {}
sample = ndata[k - self.order: k]
for ct, dat in enumerate(sample):
tdisp = common.window_index((k + time_displacement) - (self.order - ct), window_size)
sel = [ct for ct, set in enumerate(self.sets) if set.membership(dat, tdisp) > 0.0]
if len(sel) == 0:
sel.append(common.check_bounds_index(dat, self.sets, tdisp))
lags[ct] = sel
# Build the tree with all possible paths
root = tree.FLRGTreeNode(None)
self.build_tree(root, lags, 0)
# Trace the possible paths and build the PFLRG's
for p in root.paths():
path = list(reversed(list(filter(None.__ne__, p))))
flrg = HighOrderNonStationaryFLRG(self.order)
for kk in path:
flrg.appendLHS(self.sets[kk])
affected_flrgs.append(flrg)
affected_flrgs_memberships.append(flrg.get_membership(ndata[k - self.order: k], disp))
#print(affected_sets)
tmp = []
for aset in affected_sets:
if aset[0] in self.flrgs:
tmp.append(self.flrgs[aset[0].name].get_midpoint(tdisp) * aset[1])
for ct, aset in enumerate(affected_flrgs):
if aset.strLHS() in self.flrgs:
tmp.append(self.flrgs[aset.strLHS()].get_midpoint(tdisp) *
affected_flrgs_memberships[ct])
else:
tmp.append(aset[0].get_midpoint(tdisp) * aset[1])
tmp.append(aset.LHS[-1].get_midpoint(tdisp))
pto = sum(tmp)

View File

@ -32,8 +32,9 @@ class NonStationaryFTS(fts.FTS):
self.name = "Non Stationary FTS"
self.detail = ""
self.flrgs = {}
self.method = kwargs.get("method",'fuzzy')
def generateFLRG(self, flrs):
def generate_flrg(self, flrs, **kwargs):
flrgs = {}
for flr in flrs:
if flr.LHS.name in flrgs:
@ -41,9 +42,9 @@ class NonStationaryFTS(fts.FTS):
else:
flrgs[flr.LHS.name] = ConventionalNonStationaryFLRG(flr.LHS)
flrgs[flr.LHS.name].append(flr.RHS)
return (flrgs)
return flrgs
def train(self, data, sets=None,order=1,parameters=None):
def train(self, data, sets=None, order=1, parameters=None):
if sets is not None:
self.sets = sets
@ -51,14 +52,19 @@ class NonStationaryFTS(fts.FTS):
self.sets = self.partitioner.sets
ndata = self.doTransformations(data)
tmpdata = common.fuzzySeries(ndata, self.sets)
flrs = FLR.generateNonRecurrentFLRs(tmpdata)
self.flrgs = self.generateFLRG(flrs)
window_size = parameters if parameters is not None else 1
tmpdata = common.fuzzySeries(ndata, self.sets, window_size, method=self.method)
#print([k[0].name for k in tmpdata])
flrs = FLR.generateRecurrentFLRs(tmpdata)
#print([str(k) for k in flrs])
self.flrgs = self.generate_flrg(flrs)
def forecast(self, data, **kwargs):
time_displacement = kwargs.get("time_displacement",0)
window_size = kwargs.get("window_size", 1)
ndata = np.array(self.doTransformations(data))
l = len(ndata)
@ -69,25 +75,38 @@ class NonStationaryFTS(fts.FTS):
#print("input: " + str(ndata[k]))
tdisp = k + time_displacement
tdisp = common.window_index(k + time_displacement, window_size)
if self.method == 'fuzzy':
affected_sets = [ [set, set.membership(ndata[k], tdisp)]
for set in self.sets if set.membership(ndata[k], tdisp) > 0.0]
elif self.method == 'maximum':
mv = [set.membership(ndata[k], tdisp) for set in self.sets]
ix = np.ravel(np.argwhere(mv == max(mv)))
affected_sets = [self.sets[x] for x in ix]
if len(affected_sets) == 0:
if self.sets[0].get_lower(tdisp) > ndata[k]:
affected_sets.append([self.sets[0], 1.0])
elif self.sets[-1].get_upper(tdisp) < ndata[k]:
affected_sets.append([self.sets[-1], 1.0])
if self.method == 'fuzzy':
affected_sets.append([common.check_bounds(ndata[k], self.sets, tdisp), 1.0])
else:
affected_sets.append(common.check_bounds(ndata[k], self.sets, tdisp))
#print(affected_sets)
tmp = []
for aset in affected_sets:
if aset[0] in self.flrgs:
tmp.append(self.flrgs[aset[0].name].get_midpoint(tdisp) * aset[1])
if len(affected_sets) == 1 and self.method == 'fuzzy':
tmp.append(affected_sets[0][0].get_midpoint(tdisp))
else:
tmp.append(aset[0].get_midpoint(tdisp) * aset[1])
for aset in affected_sets:
if self.method == 'fuzzy':
if aset[0].name in self.flrgs:
tmp.append(self.flrgs[aset[0].name].get_midpoint(tdisp) * aset[1])
elif self.method == 'maximum':
if aset.name in self.flrgs:
tmp.append(self.flrgs[aset.name].get_midpoint(tdisp))
else:
tmp.append(aset.get_midpoint(tdisp))
pto = sum(tmp)
@ -103,6 +122,8 @@ class NonStationaryFTS(fts.FTS):
time_displacement = kwargs.get("time_displacement",0)
window_size = kwargs.get("window_size", 1)
ndata = np.array(self.doTransformations(data))
l = len(ndata)
@ -111,7 +132,7 @@ class NonStationaryFTS(fts.FTS):
for k in np.arange(0, l):
tdisp = k + time_displacement
tdisp = common.window_index(k + time_displacement, window_size)
affected_sets = [ [set.name, set.membership(ndata[k], tdisp)]
for set in self.sets if set.membership(ndata[k], tdisp) > 0.0]

View File

@ -6,29 +6,48 @@ import matplotlib.pyplot as plt
from pyFTS.common import Membership, Util
def plot_sets(uod, sets, start=0, end=10, tam=[5, 5], colors=None, save=False, file=None):
def plot_sets(sets, start=0, end=10, step=1, tam=[5, 5], colors=None,
save=False, file=None, axes=None, data=None, window_size = 1, only_lines=False):
range = np.arange(start,end,step)
ticks = []
if axes is None:
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=tam)
for t in np.arange(start,end,1):
for ct, set in enumerate(sets):
set.membership(0, t)
param = set.perturbated_parameters[t]
if not only_lines:
for t in range:
tdisp = t - (t % window_size)
set.membership(0, tdisp)
param = set.perturbated_parameters[tdisp]
if set.mf == Membership.trimf:
if t == start:
axes.plot([t, t+1, t], param, label=set.name)
line = axes.plot([t, t+1, t], param, label=set.name)
set.metadata['color'] = line[0].get_color()
else:
axes.plot([t, t + 1, t], param)
axes.plot([t, t + 1, t], param,c=set.metadata['color'])
ticks.extend(["t+"+str(t),""])
else:
tmp = []
for t in range:
tdisp = t - (t % window_size)
set.membership(0, tdisp)
param = set.perturbated_parameters[tdisp]
tmp.append(np.polyval(param, tdisp))
axes.plot(range, tmp, ls="--", c="blue")
axes.set_ylabel("Universe of Discourse")
axes.set_xlabel("Time")
plt.xticks([k for k in np.arange(0,end,1)], ticks, rotation='vertical')
plt.xticks([k for k in range], ticks, rotation='vertical')
handles0, labels0 = axes.get_legend_handles_labels()
lgd = axes.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))
if data is not None:
axes.plot(np.arange(start, start + len(data), 1), data,c="black")
plt.tight_layout()
Util.showAndSaveImage(fig, file, save)

View File

@ -79,4 +79,7 @@ class Partitioner(object):
ax.plot(tmpx, tmpy)
def __str__(self):
return self.name + ":\n ".join([str(a) + "\n" for a in self.sets])
tmp = self.name + ":\n"
for a in self.sets:
tmp += str(a)+ "\n"
return tmp

View File

@ -127,9 +127,9 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS):
flrs = FLR.generateRecurrentFLRs(tmpdata)
self.flrgs = self.generateFLRG(flrs)
else:
self.flrgs = self.generateFLRGfuzzy(data)
self.flrgs = self.generate_flrg(data)
def generateFLRGfuzzy(self, data):
def generate_flrg(self, data):
flrgs = {}
l = len(data)
for k in np.arange(self.order, l):
@ -175,7 +175,7 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS):
self.global_frequency_count = self.global_frequency_count + tmp_fq
return (flrgs)
return flrgs
def generateFLRG(self, flrs):
flrgs = {}
@ -274,18 +274,6 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS):
ret = sum(np.array([pi * s.lower for s in flrg.LHS]))
return ret
def build_tree_without_order(self, node, lags, level):
if level not in lags:
return
for s in lags[level]:
node.appendChild(tree.FLRGTreeNode(s))
for child in node.getChildren():
self.build_tree_without_order(child, lags, level + 1)
def forecast(self, data, **kwargs):
ndata = np.array(self.doTransformations(data))
@ -299,19 +287,17 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS):
# print(k)
affected_flrgs = []
affected_rhs = []
affected_flrgs_memberships = []
norms = []
mp = []
# Find the sets which membership > 0 for each lag
count = 0
lags = {}
if self.order > 1:
subset = ndata[k - (self.order - 1): k + 1]
for instance in subset:
for count, instance in enumerate(subset):
mb = FuzzySet.fuzzyInstance(instance, self.sets)
tmp = np.argwhere(mb)
idx = np.ravel(tmp) # flatten the array
@ -325,7 +311,6 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS):
raise Exception(instance)
lags[count] = idx
count = count + 1
# Build the tree with all possible paths
@ -346,7 +331,7 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS):
affected_flrgs.append(flrg)
# Find the general membership of FLRG
affected_flrgs_memberships.append(min(self.get_sequence_membership(subset, flrg.LHS)))
affected_flrgs_memberships.append(flrg.get_membership())
else:

View File

@ -1,7 +1,7 @@
import os
import numpy as np
from pyFTS.common import Membership
from pyFTS.nonstationary import common,perturbation,util,nsfts
from pyFTS.nonstationary import common,perturbation,util,nsfts, honsfts
from pyFTS.partitioners import Grid
import matplotlib.pyplot as plt
import pandas as pd
@ -50,27 +50,33 @@ print(tmp)
passengers = pd.read_csv("DataSets/AirPassengers.csv", sep=",")
passengers = np.array(passengers["Passengers"])
ts = 80
ts = 100
ws=12
trainp = passengers[:ts]
testp = passengers[ts:]
tmp_fsp = Grid.GridPartitioner(trainp[:50], 10)
tmp_fsp = Grid.GridPartitioner(trainp[:ws], 15)
fsp = common.PolynomialNonStationaryPartitioner(trainp, tmp_fsp, window_size=20, degree=1)
fsp = common.PolynomialNonStationaryPartitioner(trainp, tmp_fsp, window_size=ws, degree=1)
nsftsp = nsfts.NonStationaryFTS("", partitioner=fsp)
nsftsp.train(trainp[:50])
#nsftsp = honsfts.HighOrderNonStationaryFTS("", partitioner=fsp)
nsftsp = nsfts.NonStationaryFTS("", partitioner=fsp, method='fuzzy')
#nsftsp.train(trainp, order=1, parameters=ws)
print(fsp)
print(nsftsp)
#print(nsftsp)
tmpp = nsftsp.forecast(testp, time_displacement=ts)
#tmpp = nsftsp.forecast(passengers[55:65], time_displacement=55, window_size=ws)
print(testp)
print(tmpp)
#print(passengers[100:120])
#print(tmpp)
#util.plot_sets(fsp.sets,tam=[10, 5], start=0, end=100, step=2, data=passengers[:100],
# window_size=ws, only_lines=False)
#fig, axes = plt.subplots(nrows=1, ncols=1, figsize=[15,5])