Non Stationary Fuzzy Time Series - NSFTS
This commit is contained in:
parent
80583cc202
commit
b3db1a60a3
@ -14,6 +14,9 @@ class ConventionalFLRG(object):
|
||||
def __init__(self, LHS):
|
||||
self.LHS = LHS
|
||||
self.RHS = set()
|
||||
self.midpoint = None
|
||||
self.lower = None
|
||||
self.upper = None
|
||||
|
||||
def append(self, c):
|
||||
self.RHS.add(c)
|
||||
|
@ -36,20 +36,6 @@ class IndexedFLR(FLR):
|
||||
return str(self.index) + ": "+ self.LHS.name + " -> " + self.RHS.name
|
||||
|
||||
|
||||
def generateNonRecurrentFLRs(fuzzyData):
|
||||
"""
|
||||
Create a ordered FLR set from a list of fuzzy sets without recurrence
|
||||
:param fuzzyData: ordered list of fuzzy sets
|
||||
:return: ordered list of FLR
|
||||
"""
|
||||
flrs = {}
|
||||
for i in range(2,len(fuzzyData)):
|
||||
tmp = FLR(fuzzyData[i-1],fuzzyData[i])
|
||||
flrs[str(tmp)] = tmp
|
||||
ret = [value for key, value in flrs.items()]
|
||||
return ret
|
||||
|
||||
|
||||
def generateRecurrentFLRs(fuzzyData):
|
||||
"""
|
||||
Create a ordered FLR set from a list of fuzzy sets with recurrence
|
||||
@ -58,10 +44,32 @@ def generateRecurrentFLRs(fuzzyData):
|
||||
"""
|
||||
flrs = []
|
||||
for i in np.arange(1,len(fuzzyData)):
|
||||
flrs.append(FLR(fuzzyData[i-1],fuzzyData[i]))
|
||||
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.FLR(lhs,rhs)
|
||||
flrs.append(tmp)
|
||||
return flrs
|
||||
|
||||
|
||||
def generateNonRecurrentFLRs(fuzzyData):
|
||||
"""
|
||||
Create a ordered FLR set from a list of fuzzy sets without recurrence
|
||||
:param fuzzyData: ordered list of fuzzy sets
|
||||
:return: ordered list of FLR
|
||||
"""
|
||||
flrs = generateRecurrentFLRs(fuzzyData)
|
||||
tmp = {}
|
||||
for flr in flrs: tmp[str(flr)] = flr
|
||||
ret = [value for key, value in tmp.items()]
|
||||
return ret
|
||||
|
||||
|
||||
def generateIndexedFLRs(sets, indexer, data, transformation=None):
|
||||
"""
|
||||
Create a season-indexed ordered FLR set from a list of fuzzy sets with recurrence
|
||||
|
@ -7,7 +7,7 @@ IEEE Transactions on Fuzzy Systems, v. 16, n. 4, p. 1072-1086, 2008.
|
||||
|
||||
import numpy as np
|
||||
from pyFTS import *
|
||||
from pyFTS.common import FuzzySet as FS, Membership
|
||||
from pyFTS.common import FuzzySet as FS, Membership, FLR
|
||||
from pyFTS.partitioners import partitioner
|
||||
from pyFTS.nonstationary import perturbation
|
||||
|
||||
@ -279,3 +279,30 @@ class PolynomialNonStationaryPartitioner(partitioner.Partitioner):
|
||||
def build(self, data):
|
||||
pass
|
||||
|
||||
|
||||
def fuzzify(inst, t, fuzzySets):
|
||||
"""
|
||||
Calculate the membership values for a data point given nonstationary fuzzy sets
|
||||
:param inst: data points
|
||||
:param t: time displacement of the instance
|
||||
:param fuzzySets: list of fuzzy sets
|
||||
:return: array of membership values
|
||||
"""
|
||||
ret = []
|
||||
if not isinstance(inst, list):
|
||||
inst = [inst]
|
||||
for t, i in enumerate(inst):
|
||||
mv = np.array([fs.membership(i, t) for fs in fuzzySets])
|
||||
ret.append(mv)
|
||||
return ret
|
||||
|
||||
|
||||
def fuzzySeries(data, fuzzySets):
|
||||
fts = []
|
||||
for t, i in enumerate(data):
|
||||
mv = np.array([fs.membership(i, t) for fs in fuzzySets])
|
||||
ix = np.ravel(np.argwhere(mv > 0.0))
|
||||
sets = [fuzzySets[i] for i in ix]
|
||||
fts.append(sets)
|
||||
return fts
|
||||
|
||||
|
@ -1,12 +1,124 @@
|
||||
import numpy as np
|
||||
from pyFTS.common import FuzzySet, FLR
|
||||
from pyFTS import fts, sfts
|
||||
from pyFTS import fts, chen
|
||||
from pyFTS.nonstationary import common
|
||||
|
||||
|
||||
class NonStationaryFTS(sfts.SeasonalFTS):
|
||||
class NonStationaryFLRG(chen.ConventionalFLRG):
|
||||
"""First Order NonStationary Fuzzy Logical Relationship Group"""
|
||||
def __init__(self, LHS):
|
||||
super(NonStationaryFLRG, self).__init__(LHS)
|
||||
|
||||
def get_midpoint(self, t):
|
||||
if self.midpoint is None:
|
||||
tmp = []
|
||||
for r in self.RHS:
|
||||
tmp.append(r.get_midpoint(t))
|
||||
self.midpoint = sum(tmp)/len(tmp)
|
||||
return self.midpoint
|
||||
|
||||
def get_lower(self, t):
|
||||
if self.lower is None:
|
||||
tmp = []
|
||||
for r in self.RHS:
|
||||
tmp.append(r.get_midpoint(t))
|
||||
self.lower = min(tmp)
|
||||
return self.lower
|
||||
|
||||
def get_upper(self, t):
|
||||
if self.upper is None:
|
||||
tmp = []
|
||||
for r in self.RHS:
|
||||
tmp.append(r.get_midpoint(t))
|
||||
self.upper = max(tmp)
|
||||
return self.upper
|
||||
|
||||
|
||||
class NonStationaryFTS(fts.FTS):
|
||||
"""NonStationaryFTS Fuzzy Time Series"""
|
||||
def __init__(self, name, **kwargs):
|
||||
super(NonStationaryFTS, self).__init__(1, "NSFTS " + name, **kwargs)
|
||||
self.name = "Non Stationary FTS"
|
||||
self.detail = ""
|
||||
self.flrgs = {}
|
||||
|
||||
def generateFLRG(self, flrs):
|
||||
flrgs = {}
|
||||
for flr in flrs:
|
||||
if flr.LHS.name in flrgs:
|
||||
flrgs[flr.LHS.name].append(flr.RHS)
|
||||
else:
|
||||
flrgs[flr.LHS.name] = NonStationaryFLRG(flr.LHS)
|
||||
flrgs[flr.LHS.name].append(flr.RHS)
|
||||
return (flrgs)
|
||||
|
||||
def train(self, data, sets=None,order=1,parameters=None):
|
||||
|
||||
if sets is not None:
|
||||
self.sets = sets
|
||||
else:
|
||||
self.sets = self.partitioner.sets
|
||||
|
||||
ndata = self.doTransformations(data)
|
||||
tmpdata = common.fuzzySeries(ndata, self.sets)
|
||||
flrs = FLR.generateNonRecurrentFLRs(tmpdata)
|
||||
self.flrgs = self.generateFLRG(flrs)
|
||||
|
||||
def forecast(self, data, **kwargs):
|
||||
|
||||
time_displacement = kwargs.get("time_displacement",0)
|
||||
|
||||
ndata = np.array(self.doTransformations(data))
|
||||
|
||||
l = len(ndata)
|
||||
|
||||
ret = []
|
||||
|
||||
for k in np.arange(0, l):
|
||||
|
||||
tdisp = k + time_displacement
|
||||
|
||||
affected_sets = [ [set, set.membership(ndata[k], tdisp)]
|
||||
for set in self.sets if set.membership(ndata[k], tdisp) > 0.0]
|
||||
|
||||
tmp = []
|
||||
for aset in affected_sets:
|
||||
if aset[0] in self.flrgs:
|
||||
tmp.append(self.flrgs[aset[0].name].get_midpoint(tdisp) * aset[1])
|
||||
else:
|
||||
tmp.append(aset[0].get_midpoint(tdisp) * aset[1])
|
||||
|
||||
ret.append(sum(tmp))
|
||||
|
||||
ret = self.doInverseTransformations(ret, params=[data[self.order - 1:]])
|
||||
|
||||
return ret
|
||||
|
||||
def forecastInterval(self, data, **kwargs):
|
||||
|
||||
time_displacement = kwargs.get("time_displacement",0)
|
||||
|
||||
ndata = np.array(self.doTransformations(data))
|
||||
|
||||
l = len(ndata)
|
||||
|
||||
ret = []
|
||||
|
||||
for k in np.arange(0, l):
|
||||
|
||||
tdisp = k + time_displacement
|
||||
|
||||
affected_sets = [ [set.name, set.membership(ndata[k], tdisp)]
|
||||
for set in self.sets if set.membership(ndata[k], tdisp) > 0.0]
|
||||
|
||||
upper = []
|
||||
lower = []
|
||||
for aset in affected_sets:
|
||||
lower.append(self.flrgs[aset[0]].get_lower(tdisp) * aset[1])
|
||||
upper.append(self.flrgs[aset[0]].get_upper(tdisp) * aset[1])
|
||||
|
||||
ret.append([sum(lower), sum(upper)])
|
||||
|
||||
ret = self.doInverseTransformations(ret, params=[data[self.order - 1:]])
|
||||
|
||||
return ret
|
@ -1,7 +1,8 @@
|
||||
import numpy as np
|
||||
from pyFTS.common import Membership
|
||||
from pyFTS.nonstationary import common,perturbation,util
|
||||
from pyFTS.nonstationary import common,perturbation,util,nsfts
|
||||
from pyFTS.partitioners import Grid
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def generate_heteroskedastic_linear(mu_ini, sigma_ini, mu_inc, sigma_inc, it=10, num=35):
|
||||
@ -17,22 +18,26 @@ def generate_heteroskedastic_linear(mu_ini, sigma_ini, mu_inc, sigma_inc, it=10,
|
||||
|
||||
lmv1 = generate_heteroskedastic_linear(1,0.1,1,0.3)
|
||||
|
||||
|
||||
|
||||
ns = 5 #number of fuzzy sets
|
||||
ts = 200
|
||||
train = lmv1[:ts]
|
||||
test = lmv1[ts:]
|
||||
w = 25
|
||||
deg = 4
|
||||
|
||||
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=[10,5])
|
||||
|
||||
tmp_fs = Grid.GridPartitioner(train[:35], 10)
|
||||
|
||||
fs = common.PolynomialNonStationaryPartitioner(train, tmp_fs, window_size=35, degree=1)
|
||||
|
||||
uod = np.arange(0, 2, step=0.02)
|
||||
nsfts1 = nsfts.NonStationaryFTS("", partitioner=fs)
|
||||
|
||||
util.plot_sets(uod, fs.sets,tam=[15, 5], start=0, end=10)
|
||||
nsfts1.train(train[:35])
|
||||
|
||||
for set in fs.sets:
|
||||
print(set)
|
||||
tmp = nsfts1.forecast(test, time_displacement=200)
|
||||
|
||||
axes.plot(test)
|
||||
axes.plot(tmp)
|
||||
|
||||
print(tmp)
|
||||
|
Loading…
Reference in New Issue
Block a user