From a4903fd9320dbb8dd78e66bc5a4c568a9846376e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=C3=B4nio=20C=C3=A2ndido=20de=20Lima=20e=20Silva?= Date: Tue, 2 May 2017 11:32:03 -0300 Subject: [PATCH] - Several bugfixes - Issue #2 - PEP 8 compliance - Issue #3 - Code documentation with PEP 257 compliance --- __init__.py | 3 ++ benchmarks/Measures.py | 74 ++++++++++++++++++++++++----- benchmarks/__init__.py | 3 ++ benchmarks/arima.py | 7 ++- benchmarks/naive.py | 3 +- benchmarks/quantreg.py | 7 +-- common/FLR.py | 33 +++++++++++++ common/FuzzySet.py | 39 +++++++++++++++ common/Membership.py | 18 +++++++ common/Transformations.py | 11 ++++- ensemble.py | 12 ++--- fts.py | 76 +++++++++++++++++++++++++++--- hofts.py | 2 +- hwang.py | 6 +-- ifts.py | 6 +-- ismailefendi.py | 4 +- models/cmsfts.py | 16 +++++-- models/msfts.py | 5 +- models/seasonal/SeasonalIndexer.py | 3 ++ partitioners/__init__.py | 3 ++ partitioners/partitioner.py | 32 +++++++++++-- pwfts.py | 32 ++++++------- sadaei.py | 1 + sfts.py | 6 +-- tests/__init__.py | 3 ++ 25 files changed, 335 insertions(+), 70 deletions(-) diff --git a/__init__.py b/__init__.py index e69de29..429661b 100644 --- a/__init__.py +++ b/__init__.py @@ -0,0 +1,3 @@ +""" +pyFTS - A Python library for Fuzzy Time Series models +""" \ No newline at end of file diff --git a/benchmarks/Measures.py b/benchmarks/Measures.py index a13ba64..be31def 100644 --- a/benchmarks/Measures.py +++ b/benchmarks/Measures.py @@ -1,12 +1,21 @@ # -*- coding: utf8 -*- +""" +pyFTS module for common benchmark metrics +""" + import numpy as np import pandas as pd from pyFTS.common import FuzzySet,SortedCollection -# Autocorrelation function estimative def acf(data, k): + """ + Autocorrelation function estimative + :param data: + :param k: + :return: + """ mu = np.mean(data) sigma = np.var(data) n = len(data) @@ -17,22 +26,45 @@ def acf(data, k): return 1/((n-k)*sigma)*s -# Erro quadrático médio def rmse(targets, forecasts): + """ + Root Mean Squared Error + :param targets: + :param forecasts: + :return: + """ return np.sqrt(np.nanmean((targets - forecasts) ** 2)) def rmse_interval(targets, forecasts): + """ + Root Mean Squared Error + :param targets: + :param forecasts: + :return: + """ fmean = [np.mean(i) for i in forecasts] return np.sqrt(np.nanmean((fmean - targets) ** 2)) -# Erro Percentual médio def mape(targets, forecasts): + """ + Mean Average Percentual Error + :param targets: + :param forecasts: + :return: + """ return np.mean(np.abs(targets - forecasts) / targets) * 100 def smape(targets, forecasts, type=2): + """ + Symmetric Mean Average Percentual Error + :param targets: + :param forecasts: + :param type: + :return: + """ if type == 1: return np.mean(np.abs(forecasts - targets) / ((forecasts + targets)/2)) elif type == 2: @@ -46,8 +78,13 @@ def mape_interval(targets, forecasts): return np.mean(abs(fmean - targets) / fmean) * 100 -# Theil's U Statistic def UStatistic(targets, forecasts): + """ + Theil's U Statistic + :param targets: + :param forecasts: + :return: + """ l = len(targets) naive = [] y = [] @@ -57,8 +94,13 @@ def UStatistic(targets, forecasts): return np.sqrt(sum(y) / sum(naive)) -# Theil’s Inequality Coefficient def TheilsInequality(targets, forecasts): + """ + Theil’s Inequality Coefficient + :param targets: + :param forecasts: + :return: + """ res = targets - forecasts t = len(res) us = np.sqrt(sum([u**2 for u in res])) @@ -67,8 +109,13 @@ def TheilsInequality(targets, forecasts): return us / (ys + fs) -# Q Statistic for Box-Pierce test def BoxPierceStatistic(data, h): + """ + Q Statistic for Box-Pierce test + :param data: + :param h: + :return: + """ n = len(data) s = 0 for k in np.arange(1,h+1): @@ -77,8 +124,13 @@ def BoxPierceStatistic(data, h): return n*s -# Q Statistic for Ljung–Box test def BoxLjungStatistic(data, h): + """ + Q Statistic for Ljung–Box test + :param data: + :param h: + :return: + """ n = len(data) s = 0 for k in np.arange(1,h+1): @@ -87,21 +139,21 @@ def BoxLjungStatistic(data, h): return n*(n-2)*s -# Sharpness - Mean size of the intervals def sharpness(forecasts): + """Sharpness - Mean size of the intervals""" tmp = [i[1] - i[0] for i in forecasts] return np.mean(tmp) -# Resolution - Standard deviation of the intervals def resolution(forecasts): + """Resolution - Standard deviation of the intervals""" shp = sharpness(forecasts) tmp = [abs((i[1] - i[0]) - shp) for i in forecasts] return np.mean(tmp) -# Percent of def coverage(targets, forecasts): + """Percent of""" preds = [] for i in np.arange(0, len(forecasts)): if targets[i] >= forecasts[i][0] and targets[i] <= forecasts[i][1]: @@ -133,8 +185,8 @@ def heavyside_cdf(bins, targets): return df -# Continuous Ranked Probability Score def crps(targets, densities): + """Continuous Ranked Probability Score""" l = len(densities.columns) n = len(densities.index) Ff = pmf_to_cdf(densities) diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py index e69de29..9cea44d 100644 --- a/benchmarks/__init__.py +++ b/benchmarks/__init__.py @@ -0,0 +1,3 @@ +""" +pyFTS module for benchmarking the FTS models +""" \ No newline at end of file diff --git a/benchmarks/arima.py b/benchmarks/arima.py index fd94c62..d1d0147 100644 --- a/benchmarks/arima.py +++ b/benchmarks/arima.py @@ -7,11 +7,14 @@ from pyFTS import fts class ARIMA(fts.FTS): + """ + Façade for statsmodels.tsa.arima_model + """ def __init__(self, order, **kwargs): super(ARIMA, self).__init__(1, "ARIMA") self.name = "ARIMA" self.detail = "Auto Regressive Integrated Moving Average" - self.isHighOrder = True + self.is_high_order = True self.model = None self.model_fit = None self.trained_data = None @@ -19,7 +22,7 @@ class ARIMA(fts.FTS): self.d = 0 self.q = 0 self.benchmark_only = True - self.minOrder = 1 + self.min_order = 1 def train(self, data, sets, order=1, parameters=None): if parameters is not None: diff --git a/benchmarks/naive.py b/benchmarks/naive.py index 80d338c..1441246 100644 --- a/benchmarks/naive.py +++ b/benchmarks/naive.py @@ -5,12 +5,13 @@ from pyFTS import fts class Naive(fts.FTS): + """Naïve Forecasting method""" def __init__(self, order, name, **kwargs): super(Naive, self).__init__(1, "Naive " + name) self.name = "Naïve Model" self.detail = "Naïve Model" self.benchmark_only = True - self.isHighOrder = False + self.is_high_order = False def forecast(self, data, **kwargs): return [k for k in data] diff --git a/benchmarks/quantreg.py b/benchmarks/quantreg.py index 0426a04..d5cdabd 100644 --- a/benchmarks/quantreg.py +++ b/benchmarks/quantreg.py @@ -8,13 +8,14 @@ from pyFTS import fts class QuantileRegression(fts.FTS): + """Façade for statsmodels.regression.quantile_regression""" def __init__(self, order, **kwargs): super(QuantileRegression, self).__init__(1, "QR") self.name = "QR" self.detail = "Quantile Regression" - self.isHighOrder = True - self.hasPointForecasting = True - self.hasIntervalForecasting = True + self.is_high_order = True + self.has_point_forecasting = True + self.has_interval_forecasting = True self.benchmark_only = True self.minOrder = 1 self.alpha = 0.5 diff --git a/common/FLR.py b/common/FLR.py index bb546c8..551828e 100644 --- a/common/FLR.py +++ b/common/FLR.py @@ -1,9 +1,18 @@ import numpy as np from pyFTS.common import FuzzySet +""" +This module implements functions for Fuzzy Logical Relationship generation +""" class FLR(object): + """Fuzzy Logical Relationship""" def __init__(self, LHS, RHS): + """ + Creates a Fuzzy Logical Relationship + :param LHS: Left Hand Side fuzzy set + :param RHS: Right Hand Side fuzzy set + """ self.LHS = LHS self.RHS = RHS @@ -12,7 +21,14 @@ class FLR(object): class IndexedFLR(FLR): + """Season Indexed Fuzzy Logical Relationship""" def __init__(self, index, LHS, RHS): + """ + Create a Season Indexed Fuzzy Logical Relationship + :param index: seasonal index + :param LHS: Left Hand Side fuzzy set + :param RHS: Right Hand Side fuzzy set + """ super(IndexedFLR, self).__init__(LHS, RHS) self.index = index @@ -21,6 +37,11 @@ class IndexedFLR(FLR): 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]) @@ -30,6 +51,11 @@ def generateNonRecurrentFLRs(fuzzyData): def generateRecurrentFLRs(fuzzyData): + """ + Create a ordered FLR set from a list of fuzzy sets with recurrence + :param fuzzyData: ordered list of fuzzy sets + :return: ordered list of FLR + """ flrs = [] for i in np.arange(1,len(fuzzyData)): flrs.append(FLR(fuzzyData[i-1],fuzzyData[i])) @@ -37,6 +63,13 @@ def generateRecurrentFLRs(fuzzyData): def generateIndexedFLRs(sets, indexer, data): + """ + Create a season-indexed ordered FLR set from a list of fuzzy sets with recurrence + :param sets: fuzzy sets + :param indexer: seasonality indexer + :param data: original data + :return: ordered list of FLR + """ flrs = [] index = indexer.get_season_of_data(data) ndata = indexer.get_data(data) diff --git a/common/FuzzySet.py b/common/FuzzySet.py index ee5cb15..cc2d934 100644 --- a/common/FuzzySet.py +++ b/common/FuzzySet.py @@ -4,7 +4,17 @@ from pyFTS.common import Membership class FuzzySet: + """ + Fuzzy Set + """ def __init__(self, name, mf, parameters, centroid): + """ + Create a Fuzzy Set + :param name: fuzzy set name + :param mf: membership function + :param parameters: parameters of the membership function + :param centroid: fuzzy set center of mass + """ self.name = name self.mf = mf self.parameters = parameters @@ -17,6 +27,11 @@ class FuzzySet: self.upper = parameters[0] + parameters[1]*3 def membership(self, x): + """ + Calculate the membership value of a given input + :param x: input value + :return: membership value of x at this fuzzy set + """ return self.mf(x, self.parameters) def __str__(self): @@ -24,11 +39,23 @@ class FuzzySet: def fuzzyInstance(inst, fuzzySets): + """ + Calculate the membership values for a data point given fuzzy sets + :param inst: data point + :param fuzzySets: list of fuzzy sets + :return: array of membership values + """ mv = np.array([fs.membership(inst) for fs in fuzzySets]) return mv def fuzzyInstances(data, fuzzySets): + """ + Calculate the membership values for a data point given fuzzy sets + :param inst: data point + :param fuzzySets: list of fuzzy sets + :return: array of membership values + """ ret = [] for inst in data: mv = np.array([fs.membership(inst) for fs in fuzzySets]) @@ -37,10 +64,22 @@ def fuzzyInstances(data, fuzzySets): def getMaxMembershipFuzzySet(inst, fuzzySets): + """ + Fuzzify a data point, returning the fuzzy set with maximum membership value + :param inst: data point + :param fuzzySets: list of fuzzy sets + :return: fuzzy set with maximum membership + """ mv = fuzzyInstance(inst, fuzzySets) return fuzzySets[np.argwhere(mv == max(mv))[0, 0]] def getMaxMembershipFuzzySetIndex(inst, fuzzySets): + """ + Fuzzify a data point, returning the fuzzy set with maximum membership value + :param inst: data point + :param fuzzySets: list of fuzzy sets + :return: fuzzy set with maximum membership + """ mv = fuzzyInstance(inst, fuzzySets) return np.argwhere(mv == max(mv))[0, 0] diff --git a/common/Membership.py b/common/Membership.py index ad01263..36f5756 100644 --- a/common/Membership.py +++ b/common/Membership.py @@ -4,6 +4,12 @@ from pyFTS import * def trimf(x, parameters): + """ + Triangular fuzzy membership function + :param x: data point + :param parameters: a list with 3 real values + :return: the membership value of x given the parameters + """ xx = round(x, 3) if xx < parameters[0]: return 0 @@ -16,6 +22,12 @@ def trimf(x, parameters): def trapmf(x, parameters): + """ + Trapezoidal fuzzy membership function + :param x: data point + :param parameters: a list with 4 real values + :return: the membership value of x given the parameters + """ if x < parameters[0]: return 0 elif parameters[0] <= x < parameters[1]: @@ -29,6 +41,12 @@ def trapmf(x, parameters): def gaussmf(x, parameters): + """ + Gaussian fuzzy membership function + :param x: data point + :param parameters: a list with 2 real values (mean and variance) + :return: the membership value of x given the parameters + """ return math.exp((-(x - parameters[0])**2)/(2 * parameters[1]**2)) #return math.exp(-0.5 * ((x - parameters[0]) / parameters[1]) ** 2) diff --git a/common/Transformations.py b/common/Transformations.py index 53285aa..6054a07 100644 --- a/common/Transformations.py +++ b/common/Transformations.py @@ -4,6 +4,9 @@ from pyFTS import * class Transformation(object): + """ + Data transformation used to pre and post processing of the FTS + """ def __init__(self, parameters): self.isInversible = True @@ -21,7 +24,9 @@ class Transformation(object): class Differential(Transformation): - + """ + Differentiation data transform + """ def __init__(self, parameters): super(Differential, self).__init__(parameters) self.lag = parameters @@ -61,7 +66,9 @@ class Differential(Transformation): class AdaptiveExpectation(Transformation): - + """ + Adaptive Expectation post processing + """ def __init__(self, parameters): super(AdaptiveExpectation, self).__init__(parameters) self.h = parameters diff --git a/ensemble.py b/ensemble.py index c85a709..07c49d2 100644 --- a/ensemble.py +++ b/ensemble.py @@ -15,10 +15,10 @@ class EnsembleFTS(fts.FTS): self.shortname = "Ensemble FTS " + name self.name = "Ensemble FTS" self.flrgs = {} - self.hasPointForecasting = True - self.hasIntervalForecasting = True - self.hasDistributionForecasting = True - self.isHighOrder = True + self.has_point_forecasting = True + self.has_interval_forecasting = True + self.has_probability_forecasting = True + self.is_high_order = True self.models = [] self.parameters = [] @@ -40,7 +40,7 @@ class EnsembleFTS(fts.FTS): mfts = model("") mfts.partitioner = data_train_fs - if not mfts.isHighOrder: + if not mfts.is_high_order: if transformation is not None: mfts.appendTransformation(transformation) @@ -49,7 +49,7 @@ class EnsembleFTS(fts.FTS): self.models.append(mfts) else: for order in np.arange(1, max_order + 1): - if order >= mfts.minOrder: + if order >= mfts.min_order: mfts = model("") mfts.partitioner = data_train_fs diff --git a/fts.py b/fts.py index d50619a..73d6352 100644 --- a/fts.py +++ b/fts.py @@ -3,21 +3,31 @@ import pandas as pd from pyFTS import tree from pyFTS.common import FuzzySet, SortedCollection + class FTS(object): + """ + Fuzzy Time Series + """ def __init__(self, order, name, **kwargs): + """ + Create a Fuzzy Time Series model + :param order: model order + :param name: model name + :param kwargs: model specific parameters + """ self.sets = {} self.flrgs = {} self.order = order self.shortname = name self.name = name self.detail = name - self.isHighOrder = False - self.minOrder = 1 - self.hasSeasonality = False - self.hasPointForecasting = True - self.hasIntervalForecasting = False - self.hasDistributionForecasting = False - self.isMultivariate = False + self.is_high_order = False + self.min_order = 1 + self.has_seasonality = False + self.has_point_forecasting = True + self.has_interval_forecasting = False + self.has_probability_forecasting = False + self.is_multivariate = False self.dump = False self.transformations = [] self.transformations_param = [] @@ -28,6 +38,11 @@ class FTS(object): self.benchmark_only = False def fuzzy(self, data): + """ + Fuzzify a data point + :param data: data point + :return: maximum membership fuzzy set + """ best = {"fuzzyset": "", "membership": 0.0} for f in self.sets: @@ -39,24 +54,71 @@ class FTS(object): return best def forecast(self, data, **kwargs): + """ + Point forecast one step ahead + :param data: time series with minimal length to the order of the model + :param kwargs: + :return: + """ pass def forecastInterval(self, data, **kwargs): + """ + Interval forecast one step ahead + :param data: + :param kwargs: + :return: + """ pass def forecastDistribution(self, data, **kwargs): + """ + Probabilistic forecast one step ahead + :param data: + :param kwargs: + :return: + """ pass def forecastAhead(self, data, steps, **kwargs): + """ + Point forecast n steps ahead + :param data: + :param steps: + :param kwargs: + :return: + """ pass def forecastAheadInterval(self, data, steps, **kwargs): + """ + Interval forecast n steps ahead + :param data: + :param steps: + :param kwargs: + :return: + """ pass def forecastAheadDistribution(self, data, steps, **kwargs): + """ + Probabilistic forecast n steps ahead + :param data: + :param steps: + :param kwargs: + :return: + """ pass def train(self, data, sets, order=1, parameters=None): + """ + + :param data: + :param sets: + :param order: + :param parameters: + :return: + """ pass def getMidpoints(self, flrg): diff --git a/hofts.py b/hofts.py index 1e27702..1ad2e9f 100644 --- a/hofts.py +++ b/hofts.py @@ -46,7 +46,7 @@ class HighOrderFTS(fts.FTS): self.detail = "Chen" self.order = 1 self.setsDict = {} - self.isHighOrder = True + self.is_high_order = True def generateFLRG(self, flrs): flrgs = {} diff --git a/hwang.py b/hwang.py index ffb752b..5fe557d 100644 --- a/hwang.py +++ b/hwang.py @@ -4,10 +4,10 @@ from pyFTS import fts class HighOrderFTS(fts.FTS): - def __init__(self, order, **kwargs): + def __init__(self, order, name, **kwargs): super(HighOrderFTS, self).__init__(1, name) - self.isHighOrder = True - self.minOrder = 2 + self.is_high_order = True + self.min_order = 2 self.name = "Hwang High Order FTS" self.shortname = "Hwang" + name self.detail = "Hwang" diff --git a/ifts.py b/ifts.py index c61cd99..e634d14 100644 --- a/ifts.py +++ b/ifts.py @@ -13,9 +13,9 @@ class IntervalFTS(hofts.HighOrderFTS): self.name = "Interval FTS" self.detail = "Silva, P.; Guimarães, F.; Sadaei, H. (2016)" self.flrgs = {} - self.hasPointForecasting = False - self.hasIntervalForecasting = True - self.isHighOrder = True + self.has_point_forecasting = False + self.has_point_forecasting = True + self.is_high_order = True def getUpper(self, flrg): if flrg.strLHS() in self.flrgs: diff --git a/ismailefendi.py b/ismailefendi.py index 5fd9a34..03109c3 100644 --- a/ismailefendi.py +++ b/ismailefendi.py @@ -33,7 +33,7 @@ class ImprovedWeightedFLRG(object): class ImprovedWeightedFTS(fts.FTS): - def __init__(self, order, **kwargs): + def __init__(self, order, name, **kwargs): super(ImprovedWeightedFTS, self).__init__(1, "IWFTS " + name) self.name = "Improved Weighted FTS" self.detail = "Ismail & Efendi" @@ -49,7 +49,7 @@ class ImprovedWeightedFTS(fts.FTS): flrgs[flr.LHS.name].append(flr.RHS) return (flrgs) - def train(self, data, sets,order=1,parameters=None): + def train(self, data, sets, order=1, parameters=None): self.sets = sets for s in self.sets: self.setsDict[s.name] = s diff --git a/models/cmsfts.py b/models/cmsfts.py index ffa705b..0be037d 100644 --- a/models/cmsfts.py +++ b/models/cmsfts.py @@ -4,6 +4,9 @@ from pyFTS import fts, sfts, chen class ContextualSeasonalFLRG(object): + """ + Contextual Seasonal Fuzzy Logical Relationship Group + """ def __init__(self, seasonality): self.season = seasonality self.flrgs = {} @@ -24,16 +27,19 @@ class ContextualSeasonalFLRG(object): class ContextualMultiSeasonalFTS(sfts.SeasonalFTS): - def __init__(self, order, name, **kwargs): + """ + Contextual Multi-Seasonal Fuzzy Time Series + """ + def __init__(self, order, name, indexer, **kwargs): super(ContextualMultiSeasonalFTS, self).__init__("CMSFTS") self.name = "Contextual Multi Seasonal FTS" self.shortname = "CMSFTS " + name self.detail = "" self.seasonality = 1 - self.hasSeasonality = True - self.hasPointForecasting = True - self.isHighOrder = True - self.isMultivariate = True + self.has_seasonality = True + self.has_point_forecasting = True + self.is_high_order = True + self.is_multivariate = True self.indexer = indexer self.flrgs = {} diff --git a/models/msfts.py b/models/msfts.py index bcfdd29..f23a1c8 100644 --- a/models/msfts.py +++ b/models/msfts.py @@ -4,7 +4,10 @@ from pyFTS import fts, sfts class MultiSeasonalFTS(sfts.SeasonalFTS): - def __init__(self, order, name, **kwargs): + """ + Multi-Seasonal Fuzzy Time Series + """ + def __init__(self, order, name, indexer, **kwargs): super(MultiSeasonalFTS, self).__init__("MSFTS") self.name = "Multi Seasonal FTS" self.shortname = "MSFTS " + name diff --git a/models/seasonal/SeasonalIndexer.py b/models/seasonal/SeasonalIndexer.py index 2a0d679..d9d9b11 100644 --- a/models/seasonal/SeasonalIndexer.py +++ b/models/seasonal/SeasonalIndexer.py @@ -2,6 +2,9 @@ import numpy as np from enum import Enum class SeasonalIndexer(object): + """ + Seasonal Indexer. Responsible to find the seasonal index of a data point inside its data set + """ def __init__(self,num_seasons): self.num_seasons = num_seasons diff --git a/partitioners/__init__.py b/partitioners/__init__.py index e69de29..8c4bbd0 100644 --- a/partitioners/__init__.py +++ b/partitioners/__init__.py @@ -0,0 +1,3 @@ +""" +Module for pyFTS Universe of Discourse partitioners. +""" \ No newline at end of file diff --git a/partitioners/partitioner.py b/partitioners/partitioner.py index a466aca..6e0d4fd 100644 --- a/partitioners/partitioner.py +++ b/partitioners/partitioner.py @@ -1,9 +1,23 @@ from pyFTS.common import FuzzySet, Membership -import numpy as np +import numpy as np class Partitioner(object): - def __init__(self,name,data,npart,func = Membership.trimf, names=None, prefix="A", transformation=None): + """ + Universe of Discourse partitioner. Split data on several fuzzy sets + """ + + def __init__(self, name, data, npart, func=Membership.trimf, names=None, prefix="A", transformation=None): + """ + Universe of Discourse partitioner scheme. Split data on several fuzzy sets + :param name: partitioner name + :param data: original data to be partitioned + :param npart: number of partitions + :param func: membership function + :param names: list of partitions names. If None is given the partitions will be auto named with prefix + :param prefix: prefix of auto generated partition names + :param transformation: data transformation to be applied on data + """ self.name = name self.partitions = npart self.sets = [] @@ -31,9 +45,19 @@ class Partitioner(object): self.sets = self.build(ndata) def build(self, data): + """ + Perform the partitioning of the Universe of Discourse + :param data: + :return: + """ pass - def plot(self,ax): + def plot(self, ax): + """ + Plot the + :param ax: + :return: + """ ax.set_title(self.name) ax.set_ylim([0, 1]) ax.set_xlim([self.min, self.max]) @@ -46,4 +70,4 @@ class Partitioner(object): ax.plot(tmpx, tmpy) def __str__(self): - return self.name \ No newline at end of file + return self.name diff --git a/pwfts.py b/pwfts.py index 8ae644b..6107cb7 100644 --- a/pwfts.py +++ b/pwfts.py @@ -13,31 +13,31 @@ class ProbabilisticWeightedFLRG(hofts.HighOrderFLRG): def __init__(self, order): super(ProbabilisticWeightedFLRG, self).__init__(order) self.RHS = {} - self.frequencyCount = 0.0 + self.frequency_count = 0.0 def appendRHS(self, c): - self.frequencyCount += 1.0 + self.frequency_count += 1.0 if c.name in self.RHS: self.RHS[c.name] += 1.0 else: self.RHS[c.name] = 1.0 def appendRHSFuzzy(self, c, mv): - self.frequencyCount += mv + self.frequency_count += mv if c.name in self.RHS: self.RHS[c.name] += mv else: self.RHS[c.name] = mv def get_probability(self, c): - return self.RHS[c] / self.frequencyCount + return self.RHS[c] / self.frequency_count def __str__(self): tmp2 = "" for c in sorted(self.RHS): if len(tmp2) > 0: tmp2 = tmp2 + ", " - tmp2 = tmp2 + "(" + str(round(self.RHS[c] / self.frequencyCount, 3)) + ")" + c + tmp2 = tmp2 + "(" + str(round(self.RHS[c] / self.frequency_count, 3)) + ")" + c return self.strLHS() + " -> " + tmp2 @@ -48,11 +48,11 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): self.name = "Probabilistic FTS" self.detail = "Silva, P.; Guimarães, F.; Sadaei, H." self.flrgs = {} - self.globalFrequency = 0 - self.hasPointForecasting = True - self.hasIntervalForecasting = True - self.hasDistributionForecasting = True - self.isHighOrder = True + self.global_frequency_count = 0 + self.has_point_forecasting = True + self.has_interval_forecasting = True + self.has_probability_forecasting = True + self.is_high_order = True self.auto_update = kwargs.get('update',False) def train(self, data, sets, order=1,parameters=None): @@ -108,7 +108,7 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): for c, e in enumerate(_sets, start=0): flrgs[flrg.strLHS()].appendRHSFuzzy(e,rhs_mv[c]*max(lhs_mv)) - self.globalFrequency += max(lhs_mv) + self.global_frequency_count += max(lhs_mv) return (flrgs) @@ -130,7 +130,7 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): flrgs[flrg.strLHS()].appendRHS(flrs[k-1].RHS) if self.dump: print("RHS: " + str(flrs[k-1])) - self.globalFrequency += 1 + self.global_frequency_count += 1 return (flrgs) def update_model(self,data): @@ -147,7 +147,7 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): self.flrgs[flrg.strLHS()] = flrg self.flrgs[flrg.strLHS()].appendRHS(fzzy[self.order]) - self.globalFrequency += 1 + self.global_frequency_count += 1 def add_new_PWFLGR(self, flrg): if flrg.strLHS() not in self.flrgs: @@ -155,11 +155,11 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): for fs in flrg.LHS: tmp.appendLHS(fs) tmp.appendRHS(flrg.LHS[-1]) self.flrgs[tmp.strLHS()] = tmp; - self.globalFrequency += 1 + self.global_frequency_count += 1 def get_probability(self, flrg): if flrg.strLHS() in self.flrgs: - return self.flrgs[flrg.strLHS()].frequencyCount / self.globalFrequency + return self.flrgs[flrg.strLHS()].frequency_count / self.global_frequency_count else: self.add_new_PWFLGR(flrg) return self.get_probability(flrg) @@ -572,6 +572,6 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS): def __str__(self): tmp = self.name + ":\n" for r in sorted(self.flrgs): - p = round(self.flrgs[r].frequencyCount / self.globalFrequency, 3) + p = round(self.flrgs[r].frequencyCount / self.global_frequency_count, 3) tmp = tmp + "(" + str(p) + ") " + str(self.flrgs[r]) + "\n" return tmp diff --git a/sadaei.py b/sadaei.py index 4870f39..733b731 100644 --- a/sadaei.py +++ b/sadaei.py @@ -2,6 +2,7 @@ import numpy as np from pyFTS.common import FuzzySet,FLR from pyFTS import fts + class ExponentialyWeightedFLRG(object): def __init__(self, LHS, c): self.LHS = LHS diff --git a/sfts.py b/sfts.py index 76f3a92..b323403 100644 --- a/sfts.py +++ b/sfts.py @@ -31,9 +31,9 @@ class SeasonalFTS(fts.FTS): self.name = "Seasonal FTS" self.detail = "Chen" self.seasonality = 1 - self.hasSeasonality = True - self.hasPointForecasting = True - self.isHighOrder = False + self.has_seasonality = True + self.has_point_forecasting = True + self.is_high_order = False def generateFLRG(self, flrs): flrgs = [] diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..9a96ec1 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,3 @@ +""" +Module for testing pyFTS modules and models +""" \ No newline at end of file