Source code for pyFTS.models.nonstationary.honsfts

import numpy as np
from pyFTS.common import FuzzySet, FLR, fts, tree
from pyFTS.models import hofts
from pyFTS.models.nonstationary import common, flrg


[docs]class HighOrderNonStationaryFLRG(flrg.NonStationaryFLRG): """First Order NonStationary Fuzzy Logical Relationship Group""" def __init__(self, order, **kwargs): super(HighOrderNonStationaryFLRG, self).__init__(order, **kwargs) self.LHS = [] self.RHS = {}
[docs] def append_rhs(self, c, **kwargs): if c.name not in self.RHS: self.RHS[c.name] = c
[docs] def append_lhs(self, c): self.LHS.append(c)
def __str__(self): tmp = "" for c in sorted(self.RHS): if len(tmp) > 0: tmp = tmp + "," tmp = tmp + c return self.get_key() + " -> " + tmp
[docs]class HighOrderNonStationaryFTS(hofts.HighOrderFTS): """NonStationaryFTS Fuzzy Time Series""" def __init__(self, name, **kwargs): super(HighOrderNonStationaryFTS, self).__init__("HONSFTS " + name, **kwargs) self.name = "High Order Non Stationary FTS" self.detail = "" self.flrgs = {}
[docs] def generate_flrg(self, data, **kwargs): 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 = [self.sets[key] for key in self.partitioner.ordered_sets if self.sets[key].membership(data[k], disp) > 0.0] if len(rhs) == 0: rhs = [common.check_bounds(data[k], self.partitioner, disp)] lags = {} for o in np.arange(0, self.order): tdisp = common.window_index(k - (self.order - o), window_size) lhs = [self.sets[key] for key in self.partitioner.ordered_sets if self.sets[key].membership(sample[o], tdisp) > 0.0] if len(lhs) == 0: lhs = [common.check_bounds(sample[o], self.partitioner, tdisp)] lags[o] = lhs root = tree.FLRGTreeNode(None) tree.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 c, e in enumerate(path, start=0): flrg.append_lhs(e) if flrg.get_key() not in self.flrgs: self.flrgs[flrg.get_key()] = flrg; for st in rhs: self.flrgs[flrg.get_key()].append_rhs(st)
# flrgs = sorted(flrgs, key=lambda flrg: flrg.get_midpoint(0, window_size=1))
[docs] def train(self, data, **kwargs): if kwargs.get('order', None) is not None: self.order = kwargs.get('order', 1) if kwargs.get('sets', None) is not None: self.sets = kwargs.get('sets', None) window_size = kwargs.get('parameters', 1) self.generate_flrg(data, window_size=window_size)
def _affected_flrgs(self, sample, k, time_displacement, window_size): # print("input: " + str(ndata[k])) affected_flrgs = [] affected_flrgs_memberships = [] lags = {} for ct, dat in enumerate(sample): tdisp = common.window_index((k + time_displacement) - (self.order - ct), window_size) sel = [ct for ct, key in enumerate(self.partitioner.ordered_sets) if self.sets[key].membership(dat, tdisp) > 0.0] if len(sel) == 0: sel.append(common.check_bounds_index(dat, self.partitioner, tdisp)) lags[ct] = sel # Build the tree with all possible paths root = tree.FLRGTreeNode(None) tree.build_tree_without_order(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.append_lhs(self.sets[self.partitioner.ordered_sets[kk]]) affected_flrgs.append(flrg) # affected_flrgs_memberships.append_rhs(flrg.get_membership(sample, disp)) # print(flrg.get_key()) # the FLRG is here because of the bounds verification mv = [] for ct, dat in enumerate(sample): td = common.window_index((k + time_displacement) - (self.order - ct), window_size) tmp = flrg.LHS[ct].membership(dat, td) mv.append(tmp) # print(mv) affected_flrgs_memberships.append(np.prod(mv)) return [affected_flrgs, affected_flrgs_memberships]
[docs] def forecast(self, ndata, **kwargs): time_displacement = kwargs.get("time_displacement",0) window_size = kwargs.get("window_size", 1) l = len(ndata) ret = [] for k in np.arange(self.order, l+1): sample = ndata[k - self.order: k] affected_flrgs, affected_flrgs_memberships = self._affected_flrgs(sample, k, time_displacement, window_size) #print([str(k) for k in affected_flrgs]) #print(affected_flrgs_memberships) tmp = [] tdisp = common.window_index(k + time_displacement, window_size) if len(affected_flrgs) == 0: tmp.append(common.check_bounds(sample[-1], self.sets, tdisp)) elif len(affected_flrgs) == 1: flrg = affected_flrgs[0] if flrg.get_key() in self.flrgs: tmp.append(self.flrgs[flrg.get_key()].get_midpoint(tdisp)) else: tmp.append(flrg.LHS[-1].get_midpoint(tdisp)) else: for ct, aset in enumerate(affected_flrgs): if aset.get_key() in self.flrgs: tmp.append(self.flrgs[aset.get_key()].get_midpoint(tdisp) * affected_flrgs_memberships[ct]) else: tmp.append(aset.LHS[-1].get_midpoint(tdisp)* affected_flrgs_memberships[ct]) pto = sum(tmp) #print(pto) ret.append(pto) return ret
[docs] def forecast_interval(self, ndata, **kwargs): time_displacement = kwargs.get("time_displacement", 0) window_size = kwargs.get("window_size", 1) l = len(ndata) ret = [] for k in np.arange(self.order, l + 1): sample = ndata[k - self.order: k] affected_flrgs, affected_flrgs_memberships = self._affected_flrgs(sample, k, time_displacement, window_size) # print([str(k) for k in affected_flrgs]) # print(affected_flrgs_memberships) upper = [] lower = [] tdisp = common.window_index(k + time_displacement, window_size) if len(affected_flrgs) == 0: aset = common.check_bounds(sample[-1], self.sets, tdisp) lower.append(aset.get_lower(tdisp)) upper.append(aset.get_upper(tdisp)) elif len(affected_flrgs) == 1: _flrg = affected_flrgs[0] if _flrg.get_key() in self.flrgs: lower.append(self.flrgs[_flrg.get_key()].get_lower(tdisp)) upper.append(self.flrgs[_flrg.get_key()].get_upper(tdisp)) else: lower.append(_flrg.LHS[-1].get_lower(tdisp)) upper.append(_flrg.LHS[-1].get_upper(tdisp)) else: for ct, aset in enumerate(affected_flrgs): if aset.get_key() in self.flrgs: lower.append(self.flrgs[aset.get_key()].get_lower(tdisp) * affected_flrgs_memberships[ct]) upper.append(self.flrgs[aset.get_key()].get_upper(tdisp) * affected_flrgs_memberships[ct]) else: lower.append(aset.LHS[-1].get_lower(tdisp) * affected_flrgs_memberships[ct]) upper.append(aset.LHS[-1].get_upper(tdisp) * affected_flrgs_memberships[ct]) ret.append([sum(lower), sum(upper)]) return ret