diff --git a/benchmarks/ResidualAnalysis.py b/benchmarks/ResidualAnalysis.py index 4334a7f..9265619 100644 --- a/benchmarks/ResidualAnalysis.py +++ b/benchmarks/ResidualAnalysis.py @@ -1,6 +1,8 @@ #!/usr/bin/python # -*- coding: utf8 -*- +"""Residual Analysis methods""" + import numpy as np import pandas as pd import matplotlib as plt @@ -11,15 +13,28 @@ from scipy import stats def residuals(targets, forecasts, order=1): + """First order residuals""" return np.array(targets[order:]) - np.array(forecasts[:-1]) def ChiSquared(q,h): + """ + Chi-Squared value + :param q: + :param h: + :return: + """ p = stats.chi2.sf(q, h) return p def compareResiduals(data, models): + """ + Compare residual's statistics of several models + :param data: + :param models: + :return: + """ ret = "Model & Order & Mean & STD & Box-Pierce & Box-Ljung & P-value \\\\ \n" for mfts in models: forecasts = mfts.forecast(data) @@ -40,7 +55,15 @@ def compareResiduals(data, models): def plotResiduals(targets, models, tam=[8, 8], save=False, file=None): - + """ + Plot residuals and statistics + :param targets: + :param models: + :param tam: + :param save: + :param file: + :return: + """ fig, axes = plt.subplots(nrows=len(models), ncols=3, figsize=tam) c = 0 for mfts in models: diff --git a/benchmarks/Util.py b/benchmarks/Util.py index 445dc63..5742ae1 100644 --- a/benchmarks/Util.py +++ b/benchmarks/Util.py @@ -1,3 +1,7 @@ +""" +Benchmark utility functions +""" + import numpy as np import pandas as pd from copy import deepcopy @@ -5,6 +9,19 @@ from pyFTS.common import Util def save_dataframe_point(experiments, file, objs, rmse, save, sintetic, smape, times, u): + """ + Create a dataframe to store the benchmark results + :param experiments: dictionary with the execution results + :param file: + :param objs: + :param rmse: + :param save: + :param sintetic: + :param smape: + :param times: + :param u: + :return: + """ ret = [] if sintetic: diff --git a/benchmarks/distributed_benchmarks.py b/benchmarks/distributed_benchmarks.py index c7ec333..0ca3ec3 100644 --- a/benchmarks/distributed_benchmarks.py +++ b/benchmarks/distributed_benchmarks.py @@ -23,6 +23,17 @@ from pyFTS.benchmarks import benchmarks, parallel_benchmarks, Util as bUtil def run_point(mfts, partitioner, train_data, test_data, window_key=None, transformation=None, indexer=None): + """ + Point forecast benchmark function to be executed on cluster nodes + :param mfts: FTS model + :param partitioner: Universe of Discourse partitioner + :param train_data: data used to train the model + :param test_data: ata used to test the model + :param window_key: id of the sliding window + :param transformation: data transformation + :param indexer: seasonal indexer + :return: a dictionary with the benchmark results + """ import time from pyFTS import yu,chen,hofts,ifts,pwfts,ismailefendi,sadaei from pyFTS.partitioners import Grid, Entropy, FCM @@ -59,6 +70,25 @@ def run_point(mfts, partitioner, train_data, test_data, window_key=None, transfo def point_sliding_window(data, windowsize, train=0.8, models=None, partitioners=[Grid.GridPartitioner], partitions=[10], max_order=3, transformation=None, indexer=None, dump=False, save=False, file=None, sintetic=False,nodes=None, depends=None): + """ + Distributed sliding window benchmarks for FTS point forecasters + :param data: + :param windowsize: size of sliding window + :param train: percentual of sliding window data used to train the models + :param models: FTS point forecasters + :param partitioners: Universe of Discourse partitioner + :param partitions: the max number of partitions on the Universe of Discourse + :param max_order: the max order of the models (for high order models) + :param transformation: data transformation + :param indexer: seasonal indexer + :param dump: + :param save: save results + :param file: file path to save the results + :param sintetic: if true only the average and standard deviation of the results + :param nodes: list of cluster nodes to distribute tasks + :param depends: list of module dependencies + :return: DataFrame with the results + """ cluster = dispy.JobCluster(run_point, nodes=nodes) #, depends=dependencies) @@ -143,6 +173,17 @@ def point_sliding_window(data, windowsize, train=0.8, models=None, partitioners= def run_interval(mfts, partitioner, train_data, test_data, transformation=None, indexer=None): + """ + Interval forecast benchmark function to be executed on cluster nodes + :param mfts: FTS model + :param partitioner: Universe of Discourse partitioner + :param train_data: data used to train the model + :param test_data: ata used to test the model + :param window_key: id of the sliding window + :param transformation: data transformation + :param indexer: seasonal indexer + :return: a dictionary with the benchmark results + """ import time from pyFTS import hofts,ifts,pwfts from pyFTS.partitioners import Grid, Entropy, FCM @@ -178,6 +219,25 @@ def run_interval(mfts, partitioner, train_data, test_data, transformation=None, def interval_sliding_window(data, windowsize, train=0.8, models=None, partitioners=[Grid.GridPartitioner], partitions=[10], max_order=3, transformation=None, indexer=None, dump=False, save=False, file=None, sintetic=False,nodes=None, depends=None): + """ + Distributed sliding window benchmarks for FTS interval forecasters + :param data: + :param windowsize: size of sliding window + :param train: percentual of sliding window data used to train the models + :param models: FTS point forecasters + :param partitioners: Universe of Discourse partitioner + :param partitions: the max number of partitions on the Universe of Discourse + :param max_order: the max order of the models (for high order models) + :param transformation: data transformation + :param indexer: seasonal indexer + :param dump: + :param save: save results + :param file: file path to save the results + :param sintetic: if true only the average and standard deviation of the results + :param nodes: list of cluster nodes to distribute tasks + :param depends: list of module dependencies + :return: DataFrame with the results + """ cluster = dispy.JobCluster(run_point, nodes=nodes) #, depends=dependencies) diff --git a/chen.py b/chen.py index 18853b2..47ccacd 100644 --- a/chen.py +++ b/chen.py @@ -4,6 +4,7 @@ from pyFTS import fts class ConventionalFLRG(object): + """First Order Conventional Fuzzy Logical Relationship Group""" def __init__(self, LHS): self.LHS = LHS self.RHS = set() @@ -25,6 +26,7 @@ class ConventionalFLRG(object): class ConventionalFTS(fts.FTS): + """Conventional Fuzzy Time Series""" def __init__(self, name, **kwargs): super(ConventionalFTS, self).__init__(1, "CFTS " + name) self.name = "Conventional FTS" diff --git a/cheng.py b/cheng.py index 6617005..97c92a9 100644 --- a/cheng.py +++ b/cheng.py @@ -4,6 +4,7 @@ from pyFTS import fts, yu class TrendWeightedFLRG(yu.WeightedFTS): + """First Order Trend Weighted Fuzzy Logical Relationship Group""" def __init__(self, LHS, **kwargs): super(TrendWeightedFTS, self).__init__(LHS) @@ -31,6 +32,7 @@ class TrendWeightedFLRG(yu.WeightedFTS): class TrendWeightedFTS(yu.WeightedFTS): + """First Order Trend Weighted Fuzzy Time Series""" def __init__(self, name, **kwargs): super(TrendWeightedFTS, self).__init__(1, "TWFTS " + name) self.name = "Trend Weighted FTS" diff --git a/hofts.py b/hofts.py index f55049f..14776b9 100644 --- a/hofts.py +++ b/hofts.py @@ -4,6 +4,7 @@ from pyFTS import fts class HighOrderFLRG(object): + """Conventional High Order Fuzzy Logical Relationship Group""" def __init__(self, order): self.LHS = [] self.RHS = {} @@ -39,6 +40,7 @@ class HighOrderFLRG(object): class HighOrderFTS(fts.FTS): + """Conventional High Order Fuzzy Time Series""" def __init__(self, name, **kwargs): super(HighOrderFTS, self).__init__(1, "HOFTS" + name) self.name = "High Order FTS" diff --git a/ifts.py b/ifts.py index 34145f0..67b8c2d 100644 --- a/ifts.py +++ b/ifts.py @@ -7,6 +7,7 @@ from pyFTS import hofts, fts, tree class IntervalFTS(hofts.HighOrderFTS): + """High Order Interval Fuzzy Time Series""" def __init__(self, name, **kwargs): super(IntervalFTS, self).__init__(order=1, name="IFTS " + name) self.shortname = "IFTS " + name diff --git a/ismailefendi.py b/ismailefendi.py index 1e0fa6a..d5658de 100644 --- a/ismailefendi.py +++ b/ismailefendi.py @@ -4,6 +4,7 @@ from pyFTS import fts class ImprovedWeightedFLRG(object): + """First Order Improved Weighted Fuzzy Logical Relationship Group""" def __init__(self, LHS): self.LHS = LHS self.RHS = {} @@ -33,6 +34,7 @@ class ImprovedWeightedFLRG(object): class ImprovedWeightedFTS(fts.FTS): + """First Order Improved Weighted Fuzzy Time Series""" def __init__(self, name, **kwargs): super(ImprovedWeightedFTS, self).__init__(1, "IWFTS " + name) self.name = "Improved Weighted FTS" diff --git a/partitioners/CMeans.py b/partitioners/CMeans.py index e921395..72030c3 100644 --- a/partitioners/CMeans.py +++ b/partitioners/CMeans.py @@ -6,7 +6,7 @@ from pyFTS.common import FuzzySet, Membership from pyFTS.partitioners import partitioner -def distancia(x, y): +def distance(x, y): if isinstance(x, list): tmp = functools.reduce(operator.add, [(x[k] - y[k]) ** 2 for k in range(0, len(x))]) else: @@ -38,7 +38,7 @@ def c_means(k, dados, tam): grupotmp = grupos[inst_count] for grupo in centroides: - tmp = distancia(instancia, grupo) + tmp = distance(instancia, grupo) if tmp < dist: dist = tmp # associa a a centroide de menor distância à instância @@ -76,6 +76,7 @@ def c_means(k, dados, tam): return centroides + class CMeansPartitioner(partitioner.Partitioner): def __init__(self, data, npart, func = Membership.trimf, transformation=None): super(CMeansPartitioner, self).__init__("CMeans", data, npart, func=func, transformation=transformation) diff --git a/partitioners/Entropy.py b/partitioners/Entropy.py index d300748..fd3048a 100644 --- a/partitioners/Entropy.py +++ b/partitioners/Entropy.py @@ -78,6 +78,7 @@ def bestSplit(data, npart): class EntropyPartitioner(partitioner.Partitioner): + """Huarng Entropy Partitioner""" def __init__(self, data, npart, func = Membership.trimf, transformation=None): super(EntropyPartitioner, self).__init__("Entropy", data, npart, func=func, transformation=transformation) diff --git a/partitioners/FCM.py b/partitioners/FCM.py index 1cc5428..d4a09d8 100644 --- a/partitioners/FCM.py +++ b/partitioners/FCM.py @@ -101,6 +101,9 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001): class FCMPartitioner(partitioner.Partitioner): + """ + + """ def __init__(self, data,npart,func = Membership.trimf, transformation=None): super(FCMPartitioner, self).__init__("FCM", data, npart, func=func, transformation=transformation) diff --git a/partitioners/Grid.py b/partitioners/Grid.py index de8159a..47ff125 100644 --- a/partitioners/Grid.py +++ b/partitioners/Grid.py @@ -7,6 +7,7 @@ from pyFTS.partitioners import partitioner class GridPartitioner(partitioner.Partitioner): + """Even Length Grid Partitioner""" def __init__(self, data, npart, func = Membership.trimf, transformation=None): super(GridPartitioner, self).__init__("Grid", data, npart, func=func, transformation=transformation) diff --git a/partitioners/Huarng.py b/partitioners/Huarng.py index 441050d..3b91a8c 100644 --- a/partitioners/Huarng.py +++ b/partitioners/Huarng.py @@ -11,6 +11,7 @@ from pyFTS.partitioners import partitioner class HuarngPartitioner(partitioner.Partitioner): + """Huarng Empirical Partitioner""" def __init__(self, data,npart,func = Membership.trimf, transformation=None): super(HuarngPartitioner, self).__init__("Huarng", data, npart, func=func, transformation=transformation) diff --git a/pwfts.py b/pwfts.py index 6107cb7..9bf6ed3 100644 --- a/pwfts.py +++ b/pwfts.py @@ -10,6 +10,7 @@ from pyFTS import hofts, ifts, tree class ProbabilisticWeightedFLRG(hofts.HighOrderFLRG): + """High Order Probabilistic Weighted Fuzzy Logical Relationship Group""" def __init__(self, order): super(ProbabilisticWeightedFLRG, self).__init__(order) self.RHS = {} @@ -42,6 +43,7 @@ class ProbabilisticWeightedFLRG(hofts.HighOrderFLRG): class ProbabilisticWeightedFTS(ifts.IntervalFTS): + """High Order Probabilistic Weighted Fuzzy Time Series""" def __init__(self, name, **kwargs): super(ProbabilisticWeightedFTS, self).__init__(order=1, name=name) self.shortname = "PWFTS " + name diff --git a/sadaei.py b/sadaei.py index 57198fe..eb9b9b8 100644 --- a/sadaei.py +++ b/sadaei.py @@ -4,6 +4,7 @@ from pyFTS import fts class ExponentialyWeightedFLRG(object): + """First Order Exponentialy Weighted Fuzzy Logical Relationship Group""" def __init__(self, LHS, c): self.LHS = LHS self.RHS = [] @@ -37,6 +38,7 @@ class ExponentialyWeightedFLRG(object): class ExponentialyWeightedFTS(fts.FTS): + """First Order Exponentialy Weighted Fuzzy Time Series""" def __init__(self, name, **kwargs): super(ExponentialyWeightedFTS, self).__init__(1, "EWFTS") self.name = "Exponentialy Weighted FTS" diff --git a/sfts.py b/sfts.py index e8c3d4d..982c65c 100644 --- a/sfts.py +++ b/sfts.py @@ -4,6 +4,7 @@ from pyFTS import fts class SeasonalFLRG(FLR.FLR): + """First Order Seasonal Fuzzy Logical Relationship Group""" def __init__(self, seasonality): super(SeasonalFLRG, self).__init__(None,None) self.LHS = seasonality @@ -26,6 +27,7 @@ class SeasonalFLRG(FLR.FLR): class SeasonalFTS(fts.FTS): + """First Order Seasonal Fuzzy Time Series""" def __init__(self, name, **kwargs): super(SeasonalFTS, self).__init__(1, "SFTS") self.name = "Seasonal FTS" diff --git a/tree.py b/tree.py index 903651b..210b2f9 100644 --- a/tree.py +++ b/tree.py @@ -38,6 +38,7 @@ class FLRGTreeNode: class FLRGTree: + """Represents a FLRG set with a tree structure""" def __init__(self): self.root = FLRGTreeNode(None) diff --git a/yu.py b/yu.py index ccc9699..e4225f2 100644 --- a/yu.py +++ b/yu.py @@ -4,6 +4,7 @@ from pyFTS import fts class WeightedFLRG(object): + """First Order Weighted Fuzzy Logical Relationship Group""" def __init__(self, LHS, **kwargs): self.LHS = LHS self.RHS = [] @@ -31,6 +32,7 @@ class WeightedFLRG(object): class WeightedFTS(fts.FTS): + """First Order Weighted Fuzzy Time Series""" def __init__(self, name, **kwargs): super(WeightedFTS, self).__init__(1, "WFTS " + name) self.name = "Weighted FTS"