diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index be7ce04..d0bc3ab 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/pyFTS.benchmarks.doctree b/docs/build/doctrees/pyFTS.benchmarks.doctree index 0251184..5eebedf 100644 Binary files a/docs/build/doctrees/pyFTS.benchmarks.doctree and b/docs/build/doctrees/pyFTS.benchmarks.doctree differ diff --git a/docs/build/doctrees/pyFTS.common.doctree b/docs/build/doctrees/pyFTS.common.doctree index d8138b8..f86650d 100644 Binary files a/docs/build/doctrees/pyFTS.common.doctree and b/docs/build/doctrees/pyFTS.common.doctree differ diff --git a/docs/build/doctrees/pyFTS.doctree b/docs/build/doctrees/pyFTS.doctree index 4a6d2a6..532ad27 100644 Binary files a/docs/build/doctrees/pyFTS.doctree and b/docs/build/doctrees/pyFTS.doctree differ diff --git a/docs/build/doctrees/pyFTS.models.doctree b/docs/build/doctrees/pyFTS.models.doctree index e4f50b6..33f073c 100644 Binary files a/docs/build/doctrees/pyFTS.models.doctree and b/docs/build/doctrees/pyFTS.models.doctree differ diff --git a/docs/build/doctrees/pyFTS.models.multivariate.doctree b/docs/build/doctrees/pyFTS.models.multivariate.doctree index 297d474..1c0ff2e 100644 Binary files a/docs/build/doctrees/pyFTS.models.multivariate.doctree and b/docs/build/doctrees/pyFTS.models.multivariate.doctree differ diff --git a/docs/build/doctrees/pyFTS.models.seasonal.doctree b/docs/build/doctrees/pyFTS.models.seasonal.doctree index 7ac3fce..5dc3cc7 100644 Binary files a/docs/build/doctrees/pyFTS.models.seasonal.doctree and b/docs/build/doctrees/pyFTS.models.seasonal.doctree differ diff --git a/docs/build/doctrees/pyFTS.partitioners.doctree b/docs/build/doctrees/pyFTS.partitioners.doctree index 8024bc1..dff25d7 100644 Binary files a/docs/build/doctrees/pyFTS.partitioners.doctree and b/docs/build/doctrees/pyFTS.partitioners.doctree differ diff --git a/docs/build/html/_modules/index.html b/docs/build/html/_modules/index.html index 3d2469c..8973f86 100644 --- a/docs/build/html/_modules/index.html +++ b/docs/build/html/_modules/index.html @@ -111,6 +111,8 @@
  • pyFTS.data.mackey_glass
  • pyFTS.data.rossler
  • pyFTS.data.sunspots
  • +
  • pyFTS.hyperparam.GridSearch
  • +
  • pyFTS.hyperparam.Util
  • pyFTS.models.chen
  • pyFTS.models.cheng
  • pyFTS.models.ensemble.ensemble
  • @@ -121,10 +123,12 @@
  • pyFTS.models.incremental.Retrainer
  • pyFTS.models.ismailefendi
  • pyFTS.models.multivariate.FLR
  • +
  • pyFTS.models.multivariate.cmvfts
  • pyFTS.models.multivariate.common
  • pyFTS.models.multivariate.flrg
  • pyFTS.models.multivariate.mvfts
  • pyFTS.models.multivariate.variable
  • +
  • pyFTS.models.multivariate.wmvfts
  • pyFTS.models.nonstationary.common
  • pyFTS.models.nonstationary.cvfts
  • pyFTS.models.nonstationary.flrg
  • diff --git a/docs/build/html/_modules/pyFTS/benchmarks/Measures.html b/docs/build/html/_modules/pyFTS/benchmarks/Measures.html index d646a8a..3cf4918 100644 --- a/docs/build/html/_modules/pyFTS/benchmarks/Measures.html +++ b/docs/build/html/_modules/pyFTS/benchmarks/Measures.html @@ -419,7 +419,10 @@ if not isinstance(forecasts, (list, np.ndarray)): forecasts = [forecasts] - forecasts = np.array(forecasts[:-1]) + if len(forecasts) != len(ndata) - model.max_lag: + forecasts = np.array(forecasts[:-1]) + else: + forecasts = np.array(forecasts) ret.append(np.round(rmse(ndata[model.max_lag:], forecasts), 2)) ret.append(np.round(mape(ndata[model.max_lag:], forecasts), 2)) diff --git a/docs/build/html/_modules/pyFTS/benchmarks/benchmarks.html b/docs/build/html/_modules/pyFTS/benchmarks/benchmarks.html index 01e3a2a..778c367 100644 --- a/docs/build/html/_modules/pyFTS/benchmarks/benchmarks.html +++ b/docs/build/html/_modules/pyFTS/benchmarks/benchmarks.html @@ -93,6 +93,7 @@ from pyFTS.probabilistic import ProbabilityDistribution from pyFTS.common import Transformations from pyFTS.models import song, chen, yu, ismailefendi, sadaei, hofts, pwfts, ifts, cheng, hwang +from pyFTS.models.multivariate import mvfts, wmvfts, cmvfts from pyFTS.models.ensemble import ensemble from pyFTS.benchmarks import Measures, naive, arima, ResidualAnalysis, quantreg, knn from pyFTS.benchmarks import Util as bUtil @@ -131,10 +132,16 @@
    [docs]def get_point_methods(): """Return all FTS methods for point forecasting""" return [song.ConventionalFTS, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS, - cheng.TrendWeightedFTS, sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, hwang.HighOrderFTS, + cheng.TrendWeightedFTS, sadaei.ExponentialyWeightedFTS, + hofts.HighOrderFTS, hofts.WeightedHighOrderFTS, hwang.HighOrderFTS, pwfts.ProbabilisticWeightedFTS]
    +
    [docs]def get_point_multivariate_methods(): + """Return all multivariate FTS methods por point forecasting""" + return [mvfts.MVFTS, wmvfts.WeightedMVFTS, cmvfts.ClusteredMVFTS]
    + +
    [docs]def get_benchmark_interval_methods(): """Return all non FTS methods for point_to_interval forecasting""" return [ arima.ARIMA, quantreg.QuantileRegression]
    diff --git a/docs/build/html/_modules/pyFTS/common/Composite.html b/docs/build/html/_modules/pyFTS/common/Composite.html index 7fca042..9d7c173 100644 --- a/docs/build/html/_modules/pyFTS/common/Composite.html +++ b/docs/build/html/_modules/pyFTS/common/Composite.html @@ -85,12 +85,14 @@ """ Composite Fuzzy Set """ - def __init__(self, name, superset=False): + def __init__(self, name, superset=False, **kwargs): """ Create an empty composite fuzzy set :param name: fuzzy set name """ - super(FuzzySet, self).__init__(name, None, None, None, type='composite') + if 'type' in kwargs: + kwargs.pop('type') + super(FuzzySet, self).__init__(name, None, None, None, type='composite', **kwargs) self.superset = superset if self.superset: self.sets = [] diff --git a/docs/build/html/_modules/pyFTS/common/FuzzySet.html b/docs/build/html/_modules/pyFTS/common/FuzzySet.html index 57389fe..af36e39 100644 --- a/docs/build/html/_modules/pyFTS/common/FuzzySet.html +++ b/docs/build/html/_modules/pyFTS/common/FuzzySet.html @@ -274,10 +274,13 @@ if ordered_sets is None: ordered_sets = set_ordered(fuzzy_sets) - fs = [ordered_sets[ix] - for ix in __binary_search(inst, fuzzy_sets, ordered_sets) - if fuzzy_sets[ordered_sets[ix]].membership(inst) > alpha_cut] - return fs + try: + fs = [ordered_sets[ix] + for ix in __binary_search(inst, fuzzy_sets, ordered_sets) + if fuzzy_sets[ordered_sets[ix]].membership(inst) > alpha_cut] + return fs + except Exception as ex: + raise ex
    [docs]def get_maximum_membership_fuzzyset(inst, fuzzy_sets, ordered_sets=None): diff --git a/docs/build/html/_modules/pyFTS/common/Util.html b/docs/build/html/_modules/pyFTS/common/Util.html index 5a1eac1..dae40e7 100644 --- a/docs/build/html/_modules/pyFTS/common/Util.html +++ b/docs/build/html/_modules/pyFTS/common/Util.html @@ -307,7 +307,6 @@ return model
    -
    [docs]def distributed_train(model, train_method, nodes, fts_method, data, num_batches=10, train_parameters={}, **kwargs): import dispy, dispy.httpd, datetime diff --git a/docs/build/html/_modules/pyFTS/common/fts.html b/docs/build/html/_modules/pyFTS/common/fts.html index f6e7fcc..9baf4b4 100644 --- a/docs/build/html/_modules/pyFTS/common/fts.html +++ b/docs/build/html/_modules/pyFTS/common/fts.html @@ -168,6 +168,9 @@ :keyword distributed: boolean, indicate if the forecasting procedure will be distributed in a dispy cluster :keyword nodes: a list with the dispy cluster nodes addresses :keyword explain: try to explain, step by step, the one-step-ahead point forecasting result given the input data. + :keyword generators: for multivariate methods on multi step ahead forecasting, generators is a dict where the keys + are the variables names (except the target_variable) and the values are lambda functions that + accept one value (the actual value of the variable) and return the next value. :return: a numpy array with the forecasted data """ @@ -261,10 +264,12 @@ :param data: time series data with the minimal length equal to the max_lag of the model :param steps: the number of steps ahead to forecast - :param kwargs: model specific parameters + :keyword start: in the multi step forecasting, the index of the data where to start forecasting :return: a list with the forecasted values """ + + if isinstance(data, np.ndarray): data = data.tolist() diff --git a/docs/build/html/_modules/pyFTS/hyperparam/GridSearch.html b/docs/build/html/_modules/pyFTS/hyperparam/GridSearch.html new file mode 100644 index 0000000..0f530fa --- /dev/null +++ b/docs/build/html/_modules/pyFTS/hyperparam/GridSearch.html @@ -0,0 +1,227 @@ + + + + + + + + + pyFTS.hyperparam.GridSearch — pyFTS 1.2.3 documentation + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Source code for pyFTS.hyperparam.GridSearch

    +
    +from pyFTS.common import Util, Membership
    +from pyFTS.models import hofts
    +from pyFTS.partitioners import Grid, Entropy
    +from pyFTS.benchmarks import Measures
    +from pyFTS.hyperparam import Util as hUtil
    +import numpy as np
    +import dispy
    +from itertools import product
    +
    +
    +
    [docs]def dict_individual(mf, partitioner, partitions, order, lags, alpha_cut): + return { + 'mf': mf, + 'partitioner': partitioner, + 'npart': partitions, + 'alpha': alpha_cut, + 'order': order, + 'lags': lags + }
    + + +
    [docs]def metodo_cluster(individual, train, test): + from pyFTS.common import Util, Membership + from pyFTS.models import hofts + from pyFTS.partitioners import Grid, Entropy + from pyFTS.benchmarks import Measures + + if individual['mf'] == 1: + mf = Membership.trimf + elif individual['mf'] == 2: + mf = Membership.trapmf + elif individual['mf'] == 3 and individual['partitioner'] != 2: + mf = Membership.gaussmf + else: + mf = Membership.trimf + + if individual['partitioner'] == 1: + partitioner = Grid.GridPartitioner(data=train, npart=individual['npart'], func=mf) + elif individual['partitioner'] == 2: + npart = individual['npart'] if individual['npart'] > 10 else 10 + partitioner = Entropy.EntropyPartitioner(data=train, npart=npart, func=mf) + + + model = hofts.HighOrderFTS(partitioner=partitioner, + lags=individual['lags'], + alpha_cut=individual['alpha'], + order=individual['order']) + + model.fit(train) + + rmse, mape, u = Measures.get_point_statistics(test, model) + + return individual, rmse
    + + +
    [docs]def execute(hyperparams, datasetname, train, test, **kwargs): + + nodes = kwargs.get('nodes',['127.0.0.1']) + + individuals = [] + + if 'lags' in hyperparams: + lags = hyperparams.pop('lags') + else: + lags = [k for k in np.arange(50)] + + keys_sorted = [k for k in sorted(hyperparams.keys())] + + index = {} + for k in np.arange(len(keys_sorted)): + index[keys_sorted[k]] = k + + hp_values = [ + [v for v in hyperparams[hp]] + for hp in keys_sorted + ] + + for instance in product(*hp_values): + partitions = instance[index['partitions']] + partitioner = instance[index['partitioner']] + mf = instance[index['mf']] + alpha_cut = instance[index['alpha']] + order = instance[index['order']] + for lag1 in lags: # o é o lag1 + _lags = [lag1] + if order > 1: + for lag2 in lags: # o é o lag1 + _lags2 = [lag1, lag1+lag2] + if order > 2: + for lag3 in lags: # o é o lag1 + _lags3 = [lag1, lag1 + lag2, lag1 + lag2+lag3 ] + individuals.append(dict_individual(mf, partitioner, partitions, order, _lags3, alpha_cut)) + else: + individuals.append( + dict_individual(mf, partitioner, partitions, order, _lags2, alpha_cut)) + else: + individuals.append(dict_individual(mf, partitioner, partitions, order, _lags, alpha_cut)) + + + cluster, http_server = Util.start_dispy_cluster(metodo_cluster, nodes=nodes) + + jobs = [] + + for ind in individuals: + job = cluster.submit(ind, train, test) + jobs.append(job) + + + conn = hUtil.open_hyperparam_db('hyperparam.db') + + for job in jobs: + result, rmse = job() + if job.status == dispy.DispyJob.Finished and result is not None: + print(result) + + record = (datasetname, 'GridSearch', 'HOFTS', None, result['mf'], + result['order'], result['partitioner'], result['npart'], + result['alpha'], str(result['lags']), 'rmse', rmse) + + hUtil.insert_hyperparam(record, conn) + + else: + print(job.exception) + print(job.stdout) + + Util.stop_dispy_cluster(cluster, http_server)
    +
    + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/build/html/_modules/pyFTS/hyperparam/Util.html b/docs/build/html/_modules/pyFTS/hyperparam/Util.html new file mode 100644 index 0000000..9699c13 --- /dev/null +++ b/docs/build/html/_modules/pyFTS/hyperparam/Util.html @@ -0,0 +1,169 @@ + + + + + + + + + pyFTS.hyperparam.Util — pyFTS 1.2.3 documentation + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Source code for pyFTS.hyperparam.Util

    +"""
    +Common facilities for hyperparameter tunning
    +"""
    +
    +import sqlite3
    +
    +
    [docs]def open_hyperparam_db(name): + """ + Open a connection with a Sqlite database designed to store benchmark results. + + :param name: database filenem + :return: a sqlite3 database connection + """ + conn = sqlite3.connect(name) + + #performance optimizations + conn.execute("PRAGMA journal_mode = WAL") + conn.execute("PRAGMA synchronous = NORMAL") + + create_hyperparam_tables(conn) + return conn
    + + +
    [docs]def create_hyperparam_tables(conn): + """ + Create a sqlite3 table designed to store benchmark results. + + :param conn: a sqlite3 database connection + """ + c = conn.cursor() + + c.execute('''CREATE TABLE if not exists hyperparam( + ID integer primary key, Date int, Dataset text, Tag text, + Model text, Transformation text, mf text, 'Order' int, + Partitioner text, Partitions int, alpha real, lags text, + Measure text, Value real)''') + + conn.commit()
    + + +
    [docs]def insert_hyperparam(data, conn): + """ + Insert benchmark data on database + + :param data: a tuple with the benchmark data with format: + + Dataset: Identify on which dataset the dataset was performed + Tag: a user defined word that indentify a benchmark set + Model: FTS model + Transformation: The name of data transformation, if one was used + mf: membership function + Order: the order of the FTS method + Partitioner: UoD partitioning scheme + Partitions: Number of partitions + alpha: alpha cut + lags: lags + Measure: accuracy measure + Value: the measure value + + :param conn: a sqlite3 database connection + :return: + """ + c = conn.cursor() + + c.execute("INSERT INTO hyperparam(Date, Dataset, Tag, Model, " + + "Transformation, mf, 'Order', Partitioner, Partitions, " + + "alpha, lags, Measure, Value) " + + "VALUES(datetime('now'),?,?,?,?,?,?,?,?,?,?,?,?)", data) + conn.commit()
    +
    + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/build/html/_modules/pyFTS/models/hofts.html b/docs/build/html/_modules/pyFTS/models/hofts.html index c956567..74f4391 100644 --- a/docs/build/html/_modules/pyFTS/models/hofts.html +++ b/docs/build/html/_modules/pyFTS/models/hofts.html @@ -110,6 +110,48 @@ return len(self.RHS)
    +
    [docs]class WeightedHighOrderFLRG(flrg.FLRG): + """Weighted High Order Fuzzy Logical Relationship Group""" + + def __init__(self, order, **kwargs): + super(WeightedHighOrderFLRG, self).__init__(order, **kwargs) + self.LHS = [] + self.RHS = {} + self.count = 0.0 + self.strlhs = "" + self.w = None + +
    [docs] def append_rhs(self, fset, **kwargs): + if fset not in self.RHS: + self.RHS[fset] = 1.0 + else: + self.RHS[fset] += 1.0 + self.count += 1.0
    + +
    [docs] def append_lhs(self, c): + self.LHS.append(c)
    + +
    [docs] def weights(self): + if self.w is None: + self.w = np.array([self.RHS[c] / self.count for c in self.RHS.keys()]) + return self.w
    + +
    [docs] def get_midpoint(self, sets): + mp = np.array([sets[c].centroid for c in self.RHS.keys()]) + return mp.dot(self.weights())
    + + def __str__(self): + _str = "" + for k in self.RHS.keys(): + _str += ", " if len(_str) > 0 else "" + _str += k + " (" + str(round(self.RHS[k] / self.count, 3)) + ")" + + return self.get_key() + " -> " + _str + + def __len__(self): + return len(self.RHS)
    + +
    [docs]class HighOrderFTS(fts.FTS): """Conventional High Order Fuzzy Time Series""" def __init__(self, **kwargs): @@ -137,13 +179,19 @@ self.lags = np.arange(1, self.order+1)
    [docs] def generate_lhs_flrg(self, sample, explain=False): + + nsample = [FuzzySet.fuzzyfy(k, partitioner=self.partitioner, mode="sets", alpha_cut=self.alpha_cut) + for k in sample] + + return self.generate_lhs_flrg_fuzzyfied(nsample, explain)
    + +
    [docs] def generate_lhs_flrg_fuzzyfied(self, sample, explain=False): lags = {} flrgs = [] for ct, o in enumerate(self.lags): - lhs = FuzzySet.fuzzyfy(sample[o-1], partitioner=self.partitioner, mode="sets", alpha_cut=self.alpha_cut) - lags[ct] = lhs + lags[ct] = sample[o-1] if explain: print("\t (Lag {}) {} -> {} \n".format(o, sample[o-1], lhs)) @@ -167,24 +215,51 @@
    [docs] def generate_flrg(self, data): l = len(data) for k in np.arange(self.max_lag, l): + lags = {} + if self.dump: print("FLR: " + str(k)) sample = data[k - self.max_lag: k] + print(sample) rhs = FuzzySet.fuzzyfy(data[k], partitioner=self.partitioner, mode="sets", alpha_cut=self.alpha_cut) flrgs = self.generate_lhs_flrg(sample) for flrg in flrgs: + print('key', flrg.get_key()) 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)
    +
    [docs] def generate_flrg_fuzzyfied(self, data): + l = len(data) + for k in np.arange(self.max_lag, l): + if self.dump: print("FLR: " + str(k)) + + sample = data[k - self.max_lag: k] + + + rhs = data[k] + + flrgs = self.generate_lhs_flrg_fuzzyfied(sample) + + for flrg in flrgs: + + 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)
    +
    [docs] def train(self, data, **kwargs): self.configure_lags(**kwargs) - self.generate_flrg(data)
    + if not kwargs.get('fuzzyfied',False): + self.generate_flrg(data) + else: + self.generate_flrg_fuzzyfied(data)
    [docs] def forecast(self, ndata, **kwargs): @@ -202,7 +277,10 @@ if explain: print("Fuzzyfication \n") - flrgs = self.generate_lhs_flrg(ndata[k - self.max_lag: k], explain) + if not kwargs.get('fuzzyfied', False): + flrgs = self.generate_lhs_flrg(ndata[k - self.max_lag: k], explain) + else: + flrgs = self.generate_lhs_flrg_fuzzyfied(ndata[k - self.max_lag: k], explain) if explain: print("Rules:\n") @@ -212,16 +290,15 @@ if flrg.get_key() not in self.flrgs: if len(flrg.LHS) > 0: - mp = self.sets[flrg.LHS[-1]].centroid + mp = self.partitioner.sets[flrg.LHS[-1]].centroid tmp.append(mp) if explain: print("\t {} -> {} (Naïve)\t Midpoint: {}\n".format(str(flrg.LHS), flrg.LHS[-1], mp)) - else: flrg = self.flrgs[flrg.get_key()] - mp = flrg.get_midpoint(self.sets) + mp = flrg.get_midpoint(self.partitioner.sets) tmp.append(mp) if explain: @@ -234,6 +311,41 @@ print("Deffuzyfied value: {} \n".format(final)) return ret
    + + +
    [docs]class WeightedHighOrderFTS(HighOrderFTS): + """Weighted High Order Fuzzy Time Series""" + def __init__(self, **kwargs): + super(WeightedHighOrderFTS, self).__init__(**kwargs) + self.name = "Weighted High Order FTS" + self.shortname = "WHOFTS" + +
    [docs] def generate_lhs_flrg_fuzzyfied(self, sample, explain=False): + lags = {} + + flrgs = [] + + for ct, o in enumerate(self.lags): + lags[ct] = sample[o-1] + + if explain: + print("\t (Lag {}) {} -> {} \n".format(o, sample[o-1], lhs)) + + root = tree.FLRGTreeNode(None) + + tree.build_tree_without_order(root, lags, 0) + + # Trace the possible paths + for p in root.paths(): + flrg = WeightedHighOrderFLRG(self.order) + path = list(reversed(list(filter(None.__ne__, p)))) + + for lhs in path: + flrg.append_lhs(lhs) + + flrgs.append(flrg) + + return flrgs
    diff --git a/docs/build/html/_modules/pyFTS/models/multivariate/cmvfts.html b/docs/build/html/_modules/pyFTS/models/multivariate/cmvfts.html new file mode 100644 index 0000000..d0a5c22 --- /dev/null +++ b/docs/build/html/_modules/pyFTS/models/multivariate/cmvfts.html @@ -0,0 +1,183 @@ + + + + + + + + + pyFTS.models.multivariate.cmvfts — pyFTS 1.2.3 documentation + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Source code for pyFTS.models.multivariate.cmvfts

    +
    +import numpy as np
    +from pyFTS.common import FuzzySet, FLR, fts, flrg
    +from pyFTS.models import hofts
    +from pyFTS.models.multivariate import mvfts, grid, common
    +
    +
    +
    [docs]class ClusteredMVFTS(mvfts.MVFTS): + """ + Meta model for multivariate, high order, clustered multivariate FTS + """ + def __init__(self, **kwargs): + super(ClusteredMVFTS, self).__init__(**kwargs) + + self.cluster_method = kwargs.get('cluster_method', grid.GridCluster) + """The cluster method to be called when a new model is build""" + self.cluster_params = kwargs.get('cluster_params', {}) + """The cluster method parameters""" + self.cluster = None + """The most recent trained clusterer""" + + self.fts_method = kwargs.get('fts_method', hofts.WeightedHighOrderFTS) + """The FTS method to be called when a new model is build""" + self.fts_params = kwargs.get('fts_params', {}) + """The FTS method specific parameters""" + self.model = None + """The most recent trained model""" + self.knn = kwargs.get('knn', 2) + + self.is_high_order = True + + self.order = kwargs.get("order", 2) + self.lags = kwargs.get("lags", None) + self.alpha_cut = kwargs.get('alpha_cut', 0.25) + + self.shortname = "ClusteredMVFTS" + self.name = "Clustered Multivariate FTS" + +
    [docs] def fuzzyfy(self,data): + ndata = [] + for ct in range(1, len(data.index)+1): + ix = data.index[ct - 1] + data_point = self.format_data(data.loc[ix]) + ndata.append(common.fuzzyfy_instance_clustered(data_point, self.cluster, self.alpha_cut)) + + return ndata
    + + +
    [docs] def train(self, data, **kwargs): + + self.cluster = self.cluster_method(data=data, mvfts=self, neighbors=self.knn) + + self.model = self.fts_method(partitioner=self.cluster, **self.fts_params) + if self.model.is_high_order: + self.model.order = self.model = self.fts_method(partitioner=self.cluster, + order=self.order, **self.fts_params) + + ndata = self.fuzzyfy(data) + + self.model.train(ndata, fuzzyfied=True)
    + +
    [docs] def forecast(self, ndata, **kwargs): + + ndata = self.fuzzyfy(ndata) + + return self.model.forecast(ndata, fuzzyfied=True, **kwargs)
    + + def __str__(self): + """String representation of the model""" + + tmp = self.model.shortname + ":\n" + for r in self.model.flrgs: + tmp = tmp + str(self.model.flrgs[r]) + "\n" + return tmp + + def __len__(self): + """ + The length (number of rules) of the model + + :return: number of rules + """ + return len(self.model)
    + +
    + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/build/html/_modules/pyFTS/models/multivariate/common.html b/docs/build/html/_modules/pyFTS/models/multivariate/common.html index ac86f4e..21d31c7 100644 --- a/docs/build/html/_modules/pyFTS/models/multivariate/common.html +++ b/docs/build/html/_modules/pyFTS/models/multivariate/common.html @@ -74,13 +74,56 @@

    Source code for pyFTS.models.multivariate.common

     import numpy as np
     import pandas as pd
    -from pyFTS.common import FuzzySet
    +from pyFTS.common import FuzzySet, Composite
    +
    +
    +
    [docs]class MultivariateFuzzySet(Composite.FuzzySet): + """ + Multivariate Composite Fuzzy Set + """ + def __init__(self, name, **kwargs): + """ + Create an empty composite fuzzy set + :param name: fuzzy set name + """ + super(MultivariateFuzzySet, self).__init__(name) + self.sets = {} + self.target_variable = kwargs.get('target_variable',None) + +
    [docs] def append_set(self, variable, set): + """ + Appends a new fuzzy set from a new variable + + :param variable: an multivariate.variable instance + :param set: an common.FuzzySet instance + """ + self.sets[variable] = set + + if variable == self.target_variable.name: + self.centroid = set.centroid
    + +
    [docs] def membership(self, x): + mv = [] + for var in self.sets.keys(): + data = x[var] + mv.append(self.sets[var].membership(data)) + return np.nanmin(mv)
    + +
    [docs]def fuzzyfy_instance(data_point, var): fsets = FuzzySet.fuzzyfy(data_point, var.partitioner, mode='sets', method='fuzzy', alpha_cut=var.alpha_cut) return [(var.name, fs) for fs in fsets]
    +
    [docs]def fuzzyfy_instance_clustered(data_point, cluster, alpha_cut=0.0): + fsets = [] + for fset in cluster.knn(data_point): + if cluster.sets[fset].membership(data_point) > alpha_cut: + fsets.append(fset) + return fsets
    + +
    diff --git a/docs/build/html/_modules/pyFTS/models/multivariate/mvfts.html b/docs/build/html/_modules/pyFTS/models/multivariate/mvfts.html index d4a1b2c..aa7b0ce 100644 --- a/docs/build/html/_modules/pyFTS/models/multivariate/mvfts.html +++ b/docs/build/html/_modules/pyFTS/models/multivariate/mvfts.html @@ -85,7 +85,7 @@ Multivariate extension of Chen's ConventionalFTS method """ def __init__(self, **kwargs): - super(MVFTS, self).__init__(order=1, **kwargs) + super(MVFTS, self).__init__(**kwargs) self.explanatory_variables = [] self.target_variable = None self.flrgs = {} @@ -187,15 +187,12 @@ for flr in flrs: flrg = mvflrg.FLRG(lhs=flr.LHS) if flrg.get_key() not in self.flrgs: - #print('hit') mvs.append(0.) mps.append(0.) else: mvs.append(self.flrgs[flrg.get_key()].get_membership(self.format_data(data_point), self.explanatory_variables)) mps.append(self.flrgs[flrg.get_key()].get_midpoint(self.target_variable.partitioner.sets)) - #print('mv', mvs) - #print('mp', mps) mv = np.array(mvs) mp = np.array(mps) @@ -205,6 +202,44 @@ params=data[self.target_variable.data_label].values) return ret +
    [docs] def forecast_ahead(self, data, steps, **kwargs): + generators = kwargs.get('generators',None) + start = kwargs.get('start', 0) + + if generators is None: + raise Exception('You must provide parameter \'generators\'! generators is a dict where the keys' + + ' are the variables names (except the target_variable) and the values are ' + + 'lambda functions that accept one value (the actual value of the variable) ' + ' and return the next value.') + + ndata = self.apply_transformations(data) + + ret = [] + for k in np.arange(0, steps): + ix = ndata.index[-self.max_lag:] + sample = ndata.loc[ix] + tmp = self.forecast(sample, **kwargs) + + if isinstance(tmp, (list, np.ndarray)): + tmp = tmp[-1] + + ret.append(tmp) + + last_data_point = sample.loc[sample.index[-1]] + + new_data_point = {} + + for var in self.explanatory_variables: + if var.name != self.target_variable.name: + new_data_point[var.data_label] = generators[var.name](last_data_point[var.data_label]) + + new_data_point[self.target_variable.data_label] = tmp + + ndata = ndata.append(new_data_point, ignore_index=True) + + return ret
    + +
    [docs] def clone_parameters(self, model): super(MVFTS, self).clone_parameters(model) diff --git a/docs/build/html/_modules/pyFTS/models/multivariate/wmvfts.html b/docs/build/html/_modules/pyFTS/models/multivariate/wmvfts.html new file mode 100644 index 0000000..1b0b886 --- /dev/null +++ b/docs/build/html/_modules/pyFTS/models/multivariate/wmvfts.html @@ -0,0 +1,168 @@ + + + + + + + + + pyFTS.models.multivariate.wmvfts — pyFTS 1.2.3 documentation + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +

    Source code for pyFTS.models.multivariate.wmvfts

    +from pyFTS.common import fts, FuzzySet, FLR, Membership, tree
    +from pyFTS.partitioners import Grid
    +from pyFTS.models.multivariate import mvfts, FLR as MVFLR, common, flrg as mvflrg
    +
    +import numpy as np
    +import pandas as pd
    +
    +
    +
    [docs]class WeightedFLRG(mvflrg.FLRG): + """ + Weighted Multivariate Fuzzy Logical Rule Group + """ + + def __init__(self, **kwargs): + super(WeightedFLRG, self).__init__(**kwargs) + self.order = kwargs.get('order', 1) + self.LHS = kwargs.get('lhs', {}) + self.RHS = {} + self.count = 0.0 + self.w = None + +
    [docs] def append_rhs(self, fset, **kwargs): + if fset not in self.RHS: + self.RHS[fset] = 1.0 + else: + self.RHS[fset] += 1.0 + self.count += 1.0
    + +
    [docs] def weights(self): + if self.w is None: + self.w = np.array([self.RHS[c] / self.count for c in self.RHS.keys()]) + return self.w
    + +
    [docs] def get_midpoint(self, sets): + mp = np.array([sets[c].centroid for c in self.RHS.keys()]) + return mp.dot(self.weights())
    + + + def __str__(self): + _str = "" + for k in self.RHS.keys(): + _str += ", " if len(_str) > 0 else "" + _str += k + " (" + str(round( self.RHS[k] / self.count, 3)) + ")" + + return self.get_key() + " -> " + _str
    + + +
    [docs]class WeightedMVFTS(mvfts.MVFTS): + """ + Weighted Multivariate FTS + """ + def __init__(self, **kwargs): + super(WeightedMVFTS, self).__init__(order=1, **kwargs) + self.explanatory_variables = [] + self.target_variable = None + self.flrgs = {} + self.is_multivariate = True + self.shortname = "WeightedMVFTS" + self.name = "Weighted Multivariate FTS" + +
    [docs] def generate_flrg(self, flrs): + for flr in flrs: + flrg = WeightedFLRG(lhs=flr.LHS) + + if flrg.get_key() not in self.flrgs: + self.flrgs[flrg.get_key()] = flrg + + self.flrgs[flrg.get_key()].append_rhs(flr.RHS)
    +
    + +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/docs/build/html/_modules/pyFTS/models/seasonal/common.html b/docs/build/html/_modules/pyFTS/models/seasonal/common.html index 3867da7..3c30703 100644 --- a/docs/build/html/_modules/pyFTS/models/seasonal/common.html +++ b/docs/build/html/_modules/pyFTS/models/seasonal/common.html @@ -163,10 +163,9 @@ def __init__(self, datepart, name, mf, parameters, centroid, alpha=1.0, **kwargs): super(FuzzySet, self).__init__(name, mf, parameters, centroid, alpha, - type=kwargs.get('type', 'seasonal'), **kwargs) self.datepart = datepart - self.type = 'seasonal' + self.type = kwargs.get('type', 'seasonal')
    [docs] def transform(self, x): if self.type == 'seasonal': diff --git a/docs/build/html/_modules/pyFTS/models/seasonal/partitioner.html b/docs/build/html/_modules/pyFTS/models/seasonal/partitioner.html index 411e4a9..fd04edd 100644 --- a/docs/build/html/_modules/pyFTS/models/seasonal/partitioner.html +++ b/docs/build/html/_modules/pyFTS/models/seasonal/partitioner.html @@ -104,6 +104,8 @@ self.min = tmp self.max = self.season.value + tmp + self.type = kwargs.get('type','seasonal') + self.sets = self.build(None) if self.ordered_sets is None and self.setnames is not None: @@ -114,7 +116,7 @@
    [docs] def build(self, data): sets = {} - kwargs = {'variable': self.variable} + kwargs = {'variable': self.variable, 'type': self.type } if self.season == DateTime.year: dlen = (self.max - self.min) @@ -128,7 +130,7 @@ set_name = self.get_name(count) if self.membership_function == Membership.trimf: if c == self.min: - tmp = Composite(set_name, superset=True) + tmp = Composite(set_name, superset=True, **kwargs) tmp.append_set(FuzzySet(self.season, set_name, Membership.trimf, [self.season.value - pl2, self.season.value, self.season.value + 0.0000001], self.season.value, alpha=.5, @@ -139,7 +141,7 @@ tmp.centroid = c sets[set_name] = tmp elif c == self.max - partlen: - tmp = Composite(set_name, superset=True) + tmp = Composite(set_name, superset=True, **kwargs) tmp.append_set(FuzzySet(self.season, set_name, Membership.trimf, [0.0000001, 0.0, pl2], 0.0, alpha=.5, diff --git a/docs/build/html/_modules/pyFTS/partitioners/Entropy.html b/docs/build/html/_modules/pyFTS/partitioners/Entropy.html index b6c514b..2670897 100644 --- a/docs/build/html/_modules/pyFTS/partitioners/Entropy.html +++ b/docs/build/html/_modules/pyFTS/partitioners/Entropy.html @@ -114,7 +114,7 @@
    [docs]def bestSplit(data, npart): if len(data) < 2: - return None + return [] count = 1 ndata = list(set(np.array(data).flatten())) ndata.sort() diff --git a/docs/build/html/_modules/pyFTS/partitioners/partitioner.html b/docs/build/html/_modules/pyFTS/partitioners/partitioner.html index 0f0672b..c4061eb 100644 --- a/docs/build/html/_modules/pyFTS/partitioners/partitioner.html +++ b/docs/build/html/_modules/pyFTS/partitioners/partitioner.html @@ -101,7 +101,9 @@ """data transformation to be applied on data""" self.indexer = kwargs.get('indexer', None) self.variable = kwargs.get('variable', None) + """In a multivariate context, the variable that contains this partitioner""" self.type = kwargs.get('type', 'common') + """The type of fuzzy sets that are generated by this partitioner""" self.ordered_sets = None if kwargs.get('preprocess',True): diff --git a/docs/build/html/_sources/pyFTS.hyperparam.rst.txt b/docs/build/html/_sources/pyFTS.hyperparam.rst.txt new file mode 100644 index 0000000..14d6d15 --- /dev/null +++ b/docs/build/html/_sources/pyFTS.hyperparam.rst.txt @@ -0,0 +1,31 @@ +pyFTS.hyperparam package +======================== + +Module contents +--------------- + +.. automodule:: pyFTS.hyperparam + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +pyFTS.hyperparam.Util module +----------------------------- + +.. automodule:: pyFTS.hyperparam.Util + :members: + :undoc-members: + :show-inheritance: + +pyFTS.hyperparam.GridSearch module +---------------------------------- + +.. automodule:: pyFTS.hyperparam.GridSearch + :members: + :undoc-members: + :show-inheritance: + + diff --git a/docs/build/html/_sources/pyFTS.models.multivariate.rst.txt b/docs/build/html/_sources/pyFTS.models.multivariate.rst.txt index 44d9ff4..64ada4d 100644 --- a/docs/build/html/_sources/pyFTS.models.multivariate.rst.txt +++ b/docs/build/html/_sources/pyFTS.models.multivariate.rst.txt @@ -29,6 +29,14 @@ pyFTS.models.multivariate.common module :undoc-members: :show-inheritance: +pyFTS.models.multivariate.variable module +----------------------------------------- + +.. automodule:: pyFTS.models.multivariate.variable + :members: + :undoc-members: + :show-inheritance: + pyFTS.models.multivariate.flrg module ------------------------------------- @@ -44,19 +52,19 @@ pyFTS.models.multivariate.mvfts module :members: :undoc-members: :show-inheritance: + +pyFTS.models.multivariate.wmvfts module +--------------------------------------- -pyFTS.models.multivariate.variable module ------------------------------------------ - -.. automodule:: pyFTS.models.multivariate.variable +.. automodule:: pyFTS.models.multivariate.wmvfts :members: :undoc-members: :show-inheritance: -pyFTS.models.multivariate.wmvfts module --------------------------------------- +pyFTS.models.multivariate.cmvfts module +--------------------------------------- -.. automodule:: pyFTS.models.multivariate.mvfts +.. automodule:: pyFTS.models.multivariate.cmvfts :members: :undoc-members: :show-inheritance: diff --git a/docs/build/html/_sources/pyFTS.partitioners.rst.txt b/docs/build/html/_sources/pyFTS.partitioners.rst.txt index 76fbf18..e2364c4 100644 --- a/docs/build/html/_sources/pyFTS.partitioners.rst.txt +++ b/docs/build/html/_sources/pyFTS.partitioners.rst.txt @@ -61,7 +61,7 @@ pyFTS.partitioners.Huarng module :show-inheritance: pyFTS.partitioners.Singleton module --------------------------------- +----------------------------------- .. automodule:: pyFTS.partitioners.Singleton :members: diff --git a/docs/build/html/_sources/pyFTS.rst.txt b/docs/build/html/_sources/pyFTS.rst.txt index 707f7f7..c3fd9db 100644 --- a/docs/build/html/_sources/pyFTS.rst.txt +++ b/docs/build/html/_sources/pyFTS.rst.txt @@ -9,6 +9,7 @@ Subpackages pyFTS.benchmarks pyFTS.common pyFTS.data + pyFTS.hyperparam pyFTS.models pyFTS.partitioners pyFTS.probabilistic diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html index 748ff5b..e1d2863 100644 --- a/docs/build/html/genindex.html +++ b/docs/build/html/genindex.html @@ -139,6 +139,8 @@
  • append_lhs() (pyFTS.models.hofts.HighOrderFLRG method)
  • +
    +

    pyFTS.hyperparam.GridSearch module

    +
    +
    +pyFTS.hyperparam.GridSearch.dict_individual(mf, partitioner, partitions, order, lags, alpha_cut)[source]
    +
    + +
    +
    +pyFTS.hyperparam.GridSearch.execute(hyperparams, datasetname, train, test, **kwargs)[source]
    +
    + +
    +
    +pyFTS.hyperparam.GridSearch.metodo_cluster(individual, train, test)[source]
    +
    + +
    +
    + + +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/docs/build/html/pyFTS.models.html b/docs/build/html/pyFTS.models.html index 8a4390e..8fe5ad3 100644 --- a/docs/build/html/pyFTS.models.html +++ b/docs/build/html/pyFTS.models.html @@ -29,7 +29,7 @@ - +