CVFTS improvements on perturbation_factors

This commit is contained in:
Petrônio Cândido 2018-06-18 12:44:46 -03:00
parent bd4c0c432e
commit 74debe42ee
5 changed files with 115 additions and 21 deletions

View File

@ -58,7 +58,6 @@ class FuzzySet(FS.FuzzySet):
if self.location is None: if self.location is None:
inc = t inc = t
else: else:
l = len(self.location) l = len(self.location)
inc = sum([self.location[k](t + self.location_roots[k], self.location_params[k]) for k in np.arange(0, l)]) inc = sum([self.location[k](t + self.location_roots[k], self.location_params[k]) for k in np.arange(0, l)])

View File

@ -30,6 +30,7 @@ class HighOrderNonstationaryFLRG(hofts.HighOrderFTS):
def __len__(self): def __len__(self):
return len(self.RHS) return len(self.RHS)
class ConditionalVarianceFTS(hofts.HighOrderFTS): class ConditionalVarianceFTS(hofts.HighOrderFTS):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(ConditionalVarianceFTS, self).__init__(**kwargs) super(ConditionalVarianceFTS, self).__init__(**kwargs)
@ -45,6 +46,12 @@ class ConditionalVarianceFTS(hofts.HighOrderFTS):
self.uod_clip = False self.uod_clip = False
self.order = 1 self.order = 1
self.min_order = 1 self.min_order = 1
self.inputs = []
self.forecasts = []
self.residuals = []
self.variance_residual = 0.
self.mean_residual = 0.
self.memory_window = kwargs.get("memory_window",5)
def train(self, ndata, **kwargs): def train(self, ndata, **kwargs):
@ -52,6 +59,21 @@ class ConditionalVarianceFTS(hofts.HighOrderFTS):
flrs = FLR.generate_non_recurrent_flrs(tmpdata) flrs = FLR.generate_non_recurrent_flrs(tmpdata)
self.generate_flrg(flrs) self.generate_flrg(flrs)
self.forecasts = self.forecast(ndata, no_update=True)
self.residuals = np.array(ndata[1:]) - np.array(self.forecasts[:-1])
self.variance_residual = np.var(self.residuals) # np.max(self.residuals
self.mean_residual = np.mean(self.residuals)
self.residuals = self.residuals[-self.memory_window:].tolist()
self.forecasts = self.forecasts[-self.memory_window:]
self.inputs = np.array(ndata[-self.memory_window:]).tolist()
print(self.mean_residual)
print(self.variance_residual)
print([self.original_min,self.original_max])
def generate_flrg(self, flrs, **kwargs): def generate_flrg(self, flrs, **kwargs):
for flr in flrs: for flr in flrs:
if flr.LHS.name in self.flrgs: if flr.LHS.name in self.flrgs:
@ -64,7 +86,38 @@ class ConditionalVarianceFTS(hofts.HighOrderFTS):
def _smooth(self, a): def _smooth(self, a):
return .1 * a[0] + .3 * a[1] + .6 * a[2] return .1 * a[0] + .3 * a[1] + .6 * a[2]
def perturbation_factors(self, data): def perturbation_factors(self, data, **kwargs):
_max = 0
_min = 0
if data < self.original_min:
_min = data - self.original_min if data < 0 else self.original_min - data
elif data > self.original_max:
_max = data - self.original_max if data > 0 else self.original_max - data
self.min_stack.pop(2)
self.min_stack.insert(0, _min)
_min = min(self.min_stack)
self.max_stack.pop(2)
self.max_stack.insert(0, _max)
_max = max(self.max_stack)
_range = (_max - _min)/2
translate = np.linspace(_min, _max, self.partitioner.partitions)
var = np.std(self.residuals)
var = 0 if var < 1 else var
loc = (self.mean_residual + np.mean(self.residuals))
location = [_range + w + loc + k for k in np.linspace(-var,var) for w in translate]
perturb = [[location[k], var] for k in np.arange(0, self.partitioner.partitions)]
return perturb
def perturbation_factors__old(self, data):
_max = 0 _max = 0
_min = 0 _min = 0
if data < self.original_min: if data < self.original_min:
@ -107,39 +160,59 @@ class ConditionalVarianceFTS(hofts.HighOrderFTS):
ret = [] ret = []
no_update = kwargs.get("no_update",False)
for k in np.arange(0, l): for k in np.arange(0, l):
sample = ndata[k] sample = ndata[k]
perturb = self.perturbation_factors(sample) if not no_update:
perturb = self.perturbation_factors(sample)
else:
perturb = [[0, 1] for k in np.arange(0, self.partitioner.partitions)]
affected_sets = self._affected_sets(sample, perturb) affected_sets = self._affected_sets(sample, perturb)
tmp = [] numerator = []
denominator = []
if len(affected_sets) == 1: if len(affected_sets) == 1:
ix = affected_sets[0][0] ix = affected_sets[0][0]
aset = self.partitioner.ordered_sets[ix] aset = self.partitioner.ordered_sets[ix]
if aset in self.flrgs: if aset in self.flrgs:
tmp.append(self.flrgs[aset].get_midpoint(perturb[ix])) numerator.append(self.flrgs[aset].get_midpoint(perturb[ix]))
else: else:
fuzzy_set = self.sets[aset] fuzzy_set = self.sets[aset]
tmp.append(fuzzy_set.get_midpoint(perturb[ix])) numerator.append(fuzzy_set.get_midpoint(perturb[ix]))
denominator.append(1)
else: else:
for aset in affected_sets: for aset in affected_sets:
ix = aset[0] ix = aset[0]
fs = self.partitioner.ordered_sets[ix] fs = self.partitioner.ordered_sets[ix]
tdisp = perturb[ix] tdisp = perturb[ix]
if fs in self.flrgs: if fs in self.flrgs:
tmp.append(self.flrgs[fs].get_midpoint(tdisp) * aset[1]) numerator.append(self.flrgs[fs].get_midpoint(tdisp) * aset[1])
else: else:
fuzzy_set = self.sets[fs] fuzzy_set = self.sets[fs]
tmp.append(fuzzy_set.get_midpoint(tdisp) * aset[1]) numerator.append(fuzzy_set.get_midpoint(tdisp) * aset[1])
denominator.append(aset[1])
pto = sum(tmp) if sum(denominator) > 0:
pto = sum(numerator) /sum(denominator)
else:
pto = sum(numerator)
ret.append(pto) ret.append(pto)
if not no_update:
self.forecasts.append(pto)
self.residuals.append(self.inputs[-1] - self.forecasts[-1])
self.inputs.append(sample)
self.inputs.pop(0)
self.forecasts.pop(0)
self.residuals.pop(0)
return ret return ret

View File

@ -62,6 +62,7 @@ def plot_sets_conditional(model, data, step=1, size=[5, 5], colors=None,
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=size) fig, axes = plt.subplots(nrows=1, ncols=1, figsize=size)
for t in range: for t in range:
model.forecast([data[t]])
perturb = model.perturbation_factors(data[t]) perturb = model.perturbation_factors(data[t])
for ct, key in enumerate(model.partitioner.ordered_sets): for ct, key in enumerate(model.partitioner.ordered_sets):

View File

@ -19,7 +19,7 @@ dataset = TAIEX.get_data()
#print(len(dataset)) #print(len(dataset))
from pyFTS.partitioners import Grid, Util as pUtil from pyFTS.partitioners import Grid, Util as pUtil
partitioner = Grid.GridPartitioner(data=dataset[:800], npart=10)#, transformation=tdiff) partitioner = Grid.GridPartitioner(data=dataset[:800], npart=10, transformation=tdiff)
from pyFTS.common import Util as cUtil from pyFTS.common import Util as cUtil
@ -28,9 +28,9 @@ from pyFTS.benchmarks import benchmarks as bchmk, Util as bUtil, Measures, knn,
from pyFTS.models import pwfts, song, chen, ifts, hofts from pyFTS.models import pwfts, song, chen, ifts, hofts
from pyFTS.models.ensemble import ensemble from pyFTS.models.ensemble import ensemble
#model = chen.ConventionalFTS(partitioner=partitioner) model = chen.ConventionalFTS(partitioner=partitioner)
model = hofts.HighOrderFTS(partitioner=partitioner,order=2) #model = hofts.HighOrderFTS(partitioner=partitioner,order=2)
#model.append_transformation(tdiff) model.append_transformation(tdiff)
model.fit(dataset[:800]) model.fit(dataset[:800])
cUtil.plot_rules(model, size=[20,20], rules_by_axis=5, columns=1) cUtil.plot_rules(model, size=[20,20], rules_by_axis=5, columns=1)

View File

@ -3,7 +3,7 @@ import numpy as np
from pyFTS.common import Membership, Transformations from pyFTS.common import Membership, Transformations
from pyFTS.models.nonstationary import common, perturbation, partitioners, util from pyFTS.models.nonstationary import common, perturbation, partitioners, util
from pyFTS.models.nonstationary import nsfts, cvfts from pyFTS.models.nonstationary import nsfts, cvfts
from pyFTS.partitioners import Grid from pyFTS.partitioners import Grid, Entropy
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from pyFTS.common import Util as cUtil from pyFTS.common import Util as cUtil
import pandas as pd import pandas as pd
@ -45,23 +45,44 @@ from pyFTS.common import Util
from pyFTS.data import TAIEX from pyFTS.data import TAIEX
taiex = TAIEX.get_data() taiex = TAIEX.get_data()
taiex_diff = tdiff.apply(taiex) #taiex_diff = tdiff.apply(taiex)
train = taiex_diff[:600] train = taiex[:600]
test = taiex_diff[600:1500] test = taiex[600:800]
fs_tmp = Grid.GridPartitioner(data=train, npart=20) #, transformation=tdiff) #fs_tmp = Grid.GridPartitioner(data=train, npart=7, transformation=tdiff)
#fs_tmp = Entropy.EntropyPartitioner(data=train, npart=7, transformation=tdiff)
fs_tmp = Grid.GridPartitioner(data=train, npart=20)
fs = partitioners.SimpleNonStationaryPartitioner(train, fs_tmp) fs = partitioners.SimpleNonStationaryPartitioner(train, fs_tmp)
print(fs) print(fs)
model = cvfts.ConditionalVarianceFTS(partitioner=fs) model = cvfts.ConditionalVarianceFTS(partitioner=fs,memory_window=3)
model.fit(train) model.fit(train)
print(model) print(model)
#tmpp4 = model.predict(test, type='point') #tmpp4 = model.predict(test, type='point')
tmp = model.predict(test, type='interval') #tmp = model.predict(test, type='interval')
#util.plot_sets_conditional(model, test, step=1, tam=[10, 5]) #util.plot_sets_conditional(model, tdiff.apply(test), step=5, size=[10, 5])
#util.plot_sets_conditional(model, test, step=5, size=[10, 5])
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=[10, 5])
axes[0].plot(test[1:], label="Test Data")
forecasts = model.predict(test, type='point')
axes[0].plot(forecasts[:-1], label="CVFTS Forecasts")
handles0, labels0 = axes[0].get_legend_handles_labels()
lgd = axes[0].legend(handles0, labels0, loc=2)
residuals = np.array(test[1:]) - np.array(forecasts[:-1])
axes[1].plot(residuals)
axes[1].set_title("Residuals")
print("fim")