Added the data.artificial.SignalEmulator

This commit is contained in:
Petrônio Cândido 2019-02-20 16:02:07 -03:00
parent fc1f295150
commit 9125582c9c
6 changed files with 228 additions and 30 deletions

View File

@ -24,6 +24,8 @@ class FTS(object):
"""A string with the model name"""
self.detail = kwargs.get('name',"")
"""A string with the model detailed information"""
self.is_wrapper = False
"""Indicates that this model is a wrapper for other(s) method(s)"""
self.is_high_order = False
"""A boolean value indicating if the model support orders greater than 1, default: False"""
self.min_order = 1
@ -313,6 +315,7 @@ class FTS(object):
if 'partitioner' in kwargs:
self.partitioner = kwargs.pop('partitioner')
if not self.is_wrapper:
if (self.sets is None or len(self.sets) == 0) and not self.benchmark_only and not self.is_multivariate:
if self.partitioner is not None:
self.sets = self.partitioner.sets

View File

@ -34,6 +34,83 @@ def generate_gaussian_linear(mu_ini, sigma_ini, mu_inc, sigma_inc, it=100, num=1
return ret
def generate_linear_periodic_gaussian(period, mu_min, sigma_min, mu_max, sigma_max, it=100, num=10, vmin=None, vmax=None):
"""
:param period:
:param mu_min:
:param sigma_min:
:param mu_max:
:param sigma_max:
:param it:
:param num:
:param vmin:
:param vmax:
:return:
"""
if period > num:
raise("The 'period' parameter must be lesser than 'it' parameter")
mu_inc = (mu_max - mu_min)/period
sigma_inc = (sigma_max - sigma_min) / period
mu = mu_min
sigma = sigma_min
ret = []
signal = True
for k in np.arange(0, it):
tmp = np.random.normal(mu, sigma, num)
if vmin is not None:
tmp = np.maximum(np.full(num, vmin), tmp)
if vmax is not None:
tmp = np.minimum(np.full(num, vmax), tmp)
ret.extend(tmp)
if k % period == 0:
signal = not signal
mu += (mu_inc if signal else -mu_inc)
sigma += (sigma_inc if signal else -sigma_inc)
return ret
def generate_senoidal_periodic_gaussian(period, mu_min, sigma_min, mu_max, sigma_max, it=100, num=10, vmin=None, vmax=None):
"""
:param period:
:param mu_min:
:param sigma_min:
:param mu_max:
:param sigma_max:
:param it:
:param num:
:param vmin:
:param vmax:
:return:
"""
mu_range = mu_max - mu_min
sigma_range = sigma_max - sigma_min
mu = mu_min
sigma = sigma_min
ret = []
for k in np.arange(0, it):
tmp = np.random.normal(mu, sigma, num)
if vmin is not None:
tmp = np.maximum(np.full(num, vmin), tmp)
if vmax is not None:
tmp = np.minimum(np.full(num, vmax), tmp)
ret.extend(tmp)
mu += mu_range * np.sin (period * k)
sigma += mu_range * np.sin (period * k)
return ret
def generate_uniform_linear(min_ini, max_ini, min_inc, max_inc, it=100, num=10, vmin=None, vmax=None):
"""
Generate data sampled from Uniform distribution, with constant or linear changing bounds
@ -78,3 +155,125 @@ def random_walk(n=500, type='gaussian'):
return ret
def _append(additive, start, before, new):
if not additive:
before.extend(new)
return before
else:
for k in range(start):
new.insert(0,0)
tmp = np.array(before) + np.array(new)
return tmp
class SignalEmulator(object):
def __init__(self, **kwargs):
super(SignalEmulator, self).__init__()
self.components = []
def stationary_gaussian(self, mu, sigma, **kwargs):
"""
Creates a continuous Gaussian signal with mean mu and variance sigma.
:param mu: mean
:param sigma: variance
:keyword cummulative: If False it cancels the previous signal and start this one, if True
this signal is added to the previous one
:keyword start: lag index to start this signal, the default value is 0
:keyword it: Number of iterations, the default value is 1
:keyword length: Number of samples generated on each iteration, the default value is 100
:keyword vmin: Lower bound value of generated data, the default value is None
:keyword vmax: Upper bound value of generated data, the default value is None
:return: A list of it*num float values
"""
parameters = {'mu': mu, 'sigma': sigma}
self.components.append({'dist': 'gaussian', 'type': 'constant',
'parameters': parameters, 'args': kwargs})
def incremental_gaussian(self, mu, sigma, **kwargs):
"""
Creates an additive gaussian interference on a previous signal
:param mu:
:param sigma:
:keyword cummulative: If False it cancels the previous signal and start this one, if True
this signal is added to the previous one
:keyword start: lag index to start this signal, the default value is 0
:keyword it: Number of iterations, the default value is 1
:keyword length: Number of samples generated on each iteration, the default value is 100
:keyword vmin: Lower bound value of generated data, the default value is None
:keyword vmax: Upper bound value of generated data, the default value is None
:return: A list of it*num float values
"""
parameters = {'mu': mu, 'sigma': sigma}
self.components.append({'dist': 'gaussian', 'type': 'incremental',
'parameters': parameters, 'args': kwargs})
def periodic_gaussian(self, type, period, mu_min, sigma_min, mu_max, sigma_max, **kwargs):
"""
Creates an additive periodic gaussian interference on a previous signal
:param mu:
:param sigma:
:keyword additive: If False it cancels the previous signal and start this one, if True
this signal is added to the previous one
:keyword start: lag index to start this signal, the default value is 0
:keyword it: Number of iterations, the default value is 1
:keyword length: Number of samples generated on each iteration, the default value is 100
:keyword vmin: Lower bound value of generated data, the default value is None
:keyword vmax: Upper bound value of generated data, the default value is None
:return: A list of it*num float values
"""
parameters = {'type':type, 'period':period,
'mu_min': mu_min, 'sigma_min': sigma_min, 'mu_max': mu_max, 'sigma_max': sigma_max}
self.components.append({'dist': 'gaussian', 'type': 'periodic',
'parameters': parameters, 'args': kwargs})
def blip(self, intensity, **kwargs):
"""
:param intensity:
:param kwargs:
:return:
"""
self.components.append({'dist': 'blip', 'type': 'blip', 'parameters': [intensity, kwargs]})
def run(self):
signal = []
last_it = 10
last_num = 10
for ct, component in enumerate(self.components):
parameters = component['parameters']
kwargs = component['args']
additive = kwargs.get('additive', True)
start = kwargs.get('start', 0)
it = kwargs.get('it', last_it)
num = kwargs.get('length', last_num)
vmin = kwargs.get('vmin',None)
vmax = kwargs.get('vmax', None)
if component['type'] == 'constant':
tmp = generate_gaussian_linear(parameters['mu'], parameters['sigma'], 0, 0,
it=it, num=num, vmin=vmin, vmax=vmax)
elif component['type'] == 'incremental':
tmp = generate_gaussian_linear(0, 0, parameters['mu'], parameters['sigma'],
it=num, num=1, vmin=vmin, vmax=vmax)
elif component['type'] == 'periodic':
period = component['period']
mu_min, sigma_min = parameters['mu_min'],parameters['sigma_min']
mu_max, sigma_max = parameters['mu_max'],parameters['sigma_max']
if parameters['type'] == 'senoidal':
tmp = generate_senoidal_periodic_gaussian(period, mu_min, sigma_min, mu_max, sigma_max,
it=num, num=1, vmin=vmin, vmax=vmax)
else:
tmp = generate_linear_periodic_gaussian(period, mu_min, sigma_min, mu_max, sigma_max,
it=num, num=1, vmin=vmin, vmax=vmax)
last_num = num
last_it = it
signal = _append(additive, start, signal, tmp)
return signal

View File

@ -31,6 +31,7 @@ class EnsembleFTS(fts.FTS):
self.shortname = "EnsembleFTS"
self.name = "Ensemble FTS"
self.flrgs = {}
self.is_wrapper = True
self.has_point_forecasting = True
self.has_interval_forecasting = True
self.has_probability_forecasting = True

View File

@ -46,9 +46,10 @@ class IncrementalEnsembleFTS(ensemble.EnsembleFTS):
partitioner = self.partitioner_method(data=data, **self.partitioner_params)
model = self.fts_method(partitioner=partitioner, **self.fts_params)
if self.model.is_high_order:
self.model = self.fts_method(partitioner=partitioner, order=self.order, **self.fts_params)
if model.is_high_order:
model = self.fts_method(partitioner=partitioner, order=self.order, **self.fts_params)
model.fit(data, **kwargs)
if len(self.models) > 0:
self.models.pop(0)
self.models.append(model)

View File

@ -7,15 +7,21 @@ import numpy as np
import pandas as pd
from pyFTS.partitioners import Grid
from pyFTS.common import Transformations
from pyFTS import hofts, song, yu, cheng, ismailefendi, sadaei, hwang
from pyFTS.models import chen
from pyFTS.models.ensemble import ensemble
from pyFTS.models.incremental import IncrementalEnsemble, TimeVariant
os.chdir("/home/petronio/dados/Dropbox/Doutorado/Codigos/")
from pyFTS.data import AirPassengers
diff = Transformations.Differential(1)
passengers = pd.read_csv("DataSets/AirPassengers.csv", sep=",")
passengers = AirPassengers.get_data()
model = IncrementalEnsemble.IncrementalEnsembleFTS(order=2, window_length=20, batch_size=5)
model.fit(passengers[:40])
model.predict(passengers[40:])
'''
passengers = np.array(passengers["Passengers"])
e = ensemble.AllMethodEnsembleFTS(alpha=0.25, point_method="median", interval_method='quantile')
@ -115,5 +121,6 @@ print(_normal)
# distributions=[True,False], save=True, file="pictures/distribution_ahead_arma",
# time_from=60, time_to=10, tam=[12,5])
'''

View File

@ -14,21 +14,8 @@ from pyFTS.benchmarks import benchmarks as bchmk, Measures
from pyFTS.models import chen, yu, cheng, ismailefendi, hofts, pwfts
from pyFTS.common import Transformations, Membership
tdiff = Transformations.Differential(1)
from pyFTS.data import artificial
from pyFTS.data import TAIEX, SP500, NASDAQ, Malaysia, Enrollments
#from pyFTS.data import mackey_glass
#y = mackey_glass.get_data()
from pyFTS.partitioners import Grid
from pyFTS.models import pwfts, tsaur
x = [k for k in np.arange(-2*np.pi, 2*np.pi, 0.5)]
y = [np.sin(k) for k in x]
part = Grid.GridPartitioner(data=y, npart=35)
model = hofts.HighOrderFTS(order=2, partitioner=part)
model.fit(y)
forecasts = model.predict(y, steps_ahead=10)
cd = artificial.SignalEmulator()
cd.stationary_gaussian(10,3,length=100)
cd.incremental_gaussian(0.5,0,start=100,length=200)