All modules for which code is available
-- pyFTS.common.Composite +
- pyFTS.benchmarks.BSTS +
- pyFTS.benchmarks.Measures +
- pyFTS.benchmarks.ResidualAnalysis +
- pyFTS.benchmarks.Tests +
- pyFTS.benchmarks.Util +
- pyFTS.benchmarks.arima +
- pyFTS.benchmarks.benchmarks +
- pyFTS.benchmarks.knn +
- pyFTS.benchmarks.naive +
- pyFTS.benchmarks.quantreg +
- pyFTS.common.Composite
- pyFTS.common.FLR
- pyFTS.common.FuzzySet
- pyFTS.common.Membership
- pyFTS.common.SortedCollection +
- pyFTS.common.Util
- pyFTS.common.flrg +
- pyFTS.common.fts
- pyFTS.common.tree
- pyFTS.data.AirPassengers
- pyFTS.data.Bitcoin @@ -83,27 +95,61 @@
- pyFTS.data.mackey_glass
- pyFTS.data.rossler
- pyFTS.data.sunspots +
- pyFTS.distributed.dispy +
- pyFTS.hyperparam.Evolutionary +
- pyFTS.hyperparam.GridSearch
- pyFTS.hyperparam.Util +
- pyFTS.models.chen +
- pyFTS.models.cheng +
- pyFTS.models.ensemble.ensemble +
- pyFTS.models.ensemble.multiseasonal +
- pyFTS.models.hofts +
- pyFTS.models.hwang +
- pyFTS.models.ifts +
- pyFTS.models.incremental.IncrementalEnsemble +
- pyFTS.models.incremental.TimeVariant +
- pyFTS.models.ismailefendi
- pyFTS.models.multivariate.FLR +
- pyFTS.models.multivariate.cmvfts
- pyFTS.models.multivariate.common
- pyFTS.models.multivariate.flrg +
- pyFTS.models.multivariate.granular
- pyFTS.models.multivariate.grid +
- pyFTS.models.multivariate.mvfts
- pyFTS.models.multivariate.partitioner +
- pyFTS.models.multivariate.variable +
- pyFTS.models.multivariate.wmvfts
- pyFTS.models.nonstationary.common +
- pyFTS.models.nonstationary.cvfts
- pyFTS.models.nonstationary.flrg +
- pyFTS.models.nonstationary.honsfts +
- pyFTS.models.nonstationary.nsfts
- pyFTS.models.nonstationary.partitioners
- pyFTS.models.nonstationary.perturbation +
- pyFTS.models.nonstationary.util +
- pyFTS.models.pwfts +
- pyFTS.models.sadaei
- pyFTS.models.seasonal.SeasonalIndexer +
- pyFTS.models.seasonal.cmsfts
- pyFTS.models.seasonal.common +
- pyFTS.models.seasonal.msfts
- pyFTS.models.seasonal.partitioner +
- pyFTS.models.seasonal.sfts +
- pyFTS.models.song +
- pyFTS.models.yu
- pyFTS.partitioners.CMeans
- pyFTS.partitioners.Entropy
- pyFTS.partitioners.FCM
- pyFTS.partitioners.Grid +
- pyFTS.partitioners.Huarng
- pyFTS.partitioners.Simple
- pyFTS.partitioners.Singleton
- pyFTS.partitioners.SubClust +
- pyFTS.partitioners.Util +
- pyFTS.partitioners.parallel_util
- pyFTS.partitioners.partitioner +
- pyFTS.probabilistic.ProbabilityDistribution +
- pyFTS.probabilistic.kde
- base_dataframe_columns() (in module pyFTS.benchmarks.Util) + +
- batch_size (pyFTS.models.incremental.IncrementalEnsemble.IncrementalEnsembleFTS attribute) + +
- bellmf() (in module pyFTS.common.Membership) + +
- benchmark_only (pyFTS.common.fts.FTS attribute)
- bestSplit() (in module pyFTS.partitioners.Entropy)
- between() (pyFTS.common.SortedCollection.SortedCollection method) + +
- bins (pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution attribute)
- blip() (pyFTS.data.artificial.SignalEmulator method) + +
- BoxLjungStatistic() (in module pyFTS.benchmarks.Tests) + +
- BoxPierceStatistic() (in module pyFTS.benchmarks.Tests) + +
- brier_score() (in module pyFTS.benchmarks.Measures)
- build() (pyFTS.models.multivariate.grid.GridCluster method)
- (pyFTS.models.multivariate.partitioner.MultivariatePartitioner method) + +
- (pyFTS.models.multivariate.variable.Variable method)
- (pyFTS.models.nonstationary.partitioners.PolynomialNonStationaryPartitioner method) @@ -148,6 +276,8 @@
- (pyFTS.partitioners.FCM.FCMPartitioner method)
- (pyFTS.partitioners.Grid.GridPartitioner method) + +
- (pyFTS.partitioners.Huarng.HuarngPartitioner method)
- (pyFTS.partitioners.partitioner.Partitioner method) @@ -158,6 +288,8 @@
- build_cdf_qtl() (pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution method) +
- build_index() (pyFTS.models.multivariate.partitioner.MultivariatePartitioner method)
-
@@ -175,6 +307,14 @@
- entropy() (in module pyFTS.partitioners.Entropy) +
- elitism() (in module pyFTS.hyperparam.Evolutionary) +
- empiricalloglikelihood() (pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution method) + +
- EnsembleFTS (class in pyFTS.models.ensemble.ensemble) + +
- entropy() (in module pyFTS.partitioners.Entropy) + +
- EntropyPartitioner (class in pyFTS.partitioners.Entropy) +
- enumerate2() (in module pyFTS.common.Util) + +
- evaluate() (in module pyFTS.hyperparam.Evolutionary) + +
- execute() (in module pyFTS.hyperparam.Evolutionary) + +
- expected_value() (pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution method) + +
- explore_partitioners() (in module pyFTS.partitioners.parallel_util) + +
- exponential() (in module pyFTS.models.nonstationary.perturbation) + +
- ExponentialyWeightedFLRG (class in pyFTS.models.sadaei) + +
- ExponentialyWeightedFTS (class in pyFTS.models.sadaei) + +
- extract_measure() (in module pyFTS.benchmarks.Util)
- extractor() (pyFTS.models.seasonal.partitioner.TimeGridPartitioner method) @@ -265,6 +533,8 @@
- FCMPartitioner (class in pyFTS.partitioners.FCM)
- find() (pyFTS.common.SortedCollection.SortedCollection method) + +
- find_best() (in module pyFTS.benchmarks.Util)
- find_ge() (pyFTS.common.SortedCollection.SortedCollection method) @@ -273,6 +543,8 @@
- find_le() (pyFTS.common.SortedCollection.SortedCollection method)
- find_lt() (pyFTS.common.SortedCollection.SortedCollection method) + +
- fit() (pyFTS.common.fts.FTS method)
- flat() (in module pyFTS.common.tree) @@ -282,29 +554,245 @@
- (class in pyFTS.models.multivariate.FLR)
- flr_membership_matrix() (pyFTS.models.song.ConventionalFTS method) +
- FLRG (class in pyFTS.common.flrg) +
- flrg_lhs_conditional_probability() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- flrg_lhs_conditional_probability_fuzzyfied() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- flrg_lhs_unconditional_probability() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- flrg_rhs_conditional_probability() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- flrgs (pyFTS.common.fts.FTS attribute) +
- FLRGTree (class in pyFTS.common.tree)
- FLRGTreeNode (class in pyFTS.common.tree) -
- format_data() (pyFTS.models.multivariate.partitioner.MultivariatePartitioner method) +
- forecast() (pyFTS.benchmarks.arima.ARIMA method)
+
+
-
+
- (pyFTS.benchmarks.BSTS.ARIMA method) +
- (pyFTS.benchmarks.knn.KNearestNeighbors method) + +
- (pyFTS.benchmarks.naive.Naive method) + +
- (pyFTS.benchmarks.quantreg.QuantileRegression method) + +
- (pyFTS.common.fts.FTS method) + +
- (pyFTS.models.chen.ConventionalFTS method) + +
- (pyFTS.models.ensemble.ensemble.EnsembleFTS method) + +
- (pyFTS.models.hofts.HighOrderFTS method) + +
- (pyFTS.models.hwang.HighOrderFTS method) + +
- (pyFTS.models.incremental.IncrementalEnsemble.IncrementalEnsembleFTS method) + +
- (pyFTS.models.incremental.TimeVariant.Retrainer method) + +
- (pyFTS.models.ismailefendi.ImprovedWeightedFTS method) + +
- (pyFTS.models.multivariate.cmvfts.ClusteredMVFTS method) + +
- (pyFTS.models.multivariate.mvfts.MVFTS method) + +
- (pyFTS.models.nonstationary.cvfts.ConditionalVarianceFTS method) + +
- (pyFTS.models.nonstationary.honsfts.HighOrderNonStationaryFTS method) + +
- (pyFTS.models.nonstationary.nsfts.NonStationaryFTS method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- (pyFTS.models.sadaei.ExponentialyWeightedFTS method) + +
- (pyFTS.models.seasonal.cmsfts.ContextualMultiSeasonalFTS method) + +
- (pyFTS.models.seasonal.msfts.MultiSeasonalFTS method) + +
- (pyFTS.models.seasonal.sfts.SeasonalFTS method) + +
- (pyFTS.models.song.ConventionalFTS method) + +
- (pyFTS.models.yu.WeightedFTS method) + +
+ - forecast_ahead() (pyFTS.benchmarks.BSTS.ARIMA method)
+
+
-
+
- (pyFTS.common.fts.FTS method) + +
- (pyFTS.models.incremental.IncrementalEnsemble.IncrementalEnsembleFTS method) + +
- (pyFTS.models.incremental.TimeVariant.Retrainer method) + +
- (pyFTS.models.multivariate.mvfts.MVFTS method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- (pyFTS.models.seasonal.cmsfts.ContextualMultiSeasonalFTS method) + +
- (pyFTS.models.seasonal.msfts.MultiSeasonalFTS method) + +
+ - forecast_ahead_distribution() (pyFTS.benchmarks.arima.ARIMA method)
+
+
-
+
- (pyFTS.benchmarks.BSTS.ARIMA method) + +
- (pyFTS.benchmarks.knn.KNearestNeighbors method) + +
- (pyFTS.benchmarks.quantreg.QuantileRegression method) + +
- (pyFTS.common.fts.FTS method) + +
- (pyFTS.models.ensemble.ensemble.EnsembleFTS method) + +
- (pyFTS.models.multivariate.cmvfts.ClusteredMVFTS method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
+ - forecast_ahead_interval() (pyFTS.benchmarks.arima.ARIMA method)
+
+
-
+
- (pyFTS.benchmarks.BSTS.ARIMA method) + +
- (pyFTS.benchmarks.knn.KNearestNeighbors method) + +
- (pyFTS.benchmarks.quantreg.QuantileRegression method) + +
- (pyFTS.common.fts.FTS method) + +
- (pyFTS.models.ensemble.ensemble.EnsembleFTS method) + +
- (pyFTS.models.ifts.IntervalFTS method) + +
- (pyFTS.models.ifts.WeightedIntervalFTS method) + +
- (pyFTS.models.multivariate.mvfts.MVFTS method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
+ - forecast_ahead_multivariate() (pyFTS.common.fts.FTS method) + + +
- forecast_distribution() (pyFTS.benchmarks.arima.ARIMA method)
+
+
-
+
- (pyFTS.benchmarks.BSTS.ARIMA method) + +
- (pyFTS.benchmarks.knn.KNearestNeighbors method) + +
- (pyFTS.benchmarks.quantreg.QuantileRegression method) + +
- (pyFTS.common.fts.FTS method) + +
- (pyFTS.models.ensemble.ensemble.EnsembleFTS method) + +
- (pyFTS.models.ensemble.multiseasonal.SeasonalEnsembleFTS method) + +
- (pyFTS.models.multivariate.cmvfts.ClusteredMVFTS method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
+ - forecast_distribution_from_distribution() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- forecast_interval() (pyFTS.benchmarks.arima.ARIMA method)
+
+
-
+
- (pyFTS.benchmarks.BSTS.ARIMA method) + +
- (pyFTS.benchmarks.knn.KNearestNeighbors method) + +
- (pyFTS.benchmarks.quantreg.QuantileRegression method) + +
- (pyFTS.common.fts.FTS method) + +
- (pyFTS.models.ensemble.ensemble.EnsembleFTS method) + +
- (pyFTS.models.ifts.IntervalFTS method) + +
- (pyFTS.models.ifts.WeightedIntervalFTS method) + +
- (pyFTS.models.multivariate.cmvfts.ClusteredMVFTS method) + +
- (pyFTS.models.multivariate.mvfts.MVFTS method) + +
- (pyFTS.models.nonstationary.cvfts.ConditionalVarianceFTS method) + +
- (pyFTS.models.nonstationary.nsfts.NonStationaryFTS method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
+ - forecast_multivariate() (pyFTS.common.fts.FTS method) + + +
- forecast_step() (pyFTS.common.fts.FTS method) + +
- format_data() (pyFTS.models.multivariate.mvfts.MVFTS method) + + +
- format_experiment_table() (in module pyFTS.benchmarks.Tests) + +
- from_point() (in module pyFTS.probabilistic.ProbabilityDistribution) + +
- FTS (class in pyFTS.common.fts) + +
- fts_method (pyFTS.models.incremental.IncrementalEnsemble.IncrementalEnsembleFTS attribute) + + +
- fts_params (pyFTS.models.incremental.IncrementalEnsemble.IncrementalEnsembleFTS attribute) + +
- fuzzify() (in module pyFTS.models.nonstationary.common) + +
- fuzzy() (pyFTS.common.fts.FTS method)
- fuzzy_cmeans() (in module pyFTS.partitioners.FCM) -
- fuzzy_distance() (in module pyFTS.partitioners.FCM)
- fuzzyfy() (in module pyFTS.common.FuzzySet)
-
+
- (pyFTS.models.multivariate.cmvfts.ClusteredMVFTS method) +
- (pyFTS.models.multivariate.grid.IncrementalGridCluster method)
- (pyFTS.models.multivariate.partitioner.MultivariatePartitioner method)
@@ -345,12 +833,72 @@
- gaussmf() (in module pyFTS.common.Membership) + +
- generate_flrg() (pyFTS.models.chen.ConventionalFTS method) + +
- generate_FLRG() (pyFTS.models.cheng.TrendWeightedFTS method) + +
- generate_flrg() (pyFTS.models.hofts.HighOrderFTS method)
+
+
-
+
- (pyFTS.models.ismailefendi.ImprovedWeightedFTS method) + +
- (pyFTS.models.multivariate.mvfts.MVFTS method) + +
- (pyFTS.models.multivariate.wmvfts.WeightedMVFTS method) + +
- (pyFTS.models.nonstationary.cvfts.ConditionalVarianceFTS method) + +
- (pyFTS.models.nonstationary.honsfts.HighOrderNonStationaryFTS method) + +
- (pyFTS.models.nonstationary.nsfts.NonStationaryFTS method) + +
- (pyFTS.models.nonstationary.nsfts.WeightedNonStationaryFTS method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- (pyFTS.models.sadaei.ExponentialyWeightedFTS method) + +
- (pyFTS.models.seasonal.cmsfts.ContextualMultiSeasonalFTS method) + +
- (pyFTS.models.seasonal.msfts.MultiSeasonalFTS method) + +
- (pyFTS.models.seasonal.sfts.SeasonalFTS method) + +
+ - generate_FLRG() (pyFTS.models.yu.WeightedFTS method) + +
- generate_flrg2() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- generate_flrg_fuzzyfied() (pyFTS.models.hofts.HighOrderFTS method) + + +
- generate_flrs() (pyFTS.models.multivariate.mvfts.MVFTS method)
- generate_gaussian_linear() (in module pyFTS.data.artificial)
- generate_high_order_recurrent_flr() (in module pyFTS.common.FLR)
- generate_indexed_flrs() (in module pyFTS.common.FLR) + +
- generate_lhs_flrg() (pyFTS.models.hofts.HighOrderFTS method) + + +
- generate_lhs_flrg_fuzzyfied() (pyFTS.models.hofts.HighOrderFTS method) + + +
- generate_lhs_flrs() (pyFTS.models.multivariate.mvfts.MVFTS method)
- generate_linear_periodic_gaussian() (in module pyFTS.data.artificial) @@ -361,6 +909,16 @@
- generate_sinoidal_periodic_gaussian() (in module pyFTS.data.artificial)
- generate_uniform_linear() (in module pyFTS.data.artificial) + +
- GeneticAlgorithm() (in module pyFTS.hyperparam.Evolutionary) + +
- genotype() (in module pyFTS.hyperparam.Evolutionary) + +
- get_benchmark_interval_methods() (in module pyFTS.benchmarks.benchmarks) + +
- get_benchmark_point_methods() (in module pyFTS.benchmarks.benchmarks) + +
- get_benchmark_probabilistic_methods() (in module pyFTS.benchmarks.benchmarks)
- get_data() (in module pyFTS.data.AirPassengers) @@ -458,8 +1016,16 @@
- (in module pyFTS.data.TAIEX)
- get_dataframe_from_bd() (in module pyFTS.benchmarks.Util) +
+- get_distribution_ahead_statistics() (in module pyFTS.benchmarks.Measures) +
-
+
- get_distribution_interquantile() (pyFTS.models.ensemble.ensemble.EnsembleFTS method) + +
- get_distribution_statistics() (in module pyFTS.benchmarks.Measures) +
- get_fuzzysets() (in module pyFTS.common.FuzzySet)
- get_index() (pyFTS.models.seasonal.SeasonalIndexer.DateTimeSeasonalIndexer method) @@ -478,20 +1044,50 @@
- (pyFTS.models.seasonal.SeasonalIndexer.SeasonalIndexer method)
- get_interval() (pyFTS.models.ensemble.ensemble.EnsembleFTS method) +
+- get_interval_ahead_statistics() (in module pyFTS.benchmarks.Measures) +
+- get_interval_methods() (in module pyFTS.benchmarks.benchmarks) +
+- get_interval_statistics() (in module pyFTS.benchmarks.Measures) +
- get_key() (pyFTS.common.flrg.FLRG method)
-
+
- (pyFTS.models.chen.ConventionalFLRG method) +
- (pyFTS.models.nonstationary.flrg.NonStationaryFLRG method) + +
- (pyFTS.models.nonstationary.nsfts.ConventionalNonStationaryFLRG method) + +
- (pyFTS.models.nonstationary.nsfts.WeightedNonStationaryFLRG method) + +
- (pyFTS.models.seasonal.sfts.SeasonalFLRG method)
- get_lower() (pyFTS.common.flrg.FLRG method)
-
+
- (pyFTS.models.hofts.WeightedHighOrderFLRG method) + +
- (pyFTS.models.ifts.IntervalFTS method) + +
- (pyFTS.models.ifts.WeightedIntervalFTS method) +
- (pyFTS.models.multivariate.flrg.FLRG method) + +
- (pyFTS.models.multivariate.wmvfts.WeightedFLRG method)
- (pyFTS.models.nonstationary.common.FuzzySet method)
- (pyFTS.models.nonstationary.flrg.NonStationaryFLRG method) + +
- (pyFTS.models.nonstationary.honsfts.HighOrderNonStationaryFLRG method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFLRG method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method)
- get_maximum_membership_fuzzyset() (in module pyFTS.common.FuzzySet) @@ -504,21 +1100,57 @@
- (pyFTS.models.multivariate.flrg.FLRG method)
- (pyFTS.models.nonstationary.flrg.NonStationaryFLRG method) +
+- (pyFTS.models.pwfts.ProbabilisticWeightedFLRG method)
- get_midpoint() (pyFTS.common.flrg.FLRG method)
-
+
- (pyFTS.models.hofts.WeightedHighOrderFLRG method) + +
- (pyFTS.models.multivariate.wmvfts.WeightedFLRG method) +
- (pyFTS.models.nonstationary.common.FuzzySet method)
- (pyFTS.models.nonstationary.flrg.NonStationaryFLRG method) + +
- (pyFTS.models.nonstationary.honsfts.HighOrderNonStationaryFLRG method) + +
- (pyFTS.models.nonstationary.nsfts.WeightedNonStationaryFLRG method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFLRG method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method)
- get_midpoints() (pyFTS.common.flrg.FLRG method) + +
+- get_models_forecasts() (pyFTS.models.ensemble.ensemble.EnsembleFTS method)
- get_name() (pyFTS.partitioners.partitioner.Partitioner method) +
+- get_number_of_cpus() (in module pyFTS.distributed.dispy) +
+- get_point() (pyFTS.models.ensemble.ensemble.EnsembleFTS method) +
+- get_point_ahead_statistics() (in module pyFTS.benchmarks.Measures) +
+- get_point_methods() (in module pyFTS.benchmarks.benchmarks) +
+- get_point_multivariate_methods() (in module pyFTS.benchmarks.benchmarks) +
+- get_point_statistics() (in module pyFTS.benchmarks.Measures)
- get_polynomial_perturbations() (pyFTS.models.nonstationary.partitioners.PolynomialNonStationaryPartitioner method) +
+- get_probabilistic_methods() (in module pyFTS.benchmarks.benchmarks)
- get_season_by_index() (pyFTS.models.seasonal.SeasonalIndexer.DataFrameSeasonalIndexer method) @@ -538,16 +1170,44 @@
- (pyFTS.models.seasonal.SeasonalIndexer.LinearSeasonalIndexer method)
- (pyFTS.models.seasonal.SeasonalIndexer.SeasonalIndexer method) +
+ +- get_sequence_membership() (pyFTS.models.ifts.IntervalFTS method) + +
+- get_sets_from_both_fuzzyfication() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) +
+- get_UoD() (pyFTS.common.fts.FTS method) + +
- get_upper() (pyFTS.common.flrg.FLRG method)
-
+
- (pyFTS.models.hofts.WeightedHighOrderFLRG method) + +
- (pyFTS.models.ifts.IntervalFTS method) + +
- (pyFTS.models.ifts.WeightedIntervalFTS method) +
- (pyFTS.models.multivariate.flrg.FLRG method) + +
- (pyFTS.models.multivariate.wmvfts.WeightedFLRG method)
- (pyFTS.models.nonstationary.common.FuzzySet method)
- (pyFTS.models.nonstationary.flrg.NonStationaryFLRG method) + +
- (pyFTS.models.nonstationary.honsfts.HighOrderNonStationaryFLRG method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFLRG method) + +
- (pyFTS.models.pwfts.ProbabilisticWeightedFTS method)
- getChildren() (pyFTS.common.tree.FLRGTreeNode method) @@ -555,6 +1215,8 @@
- getStr() (pyFTS.common.tree.FLRGTreeNode method)
- grant_bounds() (in module pyFTS.common.FuzzySet) +
+- GranularWMVFTS (class in pyFTS.models.multivariate.granular)
- GridCluster (class in pyFTS.models.multivariate.grid)
@@ -566,19 +1228,45 @@H
@@ -630,21 +1368,47 @@L
-
+
- labels (pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution attribute) + +
- lag_crossover2() (in module pyFTS.hyperparam.Evolutionary) + +
- lags (pyFTS.common.fts.FTS attribute) + +
- len_total() (pyFTS.common.fts.FTS method) +
- LHS (pyFTS.common.FLR.FLR attribute) +
- lhs_conditional_probability() (pyFTS.models.pwfts.ProbabilisticWeightedFLRG method) + +
- lhs_conditional_probability_fuzzyfied() (pyFTS.models.pwfts.ProbabilisticWeightedFLRG method) +
- linear() (in module pyFTS.models.nonstationary.perturbation) -
- LinearSeasonalIndexer (class in pyFTS.models.seasonal.SeasonalIndexer) +
- linearmodel() (pyFTS.benchmarks.quantreg.QuantileRegression method)
-
+
- LinearSeasonalIndexer (class in pyFTS.models.seasonal.SeasonalIndexer) + +
- ljung_box_test() (in module pyFTS.benchmarks.ResidualAnalysis) + +
- load_env() (in module pyFTS.common.Util) + +
- load_obj() (in module pyFTS.common.Util) +
- location (pyFTS.models.nonstationary.common.FuzzySet attribute)
- location_params (pyFTS.models.nonstationary.common.FuzzySet attribute) + +
- log (pyFTS.common.fts.FTS attribute) + +
- log_result() (in module pyFTS.hyperparam.Evolutionary) + +
- logarithm_score() (in module pyFTS.benchmarks.Measures)
- lower_margin (pyFTS.partitioners.partitioner.Partitioner attribute) @@ -656,9 +1420,21 @@
- parameters (pyFTS.common.FuzzySet.FuzzySet attribute) + +
- partition_function() (pyFTS.common.FuzzySet.FuzzySet method) + +
- Partitioner (class in pyFTS.partitioners.partitioner) -
- partitions (pyFTS.partitioners.partitioner.Partitioner attribute) +
- partitioner (pyFTS.common.fts.FTS attribute) + + +
- partitioner_method (pyFTS.models.ensemble.ensemble.SimpleEnsembleFTS attribute) + + +
- partitioner_params (pyFTS.models.incremental.IncrementalEnsemble.IncrementalEnsembleFTS attribute) + + +
- partitions (pyFTS.models.ensemble.ensemble.SimpleEnsembleFTS attribute) + +
- paths() (pyFTS.common.tree.FLRGTreeNode method)
- perform_location() (pyFTS.models.nonstationary.common.FuzzySet method) @@ -888,28 +1854,148 @@
- periodic() (in module pyFTS.models.nonstationary.perturbation)
- periodic_gaussian() (pyFTS.data.artificial.SignalEmulator method) + +
- persist_env() (in module pyFTS.common.Util) + +
- persist_obj() (in module pyFTS.common.Util) + +
- persist_statistics() (in module pyFTS.hyperparam.Evolutionary)
- perturbate_parameters() (pyFTS.models.nonstationary.common.FuzzySet method) + +
- perturbation_factors() (pyFTS.models.nonstationary.cvfts.ConditionalVarianceFTS method) + +
- perturbation_factors__old() (pyFTS.models.nonstationary.cvfts.ConditionalVarianceFTS method) + +
- pftsExploreOrderAndPartitions() (in module pyFTS.benchmarks.benchmarks) + +
- phenotype() (in module pyFTS.hyperparam.Evolutionary) + +
- pinball() (in module pyFTS.benchmarks.Measures) + +
- pinball_mean() (in module pyFTS.benchmarks.Measures)
- plot() (pyFTS.models.seasonal.partitioner.TimeGridPartitioner method) +
- plot_compared_intervals_ahead() (in module pyFTS.common.Util) + +
- plot_compared_series() (in module pyFTS.benchmarks.benchmarks) + +
- plot_dataframe_interval() (in module pyFTS.benchmarks.Util) + +
- plot_dataframe_interval_pinball() (in module pyFTS.benchmarks.Util) + +
- plot_dataframe_point() (in module pyFTS.benchmarks.Util) + +
- plot_dataframe_probabilistic() (in module pyFTS.benchmarks.Util) + +
- plot_density_rectange() (in module pyFTS.common.Util) + +
- plot_distribution() (in module pyFTS.common.Util) + +
- plot_distribution2() (in module pyFTS.common.Util) + +
- plot_distribution_tiled() (in module pyFTS.common.Util) + +
- plot_interval() (in module pyFTS.common.Util) + +
- plot_interval2() (in module pyFTS.common.Util) + +
- plot_partitioners() (in module pyFTS.partitioners.Util) + +
- plot_point() (in module pyFTS.benchmarks.benchmarks) + +
- plot_probability_distributions() (in module pyFTS.common.Util) + +
- plot_residuals_by_model() (in module pyFTS.benchmarks.ResidualAnalysis) + +
- plot_rules() (in module pyFTS.common.Util) +
- plot_set() (pyFTS.partitioners.partitioner.Partitioner method) + +
- plot_sets() (in module pyFTS.models.nonstationary.util) + + +
- plot_sets_conditional() (in module pyFTS.models.nonstationary.util) + +
- plotCompared() (in module pyFTS.benchmarks.benchmarks)
- PMF() (in module pyFTS.partitioners.Entropy) + +
- point_dataframe_analytic_columns() (in module pyFTS.benchmarks.Util) + +
- point_dataframe_synthetic_columns() (in module pyFTS.benchmarks.Util) + +
- point_expected_value() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- point_heuristic() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) + +
- point_method (pyFTS.models.ensemble.ensemble.EnsembleFTS attribute) + +
- point_to_interval() (pyFTS.benchmarks.quantreg.QuantileRegression method)
- poly_width() (pyFTS.models.nonstationary.partitioners.PolynomialNonStationaryPartitioner method)
- polynomial() (in module pyFTS.models.nonstationary.perturbation)
- PolynomialNonStationaryPartitioner (class in pyFTS.models.nonstationary.partitioners) + +
- post_hoc_tests() (in module pyFTS.benchmarks.Tests) + +
- predict() (pyFTS.common.fts.FTS method)
- prefix (pyFTS.partitioners.partitioner.Partitioner attribute)
- PreFixedGridPartitioner (class in pyFTS.partitioners.Grid) + +
- print_distribution_statistics() (in module pyFTS.benchmarks.benchmarks) + +
- print_interval_statistics() (in module pyFTS.benchmarks.benchmarks) + +
- print_point_statistics() (in module pyFTS.benchmarks.benchmarks) + +
- probabilistic_dataframe_analytic_columns() (in module pyFTS.benchmarks.Util) + +
- probabilistic_dataframe_synthetic_columns() (in module pyFTS.benchmarks.Util) + +
- ProbabilisticWeightedFLRG (class in pyFTS.models.pwfts) + +
- ProbabilisticWeightedFTS (class in pyFTS.models.pwfts) + +
- probability() (pyFTS.probabilistic.kde.KernelSmoothing method) + +
- ProbabilityDistribution (class in pyFTS.probabilistic.ProbabilityDistribution) + +
- process_common_data() (in module pyFTS.benchmarks.Util) + +
- process_common_data2() (in module pyFTS.benchmarks.Util) + +
- process_experiment() (in module pyFTS.hyperparam.Evolutionary) + +
- process_interval_jobs() (in module pyFTS.benchmarks.benchmarks) + +
- process_interval_jobs2() (in module pyFTS.benchmarks.benchmarks) + +
- process_jobs() (in module pyFTS.hyperparam.GridSearch) + +
- process_point_jobs() (in module pyFTS.benchmarks.benchmarks) + +
- process_point_jobs2() (in module pyFTS.benchmarks.benchmarks) + +
- process_probabilistic_jobs() (in module pyFTS.benchmarks.benchmarks) + +
- process_probabilistic_jobs2() (in module pyFTS.benchmarks.benchmarks) + +
- product_dict() (in module pyFTS.models.multivariate.mvfts)
- prune() (pyFTS.models.multivariate.grid.IncrementalGridCluster method) @@ -917,6 +2003,10 @@
- (pyFTS.models.multivariate.partitioner.MultivariatePartitioner method)
- pseudologlikelihood() (pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution method) + +
- pwflrg_lhs_memberhip_fuzzyfied() (pyFTS.models.pwfts.ProbabilisticWeightedFTS method) +
-
pyFTS
@@ -929,6 +2019,76 @@
- module + +
+ -
+ pyFTS.benchmarks.arima
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.benchmarks
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.BSTS
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.knn
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.Measures
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.naive
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.quantreg
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.ResidualAnalysis
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.Tests
+
+
-
+
- module + +
+ -
+ pyFTS.benchmarks.Util
+
+
-
+
- module
-
@@ -957,6 +2117,13 @@
- module + +
+ -
+ pyFTS.common.fts
+
+
-
+
- module
-
@@ -985,6 +2152,13 @@
- module + +
+ -
+ pyFTS.common.Util
+
+
-
+
- module
- @@ -1057,6 +2231,8 @@
- module +
- pyFTS.data.EURUSD @@ -1106,8 +2282,6 @@
- module
-
pyFTS.data.Malaysia
@@ -1162,6 +2336,13 @@
- module + +
+ -
+ pyFTS.distributed.dispy
+
+
-
+
- module
-
@@ -1169,6 +2350,20 @@
- module + +
+ -
+ pyFTS.hyperparam.Evolutionary
+
+
-
+
- module + +
+ -
+ pyFTS.hyperparam.GridSearch
+
+
-
+
- module
-
@@ -1183,6 +2378,20 @@
- module + +
+ -
+ pyFTS.models.chen
+
+
-
+
- module + +
+ -
+ pyFTS.models.cheng
+
+
-
+
- module
-
@@ -1190,6 +2399,41 @@
- module + +
+ -
+ pyFTS.models.ensemble.ensemble
+
+
-
+
- module + +
+ -
+ pyFTS.models.ensemble.multiseasonal
+
+
-
+
- module + +
+ -
+ pyFTS.models.hofts
+
+
-
+
- module + +
+ -
+ pyFTS.models.hwang
+
+
-
+
- module + +
+ -
+ pyFTS.models.ifts
+
+
-
+
- module
-
@@ -1197,6 +2441,27 @@
- module + +
+ -
+ pyFTS.models.incremental.IncrementalEnsemble
+
+
-
+
- module + +
+ -
+ pyFTS.models.incremental.TimeVariant
+
+
-
+
- module + +
+ -
+ pyFTS.models.ismailefendi
+
+
-
+
- module
-
@@ -1204,6 +2469,13 @@
- module + +
+ -
+ pyFTS.models.multivariate.cmvfts
+
+
-
+
- module
-
@@ -1225,6 +2497,13 @@
- module + +
+ -
+ pyFTS.models.multivariate.granular
+
+
-
+
- module
-
@@ -1232,6 +2511,13 @@
- module + +
+ -
+ pyFTS.models.multivariate.mvfts
+
+
-
+
- module
-
@@ -1239,6 +2525,20 @@
- module + +
+ -
+ pyFTS.models.multivariate.variable
+
+
-
+
- module + +
+ -
+ pyFTS.models.multivariate.wmvfts
+
+
-
+
- module
-
@@ -1253,6 +2553,13 @@
- module + +
+ -
+ pyFTS.models.nonstationary.cvfts
+
+
-
+
- module
-
@@ -1260,6 +2567,20 @@
- module + +
+ -
+ pyFTS.models.nonstationary.honsfts
+
+
-
+
- module + +
+ -
+ pyFTS.models.nonstationary.nsfts
+
+
-
+
- module
-
@@ -1274,6 +2595,27 @@
- module + +
+ -
+ pyFTS.models.nonstationary.util
+
+
-
+
- module + +
+ -
+ pyFTS.models.pwfts
+
+
-
+
- module + +
+ -
+ pyFTS.models.sadaei
+
+
-
+
- module
-
@@ -1281,6 +2623,13 @@
- module + +
+ -
+ pyFTS.models.seasonal.cmsfts
+
+
-
+
- module
-
@@ -1288,6 +2637,13 @@
- module + +
+ -
+ pyFTS.models.seasonal.msfts
+
+
-
+
- module
-
@@ -1302,6 +2658,27 @@
- module + +
+ -
+ pyFTS.models.seasonal.sfts
+
+
-
+
- module + +
+ -
+ pyFTS.models.song
+
+
-
+
- module + +
+ -
+ pyFTS.models.yu
+
+
-
+
- module
-
@@ -1337,6 +2714,20 @@
- module + +
+ -
+ pyFTS.partitioners.Huarng
+
+
-
+
- module + +
+ -
+ pyFTS.partitioners.parallel_util
+
+
-
+
- module
-
@@ -1365,6 +2756,13 @@
- module + +
+ -
+ pyFTS.partitioners.Util
+
+
-
+
- module
-
@@ -1372,6 +2770,20 @@
- module + +
+ -
+ pyFTS.probabilistic.kde
+
+
-
+
- module + +
+ -
+ pyFTS.probabilistic.ProbabilityDistribution
+
+
-
+
- module
- sampler() (in module pyFTS.models.ensemble.ensemble) + +
- save_dataframe_interval() (in module pyFTS.benchmarks.Util) + +
- save_dataframe_point() (in module pyFTS.benchmarks.Util) + +
- save_dataframe_probabilistic() (in module pyFTS.benchmarks.Util) + +
- scale() (in module pyFTS.benchmarks.Util) +
- scale_down() (pyFTS.models.nonstationary.partitioners.PolynomialNonStationaryPartitioner method) + +
- scale_params() (in module pyFTS.benchmarks.Util)
- scale_up() (pyFTS.models.nonstationary.partitioners.PolynomialNonStationaryPartitioner method) @@ -1423,6 +2885,12 @@
- season (pyFTS.models.seasonal.partitioner.TimeGridPartitioner attribute) + +
- SeasonalEnsembleFTS (class in pyFTS.models.ensemble.multiseasonal) + +
- SeasonalFLRG (class in pyFTS.models.seasonal.sfts) + +
- SeasonalFTS (class in pyFTS.models.seasonal.sfts)
- SeasonalIndexer (class in pyFTS.models.seasonal.SeasonalIndexer) @@ -1433,6 +2901,10 @@
- second_of_hour (pyFTS.models.seasonal.common.DateTime attribute)
- second_of_minute (pyFTS.models.seasonal.common.DateTime attribute) + +
- SelecaoSimples_MenorRMSE() (in module pyFTS.benchmarks.benchmarks) + +
- set() (pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution method)
- set_data() (pyFTS.models.seasonal.SeasonalIndexer.DataFrameSeasonalIndexer method) @@ -1450,35 +2922,71 @@
- set_rhs() (pyFTS.models.multivariate.FLR.FLR method) -
- sharpness() (in module pyFTS.benchmarks.Measures) + +
- shortname (pyFTS.common.fts.FTS attribute) + +
- show_and_save_image() (in module pyFTS.common.Util)
- sigmf() (in module pyFTS.common.Membership)
- SignalEmulator (class in pyFTS.data.artificial) + +
- simple_model_predict() (in module pyFTS.distributed.dispy) + +
- simple_model_train() (in module pyFTS.distributed.dispy) + +
- simple_synthetic_dataframe() (in module pyFTS.benchmarks.Util) + +
- SimpleEnsembleFTS (class in pyFTS.models.ensemble.ensemble)
- simplenonstationary_gridpartitioner_builder() (in module pyFTS.models.nonstationary.partitioners)
- SimpleNonStationaryPartitioner (class in pyFTS.models.nonstationary.partitioners)
- SimplePartitioner (class in pyFTS.partitioners.Simple) + +
- simpleSearch_RMSE() (in module pyFTS.benchmarks.benchmarks) + +
- single_plot_residuals() (in module pyFTS.benchmarks.ResidualAnalysis)
- singleton() (in module pyFTS.common.Membership)
- SingletonPartitioner (class in pyFTS.partitioners.Singleton)
- sixth (pyFTS.models.seasonal.common.DateTime attribute) + +
- sliding_window() (in module pyFTS.common.Util) + +
- sliding_window_benchmarks() (in module pyFTS.benchmarks.benchmarks) + +
- sliding_window_benchmarks2() (in module pyFTS.benchmarks.benchmarks) + +
- smape() (in module pyFTS.benchmarks.Measures)
- SortedCollection (class in pyFTS.common.SortedCollection)
- splitAbove() (in module pyFTS.partitioners.Entropy)
- splitBelow() (in module pyFTS.partitioners.Entropy) + +
- standard_horizon (pyFTS.common.fts.FTS attribute) + +
- start_dispy_cluster() (in module pyFTS.distributed.dispy)
- stationary_gaussian() (pyFTS.data.artificial.SignalEmulator method) + +
- stats() (in module pyFTS.benchmarks.Util) + +
- stop_dispy_cluster() (in module pyFTS.distributed.dispy)
- strip_datepart() (in module pyFTS.models.seasonal.common) @@ -1492,9 +3000,83 @@
-
+
pyFTS.benchmarks.benchmarks.
distributed_model_train_test_time
(models, data, windowsize, train=0.8, **kwargs)[source]¶
+ Assess the train and test times for a given list of configured models and save the results on a database.
+-
+
- Parameters +
-
+
models – A list of FTS models already configured, but not yet trained,
+data – time series data, including train and test data
+windowsize – Train/test data windows
+train – Percent of data window that will be used to train the models
+kwargs –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
get_benchmark_interval_methods
()[source]¶
+ Return all non FTS methods for point_to_interval forecasting
+-
+
pyFTS.benchmarks.benchmarks.
get_benchmark_point_methods
()[source]¶
+ Return all non FTS methods for point forecasting
+-
+
pyFTS.benchmarks.benchmarks.
get_benchmark_probabilistic_methods
()[source]¶
+ Return all FTS methods for probabilistic forecasting
+-
+
pyFTS.benchmarks.benchmarks.
get_interval_methods
()[source]¶
+ Return all FTS methods for point_to_interval forecasting
+-
+
pyFTS.benchmarks.benchmarks.
get_point_methods
()[source]¶
+ Return all FTS methods for point forecasting
+-
+
pyFTS.benchmarks.benchmarks.
get_point_multivariate_methods
()[source]¶
+ Return all multivariate FTS methods por point forecasting
+-
+
pyFTS.benchmarks.benchmarks.
get_probabilistic_methods
()[source]¶
+ Return all FTS methods for probabilistic forecasting
+-
+
pyFTS.benchmarks.benchmarks.
multivariate_sliding_window_benchmarks2
(data, windowsize, train=0.8, **kwargs)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
mv_run_interval2
(mfts, train_data, test_data, window_key=None, **kwargs)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
mv_run_point2
(mfts, train_data, test_data, window_key=None, **kwargs)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
mv_run_probabilistic2
(mfts, train_data, test_data, window_key=None, **kwargs)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
pftsExploreOrderAndPartitions
(data, save=False, file=None)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
plot_compared_series
(original, models, colors, typeonlegend=False, save=False, file=None, tam=[20, 5], points=True, intervals=True, linewidth=1.5)[source]¶
+ Plot the forecasts of several one step ahead models, by point or by interval
+-
+
- Parameters +
-
+
original – Original time series data (list)
+models – List of models to compare
+colors – List of models colors
+typeonlegend – Add the type of forecast (point / interval) on legend
+save – Save the picture on file
+file – Filename to save the picture
+tam – Size of the picture
+points – True to plot the point forecasts, False otherwise
+intervals – True to plot the interval forecasts, False otherwise
+linewidth –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
plot_point
(axis, points, order, label, color='red', ls='-', linewidth=1)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
print_distribution_statistics
(original, models, steps, resolution)[source]¶
+ Run probabilistic benchmarks on given models and data and print the results
+-
+
- Parameters +
-
+
data – test data
+models – a list of FTS models to benchmark
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
print_interval_statistics
(original, models)[source]¶
+ Run interval benchmarks on given models and data and print the results
+-
+
- Parameters +
-
+
data – test data
+models – a list of FTS models to benchmark
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
print_point_statistics
(data, models, externalmodels=None, externalforecasts=None, indexers=None)[source]¶
+ Run point benchmarks on given models and data and print the results
+-
+
- Parameters +
-
+
data – test data
+models – a list of FTS models to benchmark
+externalmodels – a list with benchmark models (façades for other methods)
+externalforecasts –
+indexers –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
process_interval_jobs
(dataset, tag, job, conn)[source]¶
+ Extract information from an dictionary with interval benchmark results and save it on a database
+-
+
- Parameters +
-
+
dataset – the benchmark dataset name
+tag – alias for the benchmark group being executed
+job – a dictionary with the benchmark results
+conn – a connection to a Sqlite database
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
process_point_jobs
(dataset, tag, job, conn)[source]¶
+ Extract information from a dictionary with point benchmark results and save it on a database
+-
+
- Parameters +
-
+
dataset – the benchmark dataset name
+tag – alias for the benchmark group being executed
+job – a dictionary with the benchmark results
+conn – a connection to a Sqlite database
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
process_point_jobs2
(dataset, tag, job, conn)[source]¶
+ Extract information from a dictionary with point benchmark results and save it on a database
+-
+
- Parameters +
-
+
dataset – the benchmark dataset name
+tag – alias for the benchmark group being executed
+job – a dictionary with the benchmark results
+conn – a connection to a Sqlite database
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
process_probabilistic_jobs
(dataset, tag, job, conn)[source]¶
+ Extract information from an dictionary with probabilistic benchmark results and save it on a database
+-
+
- Parameters +
-
+
dataset – the benchmark dataset name
+tag – alias for the benchmark group being executed
+job – a dictionary with the benchmark results
+conn – a connection to a Sqlite database
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
process_probabilistic_jobs2
(dataset, tag, job, conn)[source]¶
+ Extract information from an dictionary with probabilistic benchmark results and save it on a database
+-
+
- Parameters +
-
+
dataset – the benchmark dataset name
+tag – alias for the benchmark group being executed
+job – a dictionary with the benchmark results
+conn – a connection to a Sqlite database
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.benchmarks.
run_interval
(mfts, partitioner, train_data, test_data, window_key=None, **kwargs)[source]¶
+ Run the interval forecasting benchmarks
+-
+
- Parameters +
-
+
mfts – FTS model
+partitioner – Universe of Discourse partitioner
+train_data – data used to train the model
+test_data – ata used to test the model
+window_key – id of the sliding window
+transformation – data transformation
+indexer – seasonal indexer
+
+- Returns +
a dictionary with the benchmark results
+
+
-
+
pyFTS.benchmarks.benchmarks.
run_interval2
(fts_method, order, partitioner_method, partitions, transformation, train_data, test_data, window_key=None, **kwargs)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
run_point
(mfts, partitioner, train_data, test_data, window_key=None, **kwargs)[source]¶
+ Run the point forecasting benchmarks
+-
+
- Parameters +
-
+
mfts – FTS model
+partitioner – Universe of Discourse partitioner
+train_data – data used to train the model
+test_data – ata used to test the model
+window_key – id of the sliding window
+transformation – data transformation
+indexer – seasonal indexer
+
+- Returns +
a dictionary with the benchmark results
+
+
-
+
pyFTS.benchmarks.benchmarks.
run_point2
(fts_method, order, partitioner_method, partitions, transformation, train_data, test_data, window_key=None, **kwargs)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
run_probabilistic
(mfts, partitioner, train_data, test_data, window_key=None, **kwargs)[source]¶
+ Run the probabilistic forecasting benchmarks
+-
+
- Parameters +
-
+
mfts – FTS model
+partitioner – Universe of Discourse partitioner
+train_data – data used to train the model
+test_data – ata used to test the model
+steps –
+resolution –
+window_key – id of the sliding window
+transformation – data transformation
+indexer – seasonal indexer
+
+- Returns +
a dictionary with the benchmark results
+
+
-
+
pyFTS.benchmarks.benchmarks.
run_probabilistic2
(fts_method, order, partitioner_method, partitions, transformation, train_data, test_data, window_key=None, **kwargs)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
simpleSearch_RMSE
(train, test, model, partitions, orders, save=False, file=None, tam=[10, 15], plotforecasts=False, elev=30, azim=144, intervals=False, parameters=None, partitioner=<class 'pyFTS.partitioners.Grid.GridPartitioner'>, transformation=None, indexer=None)[source]¶
+ -
+
pyFTS.benchmarks.benchmarks.
sliding_window_benchmarks
(data, windowsize, train=0.8, **kwargs)[source]¶
+ Sliding window benchmarks for FTS forecasters.
+For each data window, a train and test datasets will be splitted. For each train split, number of +partitions and partitioning method will be created a partitioner model. And for each partitioner, order, +steps ahead and FTS method a foreasting model will be trained.
+Then all trained models are benchmarked on the test data and the metrics are stored on a sqlite3 database +(identified by the ‘file’ parameter) for posterior analysis.
+All these process can be distributed on a dispy cluster, setting the atributed ‘distributed’ to true and +informing the list of dispy nodes on ‘nodes’ parameter.
+The number of experiments is determined by ‘windowsize’ and ‘inc’ parameters.
+-
+
- Parameters +
-
+
data – test data
+windowsize – size of sliding window
+train – percentual of sliding window data used to train the models
+kwargs – dict, optional arguments
+benchmark_methods – a list with Non FTS models to benchmark. The default is None.
+benchmark_methods_parameters – a list with Non FTS models parameters. The default is None.
+benchmark_models – A boolean value indicating if external FTS methods will be used on benchmark. The default is False.
+build_methods – A boolean value indicating if the default FTS methods will be used on benchmark. The default is True.
+dataset – the dataset name to identify the current set of benchmarks results on database.
+distributed – A boolean value indicating if the forecasting procedure will be distributed in a dispy cluster. . The default is False
+file – file path to save the results. The default is benchmarks.db.
+inc – a float on interval [0,1] indicating the percentage of the windowsize to move the window
+methods – a list with FTS class names. The default depends on the forecasting type and contains the list of all FTS methods.
+models – a list with prebuilt FTS objects. The default is None.
+nodes – a list with the dispy cluster nodes addresses. The default is [127.0.0.1].
+orders – a list with orders of the models (for high order models). The default is [1,2,3].
+partitions – a list with the numbers of partitions on the Universe of Discourse. The default is [10].
+partitioners_models – a list with prebuilt Universe of Discourse partitioners objects. The default is None.
+partitioners_methods – a list with Universe of Discourse partitioners class names. The default is [partitioners.Grid.GridPartitioner].
+progress – If true a progress bar will be displayed during the benchmarks. The default is False.
+start – in the multi step forecasting, the index of the data where to start forecasting. The default is 0.
+steps_ahead – a list with the forecasting horizons, i. e., the number of steps ahead to forecast. The default is 1.
+tag – a name to identify the current set of benchmarks results on database.
+type – the forecasting type, one of these values: point(default), interval or distribution. The default is point.
+transformations – a list with data transformations do apply . The default is [None].
+
+
-
+
pyFTS.benchmarks.Measures.
TheilsInequality
(targets, forecasts)[source]¶
+ Theil’s Inequality Coefficient
+-
+
- Parameters +
-
+
targets –
+forecasts –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Measures.
UStatistic
(targets, forecasts)[source]¶
+ Theil’s U Statistic
+-
+
- Parameters +
-
+
targets –
+forecasts –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Measures.
acf
(data, k)[source]¶
+ Autocorrelation function estimative
+-
+
- Parameters +
-
+
data –
+k –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Measures.
brier_score
(targets, densities)[source]¶
+ Brier Score for probabilistic forecasts. +Brier (1950). “Verification of Forecasts Expressed in Terms of Probability”. Monthly Weather Review. 78: 1–3.
+-
+
- Parameters +
-
+
targets – a list with the target values
+densities – a list with pyFTS.probabil objectsistic.ProbabilityDistribution
+
+- Returns +
float
+
+
-
+
pyFTS.benchmarks.Measures.
coverage
(targets, forecasts)[source]¶
+ Percent of target values that fall inside forecasted interval
+-
+
pyFTS.benchmarks.Measures.
crps
(targets, densities)[source]¶
+ Continuous Ranked Probability Score
+-
+
- Parameters +
-
+
targets – a list with the target values
+densities – a list with pyFTS.probabil objectsistic.ProbabilityDistribution
+
+- Returns +
float
+
+
-
+
pyFTS.benchmarks.Measures.
get_distribution_ahead_statistics
(data, distributions)[source]¶
+ Get CRPS statistic and time for a forecasting model
+-
+
- Parameters +
-
+
data – test data
+model – FTS model with probabilistic forecasting capability
+kwargs –
+
+- Returns +
a list with the CRPS and execution time
+
+
-
+
pyFTS.benchmarks.Measures.
get_distribution_statistics
(data, model, **kwargs)[source]¶
+ Get CRPS statistic and time for a forecasting model
+-
+
- Parameters +
-
+
data – test data
+model – FTS model with probabilistic forecasting capability
+kwargs –
+
+- Returns +
a list with the CRPS and execution time
+
+
-
+
pyFTS.benchmarks.Measures.
get_interval_ahead_statistics
(data, intervals, **kwargs)[source]¶
+ Condensate all measures for point interval forecasters
+-
+
- Parameters +
-
+
data – test data
+intervals – predicted intervals for each datapoint
+kwargs –
+
+- Returns +
a list with the sharpness, resolution, coverage, .05 pinball mean, +.25 pinball mean, .75 pinball mean and .95 pinball mean.
+
+
-
+
pyFTS.benchmarks.Measures.
get_interval_statistics
(data, model, **kwargs)[source]¶
+ Condensate all measures for point interval forecasters
+-
+
- Parameters +
-
+
data – test data
+model – FTS model with interval forecasting capability
+kwargs –
+
+- Returns +
a list with the sharpness, resolution, coverage, .05 pinball mean, +.25 pinball mean, .75 pinball mean and .95 pinball mean.
+
+
-
+
pyFTS.benchmarks.Measures.
get_point_ahead_statistics
(data, forecasts, **kwargs)[source]¶
+ Condensate all measures for point forecasters
+-
+
- Parameters +
-
+
data – test data
+model – FTS model with point forecasting capability
+kwargs –
+
+- Returns +
a list with the RMSE, SMAPE and U Statistic
+
+
-
+
pyFTS.benchmarks.Measures.
get_point_statistics
(data, model, **kwargs)[source]¶
+ Condensate all measures for point forecasters
+-
+
- Parameters +
-
+
data – test data
+model – FTS model with point forecasting capability
+kwargs –
+
+- Returns +
a list with the RMSE, SMAPE and U Statistic
+
+
-
+
pyFTS.benchmarks.Measures.
logarithm_score
(targets, densities)[source]¶
+ Logarithm Score for probabilistic forecasts. +Good IJ (1952). “Rational Decisions.”Journal of the Royal Statistical Society B,14(1),107–114. URLhttps://www.jstor.org/stable/2984087.
+-
+
- Parameters +
-
+
targets – a list with the target values
+densities – a list with pyFTS.probabil objectsistic.ProbabilityDistribution
+
+- Returns +
float
+
+
-
+
pyFTS.benchmarks.Measures.
mape
(targets, forecasts)[source]¶
+ Mean Average Percentual Error
+-
+
- Parameters +
-
+
targets –
+forecasts –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Measures.
pinball
(tau, target, forecast)[source]¶
+ Pinball loss function. Measure the distance of forecast to the tau-quantile of the target
+-
+
- Parameters +
-
+
tau – quantile value in the range (0,1)
+target –
+forecast –
+
+- Returns +
float, distance of forecast to the tau-quantile of the target
+
+
-
+
pyFTS.benchmarks.Measures.
pinball_mean
(tau, targets, forecasts)[source]¶
+ Mean pinball loss value of the forecast for a given tau-quantile of the targets
+-
+
- Parameters +
-
+
tau – quantile value in the range (0,1)
+targets – list of target values
+forecasts – list of prediction intervals
+
+- Returns +
float, the pinball loss mean for tau quantile
+
+
-
+
pyFTS.benchmarks.Measures.
resolution
(forecasts)[source]¶
+ Resolution - Standard deviation of the intervals
+-
+
pyFTS.benchmarks.Measures.
rmse
(targets, forecasts)[source]¶
+ Root Mean Squared Error
+-
+
- Parameters +
-
+
targets –
+forecasts –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Measures.
rmse_interval
(targets, forecasts)[source]¶
+ Root Mean Squared Error
+-
+
- Parameters +
-
+
targets –
+forecasts –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Measures.
sharpness
(forecasts)[source]¶
+ Sharpness - Mean size of the intervals
+-
+
pyFTS.benchmarks.Measures.
smape
(targets, forecasts, type=2)[source]¶
+ Symmetric Mean Average Percentual Error
+-
+
- Parameters +
-
+
targets –
+forecasts –
+type –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Measures.
winkler_mean
(tau, targets, forecasts)[source]¶
+ Mean Winkler score value of the forecast for a given tau-quantile of the targets
+-
+
- Parameters +
-
+
tau – quantile value in the range (0,1)
+targets – list of target values
+forecasts – list of prediction intervals
+
+- Returns +
float, the Winkler score mean for tau quantile
+
+
-
+
pyFTS.benchmarks.ResidualAnalysis.
compare_residuals
(data, models, alpha=0.05)[source]¶
+ Compare residual’s statistics of several models
+-
+
- Parameters +
-
+
data – test data
+models –
+
+- Returns +
a Pandas dataframe with the Box-Ljung statistic for each model
+
+
-
+
pyFTS.benchmarks.ResidualAnalysis.
ljung_box_test
(residuals, lags=[1, 2, 3], alpha=0.5)[source]¶
+ -
+
pyFTS.benchmarks.ResidualAnalysis.
plot_residuals_by_model
(targets, models, tam=[8, 8], save=False, file=None)[source]¶
+ -
+
pyFTS.benchmarks.Tests.
BoxLjungStatistic
(data, h)[source]¶
+ Q Statistic for Ljung–Box test
+-
+
- Parameters +
-
+
data –
+h –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Tests.
BoxPierceStatistic
(data, h)[source]¶
+ Q Statistic for Box-Pierce test
+-
+
- Parameters +
-
+
data –
+h –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Tests.
format_experiment_table
(df, exclude=[], replace={}, csv=True, std=False)[source]¶
+ -
+
pyFTS.benchmarks.Tests.
post_hoc_tests
(post_hoc, control_method, alpha=0.05, method='finner')[source]¶
+ Finner paired post-hoc test with NSFTS as control method.
+$H_0$: There is no significant difference between the means
+$H_1$: There is a significant difference between the means
+-
+
- Parameters +
-
+
post_hoc –
+control_method –
+alpha –
+method –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Tests.
test_mean_equality
(tests, alpha=0.05, method='friedman')[source]¶
+ Test for the equality of the means, with alpha confidence level.
+H_0: There’s no significant difference between the means +H_1: There is at least one significant difference between the means
+-
+
- Parameters +
-
+
tests –
+alpha –
+method –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Util.
create_benchmark_tables
(conn)[source]¶
+ Create a sqlite3 table designed to store benchmark results.
+-
+
- Parameters +
conn – a sqlite3 database connection
+
+
-
+
pyFTS.benchmarks.Util.
get_dataframe_from_bd
(file, filter)[source]¶
+ Query the sqlite benchmark database and return a pandas dataframe with the results
+-
+
- Parameters +
-
+
file – the url of the benchmark database
+filter – sql conditions to filter
+
+- Returns +
pandas dataframe with the query results
+
+
-
+
pyFTS.benchmarks.Util.
insert_benchmark
(data, conn)[source]¶
+ Insert benchmark data on database
+-
+
- Parameters +
data – a tuple with the benchmark data with format:
+
+
ID: integer incremental primary key +Date: Date/hour of benchmark execution +Dataset: Identify on which dataset the dataset was performed +Tag: a user defined word that indentify a benchmark set +Type: forecasting type (point, interval, distribution) +Model: FTS model +Transformation: The name of data transformation, if one was used +Order: the order of the FTS method +Scheme: UoD partitioning scheme +Partitions: Number of partitions +Size: Number of rules of the FTS model +Steps: prediction horizon, i. e., the number of steps ahead +Measure: accuracy measure +Value: the measure value
+-
+
- Parameters +
conn – a sqlite3 database connection
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Util.
open_benchmark_db
(name)[source]¶
+ Open a connection with a Sqlite database designed to store benchmark results.
+-
+
- Parameters +
name – database filenem
+
+- Returns +
a sqlite3 database connection
+
+
-
+
pyFTS.benchmarks.Util.
plot_dataframe_interval
(file_synthetic, file_analytic, experiments, tam, save=False, file=None, sort_columns=['COVAVG', 'SHARPAVG', 'COVSTD', 'SHARPSTD'], sort_ascend=[True, False, True, True], save_best=False, ignore=None, replace=None)[source]¶
+ -
+
pyFTS.benchmarks.Util.
plot_dataframe_interval_pinball
(file_synthetic, file_analytic, experiments, tam, save=False, file=None, sort_columns=['COVAVG', 'SHARPAVG', 'COVSTD', 'SHARPSTD'], sort_ascend=[True, False, True, True], save_best=False, ignore=None, replace=None)[source]¶
+ -
+
pyFTS.benchmarks.Util.
plot_dataframe_point
(file_synthetic, file_analytic, experiments, tam, save=False, file=None, sort_columns=['UAVG', 'RMSEAVG', 'USTD', 'RMSESTD'], sort_ascend=[1, 1, 1, 1], save_best=False, ignore=None, replace=None)[source]¶
+ -
+
pyFTS.benchmarks.Util.
plot_dataframe_probabilistic
(file_synthetic, file_analytic, experiments, tam, save=False, file=None, sort_columns=['CRPS1AVG', 'CRPS2AVG', 'CRPS1STD', 'CRPS2STD'], sort_ascend=[True, True, True, True], save_best=False, ignore=None, replace=None)[source]¶
+ -
+
pyFTS.benchmarks.Util.
process_common_data
(dataset, tag, type, job)[source]¶
+ Wraps benchmark information on a tuple for sqlite database
+-
+
- Parameters +
-
+
dataset – benchmark dataset
+tag – benchmark set alias
+type – forecasting type
+job – a dictionary with benchmark data
+
+- Returns +
tuple for sqlite database
+
+
-
+
pyFTS.benchmarks.Util.
process_common_data2
(dataset, tag, type, job)[source]¶
+ Wraps benchmark information on a tuple for sqlite database
+-
+
- Parameters +
-
+
dataset – benchmark dataset
+tag – benchmark set alias
+type – forecasting type
+job – a dictionary with benchmark data
+
+- Returns +
tuple for sqlite database
+
+
-
+
pyFTS.benchmarks.Util.
save_dataframe_interval
(coverage, experiments, file, objs, resolution, save, sharpness, synthetic, times, q05, q25, q75, q95, steps, method)[source]¶
+ -
+
pyFTS.benchmarks.Util.
save_dataframe_point
(experiments, file, objs, rmse, save, synthetic, smape, times, u, steps, method)[source]¶
+ Create a dataframe to store the benchmark results
+-
+
- Parameters +
-
+
experiments – dictionary with the execution results
+file –
+objs –
+rmse –
+save –
+synthetic –
+smape –
+times –
+u –
+
+- Returns +
- + +
-
+
pyFTS.benchmarks.Util.
save_dataframe_probabilistic
(experiments, file, objs, crps, times, save, synthetic, steps, method)[source]¶
+ Save benchmark results for m-step ahead probabilistic forecasters +:param experiments: +:param file: +:param objs: +:param crps_interval: +:param crps_distr: +:param times: +:param times2: +:param save: +:param synthetic: +:return:
+-
+
pyFTS.benchmarks.Util.
simple_synthetic_dataframe
(file, tag, measure, sql=None)[source]¶
+ Read experiments results from sqlite3 database in ‘file’, make a synthesis of the results +of the metric ‘measure’ with the same ‘tag’, returning a Pandas DataFrame with the mean results.
+-
+
- Parameters +
-
+
file – sqlite3 database file name
+tag – common tag of the experiments
+measure – metric to synthetize
+
+- Returns +
Pandas DataFrame with the mean results
+
+
-
+
pyFTS.benchmarks.Util.
unified_scaled_interval
(experiments, tam, save=False, file=None, sort_columns=['COVAVG', 'SHARPAVG', 'COVSTD', 'SHARPSTD'], sort_ascend=[True, False, True, True], save_best=False, ignore=None, replace=None)[source]¶
+ -
+
pyFTS.benchmarks.Util.
unified_scaled_interval_pinball
(experiments, tam, save=False, file=None, sort_columns=['COVAVG', 'SHARPAVG', 'COVSTD', 'SHARPSTD'], sort_ascend=[True, False, True, True], save_best=False, ignore=None, replace=None)[source]¶
+ -
+class
pyFTS.benchmarks.arima.
ARIMA
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Façade for statsmodels.tsa.arima_model
+ + +-
+
-
+
forecast
(ndata, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(data, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_interval
(ndata, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+
forecast_distribution
(data, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
-
+class
pyFTS.benchmarks.knn.
KNearestNeighbors
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
A façade for sklearn.neighbors
+-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(data, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_interval
(data, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+
forecast_distribution
(data, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
-
+class
pyFTS.benchmarks.naive.
Naive
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Naïve Forecasting method
+ + +-
+class
pyFTS.benchmarks.quantreg.
QuantileRegression
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Façade for statsmodels.regression.quantile_regression
+-
+
-
+
forecast
(ndata, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(ndata, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_interval
(ndata, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+
forecast_distribution
(ndata, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
-
+class
pyFTS.benchmarks.BSTS.
ARIMA
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Façade for statsmodels.tsa.arima_model
+-
+
-
+
forecast
(ndata, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(data, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_interval
(ndata, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+
forecast_distribution
(data, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
- pyFTS.benchmarks package
- Module contents
- Submodules -
- pyFTS.benchmarks.benchmarks module -
- pyFTS.benchmarks.Measures module -
- pyFTS.benchmarks.ResidualAnalysis module -
- pyFTS.benchmarks.Tests module -
- pyFTS.benchmarks.Util module -
- pyFTS.benchmarks.arima module -
- pyFTS.benchmarks.knn module -
- pyFTS.benchmarks.naive module -
- pyFTS.benchmarks.quantreg module +
- pyFTS.benchmarks.benchmarks module +
- pyFTS.benchmarks.Measures module +
- pyFTS.benchmarks.ResidualAnalysis module +
- pyFTS.benchmarks.Tests module +
- pyFTS.benchmarks.Util module +
- pyFTS.benchmarks.arima module +
- pyFTS.benchmarks.knn module +
- pyFTS.benchmarks.naive module +
- pyFTS.benchmarks.quantreg module
- pyFTS.benchmarks.gaussianproc module -
- pyFTS.benchmarks.BSTS module +
- pyFTS.benchmarks.BSTS module
diff --git a/docs/build/html/pyFTS.common.html b/docs/build/html/pyFTS.common.html
index c4dabe1..c7b82d1 100644
--- a/docs/build/html/pyFTS.common.html
+++ b/docs/build/html/pyFTS.common.html
@@ -762,11 +762,272 @@ bisect but with a simpler API and support for key functions.
-
+
pyFTS.common.Util.
current_milli_time
()¶
+ -
+
pyFTS.common.Util.
load_obj
(file)[source]¶
+ Load to memory an object stored filesystem. This function depends on Dill package
+-
+
- Parameters +
file – file name where the object is stored
+
+- Returns +
object
+
+
-
+
pyFTS.common.Util.
persist_env
(file)[source]¶
+ Persist an entire environment on file. This function depends on Dill package
+-
+
- Parameters +
file – file name to store the environment
+
+
-
+
pyFTS.common.Util.
persist_obj
(obj, file)[source]¶
+ Persist an object on filesystem. This function depends on Dill package
+-
+
- Parameters +
-
+
obj – object on memory
+file – file name to store the object
+
+
-
+
pyFTS.common.Util.
plot_compared_intervals_ahead
(original, models, colors, distributions, time_from, time_to, intervals=True, save=False, file=None, tam=[20, 5], resolution=None, cmap='Blues', linewidth=1.5)[source]¶
+ Plot the forecasts of several one step ahead models, by point or by interval
+-
+
- Parameters +
-
+
original – Original time series data (list)
+models – List of models to compare
+colors – List of models colors
+distributions – True to plot a distribution
+time_from – index of data poit to start the ahead forecasting
+time_to – number of steps ahead to forecast
+interpol – Fill space between distribution plots
+save – Save the picture on file
+file – Filename to save the picture
+tam – Size of the picture
+resolution –
+cmap – Color map to be used on distribution plot
+option – Distribution type to be passed for models
+
+- Returns +
- + +
-
+
pyFTS.common.Util.
plot_density_rectange
(ax, cmap, density, fig, resolution, time_from, time_to)[source]¶
+ Auxiliar function to plot_compared_intervals_ahead
+-
+
pyFTS.common.Util.
plot_distribution
(ax, cmap, probabilitydist, fig, time_from, reference_data=None)[source]¶
+ Plot forecasted ProbabilityDistribution objects on a matplotlib axis
+-
+
- Parameters +
-
+
ax – matplotlib axis
+cmap – matplotlib colormap name
+probabilitydist – list of ProbabilityDistribution objects
+fig – matplotlib figure
+time_from – starting time (on x axis) to begin the plots
+reference_data –
+
+- Returns +
- + +
-
+
pyFTS.common.Util.
plot_distribution2
(probabilitydist, data, **kwargs)[source]¶
+ Plot distributions in y-axis over the time (x-axis)
+-
+
- Parameters +
-
+
probabilitydist – the forecasted probability distributions to plot
+data – the original test sample
+start_at – the time index (inside of data) to start to plot the probability distributions
+ax – a matplotlib axis. If no value was provided a new axis is created.
+cmap – a matplotlib colormap name, the default value is ‘Blues’
+quantiles – the list of quantiles intervals to plot, e. g. [.05, .25, .75, .95]
+median – a boolean value indicating if the median value will be plot.
+
+
-
+
pyFTS.common.Util.
plot_distribution_tiled
(distributions, data=None, rows=5, cols=5, index=None, axis=None, size=[10, 20])[source]¶
+ Plot one distribution individually in each axis, with probability in y-axis and UoD on x-axis
+-
+
- Parameters +
-
+
distributions –
+data –
+rows –
+cols –
+index –
+axis –
+size –
+
+- Returns +
- + +
-
+
pyFTS.common.Util.
plot_interval
(axis, intervals, order, label, color='red', typeonlegend=False, ls='-', linewidth=1)[source]¶
+ Plot forecasted intervals on matplotlib
+-
+
- Parameters +
-
+
axis – matplotlib axis
+intervals – list of forecasted intervals
+order – order of the model that create the forecasts
+label – figure label
+color – matplotlib color name
+typeonlegend –
+ls – matplotlib line style
+linewidth – matplotlib width
+
+- Returns +
- + +
-
+
pyFTS.common.Util.
plot_interval2
(intervals, data, **kwargs)[source]¶
+ Plot forecasted intervals on matplotlib
+-
+
- Parameters +
-
+
intervals – list of forecasted intervals
+data – the original test sample
+start_at – the time index (inside of data) to start to plot the intervals
+label – figure label
+color – matplotlib color name
+typeonlegend –
+ls – matplotlib line style
+linewidth – matplotlib width
+
+
-
+
pyFTS.common.Util.
plot_rules
(model, size=[5, 5], axis=None, rules_by_axis=None, columns=1)[source]¶
+ Plot the FLRG rules of a FTS model on a matplotlib axis
+-
+
- Parameters +
-
+
model – FTS model
+size – figure size
+axis – matplotlib axis
+rules_by_axis – number of rules plotted by column
+columns – number of columns
+
+- Returns +
- + +
-
+
pyFTS.common.Util.
show_and_save_image
(fig, file, flag, lgd=None)[source]¶
+ Show and image and save on file
+-
+
- Parameters +
-
+
fig – Matplotlib Figure object
+file – filename to save the picture
+flag – if True the image will be saved
+lgd – legend
+
+
-
+
pyFTS.common.Util.
sliding_window
(data, windowsize, train=0.8, inc=0.1, **kwargs)[source]¶
+ Sliding window method of cross validation for time series
+-
+
- Parameters +
-
+
data – the entire dataset
+windowsize – window size
+train – percentual of the window size will be used for training the models
+inc – percentual of data used for slide the window
+
+- Returns +
window count, training set, test set
+
+
-
+class
pyFTS.common.fts.
FTS
(**kwargs)[source]¶
+ Bases:
+object
Fuzzy Time Series object model
+-
+
-
+
alpha_cut
¶
+ A float with the minimal membership to be considered on fuzzyfication process
+
-
+
-
+
append_rule
(flrg)[source]¶
+ Append FLRG rule to the model
+-
+
- Parameters +
flrg – rule
+
+- Returns +
- + +
-
+
-
+
apply_inverse_transformations
(data, params=None, **kwargs)[source]¶
+ Apply the data transformations for data postprocessing
+-
+
- Parameters +
-
+
data – input data
+params – transformation parameters
+updateUoD –
+kwargs –
+
+- Returns +
postprocessed data
+
+
-
+
-
+
apply_transformations
(data, params=None, updateUoD=False, **kwargs)[source]¶
+ Apply the data transformations for data preprocessing
+-
+
- Parameters +
-
+
data – input data
+params – transformation parameters
+updateUoD –
+kwargs –
+
+- Returns +
preprocessed data
+
+
-
+
-
+
auto_update
¶
+ A boolean value indicating that model is incremental
+
-
+
-
+
benchmark_only
¶
+ A boolean value indicating a façade for external (non-FTS) model used on benchmarks or ensembles.
+
-
+
-
+
clone_parameters
(model)[source]¶
+ Import the parameters values from other model
+-
+
- Parameters +
model – a model to clone the parameters
+
+
-
+
-
+
detail
¶
+ A string with the model detailed information
+
-
+
-
+
fit
(ndata, **kwargs)[source]¶
+ Fit the model’s parameters based on the training data.
+-
+
- Parameters +
-
+
ndata – training time series data
+kwargs –
+num_batches – split the training data in num_batches to save memory during the training process
+save_model – save final model on disk
+batch_save – save the model between each batch
+file_path – path to save the model
+distributed – boolean, indicate if the training procedure will be distributed in a dispy cluster
+nodes – a list with the dispy cluster nodes addresses
+
+
-
+
-
+
flrgs
¶
+ The list of Fuzzy Logical Relationship Groups - FLRG
+
-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(data, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_interval
(data, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+
forecast_ahead_multivariate
(data, steps, **kwargs)[source]¶
+ Multivariate forecast n step ahead
+-
+
- Parameters +
-
+
data – Pandas dataframe with one column for each variable and with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a Pandas Dataframe object representing the forecasted values for each variable
+
+
-
+
-
+
forecast_distribution
(data, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
-
+
forecast_interval
(data, **kwargs)[source]¶
+ Interval forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the prediction intervals
+
+
-
+
-
+
forecast_multivariate
(data, **kwargs)[source]¶
+ Multivariate forecast one step ahead
+-
+
- Parameters +
-
+
data – Pandas dataframe with one column for each variable and with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a Pandas Dataframe object representing the forecasted values for each variable
+
+
-
+
-
+
forecast_step
(data, step, **kwargs)[source]¶
+ Point forecast for H steps ahead, where H is given by the step parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+step – the forecasting horizon (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
fuzzy
(data)[source]¶
+ Fuzzify a data point
+-
+
- Parameters +
data – data point
+
+- Returns +
maximum membership fuzzy set
+
+
-
+
-
+
get_UoD
()[source]¶
+ Returns the interval of the known bounds of the universe of discourse (UoD), i. e., +the known minimum and maximum values of the time series.
+-
+
- Returns +
A set with the lower and the upper bounds of the UoD
+
+
-
+
-
+
has_interval_forecasting
¶
+ A boolean value indicating if the model supports interval forecasting, default: False
+
-
+
-
+
has_point_forecasting
¶
+ A boolean value indicating if the model supports point forecasting, default: True
+
-
+
-
+
has_probability_forecasting
¶
+ A boolean value indicating if the model support probabilistic forecasting, default: False
+
-
+
-
+
has_seasonality
¶
+ A boolean value indicating if the model supports seasonal indexers, default: False
+
-
+
-
+
indexer
¶
+ An pyFTS.models.seasonal.Indexer object for indexing the time series data
+
-
+
-
+
is_clustered
¶
+ A boolean value indicating if the model support multivariate time series (Pandas DataFrame), but works like +a monovariate method, default: False
+
-
+
-
+
is_high_order
¶
+ A boolean value indicating if the model support orders greater than 1, default: False
+
-
+
-
+
is_multivariate
¶
+ A boolean value indicating if the model support multivariate time series (Pandas DataFrame), default: False
+
-
+
-
+
is_time_variant
¶
+ A boolean value indicating if this model is time variant
+
-
+
-
+
is_wrapper
¶
+ Indicates that this model is a wrapper for other(s) method(s)
+
-
+
-
+
lags
¶
+ The list of lag indexes for high order models
+
-
+
-
+
len_total
()[source]¶
+ Total length of the model, adding the number of terms in all rules
+-
+
- Returns +
- + +
-
+
-
+
log
¶
+
-
+
-
+
max_lag
¶
+ A integer indicating the largest lag used by the model. This value also indicates the minimum number of past lags +needed to forecast a single step ahead
+
-
+
-
+
merge
(model)[source]¶
+ Merge the FLRG rules from other model
+-
+
- Parameters +
model – source model
+
+- Returns +
- + +
-
+
-
+
min_order
¶
+ In high order models, this integer value indicates the minimal order supported for the model, default: 1
+
-
+
-
+
name
¶
+ A string with the model name
+
-
+
-
+
offset
()[source]¶
+ Returns the number of lags to skip in the input test data in order to synchronize it with +the forecasted values given by the predict function. This is necessary due to the order of the +model, among other parameters.
+-
+
- Returns +
An integer with the number of lags to skip
+
+
-
+
-
+
order
¶
+ A integer with the model order (number of past lags are used on forecasting)
+
-
+
-
+
original_max
¶
+ A float with the upper limit of the Universe of Discourse, the maximal value found on training data
+
-
+
-
+
original_min
¶
+ A float with the lower limit of the Universe of Discourse, the minimal value found on training data
+
-
+
-
+
partitioner
¶
+ A pyFTS.partitioners.Partitioner object with the Universe of Discourse partitioner used on the model. This is a mandatory dependecy.
+
-
+
-
+
predict
(data, **kwargs)[source]¶
+ Forecast using trained model
+-
+
- Parameters +
-
+
data – time series with minimal length to the order of the model
+type – the forecasting type, one of these values: point(default), interval, distribution or multivariate.
+steps_ahead – The forecasting path H, i. e., tell the model to forecast from t+1 to t+H.
+step_to – The forecasting step H, i. e., tell the model to forecast to t+H for each input sample
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default value: 0)
+distributed – boolean, indicate if the forecasting procedure will be distributed in a dispy cluster (default value: False)
+nodes – a list with the dispy cluster nodes addresses
+explain – try to explain, step by step, the one-step-ahead point forecasting result given the input data. (default value: False)
+generators – for multivariate methods on multi step ahead forecasting, generators is a dict where the keys +are the dataframe columun 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 or trained FTS +models that accept the actual values and forecast new ones.
+
+- Returns +
a numpy array with the forecasted data
+
+
-
+
-
+
reset_calculated_values
()[source]¶
+ Reset all pre-calculated values on the FLRG’s
+-
+
- Returns +
- + +
-
+
-
+
shortname
¶
+ A string with a short name or alias for the model
+
-
+
-
+
standard_horizon
¶
+ Standard forecasting horizon (Default: 1)
+
-
+
-
+
train
(data, **kwargs)[source]¶
+ Method specific parameter fitting
+-
+
- Parameters +
-
+
data – training time series data
+kwargs – Method specific parameters
+
+
-
+
-
+
transformations
¶
+ A list with the data transformations (common.Transformations) applied on model pre and post processing, default: []
+
-
+
-
+
transformations_param
¶
+ A list with the specific parameters for each data transformation
+
-
+
-
+
uod_clip
¶
+ Flag indicating if the test data will be clipped inside the training Universe of Discourse
+
-
+
- pyFTS.common.FuzzySet module
- pyFTS.common.Membership module
- pyFTS.common.SortedCollection module -
- pyFTS.common.transformations module -
- pyFTS.common.Util module +
- pyFTS.common.Util module
- pyFTS.common.flrg module -
- pyFTS.common.fts module +
- pyFTS.common.fts module
- pyFTS.common.tree module diff --git a/docs/build/html/pyFTS.common.transformations.html b/docs/build/html/pyFTS.common.transformations.html index 0d8c65e..ef76567 100644 --- a/docs/build/html/pyFTS.common.transformations.html +++ b/docs/build/html/pyFTS.common.transformations.html @@ -89,6 +89,9 @@
- pyFTS.common.transformations.normalization module
- pyFTS.common.transformations.roi module
- pyFTS.common.transformations.scale module +
- pyFTS.common.transformations.smoothing module
- pyFTS.common.transformations.som module
- pyFTS.common.transformations.transformation module
- pyFTS.common.transformations.trend module diff --git a/docs/build/html/pyFTS.distributed.html b/docs/build/html/pyFTS.distributed.html index 77a1d17..b846d38 100644 --- a/docs/build/html/pyFTS.distributed.html +++ b/docs/build/html/pyFTS.distributed.html @@ -71,8 +71,67 @@
-
+
pyFTS.distributed.dispy.
distributed_predict
(model, parameters, nodes, data, num_batches, **kwargs)[source]¶
+ -
+
pyFTS.distributed.dispy.
distributed_train
(model, train_method, nodes, fts_method, data, num_batches=10, train_parameters={}, **kwargs)[source]¶
+ -
+
pyFTS.distributed.dispy.
start_dispy_cluster
(method, nodes)[source]¶
+ Start a new Dispy cluster on ‘nodes’ to execute the method ‘method’
+-
+
- Parameters +
-
+
method – function to be executed on each cluster node
+nodes – list of node names or IP’s.
+
+- Returns +
the dispy cluster instance and the http_server for monitoring
+
+
- pyFTS.distributed package diff --git a/docs/build/html/pyFTS.html b/docs/build/html/pyFTS.html index 472a6fb..7fb0ad2 100644 --- a/docs/build/html/pyFTS.html +++ b/docs/build/html/pyFTS.html @@ -71,17 +71,17 @@
- pyFTS.benchmarks package
- Module contents
- Submodules -
- pyFTS.benchmarks.benchmarks module -
- pyFTS.benchmarks.Measures module -
- pyFTS.benchmarks.ResidualAnalysis module -
- pyFTS.benchmarks.Tests module -
- pyFTS.benchmarks.Util module -
- pyFTS.benchmarks.arima module -
- pyFTS.benchmarks.knn module -
- pyFTS.benchmarks.naive module -
- pyFTS.benchmarks.quantreg module +
- pyFTS.benchmarks.benchmarks module +
- pyFTS.benchmarks.Measures module +
- pyFTS.benchmarks.ResidualAnalysis module +
- pyFTS.benchmarks.Tests module +
- pyFTS.benchmarks.Util module +
- pyFTS.benchmarks.arima module +
- pyFTS.benchmarks.knn module +
- pyFTS.benchmarks.naive module +
- pyFTS.benchmarks.quantreg module
- pyFTS.benchmarks.gaussianproc module -
- pyFTS.benchmarks.BSTS module +
- pyFTS.benchmarks.BSTS module
- pyFTS.common package
-
@@ -92,10 +92,9 @@
- pyFTS.common.FuzzySet module
- pyFTS.common.Membership module
- pyFTS.common.SortedCollection module -
- pyFTS.common.transformations module -
- pyFTS.common.Util module +
- pyFTS.common.Util module
- pyFTS.common.flrg module -
- pyFTS.common.fts module +
- pyFTS.common.fts module
- pyFTS.common.tree module
@@ -108,6 +107,7 @@
- pyFTS.common.transformations.normalization module
- pyFTS.common.transformations.roi module
- pyFTS.common.transformations.scale module +
- pyFTS.common.transformations.smoothing module
- pyFTS.common.transformations.som module
- pyFTS.common.transformations.transformation module
- pyFTS.common.transformations.trend module @@ -144,7 +144,7 @@
- pyFTS.distributed package @@ -152,8 +152,8 @@
- Module contents
- Submodules
- pyFTS.hyperparam.Util module -
- pyFTS.hyperparam.GridSearch module -
- pyFTS.hyperparam.Evolutionary module +
- pyFTS.hyperparam.GridSearch module +
- pyFTS.hyperparam.Evolutionary module
- pyFTS.models package
-
@@ -161,16 +161,16 @@
- Subpackages
- pyFTS.models.ensemble package
- pyFTS.models.incremental package
- pyFTS.models.multivariate package
-
@@ -178,53 +178,53 @@
- Submodules
- pyFTS.models.multivariate.FLR module
- pyFTS.models.multivariate.common module -
- pyFTS.models.multivariate.variable module +
- pyFTS.models.multivariate.variable module
- pyFTS.models.multivariate.flrg module
- pyFTS.models.multivariate.partitioner module
- pyFTS.models.multivariate.grid module -
- pyFTS.models.multivariate.mvfts module -
- pyFTS.models.multivariate.wmvfts module -
- pyFTS.models.multivariate.cmvfts module -
- pyFTS.models.multivariate.granular module +
- pyFTS.models.multivariate.mvfts module +
- pyFTS.models.multivariate.wmvfts module +
- pyFTS.models.multivariate.cmvfts module +
- pyFTS.models.multivariate.granular module
- pyFTS.models.nonstationary package
- Submodules
- pyFTS.models.nonstationary.common module -
- pyFTS.models.nonstationary.cvfts module +
- pyFTS.models.nonstationary.cvfts module
- pyFTS.models.nonstationary.flrg module -
- pyFTS.models.nonstationary.honsfts module -
- pyFTS.models.nonstationary.nsfts module +
- pyFTS.models.nonstationary.honsfts module +
- pyFTS.models.nonstationary.nsfts module
- pyFTS.models.nonstationary.partitioners module
- pyFTS.models.nonstationary.perturbation module -
- pyFTS.models.nonstationary.util module +
- pyFTS.models.nonstationary.util module
- Module contents
- pyFTS.models.seasonal package
- Submodules
- pyFTS.models.seasonal.SeasonalIndexer module -
- pyFTS.models.seasonal.cmsfts module +
- pyFTS.models.seasonal.cmsfts module
- pyFTS.models.seasonal.common module -
- pyFTS.models.seasonal.msfts module +
- pyFTS.models.seasonal.msfts module
- pyFTS.models.seasonal.partitioner module -
- pyFTS.models.seasonal.sfts module +
- pyFTS.models.seasonal.sfts module
- Module contents
- Submodules -
- pyFTS.models.song module -
- pyFTS.models.chen module -
- pyFTS.models.yu module -
- pyFTS.models.cheng module -
- pyFTS.models.hofts module -
- pyFTS.models.hwang module -
- pyFTS.models.ifts module -
- pyFTS.models.ismailefendi module -
- pyFTS.models.pwfts module -
- pyFTS.models.sadaei module +
- pyFTS.models.song module +
- pyFTS.models.chen module +
- pyFTS.models.yu module +
- pyFTS.models.cheng module +
- pyFTS.models.hofts module +
- pyFTS.models.hwang module +
- pyFTS.models.ifts module +
- pyFTS.models.ismailefendi module +
- pyFTS.models.pwfts module +
- pyFTS.models.sadaei module
- Subpackages
- pyFTS.partitioners package
-
@@ -235,19 +235,19 @@
- pyFTS.partitioners.Entropy module
- pyFTS.partitioners.FCM module
- pyFTS.partitioners.Grid module -
- pyFTS.partitioners.Huarng module +
- pyFTS.partitioners.Huarng module
- pyFTS.partitioners.Singleton module
- pyFTS.partitioners.Simple module
- pyFTS.partitioners.SubClust module -
- pyFTS.partitioners.Util module -
- pyFTS.partitioners.parallel_util module +
- pyFTS.partitioners.Util module +
- pyFTS.partitioners.parallel_util module
- pyFTS.probabilistic package diff --git a/docs/build/html/pyFTS.hyperparam.html b/docs/build/html/pyFTS.hyperparam.html index 6178e52..7e39589 100644 --- a/docs/build/html/pyFTS.hyperparam.html +++ b/docs/build/html/pyFTS.hyperparam.html @@ -131,11 +131,343 @@ Value: the measure value
-
+
pyFTS.hyperparam.Evolutionary.
GeneticAlgorithm
(dataset, **kwargs)[source]¶
+ Genetic algoritm for Distributed Evolutionary Hyperparameter Optimization (DEHO)
+-
+
- Parameters +
-
+
dataset – The time series to optimize the FTS
+ngen – An integer value with the maximum number of generations, default value: 30
+mgen – An integer value with the maximum number of generations without improvement to stop, default value 7
+npop – An integer value with the population size, default value: 20
+pcross – A float value between 0 and 1 with the probability of crossover, default: .5
+psel – A float value between 0 and 1 with the probability of selection, default: .5
+pmut – A float value between 0 and 1 with the probability of mutation, default: .3
+fts_method – The FTS method to optimize
+parameters – dict with model specific arguments for fts_method
+elitism – A boolean value indicating if the best individual must always survive to next population
+initial_operator – a function that receives npop and return a random population with size npop
+evalutation_operator – a function that receives a dataset and an individual and return its fitness
+selection_operator – a function that receives the whole population and return a selected individual
+crossover_operator – a function that receives the whole population and return a descendent individual
+mutation_operator – a function that receives one individual and return a changed individual
+window_size – An integer value with the the length of scrolling window for train/test on dataset
+train_rate – A float value between 0 and 1 with the train/test split ([0,1])
+increment_rate – A float value between 0 and 1 with the the increment of the scrolling window, +relative to the window_size ([0,1])
+collect_statistics – A boolean value indicating to collect statistics for each generation
+distributed – A value indicating it the execution will be local and sequential (distributed=False), +or parallel and distributed (distributed=’dispy’ or distributed=’spark’)
+cluster – If distributed=’dispy’ the list of cluster nodes, else if distributed=’spark’ it is the master node
+
+- Returns +
the best genotype
+
+
-
+
pyFTS.hyperparam.Evolutionary.
crossover
(population, **kwargs)[source]¶
+ Crossover operation between two parents
+-
+
- Parameters +
population – the original population
+
+- Returns +
a genotype
+
+
-
+
pyFTS.hyperparam.Evolutionary.
double_tournament
(population, **kwargs)[source]¶
+ Double tournament selection strategy.
+-
+
- Parameters +
population –
+
+- Returns +
- + +
-
+
pyFTS.hyperparam.Evolutionary.
elitism
(population, new_population, **kwargs)[source]¶
+ Elitism operation, always select the best individual of the population and discard the worst
+-
+
- Parameters +
-
+
population –
+new_population –
+
+- Returns +
- + +
-
+
pyFTS.hyperparam.Evolutionary.
evaluate
(dataset, individual, **kwargs)[source]¶
+ Evaluate an individual using a sliding window cross validation over the dataset.
+-
+
- Parameters +
-
+
dataset – Evaluation dataset
+individual – genotype to be tested
+window_size – The length of scrolling window for train/test on dataset
+train_rate – The train/test split ([0,1])
+increment_rate – The increment of the scrolling window, relative to the window_size ([0,1])
+parameters – dict with model specific arguments for fit method.
+
+- Returns +
a tuple (len_lags, rmse) with the parsimony fitness value and the accuracy fitness value
+
+
-
+
pyFTS.hyperparam.Evolutionary.
execute
(datasetname, dataset, **kwargs)[source]¶
+ Batch execution of Distributed Evolutionary Hyperparameter Optimization (DEHO) for monovariate methods
+-
+
- Parameters +
-
+
datasetname –
+dataset – The time series to optimize the FTS
+file –
+experiments –
+distributed –
+ngen – An integer value with the maximum number of generations, default value: 30
+mgen – An integer value with the maximum number of generations without improvement to stop, default value 7
+npop – An integer value with the population size, default value: 20
+pcross – A float value between 0 and 1 with the probability of crossover, default: .5
+psel – A float value between 0 and 1 with the probability of selection, default: .5
+pmut – A float value between 0 and 1 with the probability of mutation, default: .3
+fts_method – The FTS method to optimize
+parameters – dict with model specific arguments for fts_method
+elitism – A boolean value indicating if the best individual must always survive to next population
+initial_operator – a function that receives npop and return a random population with size npop
+random_individual – create an random genotype
+evalutation_operator – a function that receives a dataset and an individual and return its fitness
+selection_operator – a function that receives the whole population and return a selected individual
+crossover_operator – a function that receives the whole population and return a descendent individual
+mutation_operator – a function that receives one individual and return a changed individual
+window_size – An integer value with the the length of scrolling window for train/test on dataset
+train_rate – A float value between 0 and 1 with the train/test split ([0,1])
+increment_rate – A float value between 0 and 1 with the the increment of the scrolling window, +relative to the window_size ([0,1])
+collect_statistics – A boolean value indicating to collect statistics for each generation
+distributed – A value indicating it the execution will be local and sequential (distributed=False), +or parallel and distributed (distributed=’dispy’ or distributed=’spark’)
+cluster – If distributed=’dispy’ the list of cluster nodes, else if distributed=’spark’ it is the master node
+
+- Returns +
the best genotype
+
+
-
+
pyFTS.hyperparam.Evolutionary.
genotype
(mf, npart, partitioner, order, alpha, lags, f1, f2)[source]¶
+ Create the individual genotype
+-
+
- Parameters +
-
+
mf – membership function
+npart – number of partitions
+partitioner – partitioner method
+order – model order
+alpha – alpha-cut
+lags – array with lag indexes
+f1 – accuracy fitness value
+f2 – parsimony fitness value
+
+- Returns +
the genotype, a dictionary with all hyperparameters
+
+
-
+
pyFTS.hyperparam.Evolutionary.
initial_population
(n, **kwargs)[source]¶
+ Create a random population of size n
+-
+
- Parameters +
n – the size of the population
+
+- Returns +
a list with n random individuals
+
+
-
+
pyFTS.hyperparam.Evolutionary.
lag_crossover2
(best, worst)[source]¶
+ Cross over two lag genes
+-
+
- Parameters +
-
+
best – best genotype
+worst – worst genotype
+
+- Returns +
a tuple (order, lags)
+
+
-
+
pyFTS.hyperparam.Evolutionary.
mutation
(individual, **kwargs)[source]¶
+ Mutation operator
+-
+
- Parameters +
-
+
individual – an individual genotype
+pmut – individual probability o
+
+- Returns +
- + +
-
+
pyFTS.hyperparam.Evolutionary.
mutation_lags
(lags, order)[source]¶
+ Mutation operation for lags gene
+-
+
- Parameters +
-
+
lags –
+order –
+
+- Returns +
- + +
-
+
pyFTS.hyperparam.Evolutionary.
phenotype
(individual, train, fts_method, parameters={}, **kwargs)[source]¶
+ Instantiate the genotype, creating a fitted model with the genotype hyperparameters
+-
+
- Parameters +
-
+
individual – a genotype
+train – the training dataset
+fts_method – the FTS method
+parameters – dict with model specific arguments for fit method.
+
+- Returns +
a fitted FTS model
+
+
-
+
pyFTS.hyperparam.Evolutionary.
process_experiment
(fts_method, result, datasetname, conn)[source]¶
+ Persist the results of an DEHO execution in sqlite database (best hyperparameters) and json file (generation statistics)
+-
+
- Parameters +
-
+
fts_method –
+result –
+datasetname –
+conn –
+
+- Returns +
- + +
- Module contents
- Submodules
- pyFTS.hyperparam.Util module -
- pyFTS.hyperparam.GridSearch module -
- pyFTS.hyperparam.Evolutionary module +
- pyFTS.hyperparam.GridSearch module +
- pyFTS.hyperparam.Evolutionary module diff --git a/docs/build/html/pyFTS.models.ensemble.html b/docs/build/html/pyFTS.models.ensemble.html index 6a4754b..23a1266 100644 --- a/docs/build/html/pyFTS.models.ensemble.html +++ b/docs/build/html/pyFTS.models.ensemble.html @@ -69,11 +69,321 @@
-
+class
pyFTS.models.ensemble.ensemble.
AllMethodEnsembleFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.ensemble.ensemble.EnsembleFTS
Creates an EnsembleFTS with all point forecast methods, sharing the same partitioner
+ + + + +-
+class
pyFTS.models.ensemble.ensemble.
EnsembleFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Ensemble FTS
+-
+
-
+
alpha
¶
+ The quantiles
+
-
+
-
+
append_model
(model)[source]¶
+ Append a new trained model to the ensemble
+-
+
- Parameters +
model – FTS model
+
+
-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(data, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_interval
(data, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+
forecast_distribution
(data, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
-
+
forecast_interval
(data, **kwargs)[source]¶
+ Interval forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the prediction intervals
+
+
-
+
-
+
get_UoD
()[source]¶
+ Returns the interval of the known bounds of the universe of discourse (UoD), i. e., +the known minimum and maximum values of the time series.
+-
+
- Returns +
A set with the lower and the upper bounds of the UoD
+
+
-
+
-
+
interval_method
¶
+ The method used to mix the several model’s forecasts into a interval forecast. Options: quantile, extremum, normal
+
-
+
-
+
models
¶
+ A list of FTS models, the ensemble components
+
-
+
-
+
parameters
¶
+ A list with the parameters for each component model
+
-
+
-
+
point_method
¶
+ The method used to mix the several model’s forecasts into a unique point forecast. Options: mean, median, quantile, exponential
+
-
+
-
+class
pyFTS.models.ensemble.ensemble.
SimpleEnsembleFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.ensemble.ensemble.EnsembleFTS
An homogeneous FTS method ensemble with variations on partitionings and orders.
+-
+
-
+
method
¶
+ FTS method class that will be used on internal models
+
-
+
-
+
orders
¶
+ Possible variations of order on internal models
+
-
+
-
+
partitioner_method
¶
+ UoD partitioner class that will be used on internal methods
+
-
+
-
+
partitions
¶
+ Possible variations of number of partitions on internal models
+
-
+
-
+class
pyFTS.models.ensemble.multiseasonal.
SeasonalEnsembleFTS
(name, **kwargs)[source]¶
+ Bases:
+pyFTS.models.ensemble.ensemble.EnsembleFTS
-
+
-
+
forecast_distribution
(data, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
- pyFTS.models.ensemble package diff --git a/docs/build/html/pyFTS.models.html b/docs/build/html/pyFTS.models.html index 8888a65..0fb2b44 100644 --- a/docs/build/html/pyFTS.models.html +++ b/docs/build/html/pyFTS.models.html @@ -75,16 +75,16 @@
- pyFTS.models.ensemble package
- pyFTS.models.incremental package
- pyFTS.models.multivariate package
-
@@ -92,37 +92,37 @@
- Submodules
- pyFTS.models.multivariate.FLR module
- pyFTS.models.multivariate.common module -
- pyFTS.models.multivariate.variable module +
- pyFTS.models.multivariate.variable module
- pyFTS.models.multivariate.flrg module
- pyFTS.models.multivariate.partitioner module
- pyFTS.models.multivariate.grid module -
- pyFTS.models.multivariate.mvfts module -
- pyFTS.models.multivariate.wmvfts module -
- pyFTS.models.multivariate.cmvfts module -
- pyFTS.models.multivariate.granular module +
- pyFTS.models.multivariate.mvfts module +
- pyFTS.models.multivariate.wmvfts module +
- pyFTS.models.multivariate.cmvfts module +
- pyFTS.models.multivariate.granular module
- pyFTS.models.nonstationary package
- Submodules
- pyFTS.models.nonstationary.common module -
- pyFTS.models.nonstationary.cvfts module +
- pyFTS.models.nonstationary.cvfts module
- pyFTS.models.nonstationary.flrg module -
- pyFTS.models.nonstationary.honsfts module -
- pyFTS.models.nonstationary.nsfts module +
- pyFTS.models.nonstationary.honsfts module +
- pyFTS.models.nonstationary.nsfts module
- pyFTS.models.nonstationary.partitioners module
- pyFTS.models.nonstationary.perturbation module -
- pyFTS.models.nonstationary.util module +
- pyFTS.models.nonstationary.util module
- Module contents
- pyFTS.models.seasonal package
- Submodules
- pyFTS.models.seasonal.SeasonalIndexer module -
- pyFTS.models.seasonal.cmsfts module +
- pyFTS.models.seasonal.cmsfts module
- pyFTS.models.seasonal.common module -
- pyFTS.models.seasonal.msfts module +
- pyFTS.models.seasonal.msfts module
- pyFTS.models.seasonal.partitioner module -
- pyFTS.models.seasonal.sfts module +
- pyFTS.models.seasonal.sfts module
- Module contents
@@ -132,35 +132,1011 @@
Song and B. S. Chissom, “Fuzzy time series and its models,” Fuzzy Sets Syst., vol. 54, no. 3, pp. 269–277, 1993.
+-
+class
pyFTS.models.song.
ConventionalFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Traditional Fuzzy Time Series
+ + + + + + + + +-
+class
pyFTS.models.chen.
ConventionalFLRG
(LHS, **kwargs)[source]¶
+ Bases:
+pyFTS.common.flrg.FLRG
First Order Conventional Fuzzy Logical Relationship Group
+ + + + +-
+class
pyFTS.models.chen.
ConventionalFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Conventional Fuzzy Time Series
+ + + + + + +-
+class
pyFTS.models.yu.
WeightedFLRG
(LHS, **kwargs)[source]¶
+ Bases:
+pyFTS.common.flrg.FLRG
First Order Weighted Fuzzy Logical Relationship Group
+ + + + +-
+class
pyFTS.models.yu.
WeightedFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
First Order Weighted Fuzzy Time Series
+ + + + + + +-
+class
pyFTS.models.cheng.
TrendWeightedFLRG
(LHS, **kwargs)[source]¶
+ Bases:
+pyFTS.models.yu.WeightedFLRG
First Order Trend Weighted Fuzzy Logical Relationship Group
+ + +-
+class
pyFTS.models.cheng.
TrendWeightedFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.yu.WeightedFTS
First Order Trend Weighted Fuzzy Time Series
+ + +-
+class
pyFTS.models.hofts.
HighOrderFLRG
(order, **kwargs)[source]¶
+ Bases:
+pyFTS.common.flrg.FLRG
Conventional High Order Fuzzy Logical Relationship Group
+ + + + +-
+class
pyFTS.models.hofts.
HighOrderFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Conventional High Order Fuzzy Time Series
+ + + + + + + + + + + + + + +-
+class
pyFTS.models.hofts.
WeightedHighOrderFLRG
(order, **kwargs)[source]¶
+ Bases:
+pyFTS.common.flrg.FLRG
Weighted High Order Fuzzy Logical Relationship Group
+ + + + +-
+
-
+
get_lower
(sets)[source]¶
+ Returns the lower bound value for the RHS fuzzy sets
+-
+
- Parameters +
sets – fuzzy sets
+
+- Returns +
lower bound value
+
+
-
+
-
+
get_midpoint
(sets)[source]¶
+ Returns the midpoint value for the RHS fuzzy sets
+-
+
- Parameters +
sets – fuzzy sets
+
+- Returns +
the midpoint value
+
+
-
+
-
+class
pyFTS.models.hofts.
WeightedHighOrderFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.hofts.HighOrderFTS
Weighted High Order Fuzzy Time Series
+ + +-
+class
pyFTS.models.hwang.
HighOrderFTS
(**kwargs)[source]¶
+ Bases:
+ + + + + + +pyFTS.common.fts.FTS
-
+class
pyFTS.models.ifts.
IntervalFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.hofts.HighOrderFTS
High Order Interval Fuzzy Time Series
+-
+
-
+
forecast_ahead_interval
(data, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+class
pyFTS.models.ifts.
WeightedIntervalFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.hofts.WeightedHighOrderFTS
Weighted High Order Interval Fuzzy Time Series
+-
+
-
+
forecast_ahead_interval
(data, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+class
pyFTS.models.ismailefendi.
ImprovedWeightedFLRG
(LHS, **kwargs)[source]¶
+ Bases:
+pyFTS.common.flrg.FLRG
First Order Improved Weighted Fuzzy Logical Relationship Group
+ + + + +-
+class
pyFTS.models.ismailefendi.
ImprovedWeightedFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
First Order Improved Weighted Fuzzy Time Series
+ + + + + + +-
+class
pyFTS.models.pwfts.
ProbabilisticWeightedFLRG
(order)[source]¶
+ Bases:
+pyFTS.models.hofts.HighOrderFLRG
High Order Probabilistic Weighted Fuzzy Logical Relationship Group
+ + +-
+
-
+
get_lower
(sets)[source]¶
+ Returns the lower bound value for the RHS fuzzy sets
+-
+
- Parameters +
sets – fuzzy sets
+
+- Returns +
lower bound value
+
+
-
+
-
+
get_membership
(data, sets)[source]¶
+ Returns the membership value of the FLRG for the input data
+-
+
- Parameters +
-
+
data – input data
+sets – fuzzy sets
+
+- Returns +
the membership value
+
+
-
+
-
+class
pyFTS.models.pwfts.
ProbabilisticWeightedFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.ifts.IntervalFTS
High Order Probabilistic Weighted Fuzzy Time Series
+ + + + + + + + + + +-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(ndata, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_interval
(data, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+
forecast_distribution
(ndata, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
-
+
forecast_interval
(ndata, **kwargs)[source]¶
+ Interval forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the prediction intervals
+
+
-
+
-
+class
pyFTS.models.sadaei.
ExponentialyWeightedFLRG
(LHS, **kwargs)[source]¶
+ Bases:
+pyFTS.common.flrg.FLRG
First Order Exponentialy Weighted Fuzzy Logical Relationship Group
+ + + + +-
+class
pyFTS.models.sadaei.
ExponentialyWeightedFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
First Order Exponentialy Weighted Fuzzy Time Series
+ + + + + + +- Module contents
- Subpackages
- Submodules -
- pyFTS.models.song module -
- pyFTS.models.chen module -
- pyFTS.models.yu module -
- pyFTS.models.cheng module -
- pyFTS.models.hofts module -
- pyFTS.models.hwang module -
- pyFTS.models.ifts module -
- pyFTS.models.ismailefendi module -
- pyFTS.models.pwfts module -
- pyFTS.models.sadaei module +
- pyFTS.models.song module +
- pyFTS.models.chen module +
- pyFTS.models.yu module +
- pyFTS.models.cheng module +
- pyFTS.models.hofts module +
- pyFTS.models.hwang module +
- pyFTS.models.ifts module +
- pyFTS.models.ismailefendi module +
- pyFTS.models.pwfts module +
- pyFTS.models.sadaei module diff --git a/docs/build/html/pyFTS.models.incremental.html b/docs/build/html/pyFTS.models.incremental.html index 6d70773..283d487 100644 --- a/docs/build/html/pyFTS.models.incremental.html +++ b/docs/build/html/pyFTS.models.incremental.html @@ -73,11 +73,250 @@
-
+class
pyFTS.models.incremental.TimeVariant.
Retrainer
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Meta model for incremental/online learning that retrain its internal model after +data windows controlled by the parameter ‘batch_size’, using as the training data a +window of recent lags, whose size is controlled by the parameter ‘window_length’.
+-
+
-
+
auto_update
¶
+ If true the model is updated at each time and not recreated
+
-
+
-
+
batch_size
¶
+ The batch interval between each retraining
+
-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
fts_method
¶
+ The FTS method to be called when a new model is build
+
-
+
-
+
fts_params
¶
+ The FTS method specific parameters
+
-
+
-
+
model
¶
+ The most recent trained model
+
-
+
-
+
offset
()[source]¶
+ Returns the number of lags to skip in the input test data in order to synchronize it with +the forecasted values given by the predict function. This is necessary due to the order of the +model, among other parameters.
+-
+
- Returns +
An integer with the number of lags to skip
+
+
-
+
-
+
partitioner
¶
+ The most recent trained partitioner
+
-
+
-
+
partitioner_method
¶
+ The partitioner method to be called when a new model is build
+
-
+
-
+
partitioner_params
¶
+ The partitioner method parameters
+
-
+
-
+
train
(data, **kwargs)[source]¶
+ Method specific parameter fitting
+-
+
- Parameters +
-
+
data – training time series data
+kwargs – Method specific parameters
+
+
-
+
-
+
window_length
¶
+ The memory window length
+
-
+
-
+class
pyFTS.models.incremental.IncrementalEnsemble.
IncrementalEnsembleFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.ensemble.ensemble.EnsembleFTS
Time Variant/Incremental Ensemble of FTS methods
+-
+
-
+
batch_size
¶
+ The batch interval between each retraining
+
-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
fts_method
¶
+ The FTS method to be called when a new model is build
+
-
+
-
+
fts_params
¶
+ The FTS method specific parameters
+
-
+
-
+
num_models
¶
+ The number of models to hold in the ensemble
+
-
+
-
+
offset
()[source]¶
+ Returns the number of lags to skip in the input test data in order to synchronize it with +the forecasted values given by the predict function. This is necessary due to the order of the +model, among other parameters.
+-
+
- Returns +
An integer with the number of lags to skip
+
+
-
+
-
+
partitioner_method
¶
+ The partitioner method to be called when a new model is build
+
-
+
-
+
partitioner_params
¶
+ The partitioner method parameters
+
-
+
-
+
train
(data, **kwargs)[source]¶
+ Method specific parameter fitting
+-
+
- Parameters +
-
+
data – training time series data
+kwargs – Method specific parameters
+
+
-
+
-
+
window_length
¶
+ The memory window length
+
-
+
- pyFTS.models.incremental package diff --git a/docs/build/html/pyFTS.models.multivariate.html b/docs/build/html/pyFTS.models.multivariate.html index 0e97cd3..dfb59c8 100644 --- a/docs/build/html/pyFTS.models.multivariate.html +++ b/docs/build/html/pyFTS.models.multivariate.html @@ -146,8 +146,87 @@
-
+class
pyFTS.models.multivariate.variable.
Variable
(name, **kwargs)[source]¶
+ Bases:
+object
A variable of a fuzzy time series multivariate model. Each variable contains its own +transformations and partitioners.
+-
+
-
+
alias
¶
+ A string with the alias of the variable
+
-
+
-
+
alpha_cut
¶
+ Minimal membership value to be considered on fuzzyfication process
+
-
+
-
+
data_label
¶
+ A string with the column name on DataFrame
+
-
+
-
+
data_type
¶
+ The type of the data column on Pandas Dataframe
+
-
+
-
+
mask
¶
+ The mask for format the data column on Pandas Dataframe
+
-
+
-
+
name
¶
+ A string with the name of the variable
+
-
+
-
+
partitioner
¶
+ UoD partitioner for the variable data
+
-
+
-
+
transformation
¶
+ Pre processing transformation for the variable
+
-
+
-
+class
pyFTS.models.multivariate.mvfts.
MVFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
Multivariate extension of Chen’s ConventionalFTS method
+ + +-
+
-
+
append_variable
(var)[source]¶
+ Append a new endogenous variable to the model
+-
+
- Parameters +
var – variable object
+
+- Returns +
- + +
-
+
-
+
apply_transformations
(data, params=None, updateUoD=False, **kwargs)[source]¶
+ Apply the data transformations for data preprocessing
+-
+
- Parameters +
-
+
data – input data
+params – transformation parameters
+updateUoD –
+kwargs –
+
+- Returns +
preprocessed data
+
+
-
+
-
+
clone_parameters
(model)[source]¶
+ Import the parameters values from other model
+-
+
- Parameters +
model – a model to clone the parameters
+
+
-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_interval
(data, steps, **kwargs)[source]¶
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted intervals
+
+
-
+
-
+class
pyFTS.models.multivariate.wmvfts.
WeightedFLRG
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.multivariate.flrg.FLRG
Weighted Multivariate Fuzzy Logical Rule Group
+ + +-
+
-
+
get_lower
(sets)[source]¶
+ Returns the lower bound value for the RHS fuzzy sets
+-
+
- Parameters +
sets – fuzzy sets
+
+- Returns +
lower bound value
+
+
-
+
-
+
get_midpoint
(sets)[source]¶
+ Returns the midpoint value for the RHS fuzzy sets
+-
+
- Parameters +
sets – fuzzy sets
+
+- Returns +
the midpoint value
+
+
-
+
-
+class
pyFTS.models.multivariate.wmvfts.
WeightedMVFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.multivariate.mvfts.MVFTS
Weighted Multivariate FTS
+ + +-
+class
pyFTS.models.multivariate.cmvfts.
ClusteredMVFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.multivariate.mvfts.MVFTS
Meta model for high order, clustered multivariate FTS
+ + +-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead_distribution
(data, steps, **kwargs)[source]¶
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted Probability Distributions
+
+
-
+
-
+
forecast_ahead_multivariate
(data, steps, **kwargs)[source]¶
+ Multivariate forecast n step ahead
+-
+
- Parameters +
-
+
data – Pandas dataframe with one column for each variable and with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a Pandas Dataframe object representing the forecasted values for each variable
+
+
-
+
-
+
forecast_distribution
(data, **kwargs)[source]¶
+ Probabilistic forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+
+
-
+
-
+
forecast_interval
(data, **kwargs)[source]¶
+ Interval forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the prediction intervals
+
+
-
+
-
+
forecast_multivariate
(data, **kwargs)[source]¶
+ Multivariate forecast one step ahead
+-
+
- Parameters +
-
+
data – Pandas dataframe with one column for each variable and with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a Pandas Dataframe object representing the forecasted values for each variable
+
+
-
+
-
+
fts_method
¶
+ The FTS method to be called when a new model is build
+
-
+
-
+
fts_params
¶
+ The FTS method specific parameters
+
-
+
-
+
model
¶
+ The most recent trained model
+
-
+
-
+class
pyFTS.models.multivariate.granular.
GranularWMVFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.multivariate.cmvfts.ClusteredMVFTS
Granular multivariate weighted high order FTS
+-
+
-
+
model
¶
+ The most recent trained model
+
-
+
- Submodules
- pyFTS.models.multivariate.FLR module
- pyFTS.models.multivariate.common module -
- pyFTS.models.multivariate.variable module +
- pyFTS.models.multivariate.variable module
- pyFTS.models.multivariate.flrg module
- pyFTS.models.multivariate.partitioner module
- pyFTS.models.multivariate.grid module -
- pyFTS.models.multivariate.mvfts module -
- pyFTS.models.multivariate.wmvfts module -
- pyFTS.models.multivariate.cmvfts module -
- pyFTS.models.multivariate.granular module +
- pyFTS.models.multivariate.mvfts module +
- pyFTS.models.multivariate.wmvfts module +
- pyFTS.models.multivariate.cmvfts module +
- pyFTS.models.multivariate.granular module diff --git a/docs/build/html/pyFTS.models.nonstationary.html b/docs/build/html/pyFTS.models.nonstationary.html index 539a7fd..8807ad0 100644 --- a/docs/build/html/pyFTS.models.nonstationary.html +++ b/docs/build/html/pyFTS.models.nonstationary.html @@ -203,8 +203,94 @@ IEEE Transactions on Fuzzy Systems, v. 16, n. 4, p. 1072-1086, 2008.
-
+class
pyFTS.models.nonstationary.cvfts.
ConditionalVarianceFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.hofts.HighOrderFTS
-
+
-
+
forecast
(ndata, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+class
pyFTS.models.nonstationary.honsfts.
HighOrderNonStationaryFLRG
(order, **kwargs)[source]¶
+ Bases:
+pyFTS.models.nonstationary.flrg.NonStationaryFLRG
First Order NonStationary Fuzzy Logical Relationship Group
+ + + + +-
+
-
+
get_lower
(sets, perturb)[source]¶
+ Returns the lower bound value for the RHS fuzzy sets
+-
+
- Parameters +
sets – fuzzy sets
+
+- Returns +
lower bound value
+
+
-
+
-
+
get_midpoint
(sets, perturb)[source]¶
+ Returns the midpoint value for the RHS fuzzy sets
+-
+
- Parameters +
sets – fuzzy sets
+
+- Returns +
the midpoint value
+
+
-
+
-
+class
pyFTS.models.nonstationary.honsfts.
HighOrderNonStationaryFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.nonstationary.nsfts.NonStationaryFTS
NonStationaryFTS Fuzzy Time Series
+ + + + + + + + +-
+class
pyFTS.models.nonstationary.nsfts.
ConventionalNonStationaryFLRG
(LHS, **kwargs)[source]¶
+ Bases:
+pyFTS.models.nonstationary.flrg.NonStationaryFLRG
First Order NonStationary Fuzzy Logical Relationship Group
+ + + + +-
+class
pyFTS.models.nonstationary.nsfts.
NonStationaryFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
NonStationaryFTS Fuzzy Time Series
+ + +-
+
-
+
forecast
(ndata, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+class
pyFTS.models.nonstationary.nsfts.
WeightedNonStationaryFLRG
(LHS, **kwargs)[source]¶
+ Bases:
+pyFTS.models.nonstationary.flrg.NonStationaryFLRG
First Order NonStationary Fuzzy Logical Relationship Group
+ + + + + + + + +-
+class
pyFTS.models.nonstationary.nsfts.
WeightedNonStationaryFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.nonstationary.nsfts.NonStationaryFTS
Weighted NonStationaryFTS Fuzzy Time Series
+ + + + +- pyFTS.models.nonstationary package
- Submodules
- pyFTS.models.nonstationary.common module -
- pyFTS.models.nonstationary.cvfts module +
- pyFTS.models.nonstationary.cvfts module
- pyFTS.models.nonstationary.flrg module -
- pyFTS.models.nonstationary.honsfts module -
- pyFTS.models.nonstationary.nsfts module +
- pyFTS.models.nonstationary.honsfts module +
- pyFTS.models.nonstationary.nsfts module
- pyFTS.models.nonstationary.partitioners module
- pyFTS.models.nonstationary.perturbation module -
- pyFTS.models.nonstationary.util module +
- pyFTS.models.nonstationary.util module
- Module contents
diff --git a/docs/build/html/pyFTS.models.seasonal.html b/docs/build/html/pyFTS.models.seasonal.html
index 76d3f01..1a8029f 100644
--- a/docs/build/html/pyFTS.models.seasonal.html
+++ b/docs/build/html/pyFTS.models.seasonal.html
@@ -215,8 +215,86 @@
-
+class
pyFTS.models.seasonal.cmsfts.
ContextualMultiSeasonalFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.models.seasonal.sfts.SeasonalFTS
Contextual Multi-Seasonal Fuzzy Time Series
+-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+class
pyFTS.models.seasonal.cmsfts.
ContextualSeasonalFLRG
(seasonality)[source]¶
+ Bases:
+pyFTS.models.seasonal.sfts.SeasonalFLRG
Contextual Seasonal Fuzzy Logical Relationship Group
+ + +-
+class
pyFTS.models.seasonal.msfts.
MultiSeasonalFTS
(name, indexer, **kwargs)[source]¶
+ Bases:
+pyFTS.models.seasonal.sfts.SeasonalFTS
Multi-Seasonal Fuzzy Time Series
+-
+
-
+
forecast
(data, **kwargs)[source]¶
+ Point forecast one step ahead
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+kwargs – model specific parameters
+
+- Returns +
a list with the forecasted values
+
+
-
+
-
+
forecast_ahead
(data, steps, **kwargs)[source]¶
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+-
+
- Parameters +
-
+
data – time series data with the minimal length equal to the max_lag of the model
+steps – the number of steps ahead to forecast (default: 1)
+start_at – in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+
+- Returns +
a list with the forecasted values
+
+
-
+
Song, “Seasonal forecasting in fuzzy time series,” Fuzzy sets Syst., vol. 107, pp. 235–236, 1999.
+-
+class
pyFTS.models.seasonal.sfts.
SeasonalFLRG
(seasonality)[source]¶
+ Bases:
+pyFTS.common.flrg.FLRG
First Order Seasonal Fuzzy Logical Relationship Group
+ + + + +-
+class
pyFTS.models.seasonal.sfts.
SeasonalFTS
(**kwargs)[source]¶
+ Bases:
+pyFTS.common.fts.FTS
First Order Seasonal Fuzzy Time Series
+ + + + + + + + +- pyFTS.models.seasonal package
- Submodules
- pyFTS.models.seasonal.SeasonalIndexer module -
- pyFTS.models.seasonal.cmsfts module +
- pyFTS.models.seasonal.cmsfts module
- pyFTS.models.seasonal.common module -
- pyFTS.models.seasonal.msfts module +
- pyFTS.models.seasonal.msfts module
- pyFTS.models.seasonal.partitioner module -
- pyFTS.models.seasonal.sfts module +
- pyFTS.models.seasonal.sfts module
- Module contents
diff --git a/docs/build/html/pyFTS.partitioners.html b/docs/build/html/pyFTS.partitioners.html
index 4b9e906..e1f4121 100644
--- a/docs/build/html/pyFTS.partitioners.html
+++ b/docs/build/html/pyFTS.partitioners.html
@@ -465,8 +465,31 @@ Comput. Math. Appl., vol. 56, no. 12, pp. 3052–3063, Dec. 2008. DOI: 10.1016/j
-
+class
pyFTS.partitioners.Huarng.
HuarngPartitioner
(**kwargs)[source]¶
+ Bases:
+pyFTS.partitioners.partitioner.Partitioner
Huarng Empirical Partitioner
+ + +-
+
pyFTS.partitioners.Util.
explore_partitioners
(data, npart, methods=None, mf=None, transformation=None, size=[12, 10], save=False, file=None)[source]¶
+ Create partitioners for the mf membership functions and npart partitions and show the partitioning images. +:data: Time series data +:npart: Maximum number of partitions of the universe of discourse +:methods: A list with the partitioning methods to be used +:mf: A list with the membership functions to be used +:transformation: a transformation to be used in partitioner +:size: list, the size of the output image [width, height] +:save: boolean, if the image will be saved on disk +:file: string, the file path to save the image +:return: the list of the built partitioners
+- pyFTS.partitioners.Entropy module
- pyFTS.partitioners.FCM module
- pyFTS.partitioners.Grid module -
- pyFTS.partitioners.Huarng module +
- pyFTS.partitioners.Huarng module
- pyFTS.partitioners.Singleton module
- pyFTS.partitioners.Simple module
- pyFTS.partitioners.SubClust module -
- pyFTS.partitioners.Util module -
- pyFTS.partitioners.parallel_util module +
- pyFTS.partitioners.Util module +
- pyFTS.partitioners.parallel_util module diff --git a/docs/build/html/pyFTS.probabilistic.html b/docs/build/html/pyFTS.probabilistic.html index 80a5db9..1792e93 100644 --- a/docs/build/html/pyFTS.probabilistic.html +++ b/docs/build/html/pyFTS.probabilistic.html @@ -68,11 +68,304 @@
-
+class
pyFTS.probabilistic.ProbabilityDistribution.
ProbabilityDistribution
(type='KDE', **kwargs)[source]¶
+ Bases:
+object
Represents a discrete or continous probability distribution +If type is histogram, the PDF is discrete +If type is KDE the PDF is continuous
+-
+
-
+
append
(values)[source]¶
+ Increment the frequency count for the values
+-
+
- Parameters +
values – A list of values to account the frequency
+
+
-
+
-
+
append_interval
(intervals)[source]¶
+ Increment the frequency count for all values inside an interval
+-
+
- Parameters +
intervals – A list of intervals do increment the frequency
+
+
-
+
-
+
averageloglikelihood
(data)[source]¶
+ Average log likelihood of the probability distribution with respect to data
+-
+
- Parameters +
data –
+
+- Returns +
- + +
-
+
-
+
bins
¶
+ Number of bins on a discrete PDF
+
-
+
-
+
crossentropy
(q)[source]¶
+ Cross entropy between the actual probability distribution and the informed one, +H(P,Q) = - ∑ P(x) log ( Q(x) )
+-
+
- Parameters +
q – a probabilistic.ProbabilityDistribution object
+
+- Returns +
Cross entropy between this probability distribution and the given distribution
+
+
-
+
-
+
cumulative
(values)[source]¶
+ Return the cumulative probability densities for the input values, +such that F(x) = P(X <= x)
+-
+
- Parameters +
values – A list of input values
+
+- Returns +
The cumulative probability densities for the input values
+
+
-
+
-
+
density
(values)[source]¶
+ Return the probability densities for the input values
+-
+
- Parameters +
values – List of values to return the densities
+
+- Returns +
List of probability densities for the input values
+
+
-
+
-
+
differential_offset
(value)[source]¶
+ Auxiliary function for probability distributions of differentiated data
+-
+
- Parameters +
value –
+
+- Returns +
- + +
-
+
-
+
empiricalloglikelihood
()[source]¶
+ Empirical Log Likelihood of the probability distribution, L(P) = ∑ log( P(x) )
+-
+
- Returns +
- + +
-
+
-
+
entropy
()[source]¶
+ Return the entropy of the probability distribution, H(P) = E[ -ln P(X) ] = - ∑ P(x) log ( P(x) )
+:return:the entropy of the probability distribution
+
-
+
-
+
expected_value
()[source]¶
+ Return the expected value of the distribution, as E[X] = ∑ x * P(x)
+-
+
- Returns +
The expected value of the distribution
+
+
-
+
-
+
kullbackleiblerdivergence
(q)[source]¶
+ Kullback-Leibler divergence between the actual probability distribution and the informed one. +DKL(P || Q) = - ∑ P(x) log( P(X) / Q(x) )
+-
+
- Parameters +
q – a probabilistic.ProbabilityDistribution object
+
+- Returns +
Kullback-Leibler divergence
+
+
-
+
-
+
labels
¶
+ Bins labels on a discrete PDF
+
-
+
-
+
pseudologlikelihood
(data)[source]¶
+ Pseudo log likelihood of the probability distribution with respect to data
+-
+
- Parameters +
data –
+
+- Returns +
- + +
-
+
-
+
quantile
(values)[source]¶
+ Return the Universe of Discourse values in relation to the quantile input values, +such that Q(tau) = min( {x | F(x) >= tau })
+-
+
- Parameters +
values – input values
+
+- Returns +
The list of the quantile values for the input values
+
+
-
+
-
+
set
(value, density)[source]¶
+ Assert a probability ‘density’ for a certain value ‘value’, such that P(value) = density
+-
+
- Parameters +
-
+
value – A value in the universe of discourse from the distribution
+density – The probability density to assign to the value
+
+
-
+
-
+
type
¶
+ If type is histogram, the PDF is discrete +If type is KDE the PDF is continuous
+
-
+
-
+
uod
¶
+ Universe of discourse
+
-
+
- pyFTS.probabilistic package diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index d28c025..585b492 100644 --- a/docs/build/html/searchindex.js +++ b/docs/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["index","modules","pyFTS","pyFTS.benchmarks","pyFTS.common","pyFTS.common.transformations","pyFTS.data","pyFTS.distributed","pyFTS.hyperparam","pyFTS.models","pyFTS.models.ensemble","pyFTS.models.incremental","pyFTS.models.multivariate","pyFTS.models.nonstationary","pyFTS.models.seasonal","pyFTS.partitioners","pyFTS.probabilistic","quickstart"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","modules.rst","pyFTS.rst","pyFTS.benchmarks.rst","pyFTS.common.rst","pyFTS.common.transformations.rst","pyFTS.data.rst","pyFTS.distributed.rst","pyFTS.hyperparam.rst","pyFTS.models.rst","pyFTS.models.ensemble.rst","pyFTS.models.incremental.rst","pyFTS.models.multivariate.rst","pyFTS.models.nonstationary.rst","pyFTS.models.seasonal.rst","pyFTS.partitioners.rst","pyFTS.probabilistic.rst","quickstart.rst"],objects:{"":{pyFTS:[2,0,0,"-"]},"pyFTS.common":{Composite:[4,0,0,"-"],FLR:[4,0,0,"-"],FuzzySet:[4,0,0,"-"],Membership:[4,0,0,"-"],SortedCollection:[4,0,0,"-"],flrg:[4,0,0,"-"],tree:[4,0,0,"-"]},"pyFTS.common.Composite":{FuzzySet:[4,1,1,""]},"pyFTS.common.Composite.FuzzySet":{append:[4,2,1,""],append_set:[4,2,1,""],membership:[4,2,1,""],transform:[4,2,1,""]},"pyFTS.common.FLR":{FLR:[4,1,1,""],IndexedFLR:[4,1,1,""],generate_high_order_recurrent_flr:[4,4,1,""],generate_indexed_flrs:[4,4,1,""],generate_non_recurrent_flrs:[4,4,1,""],generate_recurrent_flrs:[4,4,1,""]},"pyFTS.common.FLR.FLR":{LHS:[4,3,1,""],RHS:[4,3,1,""]},"pyFTS.common.FLR.IndexedFLR":{index:[4,3,1,""]},"pyFTS.common.FuzzySet":{FuzzySet:[4,1,1,""],check_bounds:[4,4,1,""],check_bounds_index:[4,4,1,""],fuzzyfy:[4,4,1,""],fuzzyfy_instance:[4,4,1,""],fuzzyfy_instances:[4,4,1,""],fuzzyfy_series:[4,4,1,""],fuzzyfy_series_old:[4,4,1,""],get_fuzzysets:[4,4,1,""],get_maximum_membership_fuzzyset:[4,4,1,""],get_maximum_membership_fuzzyset_index:[4,4,1,""],grant_bounds:[4,4,1,""],set_ordered:[4,4,1,""]},"pyFTS.common.FuzzySet.FuzzySet":{Z:[4,3,1,""],alpha:[4,3,1,""],centroid:[4,3,1,""],membership:[4,2,1,""],mf:[4,3,1,""],name:[4,3,1,""],parameters:[4,3,1,""],partition_function:[4,2,1,""],transform:[4,2,1,""],type:[4,3,1,""],variable:[4,3,1,""]},"pyFTS.common.Membership":{bellmf:[4,4,1,""],gaussmf:[4,4,1,""],sigmf:[4,4,1,""],singleton:[4,4,1,""],trapmf:[4,4,1,""],trimf:[4,4,1,""]},"pyFTS.common.SortedCollection":{SortedCollection:[4,1,1,""]},"pyFTS.common.SortedCollection.SortedCollection":{around:[4,2,1,""],between:[4,2,1,""],clear:[4,2,1,""],copy:[4,2,1,""],count:[4,2,1,""],find:[4,2,1,""],find_ge:[4,2,1,""],find_gt:[4,2,1,""],find_le:[4,2,1,""],find_lt:[4,2,1,""],index:[4,2,1,""],insert:[4,2,1,""],insert_right:[4,2,1,""],inside:[4,2,1,""],key:[4,2,1,""],remove:[4,2,1,""]},"pyFTS.common.flrg":{FLRG:[4,1,1,""]},"pyFTS.common.flrg.FLRG":{LHS:[4,3,1,""],RHS:[4,3,1,""],append_rhs:[4,2,1,""],get_key:[4,2,1,""],get_lower:[4,2,1,""],get_membership:[4,2,1,""],get_midpoint:[4,2,1,""],get_midpoints:[4,2,1,""],get_upper:[4,2,1,""],order:[4,3,1,""],reset_calculated_values:[4,2,1,""]},"pyFTS.common.tree":{FLRGTree:[4,1,1,""],FLRGTreeNode:[4,1,1,""],build_tree_without_order:[4,4,1,""],flat:[4,4,1,""]},"pyFTS.common.tree.FLRGTreeNode":{appendChild:[4,2,1,""],getChildren:[4,2,1,""],getStr:[4,2,1,""],paths:[4,2,1,""]},"pyFTS.data":{AirPassengers:[6,0,0,"-"],Bitcoin:[6,0,0,"-"],DowJones:[6,0,0,"-"],EURGBP:[6,0,0,"-"],EURUSD:[6,0,0,"-"],Enrollments:[6,0,0,"-"],Ethereum:[6,0,0,"-"],GBPUSD:[6,0,0,"-"],INMET:[6,0,0,"-"],Malaysia:[6,0,0,"-"],NASDAQ:[6,0,0,"-"],SONDA:[6,0,0,"-"],SP500:[6,0,0,"-"],TAIEX:[6,0,0,"-"],artificial:[6,0,0,"-"],common:[6,0,0,"-"],henon:[6,0,0,"-"],logistic_map:[6,0,0,"-"],lorentz:[6,0,0,"-"],mackey_glass:[6,0,0,"-"],rossler:[6,0,0,"-"],sunspots:[6,0,0,"-"]},"pyFTS.data.AirPassengers":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.Bitcoin":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.DowJones":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.EURGBP":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.EURUSD":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.Enrollments":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.Ethereum":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.GBPUSD":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.INMET":{get_dataframe:[6,4,1,""]},"pyFTS.data.Malaysia":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.NASDAQ":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.SONDA":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.SP500":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.TAIEX":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.artificial":{SignalEmulator:[6,1,1,""],generate_gaussian_linear:[6,4,1,""],generate_linear_periodic_gaussian:[6,4,1,""],generate_sinoidal_periodic_gaussian:[6,4,1,""],generate_uniform_linear:[6,4,1,""],random_walk:[6,4,1,""],white_noise:[6,4,1,""]},"pyFTS.data.artificial.SignalEmulator":{blip:[6,2,1,""],components:[6,3,1,""],incremental_gaussian:[6,2,1,""],periodic_gaussian:[6,2,1,""],run:[6,2,1,""],stationary_gaussian:[6,2,1,""]},"pyFTS.data.common":{get_dataframe:[6,4,1,""]},"pyFTS.data.henon":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.logistic_map":{get_data:[6,4,1,""]},"pyFTS.data.lorentz":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.mackey_glass":{get_data:[6,4,1,""]},"pyFTS.data.rossler":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.data.sunspots":{get_data:[6,4,1,""],get_dataframe:[6,4,1,""]},"pyFTS.hyperparam":{Util:[8,0,0,"-"]},"pyFTS.hyperparam.Util":{create_hyperparam_tables:[8,4,1,""],insert_hyperparam:[8,4,1,""],open_hyperparam_db:[8,4,1,""]},"pyFTS.models":{ensemble:[10,0,0,"-"],incremental:[11,0,0,"-"],multivariate:[12,0,0,"-"],nonstationary:[13,0,0,"-"],seasonal:[14,0,0,"-"]},"pyFTS.models.multivariate":{FLR:[12,0,0,"-"],common:[12,0,0,"-"],flrg:[12,0,0,"-"],grid:[12,0,0,"-"],partitioner:[12,0,0,"-"]},"pyFTS.models.multivariate.FLR":{FLR:[12,1,1,""]},"pyFTS.models.multivariate.FLR.FLR":{set_lhs:[12,2,1,""],set_rhs:[12,2,1,""]},"pyFTS.models.multivariate.common":{MultivariateFuzzySet:[12,1,1,""],fuzzyfy_instance:[12,4,1,""],fuzzyfy_instance_clustered:[12,4,1,""]},"pyFTS.models.multivariate.common.MultivariateFuzzySet":{append_set:[12,2,1,""],membership:[12,2,1,""],set_target_variable:[12,2,1,""]},"pyFTS.models.multivariate.flrg":{FLRG:[12,1,1,""]},"pyFTS.models.multivariate.flrg.FLRG":{append_rhs:[12,2,1,""],get_lower:[12,2,1,""],get_membership:[12,2,1,""],get_upper:[12,2,1,""],set_lhs:[12,2,1,""]},"pyFTS.models.multivariate.grid":{GridCluster:[12,1,1,""],IncrementalGridCluster:[12,1,1,""]},"pyFTS.models.multivariate.grid.GridCluster":{build:[12,2,1,""],defuzzyfy:[12,2,1,""]},"pyFTS.models.multivariate.grid.IncrementalGridCluster":{fuzzyfy:[12,2,1,""],incremental_search:[12,2,1,""],prune:[12,2,1,""]},"pyFTS.models.multivariate.partitioner":{MultivariatePartitioner:[12,1,1,""]},"pyFTS.models.multivariate.partitioner.MultivariatePartitioner":{append:[12,2,1,""],build:[12,2,1,""],build_index:[12,2,1,""],change_target_variable:[12,2,1,""],format_data:[12,2,1,""],fuzzyfy:[12,2,1,""],prune:[12,2,1,""],search:[12,2,1,""]},"pyFTS.models.nonstationary":{common:[13,0,0,"-"],flrg:[13,0,0,"-"],partitioners:[13,0,0,"-"],perturbation:[13,0,0,"-"]},"pyFTS.models.nonstationary.common":{FuzzySet:[13,1,1,""],check_bounds:[13,4,1,""],check_bounds_index:[13,4,1,""],fuzzify:[13,4,1,""],fuzzySeries:[13,4,1,""],window_index:[13,4,1,""]},"pyFTS.models.nonstationary.common.FuzzySet":{get_lower:[13,2,1,""],get_midpoint:[13,2,1,""],get_upper:[13,2,1,""],location:[13,3,1,""],location_params:[13,3,1,""],membership:[13,2,1,""],noise:[13,3,1,""],noise_params:[13,3,1,""],perform_location:[13,2,1,""],perform_width:[13,2,1,""],perturbate_parameters:[13,2,1,""],width:[13,3,1,""],width_params:[13,3,1,""]},"pyFTS.models.nonstationary.flrg":{NonStationaryFLRG:[13,1,1,""]},"pyFTS.models.nonstationary.flrg.NonStationaryFLRG":{get_key:[13,2,1,""],get_lower:[13,2,1,""],get_membership:[13,2,1,""],get_midpoint:[13,2,1,""],get_upper:[13,2,1,""],unpack_args:[13,2,1,""]},"pyFTS.models.nonstationary.partitioners":{PolynomialNonStationaryPartitioner:[13,1,1,""],SimpleNonStationaryPartitioner:[13,1,1,""],simplenonstationary_gridpartitioner_builder:[13,4,1,""]},"pyFTS.models.nonstationary.partitioners.PolynomialNonStationaryPartitioner":{build:[13,2,1,""],get_polynomial_perturbations:[13,2,1,""],poly_width:[13,2,1,""],scale_down:[13,2,1,""],scale_up:[13,2,1,""]},"pyFTS.models.nonstationary.partitioners.SimpleNonStationaryPartitioner":{build:[13,2,1,""]},"pyFTS.models.nonstationary.perturbation":{exponential:[13,4,1,""],linear:[13,4,1,""],periodic:[13,4,1,""],polynomial:[13,4,1,""]},"pyFTS.models.seasonal":{SeasonalIndexer:[14,0,0,"-"],common:[14,0,0,"-"],partitioner:[14,0,0,"-"]},"pyFTS.models.seasonal.SeasonalIndexer":{DataFrameSeasonalIndexer:[14,1,1,""],DateTimeSeasonalIndexer:[14,1,1,""],LinearSeasonalIndexer:[14,1,1,""],SeasonalIndexer:[14,1,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.DataFrameSeasonalIndexer":{get_data:[14,2,1,""],get_data_by_season:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""],set_data:[14,2,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.DateTimeSeasonalIndexer":{get_data:[14,2,1,""],get_data_by_season:[14,2,1,""],get_index:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""],set_data:[14,2,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.LinearSeasonalIndexer":{get_data:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.SeasonalIndexer":{get_data:[14,2,1,""],get_data_by_season:[14,2,1,""],get_index:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""]},"pyFTS.models.seasonal.common":{DateTime:[14,1,1,""],FuzzySet:[14,1,1,""],strip_datepart:[14,4,1,""]},"pyFTS.models.seasonal.common.DateTime":{day_of_month:[14,3,1,""],day_of_week:[14,3,1,""],day_of_year:[14,3,1,""],half:[14,3,1,""],hour:[14,3,1,""],hour_of_day:[14,3,1,""],hour_of_month:[14,3,1,""],hour_of_week:[14,3,1,""],hour_of_year:[14,3,1,""],minute:[14,3,1,""],minute_of_day:[14,3,1,""],minute_of_hour:[14,3,1,""],minute_of_month:[14,3,1,""],minute_of_week:[14,3,1,""],minute_of_year:[14,3,1,""],month:[14,3,1,""],quarter:[14,3,1,""],second:[14,3,1,""],second_of_day:[14,3,1,""],second_of_hour:[14,3,1,""],second_of_minute:[14,3,1,""],sixth:[14,3,1,""],third:[14,3,1,""],year:[14,3,1,""]},"pyFTS.models.seasonal.common.FuzzySet":{transform:[14,2,1,""]},"pyFTS.models.seasonal.partitioner":{TimeGridPartitioner:[14,1,1,""]},"pyFTS.models.seasonal.partitioner.TimeGridPartitioner":{build:[14,2,1,""],build_index:[14,2,1,""],extractor:[14,2,1,""],mask:[14,3,1,""],plot:[14,2,1,""],search:[14,2,1,""],season:[14,3,1,""]},"pyFTS.partitioners":{CMeans:[15,0,0,"-"],Entropy:[15,0,0,"-"],FCM:[15,0,0,"-"],Grid:[15,0,0,"-"],Simple:[15,0,0,"-"],Singleton:[15,0,0,"-"],SubClust:[15,0,0,"-"],partitioner:[15,0,0,"-"]},"pyFTS.partitioners.CMeans":{CMeansPartitioner:[15,1,1,""],c_means:[15,4,1,""],distance:[15,4,1,""]},"pyFTS.partitioners.CMeans.CMeansPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Entropy":{EntropyPartitioner:[15,1,1,""],PMF:[15,4,1,""],bestSplit:[15,4,1,""],entropy:[15,4,1,""],informationGain:[15,4,1,""],splitAbove:[15,4,1,""],splitBelow:[15,4,1,""]},"pyFTS.partitioners.Entropy.EntropyPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.FCM":{FCMPartitioner:[15,1,1,""],fuzzy_cmeans:[15,4,1,""],fuzzy_distance:[15,4,1,""],membership:[15,4,1,""]},"pyFTS.partitioners.FCM.FCMPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Grid":{GridPartitioner:[15,1,1,""],PreFixedGridPartitioner:[15,1,1,""]},"pyFTS.partitioners.Grid.GridPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Simple":{SimplePartitioner:[15,1,1,""]},"pyFTS.partitioners.Simple.SimplePartitioner":{append:[15,2,1,""],append_complex:[15,2,1,""]},"pyFTS.partitioners.Singleton":{SingletonPartitioner:[15,1,1,""]},"pyFTS.partitioners.Singleton.SingletonPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.SubClust":{SubClustPartitioner:[15,1,1,""],imax:[15,4,1,""],subclust:[15,4,1,""]},"pyFTS.partitioners.SubClust.SubClustPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.partitioner":{Partitioner:[15,1,1,""]},"pyFTS.partitioners.partitioner.Partitioner":{build:[15,2,1,""],build_index:[15,2,1,""],check_bounds:[15,2,1,""],defuzzyfy:[15,2,1,""],extractor:[15,2,1,""],fuzzyfy:[15,2,1,""],get_name:[15,2,1,""],kdtree:[15,3,1,""],lower_margin:[15,3,1,""],lower_set:[15,2,1,""],margin:[15,3,1,""],membership_function:[15,3,1,""],name:[15,3,1,""],ordered_sets:[15,3,1,""],partitions:[15,3,1,""],plot:[15,2,1,""],plot_set:[15,2,1,""],prefix:[15,3,1,""],search:[15,2,1,""],setnames:[15,3,1,""],transformation:[15,3,1,""],type:[15,3,1,""],upper_margin:[15,3,1,""],upper_set:[15,2,1,""],variable:[15,3,1,""]},pyFTS:{benchmarks:[3,0,0,"-"],common:[4,0,0,"-"],conf:[2,0,0,"-"],data:[6,0,0,"-"],distributed:[7,0,0,"-"],hyperparam:[8,0,0,"-"],models:[9,0,0,"-"],partitioners:[15,0,0,"-"],probabilistic:[16,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:function"},terms:{"261459a0":6,"57a":6,"5egspc":6,"case":[4,17],"class":[4,6,12,13,14,15,17],"default":[6,15],"enum":14,"final":6,"float":6,"function":[4,8,12,13,14,15,17],"guimar\u00e3":0,"h\u00e9non":6,"import":[4,17],"new":[4,12,15],"organiza\u00e7\u00e3o":6,"r\u00f6ssler":6,"return":[4,6,8,12,13,14,15],"short":[0,4],"true":[6,12],"var":[6,12],"while":4,FTS:[0,3,8,10,11],LHS:[4,13],One:15,RHS:[4,12,13],The:[4,6,8,15,17],Then:17,There:17,These:[0,17],Use:14,acc:4,accord:[12,15],accuraci:8,adapativeexpect:[1,2],add:[4,13],added:[4,6],addit:6,affect:13,after:6,age:4,aged:4,aggreg:10,ahead:[4,17],ahed:17,airlin:6,airpasseng:[1,2],alabama:6,all:[4,12,15,17],almost:17,alpha:[4,8,14],alpha_cut:[4,12,15],alreadi:6,also:[0,17],ambientai:6,angela:4,api:[0,4],append:[4,12,15],append_complex:15,append_rh:[4,12],append_set:[4,12],appendchild:4,appl:15,appli:15,approach:[15,17],arg:13,argument:[4,15],arima:[1,2],around:4,arrai:[4,6,13,14],artifici:[1,2],aspx:6,assign:4,associ:6,atmospher:6,attibut:4,attractor:6,auto:15,autom:6,automat:4,averag:6,avg:6,axi:15,base:[4,6,12,13,14,15,17],befor:17,bell:4,bellmf:4,belo:[0,6],belog:4,below:17,benchmark:[1,2,8],bestsplit:15,better:17,between:4,bill:4,bisect:4,bitcoin:[1,2],bivari:6,blip:6,both:[4,12,15],bound:[4,6,12,13,15],box:17,boxcox:[1,2],brasil:6,brasilia:6,brazil:0,brazilian:0,bst:[1,2],btc:6,build:[12,13,14,15],build_index:[12,14,15],build_tree_without_ord:4,built:6,buseco:6,busi:6,c_mean:15,calcul:[4,12,13],call:4,camwa:15,can:[4,17],cancel:6,capit:6,cartesian:12,ccst:6,center:4,centroid:[4,14],chain:6,chang:[6,15],change_target_vari:12,chao:6,chaotic:[1,2],characterist:17,cheap:0,check:[4,6,15,17],check_bound:[4,13,15],check_bounds_index:[4,13],chen:[1,2],cheng:[1,2,15],child:4,chiu:15,clear:4,clone:17,closest:15,cluster:[12,15],cmean:[1,2],cmeanspartition:15,cmsft:[2,9],cmvft:[2,9],code:17,coeffici:6,colab:17,colabor:0,com:[6,17],combin:12,common:[1,2,8,9,15,17],commun:6,complet:6,complex:6,complic:6,compon:6,composit:[1,2,6,12],compress:6,comput:15,computation:0,concept:17,conf:[0,1],conn:8,connect:8,consid:[4,12,15],const_t:13,constant:6,contain:[4,15,17],content:[0,1],context:15,continu:6,control:6,copi:4,cost:15,count:4,counter:15,cox:17,creat:[4,6,8,12,15,17],create_hyperparam_t:8,csv:6,current:6,cut:[4,8],cvft:[2,9],dado:[4,6,15],dai:6,daili:6,data:[0,1,2,4,8,12,13,14,15,17],data_field:14,data_point:12,databas:8,datafram:[6,14],dataframeseasonalindex:14,dataset:[1,2,8],date:14,date_field:14,date_part:14,datepart:14,datetim:14,datetimeseasonalindex:14,david:4,day_of_month:14,day_of_week:14,day_of_year:14,dealer:6,dec:15,decemb:6,decompress:6,defin:8,defuzzyf:17,defuzzyfi:[12,15],deg:13,delet:4,deltadist:15,demand:12,demo:17,departa:0,depend:[4,12,15,17],design:[4,8,12,14,15],determinist:[6,15],develop:[0,17],dict:4,dictionari:4,differenti:[1,2,6,17],dimension:6,directli:[4,17],discours:[12,13,14,15,17],dispi:[1,2],displac:13,distanc:15,distribut:[1,2,6,16],dji:6,dnf:6,document:0,doi:[0,6,15],don:6,dow:6,dowjon:[1,2],download:6,drift:17,dynam:6,each:[6,17],easi:[0,4],easier:4,edu:6,edward:6,effici:4,electr:0,eletr:6,emul:6,energi:17,engin:0,enrol:[1,2],ensembl:[1,2,9],entropi:[1,2],entropypartition:[15,17],eps_inf:15,eps_sup:15,equal:[4,17],equat:6,espaciai:6,esrl:6,estim:15,etc:[4,17],eth:6,ethereum:[1,2],eur:[1,2],eurgbp:6,eurusd:6,even:[14,15],evolutionari:[1,2],exact:4,exampl:0,exceed:15,exchang:6,exist:6,expert:0,exploit:0,exponenti:13,extract:[6,14,15],extractor:[14,15],facil:[6,8],fals:[4,6],fcm:[1,2],fcmpartition:[15,17],feder:0,fetch:4,field:[6,14],file:6,filenam:6,filenem:8,financ:6,find:[4,14,15],find_g:4,find_gt:4,find_l:4,find_lt:4,first:4,five:4,flashquot:6,flat:4,flow:6,flr:[1,2,9],flrg:[1,2,9],flrgtree:4,flrgtreenod:4,forecast:[15,17],forex:6,fork:0,format:[8,14],format_data:12,forward:4,found:[4,17],frederico:0,from:[0,4,6,12,14,15,17],fset:12,fts:[1,2],fuzzi:[2,4,9,12,13,14,15],fuzzif:15,fuzzifi:[4,13],fuzzy_cmean:15,fuzzy_dist:15,fuzzy_set:4,fuzzydata:4,fuzzyf:[4,12,15,17],fuzzyfi:[4,12,15],fuzzyfy_inst:[4,12],fuzzyfy_instance_clust:12,fuzzyfy_seri:4,fuzzyfy_series_old:4,fuzzyseri:13,fuzzyset:[1,2,12,13,14],gadelha:0,garibaldi:13,gaussian:[4,6],gaussianproc:[1,2],gaussmf:4,gbp:[1,2],gbpusd:6,gcos_wgsp:6,gener:[1,2,4,15,17],generate_gaussian_linear:6,generate_high_order_recurrent_flr:4,generate_indexed_flr:4,generate_linear_periodic_gaussian:6,generate_non_recurrent_flr:4,generate_recurrent_flr:4,generate_sinoidal_periodic_gaussian:6,generate_uniform_linear:6,gerai:0,get:[4,6],get_data:[6,14],get_data_by_season:14,get_datafram:6,get_fuzzyset:4,get_index:14,get_index_by_season:14,get_kei:[4,13],get_low:[4,12,13],get_maximum_membership_fuzzyset:4,get_maximum_membership_fuzzyset_index:4,get_membership:[4,12,13],get_midpoint:[4,13],get_nam:15,get_polynomial_perturb:13,get_season_by_index:14,get_season_of_data:14,get_upp:[4,12,13],getchildren:4,getstr:4,git:17,github:[0,17],given:[4,12,13,15],glass:[1,2],good:17,googl:17,gov:6,grant_bound:4,granular:[2,9,14],greater:[4,6],grid:[1,2,9,14],gridclust:12,gridpartition:[15,17],gridsearch:[1,2],group:[4,12],half:14,hand:4,handl:4,hard:4,head:0,help:15,henon:[1,2],here:17,heteroskedast:13,high:17,histori:6,hoft:[1,2],honsft:[2,9],horizont:[0,6],hour:14,hour_of_dai:14,hour_of_month:14,hour_of_week:14,hour_of_year:14,hourli:6,http:[0,6,17],huarng:[1,2],huarngpartition:17,human:0,hwang:[1,2],hyndman:6,hyperparam:[1,2],hyperparamet:8,identif:[14,15],identifi:[4,8,13],ieee:13,ifmg:0,ifnmg:0,ift:[1,2],ignor:14,iii:17,imax:15,implement:[4,17],improv:17,increas:12,increment:[1,2,6,9,12],incremental_gaussian:6,incremental_search:12,incrementalensembl:[2,9],incrementalgridclust:12,ind:14,indentifi:8,index:[4,6,12,14,15],index_field:14,index_season:14,index_seri:6,indexedflr:4,indic:[4,6],infer:6,inform:15,informationgain:15,initi:[4,6],initial_valu:6,inmet:[1,2],inp:6,input:[4,12,13,15],insert:[4,6,8],insert_hyperparam:8,insert_right:4,insid:[4,14,15],inst:[4,13],instal:0,instanc:[6,12,13,14,15,17],instead:4,instituit:0,institut:0,instituto:6,integr:6,intellig:15,intend:0,interfer:6,internet:6,interpret:4,interv:17,intervalar:17,introduc:17,introduct:17,introspect:4,invers:17,ipynb:17,ismailefendi:[1,2],isol:15,item:4,itemgett:4,iter:[4,6],its:[6,14,15,17],ixic:6,januari:6,jaroszewski:13,jonathan:13,jone:[4,6],journal:[6,15],jun:15,jupyt:17,kde:[1,2],kdtree:15,kei:4,knn:[1,2],known:15,kwarg:[4,6,12,13,14,15],lab:0,lag:[4,6,8,17],last:4,later:17,layman:0,learn:11,left:4,length:[4,6,14,15,17],less:4,lett:6,level:4,librari:[2,6,17],like:[4,17],lin:15,linear:[6,13],linearseasonalindex:14,linspac:6,list:[4,6,12,13,14,15,17],load:6,local:6,locat:[4,6,13],location_param:13,log:4,logic:[4,12,17],logist:[4,6],logistic_map:[1,2],look:4,lookup:4,lorentz:[1,2],lorenz:6,lower:[4,6,12,13,15],lower_margin:15,lower_set:15,mackei:[1,2],mackey_glass:6,mai:6,main:17,malaysia:[1,2],mani:17,manual:15,map:6,marcin:13,margin:15,market:6,mask:14,mass:4,match:4,math:[6,15],mathemat:6,matplotlib:15,max:4,max_inc:6,max_ini:6,maximum:[4,6,12,15],mean:[4,6],measur:[1,2,8],membership:[1,2,8,12,13,15,17],membership_funct:15,meta:10,meteorologia:6,method:[0,4,6,8,9,10,11,12,13,15,17],middl:15,midpoint:[4,13],min:4,min_inc:6,min_ini:6,mina:0,mind:0,minim:[4,12,15],minimum:[6,17],minut:14,minute_of_dai:14,minute_of_hour:14,minute_of_month:14,minute_of_week:14,minute_of_year:14,mode:[4,12,15],model:[0,1,2,3,6,8,15,17],modul:[0,1,17],monash:6,month:14,monthli:6,more:17,most:17,msft:[2,9],mu_inc:6,mu_ini:6,mu_max:6,mu_min:6,much:4,multiseason:[2,9],multivari:[1,2,4,6,9,15,17],multivariatefuzzyset:12,multivariatepartition:12,musikasuwan:13,mvft:[2,9],nacion:6,naiv:[1,2],name:[4,6,8,12,13,14,15],nasdaq:[1,2],nation:6,nativ:[4,14],natur:6,nbin:4,nbsp:0,nearest:[12,14,15],next:17,nice:4,noaa:6,node:4,nois:[6,13],noise_param:13,non:[4,6,13,14,17],none:[4,6,13,14,15],nonperiod:6,nonstationari:[1,2,4,9],nonstationaryflrg:13,normal:[1,2,17],north:0,norton:6,notebook:17,noth:17,now:4,npart:[13,15],nsft:[2,9],num:6,num_season:14,number:[4,6,8,14,15,17],numer:17,numpi:6,object:[4,6,12,14,15,16],occur:4,occurr:4,old:4,older:4,oldest:4,onc:4,one:[4,6,8,17],onli:[4,12,15],onlin:11,open:8,open_hyperparam_db:8,oper:[4,17],optim:8,option:[4,15],order:[4,8,15,17],ordered_set:[4,13,15],ordin:4,org:[0,6],origin:[4,17],oscil:6,other:10,out:17,outlier:6,output:17,outsid:15,over:4,overlap:[12,14,15,17],p500:6,packag:[0,1],page:0,pair:6,panda:[6,14],par1:13,par2:13,parallel_util:[1,2],param:[6,13,14],paramet:[4,6,8,12,13,14,15,17],parametr:17,part:[13,17],partit:[4,8,12,13,14,15,17],partition:[1,2,4,8,9,17],partition_funct:4,passeng:6,path:4,pattern:4,pct:13,perform:[8,12,13,14,15,17],perform_loc:13,perform_width:13,period:[6,13],periodic_gaussian:6,person:[4,6],pertub:13,perturb:[2,9],perturbate_paramet:13,pesquisa:6,php:6,phy:6,physiolog:6,pip:17,plot:[14,15],plot_set:15,pmf:15,point:[4,12,13,14,15,17],poly_width:13,polynomi:13,polynomialnonstationarypartition:13,poor:6,posit:[4,14],postprocess:17,pprint:4,predict:17,prefix:15,prefixedgridpartition:15,preprocess:[4,14,17],previou:6,primit:[14,15],probabilist:[1,2,17],probabilitydistribut:[1,2],probabl:16,process:[4,6],product:[6,12],prof:0,project:15,properti:4,propos:17,provid:[0,4,17],prune:12,psd:6,pwft:[1,2],python:[2,17],quantreg:[1,2],quarter:14,quick:0,quot:6,quotat:6,rais:4,random:6,random_walk:6,rang:17,read:6,readabl:0,real:[4,17],recent:17,record:4,recurr:[4,6],relationship:[4,12],remov:4,render:6,repo:17,repr:4,repres:4,represent:17,research:[0,17],reset_calculated_valu:4,residualanalysi:[1,2],respect:4,respons:14,result:[4,8,14,15],revers:4,review:17,right:4,rng:13,robert:6,roger:4,roi:[1,2],rossler:[1,2],round:15,rule:[4,12,17],run:6,sadaei:[1,2],salang:13,same:4,sampl:[6,17],save:4,scale:[1,2,17],scale_down:13,scale_up:13,scan:4,scheme:[8,17],scienc:6,scientist:0,search:[0,4,12,14,15],season:[1,2,4,9,17],seasonalindex:[2,9],second:14,second_of_dai:14,second_of_hour:14,second_of_minut:14,secur:6,select:6,self:15,sep:6,separ:6,sequenc:4,seri:[1,2,4,9,12,13,15],set:[4,8,12,13,14,15,17],set_data:14,set_lh:12,set_ord:4,set_rh:12,set_target_vari:12,setnam:15,sever:[6,12,14,15],sft:[2,9],shape:4,show:4,side:4,sigma:6,sigma_inc:6,sigma_ini:6,sigma_max:6,sigma_min:6,sigmf:4,sigmoid:4,signal:6,signalemul:6,silva:0,simpl:[0,1,2,6],simplenonstationary_gridpartitioner_build:13,simplenonstationarypartition:13,simplepartition:15,simpler:4,singl:[4,14,15],singleton:[1,2,4],singletonpartition:15,sinoid:6,sistema:6,sixth:14,size:15,slice:4,smith:4,smooth:[4,17],social:15,solar:17,som:[1,2],sonda:[1,2],song:[1,2],sort:[4,15],sortedcollect:[1,2],sourc:[4,6,8,12,13,14,15],sp500:6,spark:[1,2],spatial:15,specif:[4,15],split:15,splitabov:15,splitbelow:15,splite:17,sqlite3:8,sqlite:8,standard:[6,17],start:[0,6],station:6,stationari:[13,17],stationary_gaussian:6,statist:0,step:[4,17],stephen:15,stochast:6,stock:6,store:[4,8],strang:6,string:[14,15],strip_datepart:14,structur:[4,14,15],student:0,studi:17,subclust:[1,2],subclustpartition:15,submodul:[0,1],subpackag:[0,1],subtract:15,suitabl:0,sunspot:[1,2],superset:4,support:4,symbol:6,synthet:[1,2],system:[6,13,15],tabl:8,tag:8,taiex:[1,2],taiwan:6,take:17,tam:15,tau:6,technol:15,tempeatur:6,tempor:[4,14,17],test:[1,2,17],than:[4,6,17],thei:4,theori:17,thi:[0,4,6,12,13,14,15,17],third:14,thoma:4,those:4,thres1:15,thres2:15,threshold:15,through:6,time:[1,2,4,9,12,13,14,15],timegridpartition:14,timeseri:6,timevari:[2,9],tool:[0,17],total:6,train:[4,12,13,14,15],transact:13,transform:[1,2,8,13,14,15,17],transit:[4,17],translat:17,trapezoid:[4,15],trapmf:4,tree:[1,2],trend:[1,2],triangular:4,trigger:4,trimf:4,tsdl:6,tupl:[4,8,12,15],tutori:0,two:6,twse:6,type:[4,6,12,14,15,17],ufmg:0,under:4,uniform:6,uniqu:[4,13],unit:14,univari:6,univers:[0,6,12,13,14,15,17],unpack_arg:13,uod:[4,8,15],upper:[4,6,12,13,15],upper_margin:15,upper_set:15,url:[0,6],usa:6,usag:0,usd:[1,2],use:[0,4,12],used:[8,17],user:8,using:[4,15,17],usual:[4,17],util:[1,2,9],val:15,valu:[4,6,8,12,13,14,15,17],valueerror:4,variabl:[2,4,9,15],varianc:[4,6],variant:17,variat:6,vec:15,vector:[4,12,15],veri:6,verifi:15,vmax:6,vmin:6,vol:15,walk:6,want:0,weight:[6,17],were:[12,14,15],when:[4,15],where:4,which:[4,8,12,17],white_nois:6,whose:0,width:13,width_param:13,window_index:13,window_s:13,without:4,wmvft:[2,9],word:8,work:[4,12,14,15],www:6,yahoo:6,year:14,yearli:6,yeh:15,you:4,young:4,younger:4,youngest:4,zenodo:0},titles:["pyFTS - Fuzzy Time Series for Python","pyFTS","pyFTS package","pyFTS.benchmarks package","pyFTS.common package","pyFTS.common.transformations package","pyFTS.data package","pyFTS.distributed package","pyFTS.hyperparam package","pyFTS.models package","pyFTS.models.ensemble package","pyFTS.models.incremental package","pyFTS.models.multivariate package","pyFTS.models.nonstationary package","pyFTS.models.seasonal package","pyFTS.partitioners package","pyFTS.probabilistic package","pyFTS Quick Start"],titleterms:{"short":17,FTS:17,adapativeexpect:5,airpasseng:6,arima:3,artifici:6,benchmark:3,bitcoin:6,boxcox:5,bst:3,chaotic:6,chen:9,cheng:9,cmean:15,cmsft:14,cmvft:12,common:[4,5,6,12,13,14],composit:4,conf:2,content:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],cvft:13,data:6,dataset:6,differenti:5,dispi:7,distribut:7,dowjon:6,enrol:6,ensembl:10,entropi:15,ethereum:6,eur:6,evolutionari:8,exampl:17,fcm:15,flr:[4,12],flrg:[4,12,13],fts:4,fuzzi:[0,17],fuzzyset:4,gaussianproc:3,gbp:6,gener:6,glass:6,granular:12,grid:[12,15],gridsearch:8,henon:6,hoft:9,honsft:13,how:[0,17],huarng:15,hwang:9,hyperparam:8,ift:9,increment:11,incrementalensembl:11,index:0,inmet:6,instal:17,ismailefendi:9,kde:16,knn:3,librari:0,logistic_map:6,lorentz:6,mackei:6,malaysia:6,measur:3,membership:4,model:[9,10,11,12,13,14],modul:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],msft:14,multiseason:10,multivari:12,mvft:12,naiv:3,nasdaq:6,nonstationari:13,normal:5,nsft:13,packag:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],parallel_util:15,partition:[12,13,14,15],perturb:13,probabilist:16,probabilitydistribut:16,pwft:9,pyft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],python:0,quantreg:3,quick:17,refer:0,residualanalysi:3,roi:5,rossler:6,sadaei:9,scale:5,season:14,seasonalindex:14,seri:[0,6,17],sft:14,simpl:15,singleton:15,som:5,sonda:6,song:9,sortedcollect:4,spark:7,start:17,subclust:15,submodul:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],subpackag:[2,9],sunspot:6,synthet:6,taiex:6,test:3,time:[0,6,17],timevari:11,transform:[4,5],tree:4,trend:5,tutori:17,usag:17,usd:6,util:[3,4,8,13,15],variabl:12,what:[0,17],wmvft:12}}) \ No newline at end of file +Search.setIndex({docnames:["index","modules","pyFTS","pyFTS.benchmarks","pyFTS.common","pyFTS.common.transformations","pyFTS.data","pyFTS.distributed","pyFTS.hyperparam","pyFTS.models","pyFTS.models.ensemble","pyFTS.models.incremental","pyFTS.models.multivariate","pyFTS.models.nonstationary","pyFTS.models.seasonal","pyFTS.partitioners","pyFTS.probabilistic","quickstart"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","modules.rst","pyFTS.rst","pyFTS.benchmarks.rst","pyFTS.common.rst","pyFTS.common.transformations.rst","pyFTS.data.rst","pyFTS.distributed.rst","pyFTS.hyperparam.rst","pyFTS.models.rst","pyFTS.models.ensemble.rst","pyFTS.models.incremental.rst","pyFTS.models.multivariate.rst","pyFTS.models.nonstationary.rst","pyFTS.models.seasonal.rst","pyFTS.partitioners.rst","pyFTS.probabilistic.rst","quickstart.rst"],objects:{"":{pyFTS:[2,0,0,"-"]},"pyFTS.benchmarks":{BSTS:[3,0,0,"-"],Measures:[3,0,0,"-"],ResidualAnalysis:[3,0,0,"-"],Tests:[3,0,0,"-"],Util:[3,0,0,"-"],arima:[3,0,0,"-"],benchmarks:[3,0,0,"-"],knn:[3,0,0,"-"],naive:[3,0,0,"-"],quantreg:[3,0,0,"-"]},"pyFTS.benchmarks.BSTS":{ARIMA:[3,1,1,""]},"pyFTS.benchmarks.BSTS.ARIMA":{forecast:[3,2,1,""],forecast_ahead:[3,2,1,""],forecast_ahead_distribution:[3,2,1,""],forecast_ahead_interval:[3,2,1,""],forecast_distribution:[3,2,1,""],forecast_interval:[3,2,1,""],inference:[3,2,1,""],train:[3,2,1,""]},"pyFTS.benchmarks.Measures":{TheilsInequality:[3,3,1,""],UStatistic:[3,3,1,""],acf:[3,3,1,""],brier_score:[3,3,1,""],coverage:[3,3,1,""],crps:[3,3,1,""],get_distribution_ahead_statistics:[3,3,1,""],get_distribution_statistics:[3,3,1,""],get_interval_ahead_statistics:[3,3,1,""],get_interval_statistics:[3,3,1,""],get_point_ahead_statistics:[3,3,1,""],get_point_statistics:[3,3,1,""],logarithm_score:[3,3,1,""],mape:[3,3,1,""],mape_interval:[3,3,1,""],pinball:[3,3,1,""],pinball_mean:[3,3,1,""],resolution:[3,3,1,""],rmse:[3,3,1,""],rmse_interval:[3,3,1,""],sharpness:[3,3,1,""],smape:[3,3,1,""],winkler_mean:[3,3,1,""],winkler_score:[3,3,1,""]},"pyFTS.benchmarks.ResidualAnalysis":{compare_residuals:[3,3,1,""],ljung_box_test:[3,3,1,""],plot_residuals_by_model:[3,3,1,""],residuals:[3,3,1,""],single_plot_residuals:[3,3,1,""]},"pyFTS.benchmarks.Tests":{BoxLjungStatistic:[3,3,1,""],BoxPierceStatistic:[3,3,1,""],format_experiment_table:[3,3,1,""],post_hoc_tests:[3,3,1,""],test_mean_equality:[3,3,1,""]},"pyFTS.benchmarks.Util":{analytic_tabular_dataframe:[3,3,1,""],analytical_data_columns:[3,3,1,""],base_dataframe_columns:[3,3,1,""],cast_dataframe_to_synthetic:[3,3,1,""],cast_dataframe_to_synthetic_interval:[3,3,1,""],cast_dataframe_to_synthetic_point:[3,3,1,""],cast_dataframe_to_synthetic_probabilistic:[3,3,1,""],check_ignore_list:[3,3,1,""],check_replace_list:[3,3,1,""],create_benchmark_tables:[3,3,1,""],extract_measure:[3,3,1,""],find_best:[3,3,1,""],get_dataframe_from_bd:[3,3,1,""],insert_benchmark:[3,3,1,""],interval_dataframe_analytic_columns:[3,3,1,""],interval_dataframe_synthetic_columns:[3,3,1,""],open_benchmark_db:[3,3,1,""],plot_dataframe_interval:[3,3,1,""],plot_dataframe_interval_pinball:[3,3,1,""],plot_dataframe_point:[3,3,1,""],plot_dataframe_probabilistic:[3,3,1,""],point_dataframe_analytic_columns:[3,3,1,""],point_dataframe_synthetic_columns:[3,3,1,""],probabilistic_dataframe_analytic_columns:[3,3,1,""],probabilistic_dataframe_synthetic_columns:[3,3,1,""],process_common_data2:[3,3,1,""],process_common_data:[3,3,1,""],save_dataframe_interval:[3,3,1,""],save_dataframe_point:[3,3,1,""],save_dataframe_probabilistic:[3,3,1,""],scale:[3,3,1,""],scale_params:[3,3,1,""],simple_synthetic_dataframe:[3,3,1,""],stats:[3,3,1,""],tabular_dataframe_columns:[3,3,1,""],unified_scaled_interval:[3,3,1,""],unified_scaled_interval_pinball:[3,3,1,""],unified_scaled_point:[3,3,1,""],unified_scaled_probabilistic:[3,3,1,""]},"pyFTS.benchmarks.arima":{ARIMA:[3,1,1,""]},"pyFTS.benchmarks.arima.ARIMA":{ar:[3,2,1,""],forecast:[3,2,1,""],forecast_ahead_distribution:[3,2,1,""],forecast_ahead_interval:[3,2,1,""],forecast_distribution:[3,2,1,""],forecast_interval:[3,2,1,""],ma:[3,2,1,""],train:[3,2,1,""]},"pyFTS.benchmarks.benchmarks":{SelecaoSimples_MenorRMSE:[3,3,1,""],common_process_interval_jobs:[3,3,1,""],common_process_point_jobs:[3,3,1,""],common_process_probabilistic_jobs:[3,3,1,""],common_process_time_jobs:[3,3,1,""],compareModelsPlot:[3,3,1,""],compareModelsTable:[3,3,1,""],distributed_model_train_test_time:[3,3,1,""],get_benchmark_interval_methods:[3,3,1,""],get_benchmark_point_methods:[3,3,1,""],get_benchmark_probabilistic_methods:[3,3,1,""],get_interval_methods:[3,3,1,""],get_point_methods:[3,3,1,""],get_point_multivariate_methods:[3,3,1,""],get_probabilistic_methods:[3,3,1,""],multivariate_sliding_window_benchmarks2:[3,3,1,""],mv_run_interval2:[3,3,1,""],mv_run_point2:[3,3,1,""],mv_run_probabilistic2:[3,3,1,""],pftsExploreOrderAndPartitions:[3,3,1,""],plotCompared:[3,3,1,""],plot_compared_series:[3,3,1,""],plot_point:[3,3,1,""],print_distribution_statistics:[3,3,1,""],print_interval_statistics:[3,3,1,""],print_point_statistics:[3,3,1,""],process_interval_jobs2:[3,3,1,""],process_interval_jobs:[3,3,1,""],process_point_jobs2:[3,3,1,""],process_point_jobs:[3,3,1,""],process_probabilistic_jobs2:[3,3,1,""],process_probabilistic_jobs:[3,3,1,""],run_interval2:[3,3,1,""],run_interval:[3,3,1,""],run_point2:[3,3,1,""],run_point:[3,3,1,""],run_probabilistic2:[3,3,1,""],run_probabilistic:[3,3,1,""],simpleSearch_RMSE:[3,3,1,""],sliding_window_benchmarks2:[3,3,1,""],sliding_window_benchmarks:[3,3,1,""],train_test_time:[3,3,1,""]},"pyFTS.benchmarks.knn":{KNearestNeighbors:[3,1,1,""]},"pyFTS.benchmarks.knn.KNearestNeighbors":{forecast:[3,2,1,""],forecast_ahead_distribution:[3,2,1,""],forecast_ahead_interval:[3,2,1,""],forecast_distribution:[3,2,1,""],forecast_interval:[3,2,1,""],knn:[3,2,1,""],train:[3,2,1,""]},"pyFTS.benchmarks.naive":{Naive:[3,1,1,""]},"pyFTS.benchmarks.naive.Naive":{forecast:[3,2,1,""]},"pyFTS.benchmarks.quantreg":{QuantileRegression:[3,1,1,""]},"pyFTS.benchmarks.quantreg.QuantileRegression":{forecast:[3,2,1,""],forecast_ahead_distribution:[3,2,1,""],forecast_ahead_interval:[3,2,1,""],forecast_distribution:[3,2,1,""],forecast_interval:[3,2,1,""],interval_to_interval:[3,2,1,""],linearmodel:[3,2,1,""],point_to_interval:[3,2,1,""],train:[3,2,1,""]},"pyFTS.common":{Composite:[4,0,0,"-"],FLR:[4,0,0,"-"],FuzzySet:[4,0,0,"-"],Membership:[4,0,0,"-"],SortedCollection:[4,0,0,"-"],Util:[4,0,0,"-"],flrg:[4,0,0,"-"],fts:[4,0,0,"-"],tree:[4,0,0,"-"]},"pyFTS.common.Composite":{FuzzySet:[4,1,1,""]},"pyFTS.common.Composite.FuzzySet":{append:[4,2,1,""],append_set:[4,2,1,""],membership:[4,2,1,""],transform:[4,2,1,""]},"pyFTS.common.FLR":{FLR:[4,1,1,""],IndexedFLR:[4,1,1,""],generate_high_order_recurrent_flr:[4,3,1,""],generate_indexed_flrs:[4,3,1,""],generate_non_recurrent_flrs:[4,3,1,""],generate_recurrent_flrs:[4,3,1,""]},"pyFTS.common.FLR.FLR":{LHS:[4,4,1,""],RHS:[4,4,1,""]},"pyFTS.common.FLR.IndexedFLR":{index:[4,4,1,""]},"pyFTS.common.FuzzySet":{FuzzySet:[4,1,1,""],check_bounds:[4,3,1,""],check_bounds_index:[4,3,1,""],fuzzyfy:[4,3,1,""],fuzzyfy_instance:[4,3,1,""],fuzzyfy_instances:[4,3,1,""],fuzzyfy_series:[4,3,1,""],fuzzyfy_series_old:[4,3,1,""],get_fuzzysets:[4,3,1,""],get_maximum_membership_fuzzyset:[4,3,1,""],get_maximum_membership_fuzzyset_index:[4,3,1,""],grant_bounds:[4,3,1,""],set_ordered:[4,3,1,""]},"pyFTS.common.FuzzySet.FuzzySet":{Z:[4,4,1,""],alpha:[4,4,1,""],centroid:[4,4,1,""],membership:[4,2,1,""],mf:[4,4,1,""],name:[4,4,1,""],parameters:[4,4,1,""],partition_function:[4,2,1,""],transform:[4,2,1,""],type:[4,4,1,""],variable:[4,4,1,""]},"pyFTS.common.Membership":{bellmf:[4,3,1,""],gaussmf:[4,3,1,""],sigmf:[4,3,1,""],singleton:[4,3,1,""],trapmf:[4,3,1,""],trimf:[4,3,1,""]},"pyFTS.common.SortedCollection":{SortedCollection:[4,1,1,""]},"pyFTS.common.SortedCollection.SortedCollection":{around:[4,2,1,""],between:[4,2,1,""],clear:[4,2,1,""],copy:[4,2,1,""],count:[4,2,1,""],find:[4,2,1,""],find_ge:[4,2,1,""],find_gt:[4,2,1,""],find_le:[4,2,1,""],find_lt:[4,2,1,""],index:[4,2,1,""],insert:[4,2,1,""],insert_right:[4,2,1,""],inside:[4,2,1,""],key:[4,2,1,""],remove:[4,2,1,""]},"pyFTS.common.Util":{current_milli_time:[4,3,1,""],draw_sets_on_axis:[4,3,1,""],enumerate2:[4,3,1,""],load_env:[4,3,1,""],load_obj:[4,3,1,""],persist_env:[4,3,1,""],persist_obj:[4,3,1,""],plot_compared_intervals_ahead:[4,3,1,""],plot_density_rectange:[4,3,1,""],plot_distribution2:[4,3,1,""],plot_distribution:[4,3,1,""],plot_distribution_tiled:[4,3,1,""],plot_interval2:[4,3,1,""],plot_interval:[4,3,1,""],plot_probability_distributions:[4,3,1,""],plot_rules:[4,3,1,""],show_and_save_image:[4,3,1,""],sliding_window:[4,3,1,""],uniquefilename:[4,3,1,""]},"pyFTS.common.flrg":{FLRG:[4,1,1,""]},"pyFTS.common.flrg.FLRG":{LHS:[4,4,1,""],RHS:[4,4,1,""],append_rhs:[4,2,1,""],get_key:[4,2,1,""],get_lower:[4,2,1,""],get_membership:[4,2,1,""],get_midpoint:[4,2,1,""],get_midpoints:[4,2,1,""],get_upper:[4,2,1,""],order:[4,4,1,""],reset_calculated_values:[4,2,1,""]},"pyFTS.common.fts":{FTS:[4,1,1,""]},"pyFTS.common.fts.FTS":{alpha_cut:[4,4,1,""],append_log:[4,2,1,""],append_rule:[4,2,1,""],append_transformation:[4,2,1,""],apply_inverse_transformations:[4,2,1,""],apply_transformations:[4,2,1,""],auto_update:[4,4,1,""],benchmark_only:[4,4,1,""],clip_uod:[4,2,1,""],clone_parameters:[4,2,1,""],detail:[4,4,1,""],fit:[4,2,1,""],flrgs:[4,4,1,""],forecast:[4,2,1,""],forecast_ahead:[4,2,1,""],forecast_ahead_distribution:[4,2,1,""],forecast_ahead_interval:[4,2,1,""],forecast_ahead_multivariate:[4,2,1,""],forecast_distribution:[4,2,1,""],forecast_interval:[4,2,1,""],forecast_multivariate:[4,2,1,""],forecast_step:[4,2,1,""],fuzzy:[4,2,1,""],get_UoD:[4,2,1,""],has_interval_forecasting:[4,4,1,""],has_point_forecasting:[4,4,1,""],has_probability_forecasting:[4,4,1,""],has_seasonality:[4,4,1,""],indexer:[4,4,1,""],is_clustered:[4,4,1,""],is_high_order:[4,4,1,""],is_multivariate:[4,4,1,""],is_time_variant:[4,4,1,""],is_wrapper:[4,4,1,""],lags:[4,4,1,""],len_total:[4,2,1,""],log:[4,4,1,""],max_lag:[4,4,1,""],merge:[4,2,1,""],min_order:[4,4,1,""],name:[4,4,1,""],offset:[4,2,1,""],order:[4,4,1,""],original_max:[4,4,1,""],original_min:[4,4,1,""],partitioner:[4,4,1,""],predict:[4,2,1,""],reset_calculated_values:[4,2,1,""],shortname:[4,4,1,""],standard_horizon:[4,4,1,""],train:[4,2,1,""],transformations:[4,4,1,""],transformations_param:[4,4,1,""],uod_clip:[4,4,1,""]},"pyFTS.common.tree":{FLRGTree:[4,1,1,""],FLRGTreeNode:[4,1,1,""],build_tree_without_order:[4,3,1,""],flat:[4,3,1,""]},"pyFTS.common.tree.FLRGTreeNode":{appendChild:[4,2,1,""],getChildren:[4,2,1,""],getStr:[4,2,1,""],paths:[4,2,1,""]},"pyFTS.data":{AirPassengers:[6,0,0,"-"],Bitcoin:[6,0,0,"-"],DowJones:[6,0,0,"-"],EURGBP:[6,0,0,"-"],EURUSD:[6,0,0,"-"],Enrollments:[6,0,0,"-"],Ethereum:[6,0,0,"-"],GBPUSD:[6,0,0,"-"],INMET:[6,0,0,"-"],Malaysia:[6,0,0,"-"],NASDAQ:[6,0,0,"-"],SONDA:[6,0,0,"-"],SP500:[6,0,0,"-"],TAIEX:[6,0,0,"-"],artificial:[6,0,0,"-"],common:[6,0,0,"-"],henon:[6,0,0,"-"],logistic_map:[6,0,0,"-"],lorentz:[6,0,0,"-"],mackey_glass:[6,0,0,"-"],rossler:[6,0,0,"-"],sunspots:[6,0,0,"-"]},"pyFTS.data.AirPassengers":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.Bitcoin":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.DowJones":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.EURGBP":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.EURUSD":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.Enrollments":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.Ethereum":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.GBPUSD":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.INMET":{get_dataframe:[6,3,1,""]},"pyFTS.data.Malaysia":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.NASDAQ":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.SONDA":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.SP500":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.TAIEX":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.artificial":{SignalEmulator:[6,1,1,""],generate_gaussian_linear:[6,3,1,""],generate_linear_periodic_gaussian:[6,3,1,""],generate_sinoidal_periodic_gaussian:[6,3,1,""],generate_uniform_linear:[6,3,1,""],random_walk:[6,3,1,""],white_noise:[6,3,1,""]},"pyFTS.data.artificial.SignalEmulator":{blip:[6,2,1,""],components:[6,4,1,""],incremental_gaussian:[6,2,1,""],periodic_gaussian:[6,2,1,""],run:[6,2,1,""],stationary_gaussian:[6,2,1,""]},"pyFTS.data.common":{get_dataframe:[6,3,1,""]},"pyFTS.data.henon":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.logistic_map":{get_data:[6,3,1,""]},"pyFTS.data.lorentz":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.mackey_glass":{get_data:[6,3,1,""]},"pyFTS.data.rossler":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.data.sunspots":{get_data:[6,3,1,""],get_dataframe:[6,3,1,""]},"pyFTS.distributed":{dispy:[7,0,0,"-"]},"pyFTS.distributed.dispy":{distributed_predict:[7,3,1,""],distributed_train:[7,3,1,""],get_number_of_cpus:[7,3,1,""],simple_model_predict:[7,3,1,""],simple_model_train:[7,3,1,""],start_dispy_cluster:[7,3,1,""],stop_dispy_cluster:[7,3,1,""]},"pyFTS.hyperparam":{Evolutionary:[8,0,0,"-"],GridSearch:[8,0,0,"-"],Util:[8,0,0,"-"]},"pyFTS.hyperparam.Evolutionary":{GeneticAlgorithm:[8,3,1,""],crossover:[8,3,1,""],double_tournament:[8,3,1,""],elitism:[8,3,1,""],evaluate:[8,3,1,""],execute:[8,3,1,""],genotype:[8,3,1,""],initial_population:[8,3,1,""],lag_crossover2:[8,3,1,""],log_result:[8,3,1,""],mutation:[8,3,1,""],mutation_lags:[8,3,1,""],persist_statistics:[8,3,1,""],phenotype:[8,3,1,""],process_experiment:[8,3,1,""],random_genotype:[8,3,1,""],tournament:[8,3,1,""]},"pyFTS.hyperparam.GridSearch":{cluster_method:[8,3,1,""],dict_individual:[8,3,1,""],execute:[8,3,1,""],process_jobs:[8,3,1,""]},"pyFTS.hyperparam.Util":{create_hyperparam_tables:[8,3,1,""],insert_hyperparam:[8,3,1,""],open_hyperparam_db:[8,3,1,""]},"pyFTS.models":{chen:[9,0,0,"-"],cheng:[9,0,0,"-"],ensemble:[10,0,0,"-"],hofts:[9,0,0,"-"],hwang:[9,0,0,"-"],ifts:[9,0,0,"-"],incremental:[11,0,0,"-"],ismailefendi:[9,0,0,"-"],multivariate:[12,0,0,"-"],nonstationary:[13,0,0,"-"],pwfts:[9,0,0,"-"],sadaei:[9,0,0,"-"],seasonal:[14,0,0,"-"],song:[9,0,0,"-"],yu:[9,0,0,"-"]},"pyFTS.models.chen":{ConventionalFLRG:[9,1,1,""],ConventionalFTS:[9,1,1,""]},"pyFTS.models.chen.ConventionalFLRG":{append_rhs:[9,2,1,""],get_key:[9,2,1,""]},"pyFTS.models.chen.ConventionalFTS":{forecast:[9,2,1,""],generate_flrg:[9,2,1,""],train:[9,2,1,""]},"pyFTS.models.cheng":{TrendWeightedFLRG:[9,1,1,""],TrendWeightedFTS:[9,1,1,""]},"pyFTS.models.cheng.TrendWeightedFLRG":{weights:[9,2,1,""]},"pyFTS.models.cheng.TrendWeightedFTS":{generate_FLRG:[9,2,1,""]},"pyFTS.models.ensemble":{ensemble:[10,0,0,"-"],multiseasonal:[10,0,0,"-"]},"pyFTS.models.ensemble.ensemble":{AllMethodEnsembleFTS:[10,1,1,""],EnsembleFTS:[10,1,1,""],SimpleEnsembleFTS:[10,1,1,""],sampler:[10,3,1,""]},"pyFTS.models.ensemble.ensemble.AllMethodEnsembleFTS":{set_transformations:[10,2,1,""],train:[10,2,1,""]},"pyFTS.models.ensemble.ensemble.EnsembleFTS":{alpha:[10,4,1,""],append_model:[10,2,1,""],forecast:[10,2,1,""],forecast_ahead_distribution:[10,2,1,""],forecast_ahead_interval:[10,2,1,""],forecast_distribution:[10,2,1,""],forecast_interval:[10,2,1,""],get_UoD:[10,2,1,""],get_distribution_interquantile:[10,2,1,""],get_interval:[10,2,1,""],get_models_forecasts:[10,2,1,""],get_point:[10,2,1,""],interval_method:[10,4,1,""],models:[10,4,1,""],parameters:[10,4,1,""],point_method:[10,4,1,""],train:[10,2,1,""]},"pyFTS.models.ensemble.ensemble.SimpleEnsembleFTS":{method:[10,4,1,""],orders:[10,4,1,""],partitioner_method:[10,4,1,""],partitions:[10,4,1,""],train:[10,2,1,""]},"pyFTS.models.ensemble.multiseasonal":{SeasonalEnsembleFTS:[10,1,1,""],train_individual_model:[10,3,1,""]},"pyFTS.models.ensemble.multiseasonal.SeasonalEnsembleFTS":{forecast_distribution:[10,2,1,""],train:[10,2,1,""],update_uod:[10,2,1,""]},"pyFTS.models.hofts":{HighOrderFLRG:[9,1,1,""],HighOrderFTS:[9,1,1,""],WeightedHighOrderFLRG:[9,1,1,""],WeightedHighOrderFTS:[9,1,1,""]},"pyFTS.models.hofts.HighOrderFLRG":{append_lhs:[9,2,1,""],append_rhs:[9,2,1,""]},"pyFTS.models.hofts.HighOrderFTS":{configure_lags:[9,2,1,""],forecast:[9,2,1,""],generate_flrg:[9,2,1,""],generate_flrg_fuzzyfied:[9,2,1,""],generate_lhs_flrg:[9,2,1,""],generate_lhs_flrg_fuzzyfied:[9,2,1,""],train:[9,2,1,""]},"pyFTS.models.hofts.WeightedHighOrderFLRG":{append_lhs:[9,2,1,""],append_rhs:[9,2,1,""],get_lower:[9,2,1,""],get_midpoint:[9,2,1,""],get_upper:[9,2,1,""],weights:[9,2,1,""]},"pyFTS.models.hofts.WeightedHighOrderFTS":{generate_lhs_flrg_fuzzyfied:[9,2,1,""]},"pyFTS.models.hwang":{HighOrderFTS:[9,1,1,""]},"pyFTS.models.hwang.HighOrderFTS":{configure_lags:[9,2,1,""],forecast:[9,2,1,""],train:[9,2,1,""]},"pyFTS.models.ifts":{IntervalFTS:[9,1,1,""],WeightedIntervalFTS:[9,1,1,""]},"pyFTS.models.ifts.IntervalFTS":{forecast_ahead_interval:[9,2,1,""],forecast_interval:[9,2,1,""],get_lower:[9,2,1,""],get_sequence_membership:[9,2,1,""],get_upper:[9,2,1,""]},"pyFTS.models.ifts.WeightedIntervalFTS":{forecast_ahead_interval:[9,2,1,""],forecast_interval:[9,2,1,""],get_lower:[9,2,1,""],get_sequence_membership:[9,2,1,""],get_upper:[9,2,1,""]},"pyFTS.models.incremental":{IncrementalEnsemble:[11,0,0,"-"],TimeVariant:[11,0,0,"-"]},"pyFTS.models.incremental.IncrementalEnsemble":{IncrementalEnsembleFTS:[11,1,1,""]},"pyFTS.models.incremental.IncrementalEnsemble.IncrementalEnsembleFTS":{batch_size:[11,4,1,""],forecast:[11,2,1,""],forecast_ahead:[11,2,1,""],fts_method:[11,4,1,""],fts_params:[11,4,1,""],num_models:[11,4,1,""],offset:[11,2,1,""],partitioner_method:[11,4,1,""],partitioner_params:[11,4,1,""],train:[11,2,1,""],window_length:[11,4,1,""]},"pyFTS.models.incremental.TimeVariant":{Retrainer:[11,1,1,""]},"pyFTS.models.incremental.TimeVariant.Retrainer":{auto_update:[11,4,1,""],batch_size:[11,4,1,""],forecast:[11,2,1,""],forecast_ahead:[11,2,1,""],fts_method:[11,4,1,""],fts_params:[11,4,1,""],model:[11,4,1,""],offset:[11,2,1,""],partitioner:[11,4,1,""],partitioner_method:[11,4,1,""],partitioner_params:[11,4,1,""],train:[11,2,1,""],window_length:[11,4,1,""]},"pyFTS.models.ismailefendi":{ImprovedWeightedFLRG:[9,1,1,""],ImprovedWeightedFTS:[9,1,1,""]},"pyFTS.models.ismailefendi.ImprovedWeightedFLRG":{append_rhs:[9,2,1,""],weights:[9,2,1,""]},"pyFTS.models.ismailefendi.ImprovedWeightedFTS":{forecast:[9,2,1,""],generate_flrg:[9,2,1,""],train:[9,2,1,""]},"pyFTS.models.multivariate":{FLR:[12,0,0,"-"],cmvfts:[12,0,0,"-"],common:[12,0,0,"-"],flrg:[12,0,0,"-"],granular:[12,0,0,"-"],grid:[12,0,0,"-"],mvfts:[12,0,0,"-"],partitioner:[12,0,0,"-"],variable:[12,0,0,"-"],wmvfts:[12,0,0,"-"]},"pyFTS.models.multivariate.FLR":{FLR:[12,1,1,""]},"pyFTS.models.multivariate.FLR.FLR":{set_lhs:[12,2,1,""],set_rhs:[12,2,1,""]},"pyFTS.models.multivariate.cmvfts":{ClusteredMVFTS:[12,1,1,""]},"pyFTS.models.multivariate.cmvfts.ClusteredMVFTS":{check_data:[12,2,1,""],forecast:[12,2,1,""],forecast_ahead_distribution:[12,2,1,""],forecast_ahead_multivariate:[12,2,1,""],forecast_distribution:[12,2,1,""],forecast_interval:[12,2,1,""],forecast_multivariate:[12,2,1,""],fts_method:[12,4,1,""],fts_params:[12,4,1,""],fuzzyfy:[12,2,1,""],model:[12,4,1,""],train:[12,2,1,""]},"pyFTS.models.multivariate.common":{MultivariateFuzzySet:[12,1,1,""],fuzzyfy_instance:[12,3,1,""],fuzzyfy_instance_clustered:[12,3,1,""]},"pyFTS.models.multivariate.common.MultivariateFuzzySet":{append_set:[12,2,1,""],membership:[12,2,1,""],set_target_variable:[12,2,1,""]},"pyFTS.models.multivariate.flrg":{FLRG:[12,1,1,""]},"pyFTS.models.multivariate.flrg.FLRG":{append_rhs:[12,2,1,""],get_lower:[12,2,1,""],get_membership:[12,2,1,""],get_upper:[12,2,1,""],set_lhs:[12,2,1,""]},"pyFTS.models.multivariate.granular":{GranularWMVFTS:[12,1,1,""]},"pyFTS.models.multivariate.granular.GranularWMVFTS":{model:[12,4,1,""],train:[12,2,1,""]},"pyFTS.models.multivariate.grid":{GridCluster:[12,1,1,""],IncrementalGridCluster:[12,1,1,""]},"pyFTS.models.multivariate.grid.GridCluster":{build:[12,2,1,""],defuzzyfy:[12,2,1,""]},"pyFTS.models.multivariate.grid.IncrementalGridCluster":{fuzzyfy:[12,2,1,""],incremental_search:[12,2,1,""],prune:[12,2,1,""]},"pyFTS.models.multivariate.mvfts":{MVFTS:[12,1,1,""],product_dict:[12,3,1,""]},"pyFTS.models.multivariate.mvfts.MVFTS":{append_transformation:[12,2,1,""],append_variable:[12,2,1,""],apply_transformations:[12,2,1,""],clone_parameters:[12,2,1,""],forecast:[12,2,1,""],forecast_ahead:[12,2,1,""],forecast_ahead_interval:[12,2,1,""],forecast_interval:[12,2,1,""],format_data:[12,2,1,""],generate_flrg:[12,2,1,""],generate_flrs:[12,2,1,""],generate_lhs_flrs:[12,2,1,""],train:[12,2,1,""]},"pyFTS.models.multivariate.partitioner":{MultivariatePartitioner:[12,1,1,""]},"pyFTS.models.multivariate.partitioner.MultivariatePartitioner":{append:[12,2,1,""],build:[12,2,1,""],build_index:[12,2,1,""],change_target_variable:[12,2,1,""],format_data:[12,2,1,""],fuzzyfy:[12,2,1,""],prune:[12,2,1,""],search:[12,2,1,""]},"pyFTS.models.multivariate.variable":{Variable:[12,1,1,""]},"pyFTS.models.multivariate.variable.Variable":{alias:[12,4,1,""],alpha_cut:[12,4,1,""],apply_inverse_transformations:[12,2,1,""],apply_transformations:[12,2,1,""],build:[12,2,1,""],data_label:[12,4,1,""],data_type:[12,4,1,""],mask:[12,4,1,""],name:[12,4,1,""],partitioner:[12,4,1,""],transformation:[12,4,1,""]},"pyFTS.models.multivariate.wmvfts":{WeightedFLRG:[12,1,1,""],WeightedMVFTS:[12,1,1,""]},"pyFTS.models.multivariate.wmvfts.WeightedFLRG":{append_rhs:[12,2,1,""],get_lower:[12,2,1,""],get_midpoint:[12,2,1,""],get_upper:[12,2,1,""],weights:[12,2,1,""]},"pyFTS.models.multivariate.wmvfts.WeightedMVFTS":{generate_flrg:[12,2,1,""]},"pyFTS.models.nonstationary":{common:[13,0,0,"-"],cvfts:[13,0,0,"-"],flrg:[13,0,0,"-"],honsfts:[13,0,0,"-"],nsfts:[13,0,0,"-"],partitioners:[13,0,0,"-"],perturbation:[13,0,0,"-"],util:[13,0,0,"-"]},"pyFTS.models.nonstationary.common":{FuzzySet:[13,1,1,""],check_bounds:[13,3,1,""],check_bounds_index:[13,3,1,""],fuzzify:[13,3,1,""],fuzzySeries:[13,3,1,""],window_index:[13,3,1,""]},"pyFTS.models.nonstationary.common.FuzzySet":{get_lower:[13,2,1,""],get_midpoint:[13,2,1,""],get_upper:[13,2,1,""],location:[13,4,1,""],location_params:[13,4,1,""],membership:[13,2,1,""],noise:[13,4,1,""],noise_params:[13,4,1,""],perform_location:[13,2,1,""],perform_width:[13,2,1,""],perturbate_parameters:[13,2,1,""],width:[13,4,1,""],width_params:[13,4,1,""]},"pyFTS.models.nonstationary.cvfts":{ConditionalVarianceFTS:[13,1,1,""],HighOrderNonstationaryFLRG:[13,1,1,""]},"pyFTS.models.nonstationary.cvfts.ConditionalVarianceFTS":{forecast:[13,2,1,""],forecast_interval:[13,2,1,""],generate_flrg:[13,2,1,""],perturbation_factors:[13,2,1,""],perturbation_factors__old:[13,2,1,""],train:[13,2,1,""]},"pyFTS.models.nonstationary.cvfts.HighOrderNonstationaryFLRG":{append_lhs:[13,2,1,""],append_rhs:[13,2,1,""]},"pyFTS.models.nonstationary.flrg":{NonStationaryFLRG:[13,1,1,""]},"pyFTS.models.nonstationary.flrg.NonStationaryFLRG":{get_key:[13,2,1,""],get_lower:[13,2,1,""],get_membership:[13,2,1,""],get_midpoint:[13,2,1,""],get_upper:[13,2,1,""],unpack_args:[13,2,1,""]},"pyFTS.models.nonstationary.honsfts":{HighOrderNonStationaryFLRG:[13,1,1,""],HighOrderNonStationaryFTS:[13,1,1,""]},"pyFTS.models.nonstationary.honsfts.HighOrderNonStationaryFLRG":{append_lhs:[13,2,1,""],append_rhs:[13,2,1,""],get_lower:[13,2,1,""],get_midpoint:[13,2,1,""],get_upper:[13,2,1,""],weights:[13,2,1,""]},"pyFTS.models.nonstationary.honsfts.HighOrderNonStationaryFTS":{configure_lags:[13,2,1,""],forecast:[13,2,1,""],generate_flrg:[13,2,1,""],train:[13,2,1,""]},"pyFTS.models.nonstationary.nsfts":{ConventionalNonStationaryFLRG:[13,1,1,""],NonStationaryFTS:[13,1,1,""],WeightedNonStationaryFLRG:[13,1,1,""],WeightedNonStationaryFTS:[13,1,1,""]},"pyFTS.models.nonstationary.nsfts.ConventionalNonStationaryFLRG":{append_rhs:[13,2,1,""],get_key:[13,2,1,""]},"pyFTS.models.nonstationary.nsfts.NonStationaryFTS":{conditional_perturbation_factors:[13,2,1,""],forecast:[13,2,1,""],forecast_interval:[13,2,1,""],generate_flrg:[13,2,1,""],train:[13,2,1,""]},"pyFTS.models.nonstationary.nsfts.WeightedNonStationaryFLRG":{append_rhs:[13,2,1,""],get_key:[13,2,1,""],get_midpoint:[13,2,1,""],weights:[13,2,1,""]},"pyFTS.models.nonstationary.nsfts.WeightedNonStationaryFTS":{generate_flrg:[13,2,1,""],train:[13,2,1,""]},"pyFTS.models.nonstationary.partitioners":{PolynomialNonStationaryPartitioner:[13,1,1,""],SimpleNonStationaryPartitioner:[13,1,1,""],simplenonstationary_gridpartitioner_builder:[13,3,1,""]},"pyFTS.models.nonstationary.partitioners.PolynomialNonStationaryPartitioner":{build:[13,2,1,""],get_polynomial_perturbations:[13,2,1,""],poly_width:[13,2,1,""],scale_down:[13,2,1,""],scale_up:[13,2,1,""]},"pyFTS.models.nonstationary.partitioners.SimpleNonStationaryPartitioner":{build:[13,2,1,""]},"pyFTS.models.nonstationary.perturbation":{exponential:[13,3,1,""],linear:[13,3,1,""],periodic:[13,3,1,""],polynomial:[13,3,1,""]},"pyFTS.models.nonstationary.util":{plot_sets:[13,3,1,""],plot_sets_conditional:[13,3,1,""]},"pyFTS.models.pwfts":{ProbabilisticWeightedFLRG:[9,1,1,""],ProbabilisticWeightedFTS:[9,1,1,""],visualize_distributions:[9,3,1,""]},"pyFTS.models.pwfts.ProbabilisticWeightedFLRG":{append_rhs:[9,2,1,""],get_lower:[9,2,1,""],get_membership:[9,2,1,""],get_midpoint:[9,2,1,""],get_upper:[9,2,1,""],lhs_conditional_probability:[9,2,1,""],lhs_conditional_probability_fuzzyfied:[9,2,1,""],partition_function:[9,2,1,""],rhs_conditional_probability:[9,2,1,""],rhs_unconditional_probability:[9,2,1,""]},"pyFTS.models.pwfts.ProbabilisticWeightedFTS":{add_new_PWFLGR:[9,2,1,""],flrg_lhs_conditional_probability:[9,2,1,""],flrg_lhs_conditional_probability_fuzzyfied:[9,2,1,""],flrg_lhs_unconditional_probability:[9,2,1,""],flrg_rhs_conditional_probability:[9,2,1,""],forecast:[9,2,1,""],forecast_ahead:[9,2,1,""],forecast_ahead_distribution:[9,2,1,""],forecast_ahead_interval:[9,2,1,""],forecast_distribution:[9,2,1,""],forecast_distribution_from_distribution:[9,2,1,""],forecast_interval:[9,2,1,""],generate_flrg2:[9,2,1,""],generate_flrg:[9,2,1,""],generate_flrg_fuzzyfied:[9,2,1,""],generate_lhs_flrg:[9,2,1,""],generate_lhs_flrg_fuzzyfied:[9,2,1,""],get_lower:[9,2,1,""],get_midpoint:[9,2,1,""],get_sets_from_both_fuzzyfication:[9,2,1,""],get_upper:[9,2,1,""],interval_heuristic:[9,2,1,""],interval_quantile:[9,2,1,""],point_expected_value:[9,2,1,""],point_heuristic:[9,2,1,""],pwflrg_lhs_memberhip_fuzzyfied:[9,2,1,""],train:[9,2,1,""],update_model:[9,2,1,""]},"pyFTS.models.sadaei":{ExponentialyWeightedFLRG:[9,1,1,""],ExponentialyWeightedFTS:[9,1,1,""]},"pyFTS.models.sadaei.ExponentialyWeightedFLRG":{append_rhs:[9,2,1,""],weights:[9,2,1,""]},"pyFTS.models.sadaei.ExponentialyWeightedFTS":{forecast:[9,2,1,""],generate_flrg:[9,2,1,""],train:[9,2,1,""]},"pyFTS.models.seasonal":{SeasonalIndexer:[14,0,0,"-"],cmsfts:[14,0,0,"-"],common:[14,0,0,"-"],msfts:[14,0,0,"-"],partitioner:[14,0,0,"-"],sfts:[14,0,0,"-"]},"pyFTS.models.seasonal.SeasonalIndexer":{DataFrameSeasonalIndexer:[14,1,1,""],DateTimeSeasonalIndexer:[14,1,1,""],LinearSeasonalIndexer:[14,1,1,""],SeasonalIndexer:[14,1,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.DataFrameSeasonalIndexer":{get_data:[14,2,1,""],get_data_by_season:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""],set_data:[14,2,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.DateTimeSeasonalIndexer":{get_data:[14,2,1,""],get_data_by_season:[14,2,1,""],get_index:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""],set_data:[14,2,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.LinearSeasonalIndexer":{get_data:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""]},"pyFTS.models.seasonal.SeasonalIndexer.SeasonalIndexer":{get_data:[14,2,1,""],get_data_by_season:[14,2,1,""],get_index:[14,2,1,""],get_index_by_season:[14,2,1,""],get_season_by_index:[14,2,1,""],get_season_of_data:[14,2,1,""]},"pyFTS.models.seasonal.cmsfts":{ContextualMultiSeasonalFTS:[14,1,1,""],ContextualSeasonalFLRG:[14,1,1,""]},"pyFTS.models.seasonal.cmsfts.ContextualMultiSeasonalFTS":{forecast:[14,2,1,""],forecast_ahead:[14,2,1,""],generate_flrg:[14,2,1,""],get_midpoints:[14,2,1,""],train:[14,2,1,""]},"pyFTS.models.seasonal.cmsfts.ContextualSeasonalFLRG":{append_rhs:[14,2,1,""]},"pyFTS.models.seasonal.common":{DateTime:[14,1,1,""],FuzzySet:[14,1,1,""],strip_datepart:[14,3,1,""]},"pyFTS.models.seasonal.common.DateTime":{day_of_month:[14,4,1,""],day_of_week:[14,4,1,""],day_of_year:[14,4,1,""],half:[14,4,1,""],hour:[14,4,1,""],hour_of_day:[14,4,1,""],hour_of_month:[14,4,1,""],hour_of_week:[14,4,1,""],hour_of_year:[14,4,1,""],minute:[14,4,1,""],minute_of_day:[14,4,1,""],minute_of_hour:[14,4,1,""],minute_of_month:[14,4,1,""],minute_of_week:[14,4,1,""],minute_of_year:[14,4,1,""],month:[14,4,1,""],quarter:[14,4,1,""],second:[14,4,1,""],second_of_day:[14,4,1,""],second_of_hour:[14,4,1,""],second_of_minute:[14,4,1,""],sixth:[14,4,1,""],third:[14,4,1,""],year:[14,4,1,""]},"pyFTS.models.seasonal.common.FuzzySet":{transform:[14,2,1,""]},"pyFTS.models.seasonal.msfts":{MultiSeasonalFTS:[14,1,1,""]},"pyFTS.models.seasonal.msfts.MultiSeasonalFTS":{forecast:[14,2,1,""],forecast_ahead:[14,2,1,""],generate_flrg:[14,2,1,""],train:[14,2,1,""]},"pyFTS.models.seasonal.partitioner":{TimeGridPartitioner:[14,1,1,""]},"pyFTS.models.seasonal.partitioner.TimeGridPartitioner":{build:[14,2,1,""],build_index:[14,2,1,""],extractor:[14,2,1,""],mask:[14,4,1,""],plot:[14,2,1,""],search:[14,2,1,""],season:[14,4,1,""]},"pyFTS.models.seasonal.sfts":{SeasonalFLRG:[14,1,1,""],SeasonalFTS:[14,1,1,""]},"pyFTS.models.seasonal.sfts.SeasonalFLRG":{append_rhs:[14,2,1,""],get_key:[14,2,1,""]},"pyFTS.models.seasonal.sfts.SeasonalFTS":{forecast:[14,2,1,""],generate_flrg:[14,2,1,""],get_midpoints:[14,2,1,""],train:[14,2,1,""]},"pyFTS.models.song":{ConventionalFTS:[9,1,1,""]},"pyFTS.models.song.ConventionalFTS":{flr_membership_matrix:[9,2,1,""],forecast:[9,2,1,""],operation_matrix:[9,2,1,""],train:[9,2,1,""]},"pyFTS.models.yu":{WeightedFLRG:[9,1,1,""],WeightedFTS:[9,1,1,""]},"pyFTS.models.yu.WeightedFLRG":{append_rhs:[9,2,1,""],weights:[9,2,1,""]},"pyFTS.models.yu.WeightedFTS":{forecast:[9,2,1,""],generate_FLRG:[9,2,1,""],train:[9,2,1,""]},"pyFTS.partitioners":{CMeans:[15,0,0,"-"],Entropy:[15,0,0,"-"],FCM:[15,0,0,"-"],Grid:[15,0,0,"-"],Huarng:[15,0,0,"-"],Simple:[15,0,0,"-"],Singleton:[15,0,0,"-"],SubClust:[15,0,0,"-"],Util:[15,0,0,"-"],parallel_util:[15,0,0,"-"],partitioner:[15,0,0,"-"]},"pyFTS.partitioners.CMeans":{CMeansPartitioner:[15,1,1,""],c_means:[15,3,1,""],distance:[15,3,1,""]},"pyFTS.partitioners.CMeans.CMeansPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Entropy":{EntropyPartitioner:[15,1,1,""],PMF:[15,3,1,""],bestSplit:[15,3,1,""],entropy:[15,3,1,""],informationGain:[15,3,1,""],splitAbove:[15,3,1,""],splitBelow:[15,3,1,""]},"pyFTS.partitioners.Entropy.EntropyPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.FCM":{FCMPartitioner:[15,1,1,""],fuzzy_cmeans:[15,3,1,""],fuzzy_distance:[15,3,1,""],membership:[15,3,1,""]},"pyFTS.partitioners.FCM.FCMPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Grid":{GridPartitioner:[15,1,1,""],PreFixedGridPartitioner:[15,1,1,""]},"pyFTS.partitioners.Grid.GridPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Huarng":{HuarngPartitioner:[15,1,1,""]},"pyFTS.partitioners.Huarng.HuarngPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Simple":{SimplePartitioner:[15,1,1,""]},"pyFTS.partitioners.Simple.SimplePartitioner":{append:[15,2,1,""],append_complex:[15,2,1,""]},"pyFTS.partitioners.Singleton":{SingletonPartitioner:[15,1,1,""]},"pyFTS.partitioners.Singleton.SingletonPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.SubClust":{SubClustPartitioner:[15,1,1,""],imax:[15,3,1,""],subclust:[15,3,1,""]},"pyFTS.partitioners.SubClust.SubClustPartitioner":{build:[15,2,1,""]},"pyFTS.partitioners.Util":{explore_partitioners:[15,3,1,""],plot_partitioners:[15,3,1,""],plot_sets:[15,3,1,""]},"pyFTS.partitioners.parallel_util":{explore_partitioners:[15,3,1,""]},"pyFTS.partitioners.partitioner":{Partitioner:[15,1,1,""]},"pyFTS.partitioners.partitioner.Partitioner":{build:[15,2,1,""],build_index:[15,2,1,""],check_bounds:[15,2,1,""],defuzzyfy:[15,2,1,""],extractor:[15,2,1,""],fuzzyfy:[15,2,1,""],get_name:[15,2,1,""],kdtree:[15,4,1,""],lower_margin:[15,4,1,""],lower_set:[15,2,1,""],margin:[15,4,1,""],membership_function:[15,4,1,""],name:[15,4,1,""],ordered_sets:[15,4,1,""],partitions:[15,4,1,""],plot:[15,2,1,""],plot_set:[15,2,1,""],prefix:[15,4,1,""],search:[15,2,1,""],setnames:[15,4,1,""],transformation:[15,4,1,""],type:[15,4,1,""],upper_margin:[15,4,1,""],upper_set:[15,2,1,""],variable:[15,4,1,""]},"pyFTS.probabilistic":{ProbabilityDistribution:[16,0,0,"-"],kde:[16,0,0,"-"]},"pyFTS.probabilistic.ProbabilityDistribution":{ProbabilityDistribution:[16,1,1,""],from_point:[16,3,1,""]},"pyFTS.probabilistic.ProbabilityDistribution.ProbabilityDistribution":{append:[16,2,1,""],append_interval:[16,2,1,""],averageloglikelihood:[16,2,1,""],bins:[16,4,1,""],build_cdf_qtl:[16,2,1,""],crossentropy:[16,2,1,""],cumulative:[16,2,1,""],density:[16,2,1,""],differential_offset:[16,2,1,""],empiricalloglikelihood:[16,2,1,""],entropy:[16,2,1,""],expected_value:[16,2,1,""],kullbackleiblerdivergence:[16,2,1,""],labels:[16,4,1,""],plot:[16,2,1,""],pseudologlikelihood:[16,2,1,""],quantile:[16,2,1,""],set:[16,2,1,""],type:[16,4,1,""],uod:[16,4,1,""]},"pyFTS.probabilistic.kde":{KernelSmoothing:[16,1,1,""]},"pyFTS.probabilistic.kde.KernelSmoothing":{h:[16,4,1,""],kernel:[16,4,1,""],kernel_function:[16,2,1,""],probability:[16,2,1,""]},pyFTS:{benchmarks:[3,0,0,"-"],common:[4,0,0,"-"],conf:[2,0,0,"-"],data:[6,0,0,"-"],distributed:[7,0,0,"-"],hyperparam:[8,0,0,"-"],models:[9,0,0,"-"],partitioners:[15,0,0,"-"],probabilistic:[16,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","function","Python function"],"4":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:function","4":"py:attribute"},terms:{"261459a0":6,"57a":6,"5egspc":6,"boolean":[3,4,8,15],"case":[4,17],"class":[3,4,6,9,10,11,12,13,14,15,16,17],"default":[3,4,6,8,9,10,11,12,14,15],"enum":14,"fa\u00e7ad":[3,4],"final":[4,6],"float":[3,4,6,8],"function":[3,4,7,8,11,12,13,14,15,16,17],"guimar\u00e3":[0,9],"h\u00e9non":6,"import":[4,12,17],"int":9,"na\u00efv":3,"new":[4,7,10,11,12,15],"organiza\u00e7\u00e3o":6,"petr\u00f4nio":9,"r\u00f6ssler":6,"return":[3,4,6,7,8,9,10,11,12,13,14,15,16],"short":[0,4,9],"true":[3,4,6,11,12,13],"try":4,"var":[6,12],"while":4,And:3,FTS:[0,3,4,8,9,10,11,12,13,14],For:3,LHS:[4,9,13],One:15,RHS:[4,9,12,13],The:[3,4,6,8,10,11,12,15,16,17],Then:[3,17],There:[3,17],These:[0,17],Use:14,abdullah:9,acc:4,accept:4,accord:[12,15],account:16,accuraci:[3,8],acf:3,actual:[4,16],adapativeexpect:[1,2],add:[3,4,13],add_new_pwflgr:9,added:[4,6],adding:4,addit:6,address:[3,4],affect:13,after:[6,11],age:4,aged:4,aggreg:10,ahead:[3,4,9,10,11,12,13,14,17],ahed:17,airlin:6,airpasseng:[1,2],alabama:6,algoritm:8,alia:[3,4,12],all:[3,4,8,10,12,15,16,17],allmethodensembleft:10,almost:17,alpha:[3,4,8,9,10,14],alpha_cut:[4,8,12,15],alreadi:[3,6],also:[0,4,17],alwai:8,ambientai:6,among:[4,11],analysi:3,analytic_tabular_datafram:3,analytical_data_column:3,angela:4,anoth:11,api:[0,4],append:[4,10,12,15,16],append_complex:15,append_interv:16,append_lh:[9,13],append_log:4,append_model:10,append_rh:[4,9,12,13,14],append_rul:4,append_set:[4,12],append_transform:[4,12],append_vari:12,appendchild:4,appl:[9,15],appli:[3,4,12,15,16],apply_inverse_transform:[4,12],apply_transform:[4,12],approach:[3,15,17],arg:13,argument:[3,4,8,15],arima:[1,2],arima_model:3,around:4,arrai:[4,6,8,13,14],artifici:[1,2],ascend:3,aspx:6,assert:16,assess:3,assign:[4,16],assoc:3,associ:6,ata:3,atmospher:6,atribut:3,attibut:4,attractor:6,auto:15,auto_upd:[4,11],autocorrel:3,autom:6,automat:4,auxiliar:4,auxiliari:16,averag:[3,6,16],averageloglikelihood:16,avg:6,axes:13,axi:[3,4,15,16],azim:3,bar:3,base:[3,4,6,9,10,11,12,13,14,15,16,17],base_dataframe_column:3,batch:[4,8,11],batch_sav:4,batch_siz:11,befor:17,begin:4,being:3,bell:4,bellmf:4,belo:[0,6],belog:4,below:17,benchmark:[1,2,4,8],benchmark_method:3,benchmark_methods_paramet:3,benchmark_model:3,benchmark_onli:4,best:8,bestsplit:15,better:17,between:[3,4,8,11,16],bill:4,bin:[9,16],bisect:4,bitcoin:[1,2],bivari:6,black:16,blip:6,blue:4,both:[4,12,15],bound:[4,6,9,10,12,13,15],box:[3,17],boxcox:[1,2],boxljungstatist:3,boxpiercestatist:3,brasil:6,brasilia:6,brazil:[0,10],brazilian:[0,10],brier:3,brier_scor:3,bst:[1,2],btc:6,build:[11,12,13,14,15],build_cdf_qtl:16,build_index:[12,14,15],build_method:3,build_tree_without_ord:4,built:[6,15],buseco:6,busi:6,c_mean:15,calcul:[4,12,13],call:[4,11,12],camwa:15,can:[3,4,17],cancel:6,capabl:3,capit:6,cartesian:12,cast_dataframe_to_synthet:3,cast_dataframe_to_synthetic_interv:3,cast_dataframe_to_synthetic_point:3,cast_dataframe_to_synthetic_probabilist:3,ccst:6,center:4,centroid:[4,14],certain:16,chain:6,chang:[6,8,15],change_target_vari:12,chao:6,chaotic:[1,2],characterist:17,cheap:0,check:[4,6,15,17],check_bound:[4,13,15],check_bounds_index:[4,13],check_data:12,check_ignore_list:3,check_replace_list:3,chen:[1,2,12,14],cheng:[1,2,15],chia:9,child:4,chissom:9,chiu:15,clear:4,clip:4,clip_uod:4,clone:[4,12,17],clone_paramet:[4,12],closest:15,cluster:[3,4,7,8,12,15],cluster_method:8,clusteredmvft:12,cmap:4,cmean:[1,2],cmeanspartition:15,cmsft:[2,9],cmvft:[2,9],code:[12,17],coeffici:[3,6],col:4,colab:17,colabor:0,collect:8,collect_statist:8,color:[3,4,13,16],colormap:4,column:[4,12],columun:4,com:[6,17],combin:12,common:[1,2,3,8,9,10,11,15,16,17],common_process_interval_job:3,common_process_point_job:3,common_process_probabilistic_job:3,common_process_time_job:3,commun:6,compar:[3,4],compare_residu:3,comparemodelsplot:3,comparemodelst:3,complet:6,complex:6,complic:6,compon:[6,10],composit:[1,2,6,12],compress:6,comput:[9,10,15],computation:0,concept:17,condens:3,condit:3,conditional_perturbation_factor:13,conditionalvarianceft:13,conf:[0,1],confer:9,confid:3,configur:3,configure_lag:[9,13],congress:10,conn:[3,8],connect:[3,8],consid:[4,8,12,15],const_t:13,constant:6,contain:[3,4,12,15,17],content:[0,1],context:15,contextu:14,contextualmultiseasonalft:14,contextualseasonalflrg:14,contin:[11,16],continu:[3,6,16],control:[3,6,11],control_method:3,convent:[9,13,14],conventionalflrg:9,conventionalft:[9,12],conventionalnonstationaryflrg:13,copi:4,cost:15,count:[4,16],counter:15,covavg:3,coverag:3,covstd:3,cox:17,creat:[3,4,6,8,10,12,15,16,17],create_benchmark_t:3,create_hyperparam_t:8,criteria:3,cross:[4,8,16],crossentropi:16,crossov:8,crossover_oper:8,crp:3,crps1avg:3,crps1std:3,crps2avg:3,crps2std:3,crps_distr:3,crps_interv:3,crpsavg:3,crpsstd:3,csv:[3,6],cumul:16,current:[3,6],current_milli_tim:4,cut:[4,8],cvft:[2,9],dado:[4,6,15],dai:6,daili:6,data:[0,1,2,3,4,7,8,9,10,11,12,13,14,15,16,17],data_column:3,data_field:14,data_label:12,data_point:12,data_typ:12,databas:[3,8],datafram:[3,4,6,12,14],dataframeseasonalindex:14,datapoint:3,dataset:[1,2,3,4,8],datasetnam:8,date:[3,14],date_field:14,date_part:14,datepart:14,datetim:14,datetimeseasonalindex:14,david:4,day_of_month:14,day_of_week:14,day_of_year:14,dealer:6,dec:15,decemb:6,decis:3,decompress:6,defin:[3,8],defuzzyf:17,defuzzyfi:[12,15],deg:13,deho:8,delet:4,deltadist:15,demand:12,demo:17,densiti:[3,4,16],departa:0,depend:[3,4,12,15,17],dependeci:4,deri:9,descend:8,design:[3,4,8,12,14,15],detail:4,determin:3,determinist:[6,15],develop:[0,17],deviat:3,dict:[3,4,8],dict_individu:8,dictionari:[3,4,8],differ:3,differenti:[1,2,6,16,17],differential_offset:16,diffus:9,dill:4,dimension:6,directli:[4,17],discard:8,discours:[3,4,10,12,13,14,15,16,17],discret:16,disk:[4,15],dispi:[1,2,3,4,8],displac:13,displai:3,distanc:[3,15],distribut:[1,2,3,4,6,8,9,10,12,16],distributed_model_train_test_tim:3,distributed_predict:7,distributed_train:7,diverg:16,dji:6,dkl:16,dnf:6,document:0,doi10:9,doi:[0,3,6,15],dollar:9,don:6,doubl:8,double_tourna:8,dow:6,dowjon:[1,2],download:6,draw_sets_on_axi:4,drift:17,due:[4,11],dure:[3,4],dynam:6,each:[3,4,6,7,8,10,11,12,17],easi:[0,4],easier:4,edu:6,edward:6,efendi:9,effect:15,effici:4,electr:[0,9],eletr:6,elev:3,elit:8,els:8,empir:[15,16],empiricalloglikelihood:16,emul:6,enayatifar:9,end:13,endogen:12,energi:[9,17],engin:0,enrol:[1,2,9,14],ensembl:[1,2,4,9,11],ensembleft:[10,11],entir:4,entropi:[1,2,16],entropypartition:[15,17],enumerate2:4,environ:4,eps_inf:15,eps_sup:15,equal:[3,4,9,10,11,12,13,14,17],equat:6,error:3,espaciai:6,esrl:6,estim:[3,15,16],etc:[4,17],eth:6,ethereum:[1,2],eur:[1,2],eurgbp:6,eurusd:6,evalu:8,evalutation_oper:8,even:[14,15],evolutionari:[1,2],exact:4,exampl:0,exceed:15,except:4,exchang:[6,9],exclud:3,execut:[3,7,8],exist:6,expect:[9,16],expected_valu:16,experi:[3,8],expert:[0,9],explain:[4,9],exploit:0,explore_partition:15,exponenti:[9,10,13],exponentiali:9,exponentialyweightedflrg:9,exponentialyweightedft:9,express:3,extens:12,extern:[3,4],externalforecast:3,externalmodel:3,extract:[3,6,14,15],extract_measur:3,extractor:[14,15],extremum:10,facil:[3,4,6,8,15],fall:3,fals:[3,4,6,8,9,10,12,13,15],fcm:[1,2],fcmpartition:[15,17],feder:0,fetch:4,field:[6,14],fig:[4,13],figur:4,file:[3,4,6,8,13,15],file_analyt:3,file_path:4,file_synthet:3,filenam:[3,4,6],filenem:[3,8],filesystem:4,fill:4,filter:3,financ:6,find:[4,14,15],find_best:3,find_g:4,find_gt:4,find_l:4,find_lt:4,finner:3,first:[3,4,9,13,14],fit:[3,4,8,9,10,11,12,13,14],five:4,flag:4,flashquot:6,flat:4,flow:6,flr:[1,2,9,13,14],flr_membership_matrix:9,flrg:[1,2,9,14],flrg_lhs_conditional_prob:9,flrg_lhs_conditional_probability_fuzzyfi:9,flrg_lhs_unconditional_prob:9,flrg_rhs_conditional_prob:9,flrgtree:4,flrgtreenod:4,foreast:3,forecast:[3,4,9,10,11,12,13,14,15,17],forecast_ahead:[3,4,9,11,12,14],forecast_ahead_distribut:[3,4,9,10,12],forecast_ahead_interv:[3,4,9,10,12],forecast_ahead_multivari:[4,12],forecast_distribut:[3,4,9,10,12],forecast_distribution_from_distribut:9,forecast_interv:[3,4,9,10,12,13],forecast_multivari:[4,12],forecast_step:4,forex:6,fork:0,format:[3,8,12,14],format_data:12,format_experiment_t:3,forward:4,found:[4,17],frederico:[0,9],frequenc:16,friedman:3,from:[0,3,4,6,9,10,11,12,14,15,16,17],from_point:16,fset:[9,12,13],fts:[1,2,3,9,10,11,12,13,14],fts_method:[3,7,8,11,12],fts_param:[11,12],fuzz:9,fuzzi:[2,4,9,10,12,13,14,15],fuzzif:15,fuzzifi:[4,13],fuzzy_cmean:15,fuzzy_dist:15,fuzzy_set:4,fuzzydata:4,fuzzyf:[4,12,15,17],fuzzyfi:[4,12,15],fuzzyfy_inst:[4,12],fuzzyfy_instance_clust:12,fuzzyfy_seri:4,fuzzyfy_series_old:4,fuzzyseri:13,fuzzyset:[1,2,9,12,13,14],gadelha:[0,9],gani:9,garibaldi:13,gaussian:[4,6],gaussianproc:[1,2],gaussmf:4,gbp:[1,2],gbpusd:6,gcos_wgsp:6,gene:8,gener:[1,2,4,8,15,17],generate_flr:12,generate_flrg2:9,generate_flrg:[9,12,13,14],generate_flrg_fuzzyfi:9,generate_gaussian_linear:6,generate_high_order_recurrent_flr:4,generate_indexed_flr:4,generate_lhs_flr:12,generate_lhs_flrg:9,generate_lhs_flrg_fuzzyfi:9,generate_linear_periodic_gaussian:6,generate_non_recurrent_flr:4,generate_recurrent_flr:4,generate_sinoidal_periodic_gaussian:6,generate_uniform_linear:6,genet:8,geneticalgorithm:8,genotyp:8,gerai:0,get:[3,4,6],get_benchmark_interval_method:3,get_benchmark_point_method:3,get_benchmark_probabilistic_method:3,get_data:[6,14],get_data_by_season:14,get_datafram:6,get_dataframe_from_bd:3,get_distribution_ahead_statist:3,get_distribution_interquantil:10,get_distribution_statist:3,get_fuzzyset:4,get_index:14,get_index_by_season:14,get_interv:10,get_interval_ahead_statist:3,get_interval_method:3,get_interval_statist:3,get_kei:[4,9,13,14],get_low:[4,9,12,13],get_maximum_membership_fuzzyset:4,get_maximum_membership_fuzzyset_index:4,get_membership:[4,9,12,13],get_midpoint:[4,9,12,13,14],get_models_forecast:10,get_nam:15,get_number_of_cpu:7,get_point:10,get_point_ahead_statist:3,get_point_method:3,get_point_multivariate_method:3,get_point_statist:3,get_polynomial_perturb:13,get_probabilistic_method:3,get_season_by_index:14,get_season_of_data:14,get_sequence_membership:9,get_sets_from_both_fuzzyf:9,get_uod:[4,10],get_upp:[4,9,12,13],getchildren:4,getstr:4,git:17,github:[0,17],given:[3,4,9,10,11,12,13,14,15,16],glass:[1,2],good:[3,17],googl:17,gov:6,grant_bound:4,granular:[2,9,14],granularwmvft:12,greater:[4,6],grid:[1,2,3,9,14],gridclust:12,gridpartition:[3,15,17],gridsearch:[1,2],group:[3,4,9,12,13,14],h_0:3,h_1:3,half:14,hand:4,handl:[4,9],hard:4,harmoni:9,has_interval_forecast:4,has_point_forecast:4,has_probability_forecast:4,has_season:4,head:0,height:15,help:15,henon:[1,2],here:17,heteroskedast:13,high:[3,4,9,12,13,17],highorderflrg:9,highorderft:[9,13],highordernonstationaryflrg:13,highordernonstationaryft:13,histogram:16,histori:6,hoang:9,hoc:3,hoft:[1,2,13],hold:11,homogen:10,honsft:[2,9],horizon:[3,4],horizont:[0,6],hossein:9,hour:[3,14],hour_of_dai:14,hour_of_month:14,hour_of_week:14,hour_of_year:14,hourli:6,http:[0,6,17],http_server:7,huarng:[1,2],huarngpartition:[15,17],human:0,hwang:[1,2],hybrid:9,hyndman:6,hyperparam:[1,2],hyperparamet:8,identif:[14,15],identifi:[3,4,8,9,13,14],ieee:[9,13],ifmg:0,ifnmg:0,ift:[1,2],ignor:[3,14],iii:17,imag:[4,15],imax:15,implement:[4,14,17],improv:[8,9,15,17],improvedweightedflrg:9,improvedweightedft:9,inc:[3,4],includ:3,increas:12,increment:[1,2,3,4,6,8,9,12,16],increment_r:8,incremental_gaussian:6,incremental_search:12,incrementalensembl:[2,9],incrementalensembleft:11,incrementalgridclust:12,ind:14,indentifi:[3,8],index:[3,4,6,8,9,10,11,12,14,15],index_field:14,index_season:14,index_seri:6,indexedflr:4,indic:[3,4,6,8],individu:[4,8],inequ:3,infer:[3,6],infil:3,inform:[3,4,15,16],informationgain:15,initi:[4,6],initial_oper:8,initial_popul:8,initial_valu:6,inmet:[1,2],innov:9,inp:6,input:[4,9,11,12,13,15,16],insert:[3,4,6,8],insert_benchmark:3,insert_hyperparam:8,insert_right:4,insid:[3,4,14,15,16],inst:[4,13],instal:0,instanc:[6,7,12,13,14,15,17],instanti:8,instead:4,instituit:0,institut:0,instituto:6,integ:[3,4,8,11],integr:6,intel:9,intellig:[9,10,15],intend:0,interfer:6,intern:[9,10,11],internet:6,interpol:4,interpret:4,interv:[3,4,9,10,11,12,13,15,16,17],interval_dataframe_analytic_column:3,interval_dataframe_synthetic_column:3,interval_heurist:9,interval_method:10,interval_quantil:9,interval_to_interv:3,intervalar:17,intervalft:9,introduc:17,introduct:17,introspect:4,invers:17,ipynb:17,is_clust:4,is_high_ord:4,is_multivari:4,is_time_vari:4,is_wrapp:4,ismail:9,ismailefendi:[1,2],isol:15,item:4,itemgett:4,iter:[4,6],its:[6,8,9,11,12,14,15,17],ixic:6,janeiro:10,januari:6,jaroszewski:13,javedani:9,jeng:9,job:[3,8],johnson:12,jonathan:13,jone:[4,6],journal:[3,6,15],json:8,jstor:3,jun:15,jupyt:17,kde:[1,2],kdtree:15,kei:[3,4],kernel:16,kernel_funct:16,kernelsmooth:16,knearestneighbor:3,knn:[1,2],known:[4,10,15],kullback:16,kullbackleiblerdiverg:16,kwarg:[3,4,6,7,8,9,10,11,12,13,14,15,16],lab:0,label:[3,4,16],lag:[3,4,6,8,11,17],lag_crossover2:8,lambda:4,largest:4,last:4,later:17,layman:0,lcolor:4,learn:11,least:3,lee:9,left:4,legend:[3,4,13],leibler:16,len_lag:8,len_tot:4,length:[3,4,6,8,9,10,11,12,13,14,15,17],less:4,lett:6,level:[3,4],lgd:4,lhs_conditional_prob:9,lhs_conditional_probability_fuzzyfi:9,lhs_mv:9,librari:[2,6,17],like:[4,17],likelihood:16,limit:4,lin:15,line:4,linear:[6,13],linearmodel:3,linearseasonalindex:14,linewidth:[3,4],linspac:6,list:[3,4,6,7,8,9,10,11,12,13,14,15,16,17],ljung:3,ljung_box_test:3,lo_param:3,load:[4,6,9],load_env:4,load_obj:4,local:[6,8],locat:[4,6,13],location_param:13,log:[4,16],log_result:8,logarithm:3,logarithm_scor:3,logic:[4,9,12,13,14,17],logist:[4,6],logistic_map:[1,2],look:4,lookup:4,lorentz:[1,2],lorenz:6,loss:3,lower:[4,6,9,10,12,13,15],lower_margin:15,lower_set:15,mackei:[1,2],mackey_glass:6,mai:6,main:17,make:3,malaysia:[1,2,9],mandatori:4,mani:17,manual:15,map:[4,6],mape:3,mape_interv:3,marcin:13,margin:15,market:6,mask:[12,14],mass:4,master:8,match:4,math:[6,15],mathemat:6,matplotlib:[4,15],max:4,max_inc:6,max_ini:6,max_lag:[3,4,9,10,11,12,13,14],maxim:4,maximum:[4,6,8,10,12,15],mean:[3,4,6,10],measur:[1,2,8],mech:9,median:[4,10],membership:[1,2,8,9,12,13,15,17],membership_funct:15,memori:[4,11],merg:4,meta:[10,11,12],meteorologia:6,method:[0,3,4,6,7,8,9,10,11,12,13,14,15,17],metric:3,mft:3,mgen:8,middl:15,midpoint:[4,9,12,13],min:[4,16],min_inc:6,min_ini:6,min_ord:4,mina:0,mind:0,ming:9,minim:[3,4,9,10,11,12,13,14,15],minimum:[4,6,10,17],minut:14,minute_of_dai:14,minute_of_hour:14,minute_of_month:14,minute_of_week:14,minute_of_year:14,mix:10,mode:[4,12,15],model:[0,1,2,3,4,6,7,8,15,17],modelo:3,models_fo:3,models_ho:3,modul:[0,1,17],monash:6,monitor:7,monovari:[4,8],month:14,monthli:[3,6],more:17,most:[11,12,17],move:3,msft:[2,9],mu_inc:6,mu_ini:6,mu_max:6,mu_min:6,much:4,multi:[3,4,9,10,11,12,14],multiseason:[2,9],multiseasonalft:14,multivari:[1,2,3,4,6,9,15,17],multivariate_sliding_window_benchmarks2:3,multivariatefuzzyset:12,multivariatepartition:12,musikasuwan:13,must:8,mutat:8,mutation_lag:8,mutation_oper:8,mv_run_interval2:3,mv_run_point2:3,mv_run_probabilistic2:3,mvft:[2,8,9],nacion:6,naiv:[1,2],name:[3,4,6,7,8,10,12,13,14,15],nasdaq:[1,2],nation:6,nativ:[4,14],natur:6,nbin:[4,9],nbsp:0,ndata:[3,4,9,13],nearest:[12,14,15],necessari:[4,11],need:4,neighbor:3,new_popul:8,next:[4,8,17],ngen:8,nice:4,noaa:6,node:[3,4,7,8],nois:[6,13],noise_param:13,non:[3,4,6,13,14,17],none:[3,4,6,12,13,14,15,16],nonperiod:6,nonstationari:[1,2,4,9],nonstationaryflrg:13,nonstationaryft:13,norm:9,normal:[1,2,10,17],north:0,norton:6,notebook:17,noth:17,nov:15,now:4,npart:[8,13,15],npop:8,nsft:[2,3,9],num:6,num_batch:[4,7],num_model:11,num_season:14,number:[3,4,6,8,9,10,11,12,14,15,16,17],numer:17,numpi:[4,6],obj:[3,4,15],object:[3,4,6,8,9,10,12,14,15,16],objectsist:3,occur:4,occurr:4,offset:[4,11],old:4,older:4,oldest:4,onc:4,one:[3,4,6,8,9,10,11,12,13,14,16,17],ones:4,onli:[4,12,15],onlin:11,only_lin:13,open:[3,8],open_benchmark_db:3,open_hyperparam_db:8,oper:[4,8,17],operation_matrix:9,optim:8,option:[3,4,10,15],order:[3,4,8,9,10,11,12,13,14,15,17],ordered_set:[4,13,15],ordin:4,org:[0,3,6],origin:[3,4,8,17],original_max:4,original_min:4,oscil:6,other:[3,4,10,11,12],otherwis:3,out:17,outfil:3,outlier:6,output:[15,17],outsid:15,over:[4,8],overlap:[12,14,15,17],own:12,p500:6,packag:[0,1],page:0,pair:[3,6],panda:[3,4,6,12,14],par1:13,par2:13,parallel:8,parallel_util:[1,2],param:[3,4,6,12,13,14],paramet:[3,4,6,7,8,9,10,11,12,13,14,15,16,17],parametr:17,parent:8,parsimoni:8,part:[13,17],partit:[3,4,8,10,12,13,14,15,17],partition:[1,2,3,4,8,9,10,11,17],partition_funct:[4,9],partitioner_method:[3,10,11],partitioner_param:11,partitioners_method:3,partitioners_model:3,pass:4,passeng:6,past:4,path:[3,4,15],pattern:4,pcross:8,pct:13,pdf:16,percent:3,percentag:3,percentu:[3,4],perform:[3,8,12,13,14,15,17],perform_loc:13,perform_width:13,period:[6,13],periodic_gaussian:6,persist:[4,8],persist_env:4,persist_obj:4,persist_statist:8,person:[4,6],pertub:13,perturb:[2,9],perturbate_paramet:13,perturbation_factor:13,perturbation_factors__old:13,pesquisa:6,pftsexploreorderandpartit:3,phenotyp:8,php:6,phy:[6,9],physiolog:6,pictur:[3,4],pierc:3,pinbal:3,pinball_mean:3,pip:17,plot:[3,4,14,15,16],plot_compared_intervals_ahead:4,plot_compared_seri:3,plot_dataframe_interv:3,plot_dataframe_interval_pinbal:3,plot_dataframe_point:3,plot_dataframe_probabilist:3,plot_density_rectang:4,plot_distribut:4,plot_distribution2:4,plot_distribution_til:4,plot_interv:4,plot_interval2:4,plot_partition:15,plot_point:3,plot_probability_distribut:4,plot_residuals_by_model:3,plot_rul:4,plot_set:[13,15],plot_sets_condit:13,plotcompar:3,plotforecast:3,pmf:[4,15],pmut:8,point:[3,4,9,10,11,12,13,14,15,16,17],point_dataframe_analytic_column:3,point_dataframe_synthetic_column:3,point_expected_valu:9,point_heurist:9,point_method:10,point_to_interv:3,poit:4,poly_width:13,polynomi:13,polynomialnonstationarypartition:13,poor:6,popul:8,por:3,posit:[4,14],possibl:10,post:[3,4],post_hoc:3,post_hoc_test:3,posterior:3,postprocess:[4,17],power:9,pprint:4,pre:[4,12],prebuilt:3,predict:[3,4,9,10,11,12,13,17],prefix:15,prefixedgridpartition:15,preprocess:[4,12,14,17],previou:6,previous_dist:9,primari:3,primit:[14,15],print:3,print_distribution_statist:3,print_interval_statist:3,print_point_statist:3,probabil:3,probabilist:[1,2,3,4,9,10,12,17],probabilistic_dataframe_analytic_column:3,probabilistic_dataframe_synthetic_column:3,probabilisticweightedflrg:9,probabilisticweightedft:9,probabilitydist:4,probabilitydistribut:[1,2,3,4,9,10,12],probabl:[3,4,8,9,10,12,16],problem:9,procedur:[3,4],process:[3,4,6,12],process_common_data2:3,process_common_data:3,process_experi:8,process_interval_job:3,process_interval_jobs2:3,process_job:8,process_point_job:3,process_point_jobs2:3,process_probabilistic_job:3,process_probabilistic_jobs2:3,product:[6,9,12],product_dict:12,prof:0,progress:3,project:15,properti:4,propos:17,provid:[0,4,10,17],prune:12,psd:6,psel:8,pseudo:16,pseudologlikelihood:16,pwflrg:9,pwflrg_lhs_memberhip_fuzzyfi:9,pwft:[1,2],python:[2,17],q05:3,q25:3,q75:3,q95:3,quantil:[3,4,10,16],quantile_regress:3,quantileregress:3,quantreg:[1,2],quarter:14,queri:3,quick:0,quot:6,quotat:6,rais:4,random:[6,8],random_genotyp:8,random_individu:8,random_walk:6,rang:[3,17],rank:3,rate:9,ration:3,read:[3,6],readabl:0,real:[4,17],receiv:8,recent:[11,12,17],record:4,recreat:11,recurr:[4,6],red:[3,4],reference_data:4,refin:9,regress:3,rel:8,relat:16,relationship:[4,9,12,13,14],remov:4,ren:9,render:6,replac:3,repo:17,repr:4,repres:[3,4,9,10,12,16],represent:17,res:3,research:[0,17],reset:4,reset_calculated_valu:4,residu:3,residualanalysi:[1,2],resolut:[3,4],respect:[4,16],respons:14,result:[3,4,8,14,15],retrain:11,revers:4,review:[3,17],rhs_conditional_prob:9,rhs_unconditional_prob:9,right:4,ringgit:9,rio:10,rmse:[3,8],rmse_interv:3,rmseavg:3,rmsestd:3,rng:13,robert:6,roger:4,roi:[1,2],root:3,rossler:[1,2],round:15,row:4,royal:3,rule:[3,4,12,17],rules_by_axi:4,run:[3,6],run_interv:3,run_interval2:3,run_point2:3,run_point:3,run_probabilist:3,run_probabilistic2:3,sadaei:[1,2],salang:13,same:[3,4,10],sampl:[3,4,6,9,17],sampler:10,save:[3,4,13,15],save_best:3,save_dataframe_interv:3,save_dataframe_point:3,save_dataframe_probabilist:3,save_model:4,scalar:16,scale:[1,2,3,17],scale_down:13,scale_param:3,scale_up:13,scan:4,scheme:[3,8,17],scienc:6,scientist:0,score:3,scroll:8,search:[0,4,9,12,14,15],season:[1,2,3,4,9,10,17],seasonalensembleft:10,seasonalflrg:14,seasonalft:14,seasonalindex:[2,9],second:14,second_of_dai:14,second_of_hour:14,second_of_minut:14,secur:6,selecaosimples_menorrms:3,select:[6,8],selection_oper:8,self:15,sep:6,separ:6,sequenc:4,sequenti:8,seri:[1,2,3,4,8,9,10,11,12,13,14,15],set:[3,4,8,9,10,12,13,14,15,16,17],set_data:14,set_lh:12,set_ord:4,set_rh:12,set_target_vari:12,set_transform:10,seth:12,setnam:15,sever:[3,4,6,10,12,14,15],severiano:9,sft:[2,9],shape:4,share:10,sharp:3,sharpavg:3,sharpstd:3,shortnam:4,show:[4,15],show_and_save_imag:4,shyi:9,side:4,sigma:6,sigma_inc:6,sigma_ini:6,sigma_max:6,sigma_min:6,sigmf:4,sigmoid:4,signal:6,signalemul:6,signific:3,silva:[0,9,10],simpl:[0,1,2,6,8,14],simple_model_predict:7,simple_model_train:7,simple_synthetic_datafram:3,simpleensembleft:10,simplenonstationary_gridpartitioner_build:13,simplenonstationarypartition:13,simplepartition:15,simpler:4,simplesearch_rms:3,singl:[4,14,15],single_plot_residu:3,singleton:[1,2,4],singletonpartition:15,sinoid:6,sistema:6,sixth:14,size:[3,4,8,11,13,15],skip:[4,11],sklearn:3,slice:4,slide:[3,4,8],sliding_window:4,sliding_window_benchmark:3,sliding_window_benchmarks2:3,smape:3,smith:4,smooth:[1,2,4,9,17],social:15,societi:3,solar:[9,17],som:[1,2],sonda:[1,2],song:[1,2,14],sort:[4,15],sort_ascend:3,sort_column:3,sortedcollect:[1,2],sourc:[3,4,6,7,8,9,10,11,12,13,14,15,16],sp500:6,space:4,spark:[1,2,8],spatial:15,specif:[3,4,8,9,10,11,12,13,14,15],split:[3,4,8,15],splitabov:15,splitbelow:15,splite:17,sql:3,sqlite3:[3,8],sqlite:[3,8],squar:3,ssci:9,stabl:3,standard:[3,4,6,17],standard_horizon:4,start:[0,3,4,6,7,9,10,11,12,13,14],start_at:[3,4,9,10,11,12,14],start_dispy_clust:7,stat:[3,9],station:6,stationari:[13,17],stationary_gaussian:6,statist:[0,3,8],statsmodel:3,std:3,step:[3,4,9,10,11,12,13,14,17],step_to:4,stephen:15,steps_ahead:[3,4],stochast:6,stock:6,stop:[7,8],stop_dispy_clust:7,store:[3,4,8],strang:6,strategi:8,string:[4,12,14,15],strip_datepart:14,structur:[4,14,15],student:0,studi:17,style:4,subclust:[1,2],subclustpartition:15,submodul:[0,1],subpackag:[0,1],subtract:15,suitabl:0,sum:9,sunspot:[1,2],superset:4,support:4,surviv:8,symbol:6,symmetr:3,symposium:9,synchron:[4,11],synthesi:3,synthet:[1,2,3],syst:[9,14,15],system:[6,9,13,15],tabl:[3,8],tabular_dataframe_column:3,tag:[3,8],taiex:[1,2,9],taiwan:6,take:17,tam:[3,4,13,15,16],target:3,target_vari:4,tau:[3,6,16],technol:15,tell:4,tempeatur:6,tempor:[4,14,17],term:[3,4,9],test:[1,2,4,8,11,17],test_data:3,test_mean_equ:3,than:[4,6,17],thei:4,theil:3,theilsinequ:3,theoret:3,theori:17,thi:[0,4,6,9,11,12,13,14,15,16,17],third:14,thoma:4,those:4,thres1:15,thres2:15,threshold:15,through:6,time:[1,2,3,4,8,9,10,11,12,13,14,15],time_from:4,time_to:4,timegridpartition:14,times2:3,timeseri:6,timevari:[2,9],titl:[3,15,16],tool:[0,17],total:[4,6],tournament:8,tradit:9,train:[3,4,8,9,10,11,12,13,14,15],train_data:[3,10],train_individual_model:10,train_method:7,train_paramet:7,train_rat:8,train_test_tim:3,transact:13,transform:[1,2,3,4,8,12,13,14,15,17],transformations_param:4,transit:[4,17],translat:17,trapezoid:[4,15],trapmf:4,tree:[1,2],trend:[1,2,9],trendweightedflrg:9,trendweightedft:9,triangular:4,trigger:4,trimf:4,tsa:3,tsdl:6,tupl:[3,4,8,12,15],tutori:0,two:[6,8],twse:6,type:[3,4,6,12,14,15,16,17],typeonlegend:[3,4],uavg:3,ufmg:0,under:4,unified_scaled_interv:3,unified_scaled_interval_pinbal:3,unified_scaled_point:3,unified_scaled_probabilist:3,uniform:6,uniqu:[4,9,10,13,14],uniquefilenam:4,unit:14,univari:6,univers:[0,3,4,6,10,12,13,14,15,16,17],unpack_arg:13,uod:[3,4,8,9,10,12,15,16],uod_clip:4,up_param:3,updat:11,update_model:9,update_uod:10,updateuod:[4,12],upper:[4,6,9,10,12,13,15],upper_margin:15,upper_set:15,url:[0,3,6],urlhttp:3,usa:6,usag:0,usd:[1,2],use:[0,4,12],used:[3,4,8,9,10,15,17],user:[3,8],using:[4,8,9,11,15,17],ustatist:3,ustd:3,usual:[4,17],util:[1,2,9],val:15,valid:[4,8],valu:[3,4,6,8,9,10,11,12,13,14,15,16,17],valueerror:4,variabl:[2,4,9,15],varianc:[4,6],variant:[4,11,17],variat:[6,10],vec:15,vector:[4,12,15],veri:[6,9],verif:3,verifi:15,visualize_distribut:9,vmax:6,vmin:6,vol:[9,14,15],walk:6,want:0,weather:3,weight:[6,9,12,13,17],weightedflrg:[9,12],weightedft:9,weightedhighorderflrg:9,weightedhighorderft:9,weightedintervalft:9,weightedmvft:12,weightednonstationaryflrg:13,weightednonstationaryft:13,were:[12,14,15],when:[4,11,12,15],where:[3,4,9,10,11,12,14],which:[3,4,8,12,17],white_nois:6,whole:8,whose:[0,11],width:[4,13,15,16],width_param:13,window:[3,4,8,11],window_index:13,window_kei:3,window_length:11,window_s:[8,13],windows:[3,4],winkler:3,winkler_mean:3,winkler_scor:3,without:[4,8],wmvft:[2,9],word:[3,8],work:[4,12,14,15],worst:8,wrap:[3,10,11],wrapper:4,www:[3,6],xiii:10,yahoo:6,year:14,yearli:6,yeh:15,yet:3,you:4,young:4,younger:4,youngest:4,zenodo:0},titles:["pyFTS - Fuzzy Time Series for Python","pyFTS","pyFTS package","pyFTS.benchmarks package","pyFTS.common package","pyFTS.common.transformations package","pyFTS.data package","pyFTS.distributed package","pyFTS.hyperparam package","pyFTS.models package","pyFTS.models.ensemble package","pyFTS.models.incremental package","pyFTS.models.multivariate package","pyFTS.models.nonstationary package","pyFTS.models.seasonal package","pyFTS.partitioners package","pyFTS.probabilistic package","pyFTS Quick Start"],titleterms:{"short":17,FTS:17,adapativeexpect:5,airpasseng:6,arima:3,artifici:6,benchmark:3,bitcoin:6,boxcox:5,bst:3,chaotic:6,chen:9,cheng:9,cmean:15,cmsft:14,cmvft:12,common:[4,5,6,12,13,14],composit:4,conf:2,content:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],cvft:13,data:6,dataset:6,differenti:5,dispi:7,distribut:7,dowjon:6,enrol:6,ensembl:10,entropi:15,ethereum:6,eur:6,evolutionari:8,exampl:17,fcm:15,flr:[4,12],flrg:[4,12,13],fts:4,fuzzi:[0,17],fuzzyset:4,gaussianproc:3,gbp:6,gener:6,glass:6,granular:12,grid:[12,15],gridsearch:8,henon:6,hoft:9,honsft:13,how:[0,17],huarng:15,hwang:9,hyperparam:8,ift:9,increment:11,incrementalensembl:11,index:0,inmet:6,instal:17,ismailefendi:9,kde:16,knn:3,librari:0,logistic_map:6,lorentz:6,mackei:6,malaysia:6,measur:3,membership:4,model:[9,10,11,12,13,14],modul:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],msft:14,multiseason:10,multivari:12,mvft:12,naiv:3,nasdaq:6,nonstationari:13,normal:5,nsft:13,packag:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],parallel_util:15,partition:[12,13,14,15],perturb:13,probabilist:16,probabilitydistribut:16,pwft:9,pyft:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],python:0,quantreg:3,quick:17,refer:0,residualanalysi:3,roi:5,rossler:6,sadaei:9,scale:5,season:14,seasonalindex:14,seri:[0,6,17],sft:14,simpl:15,singleton:15,smooth:5,som:5,sonda:6,song:9,sortedcollect:4,spark:7,start:17,subclust:15,submodul:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],subpackag:[2,9],sunspot:6,synthet:6,taiex:6,test:3,time:[0,6,17],timevari:11,transform:5,tree:4,trend:5,tutori:17,usag:17,usd:6,util:[3,4,8,13,15],variabl:12,what:[0,17],wmvft:12}}) \ No newline at end of file diff --git a/docs/pyFTS.common.rst b/docs/pyFTS.common.rst index 1e6db4b..412bd44 100644 --- a/docs/pyFTS.common.rst +++ b/docs/pyFTS.common.rst @@ -52,14 +52,6 @@ pyFTS.common.SortedCollection module :undoc-members: :show-inheritance: -pyFTS.common.transformations module ------------------------------------ - -.. automodule:: pyFTS.common.Transformations - :members: - :undoc-members: - :show-inheritance: - pyFTS.common.Util module ------------------------ diff --git a/docs/pyFTS.common.transformations.rst b/docs/pyFTS.common.transformations.rst index a604d7d..089f361 100644 --- a/docs/pyFTS.common.transformations.rst +++ b/docs/pyFTS.common.transformations.rst @@ -60,6 +60,14 @@ pyFTS.common.transformations.scale module :undoc-members: :show-inheritance: +pyFTS.common.transformations.smoothing module +--------------------------------------------- + +.. automodule:: pyFTS.common.transformations.smoothing + :members: + :undoc-members: + :show-inheritance: + pyFTS.common.transformations.som module --------------------------------------- diff --git a/pyFTS/common/Transformations.py b/pyFTS/common/Transformations.py index 205251b..c911c1b 100644 --- a/pyFTS/common/Transformations.py +++ b/pyFTS/common/Transformations.py @@ -5,15 +5,15 @@ Common data transformation used on pre and post processing of the FTS import numpy as np import pandas as pd import math -from pyFTS.common.transformations.transformation import Transformation -from pyFTS.common.transformations.differential import Differential -from pyFTS.common.transformations.scale import Scale -from pyFTS.common.transformations.adaptiveexpectation import AdaptiveExpectation -from pyFTS.common.transformations.boxcox import BoxCox -from pyFTS.common.transformations.roi import ROI -from pyFTS.common.transformations.trend import LinearTrend -from pyFTS.common.transformations.som import SOMTransformation -from pyFTS.common.transformations.normalization import Normalization +#from pyFTS.common.transformations.transformation import Transformation +#from pyFTS.common.transformations.differential import Differential +#from pyFTS.common.transformations.scale import Scale +#from pyFTS.common.transformations.adaptiveexpectation import AdaptiveExpectation +#from pyFTS.common.transformations.boxcox import BoxCox +#from pyFTS.common.transformations.roi import ROI +#from pyFTS.common.transformations.trend import LinearTrend +#from pyFTS.common.transformations.som import SOMTransformation +#from pyFTS.common.transformations.normalization import Normalization diff --git a/pyFTS/common/transformations/som.py b/pyFTS/common/transformations/som.py index 7a703c9..e98b48b 100644 --- a/pyFTS/common/transformations/som.py +++ b/pyFTS/common/transformations/som.py @@ -2,7 +2,6 @@ Kohonen Self Organizing Maps for Fuzzy Time Series """ import pandas as pd -import SimpSOM as sps from pyFTS.models.multivariate import wmvfts from typing import Tuple from pyFTS.common.Transformations import Transformation @@ -14,6 +13,9 @@ class SOMTransformation(Transformation): def __init__(self, grid_dimension: Tuple, **kwargs): + + import SimpSOM as sps + # SOM attributes self.load_file = kwargs.get('loadFile') self.net: sps.somNet = None
M
N
O
@@ -872,13 +1804,47 @@ + - @@ -1380,6 +2792,12 @@Q
+ @@ -1388,21 +2806,53 @@ R
S
--
+
+ -
+
T
Submodules¶
-pyFTS.benchmarks.benchmarks module¶
++-pyFTS.benchmarks.benchmarks module¶
+Benchmarks methods for FTS methods
+ + + + + + + + + + + + + + +-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-pyFTS.benchmarks.Measures module¶
++-pyFTS.benchmarks.Measures module¶
+pyFTS module for common benchmark metrics
+-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-pyFTS.benchmarks.ResidualAnalysis module¶
++-pyFTS.benchmarks.ResidualAnalysis module¶
+Residual Analysis methods
+-
+
-
+
-
+
-pyFTS.benchmarks.Tests module¶
++-pyFTS.benchmarks.Tests module¶
+-
+
-
+
-
+
-
+
-
+
-pyFTS.benchmarks.Util module¶
++-pyFTS.benchmarks.Util module¶
+Facilities for pyFTS Benchmark module
+ + + + + + + + + + + + + + + + + + +-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-pyFTS.benchmarks.arima module¶
++-pyFTS.benchmarks.arima module¶
+-
+
-pyFTS.benchmarks.knn module¶
++-pyFTS.benchmarks.knn module¶
+-
+
-pyFTS.benchmarks.naive module¶
++-pyFTS.benchmarks.naive module¶
+-
+
--pyFTS.benchmarks.quantreg module¶
++pyFTS.benchmarks.quantreg module¶
+-
+
pyFTS.benchmarks.gaussianproc module¶
-@@ -119,17 +1909,17 @@pyFTS.benchmarks.BSTS module¶
++pyFTS.benchmarks.BSTS module¶
+-
+
--pyFTS.common.transformations module¶
--pyFTS.common.Util module¶
++pyFTS.common.Util module¶
+Common facilities for pyFTS
+-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
pyFTS.common.flrg module¶
@@ -878,8 +1139,562 @@ when the LHS pattern is identified on time t.-pyFTS.common.fts module¶
++pyFTS.common.fts module¶
+-
+
pyFTS.common.tree module¶
@@ -948,10 +1763,9 @@ when the LHS pattern is identified on time t.pyFTS.common.transformations.scale module¶
+pyFTS.common.transformations.smoothing module¶
+pyFTS.common.transformations.som module¶
Submodules¶
-pyFTS.distributed.dispy module¶
++pyFTS.distributed.dispy module¶
+-
+
-
+
-
+
pyFTS.distributed.spark module¶
@@ -91,7 +150,7 @@-pyFTS.hyperparam.GridSearch module¶
++-pyFTS.hyperparam.GridSearch module¶
+ + + + + + + +-@@ -152,8 +484,8 @@ Value: the measure valuepyFTS.hyperparam.Evolutionary module¶
++pyFTS.hyperparam.Evolutionary module¶
+Distributed Evolutionary Hyperparameter Optimization (DEHO) for MVFTS
+-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
Submodules¶
-pyFTS.models.ensemble.ensemble module¶
++-pyFTS.models.ensemble.ensemble module¶
+EnsembleFTS wraps several FTS methods to ensemble their forecasts, providing point, +interval and probabilistic forecasting.
+Silva, P. C. L et al. Probabilistic Forecasting with Seasonal Ensemble Fuzzy Time-Series +XIII Brazilian Congress on Computational Intelligence, 2017. Rio de Janeiro, Brazil.
+-
+
-
+
-
+
-pyFTS.models.ensemble.multiseasonal module¶
++pyFTS.models.ensemble.multiseasonal module¶
+Silva, P. C. L et al. Probabilistic Forecasting with Seasonal Ensemble Fuzzy Time-Series +XIII Brazilian Congress on Computational Intelligence, 2017. Rio de Janeiro, Brazil.
+-
+
Module contents¶
@@ -92,8 +402,8 @@Submodules¶
-pyFTS.models.song module¶
++-pyFTS.models.song module¶
+First Order Traditional Fuzzy Time Series method by Song & Chissom (1993)
+-
+
-
+
-pyFTS.models.chen module¶
++-pyFTS.models.chen module¶
+First Order Conventional Fuzzy Time Series by Chen (1996)
+S.-M. Chen, “Forecasting enrollments based on fuzzy time series,” Fuzzy Sets Syst., vol. 81, no. 3, pp. 311–319, 1996.
+-
+
-
+
-pyFTS.models.yu module¶
++-pyFTS.models.yu module¶
+First Order Weighted Fuzzy Time Series by Yu(2005)
+H.-K. Yu, “Weighted fuzzy time series models for TAIEX forecasting,” +Phys. A Stat. Mech. its Appl., vol. 349, no. 3, pp. 609–624, 2005.
+-
+
-
+
-pyFTS.models.cheng module¶
++-pyFTS.models.cheng module¶
+Trend Weighted Fuzzy Time Series by Cheng, Chen and Wu (2009)
+C.-H. Cheng, Y.-S. Chen, and Y.-L. Wu, “Forecasting innovation diffusion of products using trend-weighted fuzzy time-series model,” +Expert Syst. Appl., vol. 36, no. 2, pp. 1826–1832, 2009.
+-
+
-
+
-pyFTS.models.hofts module¶
++-pyFTS.models.hofts module¶
+High Order FTS
+Severiano, S. A. Jr; Silva, P. C. L.; Sadaei, H. J.; Guimarães, F. G. Very Short-term Solar Forecasting +using Fuzzy Time Series. 2017 IEEE International Conference on Fuzzy Systems. DOI10.1109/FUZZ-IEEE.2017.8015732
+-
+
-
+
-
+
-
+
-pyFTS.models.hwang module¶
++-pyFTS.models.hwang module¶
+High Order Fuzzy Time Series by Hwang, Chen and Lee (1998)
+Jeng-Ren Hwang, Shyi-Ming Chen, and Chia-Hoang Lee, “Handling forecasting problems using fuzzy time series,” +Fuzzy Sets Syst., no. 100, pp. 217–228, 1998.
+-
+
-pyFTS.models.ifts module¶
++-pyFTS.models.ifts module¶
+High Order Interval Fuzzy Time Series
+SILVA, Petrônio CL; SADAEI, Hossein Javedani; GUIMARÃES, Frederico Gadelha. Interval Forecasting with Fuzzy Time Series. +In: Computational Intelligence (SSCI), 2016 IEEE Symposium Series on. IEEE, 2016. p. 1-8.
+-
+
-
+
-pyFTS.models.ismailefendi module¶
++-pyFTS.models.ismailefendi module¶
+First Order Improved Weighted Fuzzy Time Series by Efendi, Ismail and Deris (2013)
+R. Efendi, Z. Ismail, and M. M. Deris, “Improved weight Fuzzy Time Series as used in the exchange rates forecasting of +US Dollar to Ringgit Malaysia,” Int. J. Comput. Intell. Appl., vol. 12, no. 1, p. 1350005, 2013.
+-
+
-
+
-pyFTS.models.pwfts module¶
++-pyFTS.models.pwfts module¶
+-
+
-
+
-@@ -177,16 +1153,16 @@pyFTS.models.sadaei module¶
++pyFTS.models.sadaei module¶
+First Order Exponentialy Weighted Fuzzy Time Series by Sadaei et al. (2013)
+H. J. Sadaei, R. Enayatifar, A. H. Abdullah, and A. Gani, “Short-term load forecasting using a hybrid model with a +refined exponentially weighted fuzzy time series and an improved harmony search,” Int. J. Electr. Power Energy Syst., vol. 62, no. from 2005, pp. 118–129, 2014.
+-
+
-
+
Submodules¶
--pyFTS.models.incremental.TimeVariant module¶
++-pyFTS.models.incremental.TimeVariant module¶
+Meta model that wraps another FTS method and continously retrain it using a data window with +the most recent data
+-
+
-@@ -93,8 +332,8 @@pyFTS.models.incremental.IncrementalEnsemble module¶
++pyFTS.models.incremental.IncrementalEnsemble module¶
+Time Variant/Incremental Ensemble of FTS methods
+-
+
-pyFTS.models.multivariate.variable module¶
++pyFTS.models.multivariate.variable module¶
+-
+
pyFTS.models.multivariate.flrg module¶
@@ -364,17 +443,436 @@ multivariate fuzzy set base.-pyFTS.models.multivariate.mvfts module¶
++-pyFTS.models.multivariate.mvfts module¶
+-
+
-pyFTS.models.multivariate.wmvfts module¶
++-pyFTS.models.multivariate.wmvfts module¶
+-
+
-
+
--pyFTS.models.multivariate.cmvfts module¶
++-pyFTS.models.multivariate.cmvfts module¶
+-
+
-@@ -392,14 +890,14 @@ multivariate fuzzy set base.pyFTS.models.multivariate.granular module¶
++pyFTS.models.multivariate.granular module¶
+-
+
-pyFTS.models.nonstationary.cvfts module¶
++pyFTS.models.nonstationary.cvfts module¶
+-
+
pyFTS.models.nonstationary.flrg module¶
@@ -285,11 +371,269 @@ IEEE Transactions on Fuzzy Systems, v. 16, n. 4, p. 1072-1086, 2008.-pyFTS.models.nonstationary.honsfts module¶
++-pyFTS.models.nonstationary.honsfts module¶
+-
+
-
+
-pyFTS.models.nonstationary.nsfts module¶
++pyFTS.models.nonstationary.nsfts module¶
+-
+
-
+
-
+
-
+
pyFTS.models.nonstationary.partitioners module¶
@@ -385,8 +729,18 @@ IEEE Transactions on Fuzzy Systems, v. 16, n. 4, p. 1072-1086, 2008.-pyFTS.models.nonstationary.util module¶
++pyFTS.models.nonstationary.util module¶
+ + + +Module contents¶
@@ -406,13 +760,13 @@ IEEE Transactions on Fuzzy Systems, v. 16, n. 4, p. 1072-1086, 2008.-pyFTS.models.seasonal.cmsfts module¶
++pyFTS.models.seasonal.cmsfts module¶
+-
+
-
+
pyFTS.models.seasonal.common module¶
@@ -374,8 +452,69 @@-pyFTS.models.seasonal.msfts module¶
++pyFTS.models.seasonal.msfts module¶
+-
+
pyFTS.models.seasonal.partitioner module¶
@@ -451,8 +590,79 @@ overlapped fuzzy sets.-pyFTS.models.seasonal.sfts module¶
++pyFTS.models.seasonal.sfts module¶
+Simple First Order Seasonal Fuzzy Time Series implementation of Song (1999) based of Conventional FTS by Chen (1996)
+-
+
S.-M. Chen, “Forecasting enrollments based on fuzzy time series,” Fuzzy Sets Syst., vol. 81, no. 3, pp. 311–319, 1996.
+-
+
-
+
Module contents¶
@@ -471,11 +681,11 @@ overlapped fuzzy sets.-pyFTS.partitioners.Huarng module¶
++pyFTS.partitioners.Huarng module¶
+K. H. Huarng, “Effective lengths of intervals to improve forecasting in fuzzy time series,” +Fuzzy Sets Syst., vol. 123, no. 3, pp. 387–394, Nov. 2001.
+-
+
pyFTS.partitioners.Singleton module¶
@@ -560,11 +583,42 @@ Comput. Math. Appl., vol. 56, no. 12, pp. 3052–3063, Dec. 2008. DOI: 10.1016/j-pyFTS.partitioners.Util module¶
++-pyFTS.partitioners.Util module¶
+Facility methods for pyFTS partitioners module
+-
+
-@@ -585,12 +639,12 @@ Comput. Math. Appl., vol. 56, no. 12, pp. 3052–3063, Dec. 2008. DOI: 10.1016/jpyFTS.partitioners.parallel_util module¶
+Submodules¶
-pyFTS.probabilistic.ProbabilityDistribution module¶
++-pyFTS.probabilistic.ProbabilityDistribution module¶
+-
+
-@@ -88,8 +381,8 @@pyFTS.probabilistic.kde module¶
+
D
E
-
-
+-
+
--
+
Source code for pyFTS.benchmarks.BSTS
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+import numpy as np
+import pandas as pd
+import scipy.stats as st
+from pyFTS.common import SortedCollection, fts
+from pyFTS.probabilistic import ProbabilityDistribution
+
+
+[docs]class ARIMA(fts.FTS):
+ """
+ Façade for statsmodels.tsa.arima_model
+ """
+ def __init__(self, **kwargs):
+ super(ARIMA, self).__init__(**kwargs)
+ self.name = "BSTS"
+ self.detail = "Bayesian Structural Time Series"
+ self.is_high_order = True
+ self.has_point_forecasting = True
+ self.has_interval_forecasting = True
+ self.has_probability_forecasting = True
+ self.uod_clip = False
+ self.model = None
+ self.model_fit = None
+ self.trained_data = None
+ self.p = 1
+ self.d = 0
+ self.q = 0
+ self.benchmark_only = True
+ self.min_order = 1
+ self.alpha = kwargs.get("alpha", 0.05)
+ self.order = kwargs.get("order", (1,0,0))
+ self._decompose_order(self.order)
+ self.model = None
+
+ def _decompose_order(self, order):
+ if isinstance(order, (tuple, set, list)):
+ self.p = order[0]
+ self.d = order[1]
+ self.q = order[2]
+ self.order = self.p + self.q + (self.q - 1 if self.q > 0 else 0)
+ self.max_lag = self.order
+ self.d = len(self.transformations)
+ self.shortname = "BSTS({},{},{})-{}".format(self.p,self.d,self.q,self.alpha)
+
+[docs] def train(self, data, **kwargs):
+ import pyflux as pf
+
+ if 'order' in kwargs:
+ order = kwargs.pop('order')
+ self._decompose_order(order)
+
+ if self.indexer is not None:
+ data = self.indexer.get_data(data)
+
+ try:
+ self.model = pf.ARIMA(data=data, ar=self.p, ma=self.q, integ=self.d, family=pf.Normal())
+ self.model_fit = self.model.fit('M-H', nsims=20000)
+ except Exception as ex:
+ print(ex)
+ self.model_fit = None
+
+[docs] def inference(self, steps):
+ t_z = self.model.transform_z()
+ mu, Y = self.model._model(self.model.latent_variables.get_z_values())
+ date_index = self.model.shift_dates(steps)
+ sim_vector = self.model._sim_prediction(mu, Y, steps, t_z, 1000)
+
+ return sim_vector
+
+
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+ return self.model.predict(steps, intervals=False).values.flatten().tolist()
+
+
+
+[docs] def forecast_ahead_interval(self, ndata, steps, **kwargs):
+ sim_vector = self.inference(steps)
+
+ if 'alpha' in kwargs:
+ alpha = kwargs.get('alpha')
+ else:
+ alpha = self.alpha
+
+ ret = []
+
+ for ct, sample in enumerate(sim_vector):
+ i = np.percentile(sample, [alpha*100, (1-alpha)*100]).tolist()
+ ret.append(i)
+
+ return ret
+
+[docs] def forecast_distribution(self, data, **kwargs):
+ import pyflux as pf
+
+ sim_vector = self.inference(1)
+
+ ret = []
+
+ for ct, sample in enumerate(sim_vector):
+ pd = ProbabilityDistribution.ProbabilityDistribution(type='histogram', data=sample, nbins=500)
+ ret.append(pd)
+
+ return ret
+
+
+[docs] def forecast_ahead_distribution(self, data, steps, **kwargs):
+
+ sim_vector = self.inference(steps)
+
+ ret = []
+
+ for ct, sample in enumerate(sim_vector):
+ pd = ProbabilityDistribution.ProbabilityDistribution(type='histogram', data=sample, nbins=500)
+ ret.append(pd)
+
+ return ret
+
Source code for pyFTS.benchmarks.Measures
+# -*- coding: utf8 -*-
+
+"""
+pyFTS module for common benchmark metrics
+"""
+
+import time
+import numpy as np
+import pandas as pd
+from pyFTS.common import FuzzySet, SortedCollection
+from pyFTS.probabilistic import ProbabilityDistribution
+
+
+[docs]def acf(data, k):
+ """
+ Autocorrelation function estimative
+
+ :param data:
+ :param k:
+ :return:
+ """
+ mu = np.nanmean(data)
+ sigma = np.var(data)
+ n = len(data)
+ s = 0
+ for t in np.arange(0, n - k):
+ s += (data[t] - mu) * (data[t + k] - mu)
+
+ return 1 / ((n - k) * sigma) * s
+
+
+[docs]def rmse(targets, forecasts):
+ """
+ Root Mean Squared Error
+
+ :param targets:
+ :param forecasts:
+ :return:
+ """
+ if isinstance(targets, list):
+ targets = np.array(targets)
+ if isinstance(forecasts, list):
+ forecasts = np.array(forecasts)
+ return np.sqrt(np.nanmean((targets - forecasts) ** 2))
+
+
+[docs]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))
+
+
+[docs]def mape(targets, forecasts):
+ """
+ Mean Average Percentual Error
+
+ :param targets:
+ :param forecasts:
+ :return:
+ """
+ if isinstance(targets, list):
+ targets = np.array(targets)
+ if isinstance(forecasts, list):
+ forecasts = np.array(forecasts)
+ return np.nanmean(np.abs(np.divide(np.subtract(targets, forecasts), targets))) * 100
+
+
+[docs]def smape(targets, forecasts, type=2):
+ """
+ Symmetric Mean Average Percentual Error
+
+ :param targets:
+ :param forecasts:
+ :param type:
+ :return:
+ """
+ if isinstance(targets, list):
+ targets = np.array(targets)
+ if isinstance(forecasts, list):
+ forecasts = np.array(forecasts)
+ if type == 1:
+ return np.nanmean(np.abs(forecasts - targets) / ((forecasts + targets) / 2))
+ elif type == 2:
+ return np.nanmean(np.abs(forecasts - targets) / (np.abs(forecasts) + abs(targets))) * 100
+ else:
+ return np.nansum(np.abs(forecasts - targets)) / np.nansum(forecasts + targets)
+
+
+[docs]def mape_interval(targets, forecasts):
+ fmean = [np.mean(i) for i in forecasts]
+ return np.mean(abs(fmean - targets) / fmean) * 100
+
+
+[docs]def UStatistic(targets, forecasts):
+ """
+ Theil's U Statistic
+
+ :param targets:
+ :param forecasts:
+ :return:
+ """
+
+ if not isinstance(forecasts, (list, np.ndarray)):
+ forecasts = np.array([forecasts])
+ else:
+ forecasts = np.array(forecasts)
+
+ if not isinstance(targets, (list, np.ndarray)):
+ targets = np.array([targets])
+ else:
+ targets = np.array(targets)
+
+ l = forecasts.size
+ l = 2 if l == 1 else l
+
+ naive = []
+ y = []
+ for k in np.arange(0, l - 1):
+ y.append(np.subtract(forecasts[k], targets[k]) ** 2)
+ naive.append(np.subtract(targets[k + 1], targets[k]) ** 2)
+ return np.sqrt(np.divide(np.nansum(y), np.nansum(naive)))
+
+
+[docs]def TheilsInequality(targets, forecasts):
+ """
+ Theil’s Inequality Coefficient
+
+ :param targets:
+ :param forecasts:
+ :return:
+ """
+ res = targets - forecasts
+ t = len(res)
+ us = np.sqrt(np.nansum([u ** 2 for u in res]))
+ ys = np.sqrt(np.nansum([y ** 2 for y in targets]))
+ fs = np.sqrt(np.nansum([f ** 2 for f in forecasts]))
+ return us / (ys + fs)
+
+
+[docs]def sharpness(forecasts):
+ """Sharpness - Mean size of the intervals"""
+ tmp = [i[1] - i[0] for i in forecasts]
+ return np.mean(tmp)
+
+
+[docs]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)
+
+
+[docs]def coverage(targets, forecasts):
+ """Percent of target values that fall inside forecasted interval"""
+
+ preds = []
+ for i in np.arange(0, len(forecasts)):
+ if targets[i] >= forecasts[i][0] and targets[i] <= forecasts[i][1]:
+ preds.append(1)
+ else:
+ preds.append(0)
+ return np.nanmean(preds)
+
+
+[docs]def pinball(tau, target, forecast):
+ """
+ Pinball loss function. Measure the distance of forecast to the tau-quantile of the target
+
+ :param tau: quantile value in the range (0,1)
+ :param target:
+ :param forecast:
+ :return: float, distance of forecast to the tau-quantile of the target
+ """
+
+ if target >= forecast:
+ return np.subtract(target, forecast) * tau
+ else:
+ return np.subtract(forecast, target) * (1 - tau)
+
+
+[docs]def pinball_mean(tau, targets, forecasts):
+ """
+ Mean pinball loss value of the forecast for a given tau-quantile of the targets
+
+ :param tau: quantile value in the range (0,1)
+ :param targets: list of target values
+ :param forecasts: list of prediction intervals
+ :return: float, the pinball loss mean for tau quantile
+ """
+
+ if tau <= 0.5:
+ preds = [pinball(tau, targets[i], forecasts[i][0]) for i in np.arange(0, len(forecasts))]
+ else:
+ preds = [pinball(tau, targets[i], forecasts[i][1]) for i in np.arange(0, len(forecasts))]
+ return np.nanmean(preds)
+
+
+[docs]def winkler_score(tau, target, forecast):
+ """
+ R. L. Winkler, A Decision-Theoretic Approach to Interval Estimation, J. Am. Stat. Assoc. 67 (337) (1972) 187–191. doi:10.2307/2284720.
+
+ :param tau:
+ :param target:
+ :param forecast:
+ :return:
+ """
+
+ delta = forecast[1] - forecast[0]
+ if forecast[0] <= target <= forecast[1]:
+ return delta
+ elif forecast[0] > target:
+ return delta + (2 * (forecast[0] - target)) / tau
+ elif forecast[1] < target:
+ return delta + (2 * (target - forecast[1])) / tau
+
+
+[docs]def winkler_mean(tau, targets, forecasts):
+ """
+ Mean Winkler score value of the forecast for a given tau-quantile of the targets
+
+ :param tau: quantile value in the range (0,1)
+ :param targets: list of target values
+ :param forecasts: list of prediction intervals
+ :return: float, the Winkler score mean for tau quantile
+ """
+
+ preds = [winkler_score(tau, targets[i], forecasts[i]) for i in np.arange(0, len(forecasts))]
+
+ return np.nanmean(preds)
+
+
+[docs]def brier_score(targets, densities):
+ """
+ Brier Score for probabilistic forecasts.
+ Brier (1950). "Verification of Forecasts Expressed in Terms of Probability". Monthly Weather Review. 78: 1–3.
+
+ :param targets: a list with the target values
+ :param densities: a list with pyFTS.probabil objectsistic.ProbabilityDistribution
+ :return: float
+ """
+
+ if not isinstance(densities, list):
+ densities = [densities]
+ targets = [targets]
+
+ ret = []
+
+ for ct, d in enumerate(densities):
+ try:
+ v = d.bin_index.find_le(targets[ct])
+
+ score = np.nansum([d.density(k) ** 2 for k in d.bins if k != v])
+ score += (d.density(v) - 1) ** 2
+ ret.append(score)
+ except ValueError as ex:
+ ret.append(np.nansum([d.density(k) ** 2 for k in d.bins]))
+ return np.nansum(ret) / len(ret)
+
+
+[docs]def logarithm_score(targets, densities):
+ """
+ Logarithm Score for probabilistic forecasts.
+ Good IJ (1952). “Rational Decisions.”Journal of the Royal Statistical Society B,14(1),107–114. URLhttps://www.jstor.org/stable/2984087.
+
+ :param targets: a list with the target values
+ :param densities: a list with pyFTS.probabil objectsistic.ProbabilityDistribution
+ :return: float
+ """
+
+ _ls = float(0.0)
+ if isinstance(densities, ProbabilityDistribution.ProbabilityDistribution):
+ densities = [densities]
+ targets = [targets]
+
+ n = len(densities)
+ for ct, df in enumerate(densities):
+ _ls += -np.log(df.density(targets[ct]))
+
+ return _ls / n
+
+
+[docs]def crps(targets, densities):
+ """
+ Continuous Ranked Probability Score
+
+ :param targets: a list with the target values
+ :param densities: a list with pyFTS.probabil objectsistic.ProbabilityDistribution
+ :return: float
+ """
+
+ _crps = float(0.0)
+ if isinstance(densities, ProbabilityDistribution.ProbabilityDistribution):
+ densities = [densities]
+ targets = [targets]
+
+ n = len(densities)
+ if n == 0:
+ return np.nan
+
+ for ct, df in enumerate(densities):
+ _crps += np.nansum([(df.cumulative(bin) - (1 if bin >= targets[ct] else 0)) ** 2 for bin in df.bins])
+
+ return _crps / n
+
+
+[docs]def get_point_statistics(data, model, **kwargs):
+ """
+ Condensate all measures for point forecasters
+
+ :param data: test data
+ :param model: FTS model with point forecasting capability
+ :param kwargs:
+ :return: a list with the RMSE, SMAPE and U Statistic
+ """
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ kwargs['type'] = 'point'
+
+ indexer = kwargs.get('indexer', None)
+
+ if indexer is not None:
+ ndata = np.array(indexer.get_data(data))
+ elif model.is_multivariate:
+ if not isinstance(data, pd.DataFrame):
+ raise ValueError("Multivariate data must be a Pandas DataFrame!")
+ ndata = data
+ else:
+ ndata = np.array(data)
+
+ ret = list()
+
+ if steps_ahead == 1:
+ forecasts = model.predict(ndata, **kwargs)
+
+ if model.is_multivariate and model.has_seasonality:
+ ndata = model.indexer.get_data(ndata)
+ elif model.is_multivariate:
+ ndata = ndata[model.target_variable.data_label].values
+
+ if not isinstance(forecasts, (list, np.ndarray)):
+ forecasts = [forecasts]
+
+ 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))
+ ret.append(np.round(UStatistic(ndata[model.max_lag:], forecasts), 2))
+ else:
+ steps_ahead_sampler = kwargs.get('steps_ahead_sampler', 1)
+ nforecasts = []
+ for k in np.arange(model.order, len(ndata) - steps_ahead, steps_ahead_sampler):
+ sample = ndata[k - model.order: k]
+ tmp = model.predict(sample, **kwargs)
+ nforecasts.append(tmp[-1])
+
+ start = model.max_lag + steps_ahead - 1
+ ret.append(np.round(rmse(ndata[start:-1:steps_ahead_sampler], nforecasts), 2))
+ ret.append(np.round(mape(ndata[start:-1:steps_ahead_sampler], nforecasts), 2))
+ ret.append(np.round(UStatistic(ndata[start:-1:steps_ahead_sampler], nforecasts), 2))
+
+ return ret
+
+
+[docs]def get_point_ahead_statistics(data, forecasts, **kwargs):
+ """
+ Condensate all measures for point forecasters
+
+ :param data: test data
+ :param model: FTS model with point forecasting capability
+ :param kwargs:
+ :return: a list with the RMSE, SMAPE and U Statistic
+ """
+
+ l = len(forecasts)
+
+ if len(data) != l:
+ raise Exception("Data and intervals have different lenghts!")
+
+ lags = {}
+
+ for lag in range(l):
+ ret = {}
+ datum = data[lag]
+ forecast = forecasts[lag]
+ ret['steps'] = lag
+ ret['method'] = ''
+ ret['rmse'] = rmse(datum, forecast)
+ ret['mape'] = mape(datum, forecast)
+ sample = data[lag-1:lag+1] if lag > 0 else [datum, datum]
+ ret['u'] = UStatistic(sample, forecast)
+ lags[lag] = ret
+
+ return lags
+
+
+[docs]def get_interval_statistics(data, model, **kwargs):
+ """
+ Condensate all measures for point interval forecasters
+
+ :param data: test data
+ :param model: FTS model with interval forecasting capability
+ :param kwargs:
+ :return: a list with the sharpness, resolution, coverage, .05 pinball mean,
+ .25 pinball mean, .75 pinball mean and .95 pinball mean.
+ """
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ kwargs['type'] = 'interval'
+
+ ret = list()
+
+ if steps_ahead == 1:
+ forecasts = model.predict(data, **kwargs)
+ ret.append(round(sharpness(forecasts), 2))
+ ret.append(round(resolution(forecasts), 2))
+ if model.is_multivariate:
+ data = data[model.target_variable.data_label].values
+ ret.append(round(coverage(data[model.max_lag:], forecasts[:-1]), 2))
+ ret.append(round(pinball_mean(0.05, data[model.max_lag:], forecasts[:-1]), 2))
+ ret.append(round(pinball_mean(0.25, data[model.max_lag:], forecasts[:-1]), 2))
+ ret.append(round(pinball_mean(0.75, data[model.max_lag:], forecasts[:-1]), 2))
+ ret.append(round(pinball_mean(0.95, data[model.max_lag:], forecasts[:-1]), 2))
+ ret.append(round(winkler_mean(0.05, data[model.max_lag:], forecasts[:-1]), 2))
+ ret.append(round(winkler_mean(0.25, data[model.max_lag:], forecasts[:-1]), 2))
+ else:
+ forecasts = []
+ for k in np.arange(model.order, len(data) - steps_ahead):
+ sample = data[k - model.order: k]
+ tmp = model.predict(sample, **kwargs)
+ forecasts.append(tmp[-1])
+
+ start = model.max_lag + steps_ahead - 1
+ ret.append(round(sharpness(forecasts), 2))
+ ret.append(round(resolution(forecasts), 2))
+ if model.is_multivariate:
+ data = data[model.target_variable.data_label].values
+ ret.append(round(coverage(data[model.max_lag:], forecasts), 2))
+ ret.append(round(pinball_mean(0.05, data[start:], forecasts), 2))
+ ret.append(round(pinball_mean(0.25, data[start:], forecasts), 2))
+ ret.append(round(pinball_mean(0.75, data[start:], forecasts), 2))
+ ret.append(round(pinball_mean(0.95, data[start:], forecasts), 2))
+ ret.append(round(winkler_mean(0.05, data[start:], forecasts), 2))
+ ret.append(round(winkler_mean(0.25, data[start:], forecasts), 2))
+ return ret
+
+
+[docs]def get_interval_ahead_statistics(data, intervals, **kwargs):
+ """
+ Condensate all measures for point interval forecasters
+
+ :param data: test data
+ :param intervals: predicted intervals for each datapoint
+ :param kwargs:
+ :return: a list with the sharpness, resolution, coverage, .05 pinball mean,
+ .25 pinball mean, .75 pinball mean and .95 pinball mean.
+ """
+
+ l = len(intervals)
+
+ if len(data) != l:
+ raise Exception("Data and intervals have different lenghts!")
+
+ lags = {}
+
+ for lag in range(l):
+ ret = {}
+ datum = data[lag]
+ interval = intervals[lag]
+ ret['steps'] = lag
+ ret['method'] = ''
+ ret['sharpness'] = round(interval[1] - interval[0], 2)
+ ret['coverage'] = 1 if interval[0] <= datum <= interval[1] else 0
+ ret['pinball05'] = round(pinball(0.05, datum, interval[0]), 2)
+ ret['pinball25'] = round(pinball(0.25, datum, interval[0]), 2)
+ ret['pinball75'] = round(pinball(0.75, datum, interval[1]), 2)
+ ret['pinball95'] = round(pinball(0.95, datum, interval[1]), 2)
+ ret['winkler05'] = round(winkler_score(0.05, datum, interval), 2)
+ ret['winkler25'] = round(winkler_score(0.25, datum, interval), 2)
+ lags[lag] = ret
+
+ return lags
+
+
+[docs]def get_distribution_statistics(data, model, **kwargs):
+ """
+ Get CRPS statistic and time for a forecasting model
+
+ :param data: test data
+ :param model: FTS model with probabilistic forecasting capability
+ :param kwargs:
+ :return: a list with the CRPS and execution time
+ """
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ kwargs['type'] = 'distribution'
+
+ ret = list()
+
+ if steps_ahead == 1:
+ _s1 = time.time()
+ forecasts = model.predict(data, **kwargs)
+ _e1 = time.time()
+ if model.is_multivariate:
+ data = data[model.target_variable.data_label].values
+ ret.append(round(crps(data[model.max_lag:], forecasts[:-1]), 3))
+ ret.append(round(_e1 - _s1, 3))
+ ret.append(round(brier_score(data[model.max_lag:], forecasts[:-1]), 3))
+ else:
+ skip = kwargs.get('steps_ahead_sampler', 1)
+ forecasts = []
+ _s1 = time.time()
+ for k in np.arange(model.max_lag, len(data) - steps_ahead, skip):
+ sample = data[k - model.max_lag: k]
+ tmp = model.predict(sample, **kwargs)
+ forecasts.append(tmp[-1])
+ _e1 = time.time()
+
+ start = model.max_lag + steps_ahead
+ if model.is_multivariate:
+ data = data[model.target_variable.data_label].values
+ ret.append(round(crps(data[start:-1:skip], forecasts), 3))
+ ret.append(round(_e1 - _s1, 3))
+ ret.append(round(brier_score(data[start:-1:skip], forecasts), 3))
+ return ret
+
+
+[docs]def get_distribution_ahead_statistics(data, distributions):
+ """
+ Get CRPS statistic and time for a forecasting model
+
+ :param data: test data
+ :param model: FTS model with probabilistic forecasting capability
+ :param kwargs:
+ :return: a list with the CRPS and execution time
+ """
+
+ l = len(distributions)
+
+ if len(data) != l:
+ raise Exception("Data and distributions have different lenghts!")
+
+ lags = {}
+
+ for lag in range(l):
+ ret = {}
+ datum = data[lag]
+ dist = distributions[lag]
+ ret['steps'] = lag
+ ret['method'] = ''
+ ret['crps'] = round(crps(datum, dist), 3)
+ ret['brier'] = round(brier_score(datum, dist), 3)
+ ret['log'] = round(logarithm_score(datum, dist), 3)
+ lags[lag] = ret
+
+ return lags
+
Source code for pyFTS.benchmarks.ResidualAnalysis
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+"""Residual Analysis methods"""
+
+import numpy as np
+import pandas as pd
+import matplotlib as plt
+import matplotlib.pyplot as plt
+from pyFTS.common import Transformations,Util
+from pyFTS.benchmarks import Measures
+from scipy import stats
+
+
+[docs]def residuals(targets, forecasts, order=1):
+ """First order residuals"""
+ return np.array(targets[order:]) - np.array(forecasts[:-1])
+
+
+[docs]def ljung_box_test(residuals, lags=[1,2,3], alpha=0.5):
+ from statsmodels.stats.diagnostic import acorr_ljungbox
+ from scipy.stats import chi2
+
+ stat, pval = acorr_ljungbox(residuals, lags=lags)
+
+ rows = []
+
+ for ct, Q in enumerate(stat):
+ lag = ct+1
+ p_value = 1 - chi2.cdf(Q, df=lag)
+ critical_value = chi2.ppf(1 - alpha, df=lag)
+ rows.append([lag, Q, p_value, critical_value, 'H0 accepted' if Q > critical_value else 'H0 rejected'])
+
+ return pd.DataFrame(rows, columns=['Lag','Statistic','p-Value','Critical Value', 'Result'])
+
+
+[docs]def compare_residuals(data, models, alpha=.05):
+ """
+ Compare residual's statistics of several models
+
+ :param data: test data
+ :param models:
+ :return: a Pandas dataframe with the Box-Ljung statistic for each model
+ """
+ from statsmodels.stats.diagnostic import acorr_ljungbox
+ rows = []
+ columns = ["Model","Order","AVG","STD","Box-Ljung","p-value","Result"]
+ for mfts in models:
+ forecasts = mfts.predict(data)
+ res = residuals(data, forecasts, mfts.order+1)
+ mu = np.mean(res)
+ sig = np.std(res)
+ row = [mfts.shortname, mfts.order, mu, sig]
+ stat, pval = acorr_ljungbox(res)
+ test = 'H0 Accepted' if pval > alpha else 'H0 Rejected'
+ row.extend([stat, pval, test])
+ rows.append(row)
+ return pd.DataFrame(rows, columns=columns)
+
+
+[docs]def plot_residuals_by_model(targets, models, tam=[8, 8], save=False, file=None):
+ import scipy as sp
+
+ fig, axes = plt.subplots(nrows=len(models), ncols=4, figsize=tam)
+
+ for c, mfts in enumerate(models, start=0):
+ if len(models) > 1:
+ ax = axes[c]
+ else:
+ ax = axes
+ forecasts = mfts.predict(targets)
+ res = residuals(targets, forecasts, mfts.order)
+ mu = np.mean(res)
+ sig = np.std(res)
+
+ if c == 0: ax[0].set_title("Residuals", size='large')
+ ax[0].set_ylabel(mfts.shortname, size='large')
+ ax[0].set_xlabel(' ')
+ ax[0].plot(res)
+
+ if c == 0: ax[1].set_title("Autocorrelation", size='large')
+ ax[1].set_ylabel('ACS')
+ ax[1].set_xlabel('Lag')
+ ax[1].acorr(res)
+
+ if c == 0: ax[2].set_title("Histogram", size='large')
+ ax[2].set_ylabel('Freq')
+ ax[2].set_xlabel('Bins')
+ ax[2].hist(res)
+
+ if c == 0: ax[3].set_title("QQ Plot", size='large')
+
+ _, (__, ___, r) = sp.stats.probplot(res, plot=ax[3], fit=True)
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+[docs]def single_plot_residuals(res, order, tam=[10, 7], save=False, file=None):
+ import scipy as sp
+
+ fig, ax = plt.subplots(nrows=2, ncols=2, figsize=tam)
+
+ ax[0][0].set_title("Residuals", size='large')
+ ax[0][0].plot(res)
+
+ ax[0][1].set_title("Autocorrelation", size='large')
+ ax[0][1].set_ylabel('ACF')
+ ax[0][1].set_xlabel('Lag')
+ ax[0][1].acorr(res)
+
+ ax[1][0].set_title("Histogram", size='large')
+ ax[1][0].set_ylabel('Freq')
+ ax[1][0].set_xlabel('Bins')
+ ax[1][0].hist(res)
+
+ _, (__, ___, r) = sp.stats.probplot(res, plot=ax[1][1], fit=True)
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
Source code for pyFTS.benchmarks.Tests
+
+import numpy as np
+import pandas as pd
+
+from pyFTS.benchmarks.Measures import acf
+
+
+[docs]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):
+ r = acf(data, k)
+ s += r ** 2
+ return n * s
+
+
+[docs]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):
+ r = acf(data, k)
+ s += r ** 2 / (n - k)
+ return n * (n - 2) * s
+
+
+[docs]def format_experiment_table(df, exclude=[], replace={}, csv=True, std=False):
+ rows = []
+ columns = []
+ datasets = df.Dataset.unique()
+ models = df.Model.unique()
+ for model in models:
+ test = np.any([model.rfind(k) != -1 for k in exclude]) if len(exclude) > 0 else False
+ if not test:
+ columns.append(model)
+
+ for dataset in datasets:
+ row = [dataset]
+ if std:
+ row_std = [dataset]
+ for model in columns:
+ avg = np.nanmin(df[(df.Dataset == dataset) & (df.Model == model)]["AVG"].values)
+ row.append(round(avg, 3))
+ if std:
+ _std = np.nanmin(df[(df.Dataset == dataset) & (df.Model == model)]["STD"].values)
+ row_std.append("(" + str(round(_std, 3)) + ")")
+
+ rows.append(row)
+ if std:
+ rows.append(row_std)
+
+ for k in range(len(columns)):
+ if columns[k] in replace:
+ columns[k] = replace[columns[k]]
+
+ columns.insert(0, "dataset")
+
+ if csv:
+ header = ""
+ for k in range(len(columns)):
+ if k > 0:
+ header += ","
+ header += columns[k]
+
+ body = ""
+ for k in range(len(rows)):
+ row = ""
+ for w in range(len(rows[k])):
+ if w > 0:
+ row += ","
+ row += str(rows[k][w])
+ body += '\n{}'.format(row)
+
+ return header + body
+ else:
+ ret = pd.DataFrame(rows, columns=columns)
+ return ret
+
+
+[docs]def test_mean_equality(tests, alpha=.05, method='friedman'):
+ """
+ Test for the equality of the means, with alpha confidence level.
+
+ H_0: There's no significant difference between the means
+ H_1: There is at least one significant difference between the means
+
+ :param tests:
+ :param alpha:
+ :param method:
+ :return:
+ """
+ from stac.stac import nonparametric_tests as npt
+
+ methods = tests.columns[1:]
+
+ values = []
+ for k in methods:
+ values.append(tests[k].values)
+
+ if method=='quade':
+ f_value, p_value, rankings, pivots = npt.quade_test(*values)
+ elif method=='friedman':
+ f_value, p_value, rankings, pivots = npt.friedman_aligned_ranks_test(*values)
+ else:
+ raise Exception('Unknown test method!')
+
+ print("F-Value: {} \tp-Value: {}".format(f_value, p_value))
+
+ if p_value < alpha:
+ print("\nH0 is rejected!\n")
+ else:
+ print("\nH0 is accepted!\n")
+
+ post_hoc = {}
+ rows = []
+ for k in np.arange(0, len(methods)):
+ rows.append([methods[k], rankings[k]])
+ post_hoc[methods[k]] = pivots[k]
+
+ return [pd.DataFrame(rows, columns=['METHOD', 'RANK']).sort_values(['RANK']), post_hoc]
+
+
+[docs]def post_hoc_tests(post_hoc, control_method, alpha=.05, method='finner'):
+ '''
+ Finner paired post-hoc test with NSFTS as control method.
+
+ $H_0$: There is no significant difference between the means
+
+ $H_1$: There is a significant difference between the means
+
+ :param post_hoc:
+ :param control_method:
+ :param alpha:
+ :param method:
+ :return:
+ '''
+ from stac.stac import nonparametric_tests as npt
+
+ if method == 'bonferroni_dunn':
+ comparisons, z_values, p_values, adj_p_values = npt.bonferroni_dunn_test(post_hoc,control_method)
+ elif method == 'holm':
+ comparisons, z_values, p_values, adj_p_values = npt.holm_test(post_hoc,control_method)
+ elif method == 'finner':
+ comparisons, z_values, p_values, adj_p_values = npt.finner_test(post_hoc, control_method)
+ else:
+ raise Exception('Unknown test method!')
+
+ rows = []
+ for k in np.arange(len(comparisons)):
+ test = 'H0 Accepted' if adj_p_values[k] > alpha else 'H0 Rejected'
+ rows.append([comparisons[k], z_values[k], p_values[k], adj_p_values[k], test])
+
+ return pd.DataFrame(rows, columns=['COMPARISON', 'Z-VALUE', 'P-VALUE', 'ADJUSTED P-VALUE', 'Result'])
+
+
Source code for pyFTS.benchmarks.Util
+"""
+Facilities for pyFTS Benchmark module
+"""
+
+import matplotlib as plt
+import matplotlib.cm as cmx
+import matplotlib.colors as pltcolors
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import sqlite3
+#from mpl_toolkits.mplot3d import Axes3D
+
+
+from copy import deepcopy
+from pyFTS.common import Util
+
+
+[docs]def open_benchmark_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_benchmark_tables(conn)
+ return conn
+
+
+[docs]def create_benchmark_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 benchmarks(
+ ID integer primary key, Date int, Dataset text, Tag text,
+ Type text, Model text, Transformation text, 'Order' int,
+ Scheme text, Partitions int,
+ Size int, Steps int, Method text, Measure text, Value real)''')
+
+ conn.commit()
+
+
+[docs]def insert_benchmark(data, conn):
+ """
+ Insert benchmark data on database
+
+ :param data: a tuple with the benchmark data with format:
+
+ ID: integer incremental primary key
+ Date: Date/hour of benchmark execution
+ Dataset: Identify on which dataset the dataset was performed
+ Tag: a user defined word that indentify a benchmark set
+ Type: forecasting type (point, interval, distribution)
+ Model: FTS model
+ Transformation: The name of data transformation, if one was used
+ Order: the order of the FTS method
+ Scheme: UoD partitioning scheme
+ Partitions: Number of partitions
+ Size: Number of rules of the FTS model
+ Steps: prediction horizon, i. e., the number of steps ahead
+ Measure: accuracy measure
+ Value: the measure value
+
+ :param conn: a sqlite3 database connection
+ :return:
+ """
+ c = conn.cursor()
+
+ c.execute("INSERT INTO benchmarks(Date, Dataset, Tag, Type, Model, "
+ + "Transformation, 'Order', Scheme, Partitions, "
+ + "Size, Steps, Method, Measure, Value) "
+ + "VALUES(datetime('now'),?,?,?,?,?,?,?,?,?,?,?,?,?)", data)
+ conn.commit()
+
+
+[docs]def process_common_data(dataset, tag, type, job):
+ """
+ Wraps benchmark information on a tuple for sqlite database
+
+ :param dataset: benchmark dataset
+ :param tag: benchmark set alias
+ :param type: forecasting type
+ :param job: a dictionary with benchmark data
+ :return: tuple for sqlite database
+ """
+ model = job["obj"]
+ if model.benchmark_only:
+ data = [dataset, tag, type, model.shortname,
+ str(model.transformations[0]) if len(model.transformations) > 0 else None,
+ model.order, None, None,
+ None]
+ else:
+ data = [dataset, tag, type, model.shortname,
+ str(model.partitioner.transformation) if model.partitioner.transformation is not None else None,
+ model.order, model.partitioner.name, str(model.partitioner.partitions),
+ len(model)]
+
+ return data
+
+
+[docs]def process_common_data2(dataset, tag, type, job):
+ """
+ Wraps benchmark information on a tuple for sqlite database
+
+ :param dataset: benchmark dataset
+ :param tag: benchmark set alias
+ :param type: forecasting type
+ :param job: a dictionary with benchmark data
+ :return: tuple for sqlite database
+ """
+ data = [dataset, tag, type,
+ job['model'],
+ job['transformation'],
+ job['order'],
+ job['partitioner'],
+ job['partitions'],
+ job['size']
+ ]
+
+ return data
+
+
+[docs]def get_dataframe_from_bd(file, filter):
+ """
+ Query the sqlite benchmark database and return a pandas dataframe with the results
+
+ :param file: the url of the benchmark database
+ :param filter: sql conditions to filter
+ :return: pandas dataframe with the query results
+ """
+ con = sqlite3.connect(file)
+ sql = "SELECT * from benchmarks"
+ if filter is not None:
+ sql += " WHERE " + filter
+ return pd.read_sql_query(sql, con)
+
+
+
+[docs]def extract_measure(dataframe, measure, data_columns):
+ if not dataframe.empty:
+ df = dataframe[(dataframe.Measure == measure)][data_columns]
+ tmp = df.to_dict(orient="records")[0]
+ ret = [k for k in tmp.values() if not np.isnan(k)]
+ return ret
+ else:
+ return None
+
+
+[docs]def find_best(dataframe, criteria, ascending):
+ models = dataframe.Model.unique()
+ orders = dataframe.Order.unique()
+ ret = {}
+ for m in models:
+ for o in orders:
+ mod = {}
+ df = dataframe[(dataframe.Model == m) & (dataframe.Order == o)].sort_values(by=criteria, ascending=ascending)
+ if not df.empty:
+ _key = str(m) + str(o)
+ best = df.loc[df.index[0]]
+ mod['Model'] = m
+ mod['Order'] = o
+ mod['Scheme'] = best["Scheme"]
+ mod['Partitions'] = best["Partitions"]
+
+ ret[_key] = mod
+
+ return ret
+
+
+[docs]def simple_synthetic_dataframe(file, tag, measure, sql=None):
+ '''
+ Read experiments results from sqlite3 database in 'file', make a synthesis of the results
+ of the metric 'measure' with the same 'tag', returning a Pandas DataFrame with the mean results.
+
+ :param file: sqlite3 database file name
+ :param tag: common tag of the experiments
+ :param measure: metric to synthetize
+ :return: Pandas DataFrame with the mean results
+ '''
+ df = get_dataframe_from_bd(file,"tag = '{}' and measure = '{}' {}"
+ .format(tag, measure,
+ '' if sql is None else 'and {}'.format(sql)))
+ data = []
+
+ models = df.Model.unique()
+ datasets = df.Dataset.unique()
+ for dataset in datasets:
+ for model in models:
+ _filter = (df.Dataset == dataset) & (df.Model == model)
+ avg = np.nanmean(df[_filter].Value)
+ std = np.nanstd(df[_filter].Value)
+ data.append([dataset, model, avg, std])
+
+ dat = pd.DataFrame(data, columns=['Dataset', 'Model', 'AVG', 'STD'])
+ dat = dat.sort_values(['AVG', 'STD'])
+
+ best = []
+
+ for dataset in datasets:
+ for model in models:
+ ix = dat[(dat.Dataset == dataset) & (dat.Model == model)].index[0]
+ best.append(ix)
+
+ ret = dat.loc[best].sort_values(['AVG', 'STD'])
+ ret.groupby('Dataset')
+
+ return ret
+
+
+[docs]def analytic_tabular_dataframe(dataframe):
+ experiments = len(dataframe.columns) - len(base_dataframe_columns()) - 1
+ models = dataframe.Model.unique()
+ orders = dataframe.Order.unique()
+ schemes = dataframe.Scheme.unique()
+ partitions = dataframe.Partitions.unique()
+ steps = dataframe.Steps.unique()
+ measures = dataframe.Measure.unique()
+ data_columns = analytical_data_columns(experiments)
+
+ ret = []
+
+ for m in models:
+ for o in orders:
+ for s in schemes:
+ for p in partitions:
+ for st in steps:
+ for ms in measures:
+ df = dataframe[(dataframe.Model == m) & (dataframe.Order == o)
+ & (dataframe.Scheme == s) & (dataframe.Partitions == p)
+ & (dataframe.Steps == st) & (dataframe.Measure == ms) ]
+
+ if not df.empty:
+ for col in data_columns:
+ mod = [m, o, s, p, st, ms, df[col].values[0]]
+ ret.append(mod)
+
+ dat = pd.DataFrame(ret, columns=tabular_dataframe_columns())
+ return dat
+
+
+[docs]def tabular_dataframe_columns():
+ return ["Model", "Order", "Scheme", "Partitions", "Steps", "Measure", "Value"]
+
+
+[docs]def base_dataframe_columns():
+ return ["Model", "Order", "Scheme", "Partitions", "Size", "Steps", "Method"]
+
+[docs]def point_dataframe_synthetic_columns():
+ return base_dataframe_columns().extend(["RMSEAVG", "RMSESTD",
+ "SMAPEAVG", "SMAPESTD", "UAVG","USTD", "TIMEAVG", "TIMESTD"])
+
+
+[docs]def point_dataframe_analytic_columns(experiments):
+ columns = [str(k) for k in np.arange(0, experiments)]
+ columns.insert(0, "Model")
+ columns.insert(1, "Order")
+ columns.insert(2, "Scheme")
+ columns.insert(3, "Partitions")
+ columns.insert(4, "Size")
+ columns.insert(5, "Steps")
+ columns.insert(6, "Method")
+ columns.insert(7, "Measure")
+ return columns
+
+
+[docs]def save_dataframe_point(experiments, file, objs, rmse, save, synthetic, smape, times, u, steps, method):
+ """
+ Create a dataframe to store the benchmark results
+
+ :param experiments: dictionary with the execution results
+ :param file:
+ :param objs:
+ :param rmse:
+ :param save:
+ :param synthetic:
+ :param smape:
+ :param times:
+ :param u:
+ :return:
+ """
+ ret = []
+
+ if synthetic:
+
+ for k in sorted(objs.keys()):
+ try:
+ mod = []
+ mfts = objs[k]
+ mod.append(mfts.shortname)
+ mod.append(mfts.order)
+ if not mfts.benchmark_only:
+ mod.append(mfts.partitioner.name)
+ mod.append(mfts.partitioner.partitions)
+ mod.append(len(mfts))
+ else:
+ mod.append('-')
+ mod.append('-')
+ mod.append('-')
+ mod.append(steps[k])
+ mod.append(method[k])
+ mod.append(np.round(np.nanmean(rmse[k]), 2))
+ mod.append(np.round(np.nanstd(rmse[k]), 2))
+ mod.append(np.round(np.nanmean(smape[k]), 2))
+ mod.append(np.round(np.nanstd(smape[k]), 2))
+ mod.append(np.round(np.nanmean(u[k]), 2))
+ mod.append(np.round(np.nanstd(u[k]), 2))
+ mod.append(np.round(np.nanmean(times[k]), 4))
+ mod.append(np.round(np.nanstd(times[k]), 4))
+ ret.append(mod)
+ except Exception as ex:
+ print("Erro ao salvar ", k)
+ print("Exceção ", ex)
+
+ columns = point_dataframe_synthetic_columns()
+ else:
+ for k in sorted(objs.keys()):
+ try:
+ mfts = objs[k]
+ n = mfts.shortname
+ o = mfts.order
+ if not mfts.benchmark_only:
+ s = mfts.partitioner.name
+ p = mfts.partitioner.partitions
+ l = len(mfts)
+ else:
+ s = '-'
+ p = '-'
+ l = '-'
+ st = steps[k]
+ mt = method[k]
+ tmp = [n, o, s, p, l, st, mt, 'RMSE']
+ tmp.extend(rmse[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'SMAPE']
+ tmp.extend(smape[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'U']
+ tmp.extend(u[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'TIME']
+ tmp.extend(times[k])
+ ret.append(deepcopy(tmp))
+ except Exception as ex:
+ print("Erro ao salvar ", k)
+ print("Exceção ", ex)
+ columns = point_dataframe_analytic_columns(experiments)
+ try:
+ dat = pd.DataFrame(ret, columns=columns)
+ if save: dat.to_csv(Util.uniquefilename(file), sep=";", index=False)
+ return dat
+ except Exception as ex:
+ print(ex)
+ print(experiments)
+ print(columns)
+ print(ret)
+
+
+[docs]def cast_dataframe_to_synthetic(infile, outfile, experiments, type):
+ if type == 'point':
+ analytic_columns = point_dataframe_analytic_columns
+ synthetic_columns = point_dataframe_synthetic_columns
+ synthetize_measures = cast_dataframe_to_synthetic_point
+ elif type == 'interval':
+ analytic_columns = interval_dataframe_analytic_columns
+ synthetic_columns = interval_dataframe_synthetic_columns
+ synthetize_measures = cast_dataframe_to_synthetic_interval
+ elif type == 'distribution':
+ analytic_columns = probabilistic_dataframe_analytic_columns
+ synthetic_columns = probabilistic_dataframe_synthetic_columns
+ synthetize_measures = cast_dataframe_to_synthetic_probabilistic
+ else:
+ raise ValueError("Type parameter has an unknown value!")
+
+ columns = analytic_columns(experiments)
+ dat = pd.read_csv(infile, sep=";", usecols=columns)
+ models = dat.Model.unique()
+ orders = dat.Order.unique()
+ schemes = dat.Scheme.unique()
+ partitions = dat.Partitions.unique()
+ steps = dat.Steps.unique()
+ methods = dat.Method.unique()
+
+ data_columns = analytical_data_columns(experiments)
+
+ ret = []
+
+ for m in models:
+ for o in orders:
+ for s in schemes:
+ for p in partitions:
+ for st in steps:
+ for mt in methods:
+ df = dat[(dat.Model == m) & (dat.Order == o) & (dat.Scheme == s) &
+ (dat.Partitions == p) & (dat.Steps == st) & (dat.Method == mt)]
+ if not df.empty:
+ mod = synthetize_measures(df, data_columns)
+ mod.insert(0, m)
+ mod.insert(1, o)
+ mod.insert(2, s)
+ mod.insert(3, p)
+ mod.insert(4, df.iat[0,5])
+ mod.insert(5, st)
+ mod.insert(6, mt)
+ ret.append(mod)
+
+ dat = pd.DataFrame(ret, columns=synthetic_columns())
+ dat.to_csv(outfile, sep=";", index=False)
+
+
+[docs]def cast_dataframe_to_synthetic_point(df, data_columns):
+ ret = []
+ rmse = extract_measure(df, 'RMSE', data_columns)
+ smape = extract_measure(df, 'SMAPE', data_columns)
+ u = extract_measure(df, 'U', data_columns)
+ times = extract_measure(df, 'TIME', data_columns)
+ ret.append(np.round(np.nanmean(rmse), 2))
+ ret.append(np.round(np.nanstd(rmse), 2))
+ ret.append(np.round(np.nanmean(smape), 2))
+ ret.append(np.round(np.nanstd(smape), 2))
+ ret.append(np.round(np.nanmean(u), 2))
+ ret.append(np.round(np.nanstd(u), 2))
+ ret.append(np.round(np.nanmean(times), 4))
+ ret.append(np.round(np.nanstd(times), 4))
+
+ return ret
+
+
+[docs]def analytical_data_columns(experiments):
+ data_columns = [str(k) for k in np.arange(0, experiments)]
+ return data_columns
+
+
+[docs]def scale_params(data):
+ vmin = np.nanmin(data)
+ vlen = np.nanmax(data) - vmin
+ return (vmin, vlen)
+
+
+
+
+
+
+
+
+
+[docs]def unified_scaled_point(experiments, tam, save=False, file=None,
+ sort_columns=['UAVG', 'RMSEAVG', 'USTD', 'RMSESTD'],
+ sort_ascend=[1, 1, 1, 1],save_best=False,
+ ignore=None, replace=None):
+
+ fig, axes = plt.subplots(nrows=3, ncols=1, figsize=tam)
+
+ axes[0].set_title('RMSE')
+ axes[1].set_title('SMAPE')
+ axes[2].set_title('U Statistic')
+
+ models = {}
+
+ for experiment in experiments:
+
+ mdl = {}
+
+ dat_syn = pd.read_csv(experiment[0], sep=";", usecols=point_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(experiment[1], sep=";", usecols=point_dataframe_analytic_columns(experiment[2]))
+
+ rmse = []
+ smape = []
+ u = []
+ times = []
+
+ data_columns = analytical_data_columns(experiment[2])
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+
+ if b not in models:
+ models[b] = {}
+ models[b]['rmse'] = []
+ models[b]['smape'] = []
+ models[b]['u'] = []
+ models[b]['times'] = []
+
+ if b not in mdl:
+ mdl[b] = {}
+ mdl[b]['rmse'] = []
+ mdl[b]['smape'] = []
+ mdl[b]['u'] = []
+ mdl[b]['times'] = []
+
+ best = bests[b]
+ tmp = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ tmpl = extract_measure(tmp,'RMSE',data_columns)
+ mdl[b]['rmse'].extend( tmpl )
+ rmse.extend( tmpl )
+ tmpl = extract_measure(tmp, 'SMAPE', data_columns)
+ mdl[b]['smape'].extend(tmpl)
+ smape.extend(tmpl)
+ tmpl = extract_measure(tmp, 'U', data_columns)
+ mdl[b]['u'].extend(tmpl)
+ u.extend(tmpl)
+ tmpl = extract_measure(tmp, 'TIME', data_columns)
+ mdl[b]['times'].extend(tmpl)
+ times.extend(tmpl)
+
+ models[b]['label'] = check_replace_list(best["Model"] + " " + str(best["Order"]), replace)
+
+ print("GLOBAL")
+ rmse_param = scale_params(rmse)
+ stats("rmse", rmse)
+ smape_param = scale_params(smape)
+ stats("smape", smape)
+ u_param = scale_params(u)
+ stats("u", u)
+ times_param = scale_params(times)
+
+ for key in sorted(models.keys()):
+ models[key]['rmse'].extend( scale(mdl[key]['rmse'], rmse_param) )
+ models[key]['smape'].extend( scale(mdl[key]['smape'], smape_param) )
+ models[key]['u'].extend( scale(mdl[key]['u'], u_param) )
+ models[key]['times'].extend( scale(mdl[key]['times'], times_param) )
+
+ rmse = []
+ smape = []
+ u = []
+ times = []
+ labels = []
+ for key in sorted(models.keys()):
+ print(key)
+ rmse.append(models[key]['rmse'])
+ stats("rmse", models[key]['rmse'])
+ smape.append(models[key]['smape'])
+ stats("smape", models[key]['smape'])
+ u.append(models[key]['u'])
+ stats("u", models[key]['u'])
+ times.append(models[key]['times'])
+ labels.append(models[key]['label'])
+
+ axes[0].boxplot(rmse, labels=labels, autorange=True, showmeans=True)
+ axes[0].set_title("RMSE")
+ axes[1].boxplot(smape, labels=labels, autorange=True, showmeans=True)
+ axes[1].set_title("SMAPE")
+ axes[2].boxplot(u, labels=labels, autorange=True, showmeans=True)
+ axes[2].set_title("U Statistic")
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+[docs]def plot_dataframe_point(file_synthetic, file_analytic, experiments, tam, save=False, file=None,
+ sort_columns=['UAVG', 'RMSEAVG', 'USTD', 'RMSESTD'],
+ sort_ascend=[1, 1, 1, 1],save_best=False,
+ ignore=None,replace=None):
+
+ fig, axes = plt.subplots(nrows=3, ncols=1, figsize=tam)
+
+ axes[0].set_title('RMSE')
+ axes[1].set_title('SMAPE')
+ axes[2].set_title('U Statistic')
+
+ dat_syn = pd.read_csv(file_synthetic, sep=";", usecols=point_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(file_analytic, sep=";", usecols=point_dataframe_analytic_columns(experiments))
+
+ data_columns = analytical_data_columns(experiments)
+
+ if save_best:
+ dat = pd.DataFrame.from_dict(bests, orient='index')
+ dat.to_csv(Util.uniquefilename(file_synthetic.replace("synthetic","best")), sep=";", index=False)
+
+ rmse = []
+ smape = []
+ u = []
+ times = []
+ labels = []
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+
+ best = bests[b]
+ tmp = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ rmse.append( extract_measure(tmp,'RMSE',data_columns) )
+ smape.append(extract_measure(tmp, 'SMAPE', data_columns))
+ u.append(extract_measure(tmp, 'U', data_columns))
+ times.append(extract_measure(tmp, 'TIME', data_columns))
+
+ labels.append(check_replace_list(best["Model"] + " " + str(best["Order"]),replace))
+
+ axes[0].boxplot(rmse, labels=labels, autorange=True, showmeans=True)
+ axes[0].set_title("RMSE")
+ axes[1].boxplot(smape, labels=labels, autorange=True, showmeans=True)
+ axes[1].set_title("SMAPE")
+ axes[2].boxplot(u, labels=labels, autorange=True, showmeans=True)
+ axes[2].set_title("U Statistic")
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+
+[docs]def check_replace_list(m, replace):
+ if replace is not None:
+ for r in replace:
+ if r[0] in m:
+ return r[1]
+ return m
+
+
+
+[docs]def check_ignore_list(b, ignore):
+ flag = False
+ if ignore is not None:
+ for i in ignore:
+ if i in b:
+ flag = True
+ return flag
+
+
+[docs]def save_dataframe_interval(coverage, experiments, file, objs, resolution, save, sharpness, synthetic, times,
+ q05, q25, q75, q95, steps, method):
+ ret = []
+ if synthetic:
+ for k in sorted(objs.keys()):
+ mod = []
+ mfts = objs[k]
+ mod.append(mfts.shortname)
+ mod.append(mfts.order)
+ l = len(mfts)
+ if not mfts.benchmark_only:
+ mod.append(mfts.partitioner.name)
+ mod.append(mfts.partitioner.partitions)
+ mod.append(l)
+ else:
+ mod.append('-')
+ mod.append('-')
+ mod.append('-')
+ mod.append(steps[k])
+ mod.append(method[k])
+ mod.append(round(np.nanmean(sharpness[k]), 2))
+ mod.append(round(np.nanstd(sharpness[k]), 2))
+ mod.append(round(np.nanmean(resolution[k]), 2))
+ mod.append(round(np.nanstd(resolution[k]), 2))
+ mod.append(round(np.nanmean(coverage[k]), 2))
+ mod.append(round(np.nanstd(coverage[k]), 2))
+ mod.append(round(np.nanmean(times[k]), 2))
+ mod.append(round(np.nanstd(times[k]), 2))
+ mod.append(round(np.nanmean(q05[k]), 2))
+ mod.append(round(np.nanstd(q05[k]), 2))
+ mod.append(round(np.nanmean(q25[k]), 2))
+ mod.append(round(np.nanstd(q25[k]), 2))
+ mod.append(round(np.nanmean(q75[k]), 2))
+ mod.append(round(np.nanstd(q75[k]), 2))
+ mod.append(round(np.nanmean(q95[k]), 2))
+ mod.append(round(np.nanstd(q95[k]), 2))
+ mod.append(l)
+ ret.append(mod)
+
+ columns = interval_dataframe_synthetic_columns()
+ else:
+ for k in sorted(objs.keys()):
+ try:
+ mfts = objs[k]
+ n = mfts.shortname
+ o = mfts.order
+ if not mfts.benchmark_only:
+ s = mfts.partitioner.name
+ p = mfts.partitioner.partitions
+ l = len(mfts)
+ else:
+ s = '-'
+ p = '-'
+ l = '-'
+ st = steps[k]
+ mt = method[k]
+ tmp = [n, o, s, p, l, st, mt, 'Sharpness']
+ tmp.extend(sharpness[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'Resolution']
+ tmp.extend(resolution[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'Coverage']
+ tmp.extend(coverage[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'TIME']
+ tmp.extend(times[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'Q05']
+ tmp.extend(q05[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'Q25']
+ tmp.extend(q25[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'Q75']
+ tmp.extend(q75[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'Q95']
+ tmp.extend(q95[k])
+ ret.append(deepcopy(tmp))
+ except Exception as ex:
+ print("Erro ao salvar ", k)
+ print("Exceção ", ex)
+ columns = interval_dataframe_analytic_columns(experiments)
+ dat = pd.DataFrame(ret, columns=columns)
+ if save: dat.to_csv(Util.uniquefilename(file), sep=";")
+ return dat
+
+
+[docs]def interval_dataframe_analytic_columns(experiments):
+ columns = [str(k) for k in np.arange(0, experiments)]
+ columns.insert(0, "Model")
+ columns.insert(1, "Order")
+ columns.insert(2, "Scheme")
+ columns.insert(3, "Partitions")
+ columns.insert(4, "Size")
+ columns.insert(5, "Steps")
+ columns.insert(6, "Method")
+ columns.insert(7, "Measure")
+ return columns
+
+
+
+[docs]def interval_dataframe_synthetic_columns():
+ columns = ["Model", "Order", "Scheme", "Partitions","SIZE", "Steps","Method" "SHARPAVG", "SHARPSTD", "RESAVG", "RESSTD", "COVAVG",
+ "COVSTD", "TIMEAVG", "TIMESTD", "Q05AVG", "Q05STD", "Q25AVG", "Q25STD", "Q75AVG", "Q75STD", "Q95AVG", "Q95STD"]
+ return columns
+
+
+[docs]def cast_dataframe_to_synthetic_interval(df, data_columns):
+ sharpness = extract_measure(df, 'Sharpness', data_columns)
+ resolution = extract_measure(df, 'Resolution', data_columns)
+ coverage = extract_measure(df, 'Coverage', data_columns)
+ times = extract_measure(df, 'TIME', data_columns)
+ q05 = extract_measure(df, 'Q05', data_columns)
+ q25 = extract_measure(df, 'Q25', data_columns)
+ q75 = extract_measure(df, 'Q75', data_columns)
+ q95 = extract_measure(df, 'Q95', data_columns)
+ ret = []
+ ret.append(np.round(np.nanmean(sharpness), 2))
+ ret.append(np.round(np.nanstd(sharpness), 2))
+ ret.append(np.round(np.nanmean(resolution), 2))
+ ret.append(np.round(np.nanstd(resolution), 2))
+ ret.append(np.round(np.nanmean(coverage), 2))
+ ret.append(np.round(np.nanstd(coverage), 2))
+ ret.append(np.round(np.nanmean(times), 4))
+ ret.append(np.round(np.nanstd(times), 4))
+ ret.append(np.round(np.nanmean(q05), 4))
+ ret.append(np.round(np.nanstd(q05), 4))
+ ret.append(np.round(np.nanmean(q25), 4))
+ ret.append(np.round(np.nanstd(q25), 4))
+ ret.append(np.round(np.nanmean(q75), 4))
+ ret.append(np.round(np.nanstd(q75), 4))
+ ret.append(np.round(np.nanmean(q95), 4))
+ ret.append(np.round(np.nanstd(q95), 4))
+ return ret
+
+
+
+
+[docs]def unified_scaled_interval(experiments, tam, save=False, file=None,
+ sort_columns=['COVAVG', 'SHARPAVG', 'COVSTD', 'SHARPSTD'],
+ sort_ascend=[True, False, True, True],save_best=False,
+ ignore=None, replace=None):
+ fig, axes = plt.subplots(nrows=3, ncols=1, figsize=tam)
+
+ axes[0].set_title('Sharpness')
+ axes[1].set_title('Resolution')
+ axes[2].set_title('Coverage')
+
+ models = {}
+
+ for experiment in experiments:
+
+ mdl = {}
+
+ dat_syn = pd.read_csv(experiment[0], sep=";", usecols=interval_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(experiment[1], sep=";", usecols=interval_dataframe_analytic_columns(experiment[2]))
+
+ sharpness = []
+ resolution = []
+ coverage = []
+ times = []
+
+ data_columns = analytical_data_columns(experiment[2])
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+
+ if b not in models:
+ models[b] = {}
+ models[b]['sharpness'] = []
+ models[b]['resolution'] = []
+ models[b]['coverage'] = []
+ models[b]['times'] = []
+
+ if b not in mdl:
+ mdl[b] = {}
+ mdl[b]['sharpness'] = []
+ mdl[b]['resolution'] = []
+ mdl[b]['coverage'] = []
+ mdl[b]['times'] = []
+
+ best = bests[b]
+ print(best)
+ tmp = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ tmpl = extract_measure(tmp, 'Sharpness', data_columns)
+ mdl[b]['sharpness'].extend(tmpl)
+ sharpness.extend(tmpl)
+ tmpl = extract_measure(tmp, 'Resolution', data_columns)
+ mdl[b]['resolution'].extend(tmpl)
+ resolution.extend(tmpl)
+ tmpl = extract_measure(tmp, 'Coverage', data_columns)
+ mdl[b]['coverage'].extend(tmpl)
+ coverage.extend(tmpl)
+ tmpl = extract_measure(tmp, 'TIME', data_columns)
+ mdl[b]['times'].extend(tmpl)
+ times.extend(tmpl)
+
+ models[b]['label'] = check_replace_list(best["Model"] + " " + str(best["Order"]), replace)
+
+ sharpness_param = scale_params(sharpness)
+ resolution_param = scale_params(resolution)
+ coverage_param = scale_params(coverage)
+ times_param = scale_params(times)
+
+ for key in sorted(models.keys()):
+ models[key]['sharpness'].extend(scale(mdl[key]['sharpness'], sharpness_param))
+ models[key]['resolution'].extend(scale(mdl[key]['resolution'], resolution_param))
+ models[key]['coverage'].extend(scale(mdl[key]['coverage'], coverage_param))
+ models[key]['times'].extend(scale(mdl[key]['times'], times_param))
+
+ sharpness = []
+ resolution = []
+ coverage = []
+ times = []
+ labels = []
+ for key in sorted(models.keys()):
+ sharpness.append(models[key]['sharpness'])
+ resolution.append(models[key]['resolution'])
+ coverage.append(models[key]['coverage'])
+ times.append(models[key]['times'])
+ labels.append(models[key]['label'])
+
+ axes[0].boxplot(sharpness, labels=labels, autorange=True, showmeans=True)
+ axes[1].boxplot(resolution, labels=labels, autorange=True, showmeans=True)
+ axes[2].boxplot(coverage, labels=labels, autorange=True, showmeans=True)
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+
+[docs]def plot_dataframe_interval(file_synthetic, file_analytic, experiments, tam, save=False, file=None,
+ sort_columns=['COVAVG', 'SHARPAVG', 'COVSTD', 'SHARPSTD'],
+ sort_ascend=[True, False, True, True],save_best=False,
+ ignore=None, replace=None):
+
+ fig, axes = plt.subplots(nrows=3, ncols=1, figsize=tam)
+
+ axes[0].set_title('Sharpness')
+ axes[1].set_title('Resolution')
+ axes[2].set_title('Coverage')
+
+ dat_syn = pd.read_csv(file_synthetic, sep=";", usecols=interval_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(file_analytic, sep=";", usecols=interval_dataframe_analytic_columns(experiments))
+
+ data_columns = analytical_data_columns(experiments)
+
+ if save_best:
+ dat = pd.DataFrame.from_dict(bests, orient='index')
+ dat.to_csv(Util.uniquefilename(file_synthetic.replace("synthetic","best")), sep=";", index=False)
+
+ sharpness = []
+ resolution = []
+ coverage = []
+ times = []
+ labels = []
+ bounds_shp = []
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+ best = bests[b]
+ df = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ sharpness.append( extract_measure(df,'Sharpness',data_columns) )
+ resolution.append(extract_measure(df, 'Resolution', data_columns))
+ coverage.append(extract_measure(df, 'Coverage', data_columns))
+ times.append(extract_measure(df, 'TIME', data_columns))
+ labels.append(check_replace_list(best["Model"] + " " + str(best["Order"]), replace))
+
+ axes[0].boxplot(sharpness, labels=labels, autorange=True, showmeans=True)
+ axes[0].set_title("Sharpness")
+ axes[1].boxplot(resolution, labels=labels, autorange=True, showmeans=True)
+ axes[1].set_title("Resolution")
+ axes[2].boxplot(coverage, labels=labels, autorange=True, showmeans=True)
+ axes[2].set_title("Coverage")
+ axes[2].set_ylim([0, 1.1])
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+
+[docs]def unified_scaled_interval_pinball(experiments, tam, save=False, file=None,
+ sort_columns=['COVAVG','SHARPAVG','COVSTD','SHARPSTD'],
+ sort_ascend=[True, False, True, True], save_best=False,
+ ignore=None, replace=None):
+ fig, axes = plt.subplots(nrows=1, ncols=4, figsize=tam)
+ axes[0].set_title(r'$\tau=0.05$')
+ axes[1].set_title(r'$\tau=0.25$')
+ axes[2].set_title(r'$\tau=0.75$')
+ axes[3].set_title(r'$\tau=0.95$')
+ models = {}
+
+ for experiment in experiments:
+
+ mdl = {}
+
+ dat_syn = pd.read_csv(experiment[0], sep=";", usecols=interval_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(experiment[1], sep=";", usecols=interval_dataframe_analytic_columns(experiment[2]))
+
+ q05 = []
+ q25 = []
+ q75 = []
+ q95 = []
+
+ data_columns = analytical_data_columns(experiment[2])
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+
+ if b not in models:
+ models[b] = {}
+ models[b]['q05'] = []
+ models[b]['q25'] = []
+ models[b]['q75'] = []
+ models[b]['q95'] = []
+
+ if b not in mdl:
+ mdl[b] = {}
+ mdl[b]['q05'] = []
+ mdl[b]['q25'] = []
+ mdl[b]['q75'] = []
+ mdl[b]['q95'] = []
+
+ best = bests[b]
+ print(best)
+ tmp = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ tmpl = extract_measure(tmp, 'Q05', data_columns)
+ mdl[b]['q05'].extend(tmpl)
+ q05.extend(tmpl)
+ tmpl = extract_measure(tmp, 'Q25', data_columns)
+ mdl[b]['q25'].extend(tmpl)
+ q25.extend(tmpl)
+ tmpl = extract_measure(tmp, 'Q75', data_columns)
+ mdl[b]['q75'].extend(tmpl)
+ q75.extend(tmpl)
+ tmpl = extract_measure(tmp, 'Q95', data_columns)
+ mdl[b]['q95'].extend(tmpl)
+ q95.extend(tmpl)
+
+ models[b]['label'] = check_replace_list(best["Model"] + " " + str(best["Order"]), replace)
+
+ q05_param = scale_params(q05)
+ q25_param = scale_params(q25)
+ q75_param = scale_params(q75)
+ q95_param = scale_params(q95)
+
+ for key in sorted(models.keys()):
+ models[key]['q05'].extend(scale(mdl[key]['q05'], q05_param))
+ models[key]['q25'].extend(scale(mdl[key]['q25'], q25_param))
+ models[key]['q75'].extend(scale(mdl[key]['q75'], q75_param))
+ models[key]['q95'].extend(scale(mdl[key]['q95'], q95_param))
+
+ q05 = []
+ q25 = []
+ q75 = []
+ q95 = []
+ labels = []
+ for key in sorted(models.keys()):
+ q05.append(models[key]['q05'])
+ q25.append(models[key]['q25'])
+ q75.append(models[key]['q75'])
+ q95.append(models[key]['q95'])
+ labels.append(models[key]['label'])
+
+ axes[0].boxplot(q05, labels=labels, vert=False, autorange=True, showmeans=True)
+ axes[1].boxplot(q25, labels=labels, vert=False, autorange=True, showmeans=True)
+ axes[2].boxplot(q75, labels=labels, vert=False, autorange=True, showmeans=True)
+ axes[3].boxplot(q95, labels=labels, vert=False, autorange=True, showmeans=True)
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+
+[docs]def plot_dataframe_interval_pinball(file_synthetic, file_analytic, experiments, tam, save=False, file=None,
+ sort_columns=['COVAVG','SHARPAVG','COVSTD','SHARPSTD'],
+ sort_ascend=[True, False, True, True], save_best=False,
+ ignore=None, replace=None):
+
+ fig, axes = plt.subplots(nrows=1, ncols=4, figsize=tam)
+ axes[0].set_title(r'$\tau=0.05$')
+ axes[1].set_title(r'$\tau=0.25$')
+ axes[2].set_title(r'$\tau=0.75$')
+ axes[3].set_title(r'$\tau=0.95$')
+
+ dat_syn = pd.read_csv(file_synthetic, sep=";", usecols=interval_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(file_analytic, sep=";", usecols=interval_dataframe_analytic_columns(experiments))
+
+ data_columns = analytical_data_columns(experiments)
+
+ if save_best:
+ dat = pd.DataFrame.from_dict(bests, orient='index')
+ dat.to_csv(Util.uniquefilename(file_synthetic.replace("synthetic","best")), sep=";", index=False)
+
+ q05 = []
+ q25 = []
+ q75 = []
+ q95 = []
+ labels = []
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+ best = bests[b]
+ df = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ q05.append(extract_measure(df, 'Q05', data_columns))
+ q25.append(extract_measure(df, 'Q25', data_columns))
+ q75.append(extract_measure(df, 'Q75', data_columns))
+ q95.append(extract_measure(df, 'Q95', data_columns))
+ labels.append(check_replace_list(best["Model"] + " " + str(best["Order"]), replace))
+
+ axes[0].boxplot(q05, labels=labels, vert=False, autorange=True, showmeans=True)
+ axes[1].boxplot(q25, labels=labels, vert=False, autorange=True, showmeans=True)
+ axes[2].boxplot(q75, labels=labels, vert=False, autorange=True, showmeans=True)
+ axes[3].boxplot(q95, labels=labels, vert=False, autorange=True, showmeans=True)
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+[docs]def save_dataframe_probabilistic(experiments, file, objs, crps, times, save, synthetic, steps, method):
+ """
+ Save benchmark results for m-step ahead probabilistic forecasters
+ :param experiments:
+ :param file:
+ :param objs:
+ :param crps_interval:
+ :param crps_distr:
+ :param times:
+ :param times2:
+ :param save:
+ :param synthetic:
+ :return:
+ """
+ ret = []
+
+ if synthetic:
+
+ for k in sorted(objs.keys()):
+ try:
+ ret = []
+ for k in sorted(objs.keys()):
+ try:
+ mod = []
+ mfts = objs[k]
+ mod.append(mfts.shortname)
+ mod.append(mfts.order)
+ if not mfts.benchmark_only:
+ mod.append(mfts.partitioner.name)
+ mod.append(mfts.partitioner.partitions)
+ mod.append(len(mfts))
+ else:
+ mod.append('-')
+ mod.append('-')
+ mod.append('-')
+ mod.append(steps[k])
+ mod.append(method[k])
+ mod.append(np.round(np.nanmean(crps[k]), 2))
+ mod.append(np.round(np.nanstd(crps[k]), 2))
+ mod.append(np.round(np.nanmean(times[k]), 4))
+ mod.append(np.round(np.nanstd(times[k]), 4))
+ ret.append(mod)
+ except Exception as e:
+ print('Erro: %s' % e)
+ except Exception as ex:
+ print("Erro ao salvar ", k)
+ print("Exceção ", ex)
+
+ columns = probabilistic_dataframe_synthetic_columns()
+ else:
+ for k in sorted(objs.keys()):
+ try:
+ mfts = objs[k]
+ n = mfts.shortname
+ o = mfts.order
+ if not mfts.benchmark_only:
+ s = mfts.partitioner.name
+ p = mfts.partitioner.partitions
+ l = len(mfts)
+ else:
+ s = '-'
+ p = '-'
+ l = '-'
+ st = steps[k]
+ mt = method[k]
+ tmp = [n, o, s, p, l, st, mt, 'CRPS']
+ tmp.extend(crps[k])
+ ret.append(deepcopy(tmp))
+ tmp = [n, o, s, p, l, st, mt, 'TIME']
+ tmp.extend(times[k])
+ ret.append(deepcopy(tmp))
+ except Exception as ex:
+ print("Erro ao salvar ", k)
+ print("Exceção ", ex)
+ columns = probabilistic_dataframe_analytic_columns(experiments)
+ dat = pd.DataFrame(ret, columns=columns)
+ if save: dat.to_csv(Util.uniquefilename(file), sep=";")
+ return dat
+
+
+[docs]def probabilistic_dataframe_analytic_columns(experiments):
+ columns = [str(k) for k in np.arange(0, experiments)]
+ columns.insert(0, "Model")
+ columns.insert(1, "Order")
+ columns.insert(2, "Scheme")
+ columns.insert(3, "Partitions")
+ columns.insert(4, "Size")
+ columns.insert(5, "Steps")
+ columns.insert(6, "Method")
+ columns.insert(7, "Measure")
+ return columns
+
+
+[docs]def probabilistic_dataframe_synthetic_columns():
+ columns = ["Model", "Order", "Scheme", "Partitions","Size", "Steps", "Method", "CRPSAVG", "CRPSSTD",
+ "TIMEAVG", "TIMESTD"]
+ return columns
+
+
+[docs]def cast_dataframe_to_synthetic_probabilistic(df, data_columns):
+ crps1 = extract_measure(df, 'CRPS', data_columns)
+ times1 = extract_measure(df, 'TIME', data_columns)
+ ret = []
+ ret.append(np.round(np.nanmean(crps1), 2))
+ ret.append(np.round(np.nanstd(crps1), 2))
+ ret.append(np.round(np.nanmean(times1), 2))
+ ret.append(np.round(np.nanstd(times1), 2))
+ return ret
+
+
+[docs]def unified_scaled_probabilistic(experiments, tam, save=False, file=None,
+ sort_columns=['CRPSAVG', 'CRPSSTD'],
+ sort_ascend=[True, True], save_best=False,
+ ignore=None, replace=None):
+ fig, axes = plt.subplots(nrows=1, ncols=1, figsize=tam)
+
+ axes.set_title('CRPS')
+ #axes[1].set_title('CRPS Distribution Ahead')
+
+ models = {}
+
+ for experiment in experiments:
+
+ print(experiment)
+
+ mdl = {}
+
+ dat_syn = pd.read_csv(experiment[0], sep=";", usecols=probabilistic_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(experiment[1], sep=";", usecols=probabilistic_dataframe_analytic_columns(experiment[2]))
+
+ crps1 = []
+ crps2 = []
+
+ data_columns = analytical_data_columns(experiment[2])
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+
+ if b not in models:
+ models[b] = {}
+ models[b]['crps1'] = []
+ models[b]['crps2'] = []
+
+ if b not in mdl:
+ mdl[b] = {}
+ mdl[b]['crps1'] = []
+ mdl[b]['crps2'] = []
+
+ best = bests[b]
+
+ print(best)
+
+ tmp = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ tmpl = extract_measure(tmp, 'CRPS_Interval', data_columns)
+ mdl[b]['crps1'].extend(tmpl)
+ crps1.extend(tmpl)
+ tmpl = extract_measure(tmp, 'CRPS_Distribution', data_columns)
+ mdl[b]['crps2'].extend(tmpl)
+ crps2.extend(tmpl)
+
+ models[b]['label'] = check_replace_list(best["Model"] + " " + str(best["Order"]), replace)
+
+ crps1_param = scale_params(crps1)
+ crps2_param = scale_params(crps2)
+
+ for key in sorted(mdl.keys()):
+ print(key)
+ models[key]['crps1'].extend(scale(mdl[key]['crps1'], crps1_param))
+ models[key]['crps2'].extend(scale(mdl[key]['crps2'], crps2_param))
+
+ crps1 = []
+ crps2 = []
+ labels = []
+ for key in sorted(models.keys()):
+ crps1.append(models[key]['crps1'])
+ crps2.append(models[key]['crps2'])
+ labels.append(models[key]['label'])
+
+ axes[0].boxplot(crps1, labels=labels, autorange=True, showmeans=True)
+ axes[1].boxplot(crps2, labels=labels, autorange=True, showmeans=True)
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+
+[docs]def plot_dataframe_probabilistic(file_synthetic, file_analytic, experiments, tam, save=False, file=None,
+ sort_columns=['CRPS1AVG', 'CRPS2AVG', 'CRPS1STD', 'CRPS2STD'],
+ sort_ascend=[True, True, True, True], save_best=False,
+ ignore=None, replace=None):
+
+ fig, axes = plt.subplots(nrows=2, ncols=1, figsize=tam)
+
+ axes[0].set_title('CRPS')
+ axes[1].set_title('CRPS')
+
+ dat_syn = pd.read_csv(file_synthetic, sep=";", usecols=probabilistic_dataframe_synthetic_columns())
+
+ bests = find_best(dat_syn, sort_columns, sort_ascend)
+
+ dat_ana = pd.read_csv(file_analytic, sep=";", usecols=probabilistic_dataframe_analytic_columns(experiments))
+
+ data_columns = analytical_data_columns(experiments)
+
+ if save_best:
+ dat = pd.DataFrame.from_dict(bests, orient='index')
+ dat.to_csv(Util.uniquefilename(file_synthetic.replace("synthetic","best")), sep=";", index=False)
+
+ crps1 = []
+ crps2 = []
+ labels = []
+
+ for b in sorted(bests.keys()):
+ if check_ignore_list(b, ignore):
+ continue
+ best = bests[b]
+ df = dat_ana[(dat_ana.Model == best["Model"]) & (dat_ana.Order == best["Order"])
+ & (dat_ana.Scheme == best["Scheme"]) & (dat_ana.Partitions == best["Partitions"])]
+ crps1.append( extract_measure(df,'CRPS_Interval',data_columns) )
+ crps2.append(extract_measure(df, 'CRPS_Distribution', data_columns))
+ labels.append(check_replace_list(best["Model"] + " " + str(best["Order"]), replace))
+
+ axes[0].boxplot(crps1, labels=labels, autorange=True, showmeans=True)
+ axes[1].boxplot(crps2, labels=labels, autorange=True, showmeans=True)
+
+ plt.tight_layout()
+ Util.show_and_save_image(fig, file, save)
+
+
Source code for pyFTS.benchmarks.arima
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+import numpy as np
+import pandas as pd
+from statsmodels.tsa.arima_model import ARIMA as stats_arima
+import scipy.stats as st
+from pyFTS.common import SortedCollection, fts
+from pyFTS.probabilistic import ProbabilityDistribution
+
+
+[docs]class ARIMA(fts.FTS):
+ """
+ Façade for statsmodels.tsa.arima_model
+ """
+ def __init__(self, **kwargs):
+ super(ARIMA, self).__init__(**kwargs)
+ self.name = "ARIMA"
+ self.detail = "Auto Regressive Integrated Moving Average"
+ self.is_high_order = True
+ self.has_point_forecasting = True
+ self.has_interval_forecasting = True
+ self.has_probability_forecasting = True
+ self.uod_clip = False
+ self.model = None
+ self.model_fit = None
+ self.trained_data = None
+ self.p = 1
+ self.d = 0
+ self.q = 0
+ self.benchmark_only = True
+ self.min_order = 1
+ self.alpha = kwargs.get("alpha", 0.05)
+ self.order = kwargs.get("order", (1,0,0))
+ self._decompose_order(self.order)
+
+ def _decompose_order(self, order):
+ if isinstance(order, (tuple, set, list)):
+ self.p = order[0]
+ self.d = order[1]
+ self.q = order[2]
+ self.order = self.p + self.q + (self.q - 1 if self.q > 0 else 0)
+ self.max_lag = self.order
+ self.d = len(self.transformations)
+ self.shortname = "ARIMA({},{},{})-{}".format(self.p, self.d, self.q, self.alpha)
+
+[docs] def train(self, data, **kwargs):
+
+ if 'order' in kwargs:
+ order = kwargs.pop('order')
+ self._decompose_order(order)
+
+ if self.indexer is not None:
+ data = self.indexer.get_data(data)
+
+ try:
+ self.model = stats_arima(data, order=(self.p, self.d, self.q))
+ self.model_fit = self.model.fit(disp=0)
+ except Exception as ex:
+ print(ex)
+ self.model_fit = None
+
+
+
+
+
+[docs] def forecast(self, ndata, **kwargs):
+ if self.model_fit is None:
+ return np.nan
+
+ ndata = np.array(ndata)
+
+ l = len(ndata)
+
+ ret = []
+
+ ar = np.array([self.ar(ndata[k - self.p: k]) for k in np.arange(self.p, l+1)]) #+1 to forecast one step ahead given all available lags
+
+ if self.q > 0:
+ residuals = ndata[self.p-1:] - ar
+
+ ma = np.array([self.ma(residuals[k - self.q: k]) for k in np.arange(self.q, len(residuals) + 1)])
+
+ ret = ar[self.q - 1:] + ma
+ ret = ret[self.q:]
+ else:
+ ret = ar
+
+ #ret = self.apply_inverse_transformations(ret, params=[data[self.order - 1:]]) nforecasts = np.array(forecasts)
+
+ return ret
+
+[docs] def forecast_interval(self, data, **kwargs):
+
+ if self.model_fit is None:
+ return np.nan
+
+ if 'alpha' in kwargs:
+ alpha = kwargs.get('alpha',0.05)
+ else:
+ alpha = self.alpha
+
+ sigma = np.sqrt(self.model_fit.sigma2)
+
+ l = len(data)
+
+ ret = []
+
+ for k in np.arange(self.order, l+1):
+ tmp = []
+
+ sample = [data[i] for i in np.arange(k - self.order, k)]
+
+ mean = self.forecast(sample)
+
+ if isinstance(mean,(list, np.ndarray)):
+ mean = mean[0]
+
+ tmp.append(mean + st.norm.ppf(alpha) * sigma)
+ tmp.append(mean + st.norm.ppf(1 - alpha) * sigma)
+
+ ret.append(tmp)
+
+ return ret
+
+[docs] def forecast_ahead_interval(self, ndata, steps, **kwargs):
+ if self.model_fit is None:
+ return np.nan
+
+ if 'alpha' in kwargs:
+ alpha = kwargs.get('alpha',0.05)
+ else:
+ alpha = self.alpha
+
+ smoothing = kwargs.get("smoothing",0.5)
+
+ sigma = np.sqrt(self.model_fit.sigma2)
+
+ l = len(ndata)
+
+ nmeans = self.forecast_ahead(ndata, steps, **kwargs)
+
+ ret = []
+
+ for k in np.arange(0, steps):
+ tmp = []
+
+ hsigma = (1 + k*smoothing)*sigma
+
+ tmp.append(nmeans[k] + st.norm.ppf(alpha) * hsigma)
+ tmp.append(nmeans[k] + st.norm.ppf(1 - alpha) * hsigma)
+
+ ret.append(tmp)
+
+ return ret[-steps:]
+
+[docs] def forecast_distribution(self, data, **kwargs):
+
+ sigma = np.sqrt(self.model_fit.sigma2)
+
+ l = len(data)
+
+ ret = []
+
+ for k in np.arange(self.order, l + 1):
+ sample = [data[i] for i in np.arange(k - self.order, k)]
+
+ mean = self.forecast(sample)
+
+ if isinstance(mean, (list, np.ndarray)):
+ mean = mean[0]
+
+ dist = ProbabilityDistribution.ProbabilityDistribution(type="histogram", uod=[self.original_min, self.original_max])
+ intervals = []
+ for alpha in np.arange(0.05, 0.5, 0.05):
+
+ qt1 = mean + st.norm.ppf(alpha) * sigma
+ qt2 = mean + st.norm.ppf(1 - alpha) * sigma
+
+ intervals.append([qt1, qt2])
+
+ dist.append_interval(intervals)
+
+ ret.append(dist)
+
+ return ret
+
+
+[docs] def forecast_ahead_distribution(self, data, steps, **kwargs):
+ smoothing = kwargs.get("smoothing", 0.5)
+
+ sigma = np.sqrt(self.model_fit.sigma2)
+
+ l = len(data)
+
+ ret = []
+
+ nmeans = self.forecast_ahead(data, steps, **kwargs)
+
+ for k in np.arange(0, steps):
+ dist = ProbabilityDistribution.ProbabilityDistribution(type="histogram",
+ uod=[self.original_min, self.original_max])
+ intervals = []
+ for alpha in np.arange(0.05, 0.5, 0.05):
+ tmp = []
+
+ hsigma = (1 + k * smoothing) * sigma
+
+ tmp.append(nmeans[k] + st.norm.ppf(alpha) * hsigma)
+ tmp.append(nmeans[k] + st.norm.ppf(1 - alpha) * hsigma)
+
+ intervals.append(tmp)
+
+ dist.append_interval(intervals)
+
+ ret.append(dist)
+
+ return ret[-steps:]
+
+
Source code for pyFTS.benchmarks.benchmarks
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+"""Benchmarks methods for FTS methods"""
+
+
+import datetime
+import time
+from copy import deepcopy
+import traceback
+
+import matplotlib as plt
+
+import matplotlib.pyplot as plt
+import numpy as np
+from mpl_toolkits.mplot3d import Axes3D
+from itertools import product
+
+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
+from pyFTS.common import Util as cUtil
+# from sklearn.cross_validation import KFold
+from pyFTS.partitioners import Grid
+
+colors = ['grey', 'darkgrey', 'rosybrown', 'maroon', 'red','orange', 'gold', 'yellow', 'olive', 'green',
+ 'darkgreen', 'cyan', 'lightblue','blue', 'darkblue', 'purple', 'darkviolet' ]
+
+ncol = len(colors)
+
+styles = ['-','--','-.',':','.']
+
+nsty = len(styles)
+
+
+def __pop(key, default, kwargs):
+ if key in kwargs:
+ return kwargs.pop(key)
+ else:
+ return default
+
+
+[docs]def get_benchmark_point_methods():
+ """Return all non FTS methods for point forecasting"""
+ return [naive.Naive, arima.ARIMA, quantreg.QuantileRegression]
+
+
+[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, 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]
+
+
+[docs]def get_interval_methods():
+ """Return all FTS methods for point_to_interval forecasting"""
+ return [ifts.IntervalFTS, ifts.WeightedIntervalFTS, pwfts.ProbabilisticWeightedFTS]
+
+
+[docs]def get_probabilistic_methods():
+ """Return all FTS methods for probabilistic forecasting"""
+ return [ensemble.AllMethodEnsembleFTS, pwfts.ProbabilisticWeightedFTS]
+
+
+[docs]def get_benchmark_probabilistic_methods():
+ """Return all FTS methods for probabilistic forecasting"""
+ return [arima.ARIMA, quantreg.QuantileRegression, knn.KNearestNeighbors]
+
+
+[docs]def multivariate_sliding_window_benchmarks2(data, windowsize, train=0.8, **kwargs):
+ from pyFTS.models.multivariate import common, variable, mvfts
+
+ tag = __pop('tag', None, kwargs)
+ dataset = __pop('dataset', None, kwargs)
+
+ distributed = __pop('distributed', False, kwargs)
+
+ variables = __pop('variables', {}, kwargs)
+
+ target_variable = __pop('target_variable', '', kwargs)
+
+ type = kwargs.get("type", 'point')
+
+ steps_ahead = __pop('steps_ahead', [1], kwargs)
+
+ steps_ahead = [k for k in steps_ahead]
+
+ fts_methods = __pop('methods', [], kwargs)
+
+ if fts_methods is not None:
+ methods_parameters = __pop('methods_parameters', None, kwargs)
+
+ if type == 'point':
+ experiment_method = mv_run_point2
+ synthesis_method = process_point_jobs2
+ elif type == 'interval':
+ experiment_method = mv_run_interval2
+ synthesis_method = process_interval_jobs2
+ elif type == 'distribution':
+ experiment_method = mv_run_probabilistic2
+ synthesis_method = process_probabilistic_jobs2
+ else:
+ raise ValueError("Type parameter has a unkown value!")
+
+ if distributed:
+ import pyFTS.distributed.dispy as dispy
+
+ nodes = kwargs.get("nodes", ['127.0.0.1'])
+ cluster, http_server = dispy.start_dispy_cluster(experiment_method, nodes)
+
+ inc = __pop("inc", 0.1, kwargs)
+
+ file = kwargs.get('file', "benchmarks.db")
+
+ conn = bUtil.open_benchmark_db(file)
+
+ jobs = []
+ for ct, train, test in cUtil.sliding_window(data, windowsize, train, inc=inc, **kwargs):
+ for id, fts_method in enumerate(fts_methods):
+
+ kwargs['steps_ahead'] = max(steps_ahead)
+ parameters = {}
+ if methods_parameters is not None:
+ parameters = methods_parameters[id]
+
+ vars = []
+ tvar = None
+
+ for key, value in variables.items():
+ var = variable.Variable(key, data=train, **value)
+ vars.append(var)
+ if key == target_variable:
+ tvar = var
+
+
+ model = fts_method(explanatory_variables=vars, target_variable=tvar,
+ **parameters)
+
+ if not distributed:
+ try:
+ job = experiment_method(model, train, test, ct, **kwargs)
+ synthesis_method(dataset, tag, job, conn)
+ except Exception as ex:
+ print('EXCEPTION! ', fts_method)
+ traceback.print_exc()
+ else:
+ job = cluster.submit(model, train, test, ct, **kwargs)
+ job.id = id
+ jobs.append(job)
+
+ if distributed:
+ for job in jobs:
+ job()
+ if job.status == dispy.dispy.DispyJob.Finished and job is not None:
+ tmp = job.result
+ synthesis_method(dataset, tag, tmp, conn)
+ else:
+ print("status", job.status)
+ print("result", job.result)
+ print("stdout", job.stdout)
+ print("stderr", job.exception)
+
+ cluster.wait() # wait for all jobs to finish
+ dispy.stop_dispy_cluster(cluster, http_server)
+
+ conn.close()
+
+
+[docs]def sliding_window_benchmarks2(data, windowsize, train=0.8, **kwargs):
+ tag = __pop('tag', None, kwargs)
+ dataset = __pop('dataset', None, kwargs)
+
+ distributed = __pop('distributed', False, kwargs)
+
+ transformations = kwargs.get('transformations', [None])
+
+ type = kwargs.get("type", 'point')
+
+ orders = __pop("orders", [1, 2, 3], kwargs)
+
+ partitioners_methods = __pop("partitioners_methods", [Grid.GridPartitioner], kwargs)
+ partitions = __pop("partitions", [10], kwargs)
+
+ partitions = [k for k in partitions]
+
+ steps_ahead = __pop('steps_ahead', [1], kwargs)
+
+ steps_ahead = [k for k in steps_ahead]
+
+ fts_methods = __pop('methods', [], kwargs)
+
+ if fts_methods is not None:
+ methods_parameters = __pop('methods_parameters', None, kwargs)
+
+ ix_methods = [k for k in np.arange(len(fts_methods))]
+
+ benchmark_models = __pop("benchmark_models", False, kwargs)
+ benchmark_methods = __pop("benchmark_methods", None, kwargs)
+ benchmark_methods_parameters = __pop("benchmark_methods_parameters", None, kwargs)
+
+ if type == 'point':
+ experiment_method = run_point2
+ synthesis_method = process_point_jobs2
+ elif type == 'interval':
+ experiment_method = run_interval2
+ synthesis_method = process_interval_jobs2
+ elif type == 'distribution':
+ experiment_method = run_probabilistic2
+ synthesis_method = process_probabilistic_jobs2
+ else:
+ raise ValueError("Type parameter has a unkown value!")
+
+ if distributed:
+ import pyFTS.distributed.dispy as dispy
+
+ nodes = kwargs.get("nodes", ['127.0.0.1'])
+ cluster, http_server = dispy.start_dispy_cluster(experiment_method, nodes)
+
+ inc = __pop("inc", 0.1, kwargs)
+
+ file = kwargs.get('file', "benchmarks.db")
+
+ conn = bUtil.open_benchmark_db(file)
+
+ jobs = []
+ for ct, train, test in cUtil.sliding_window(data, windowsize, train, inc=inc, **kwargs):
+
+ if benchmark_models:
+ for bm, method in enumerate(benchmark_methods):
+ kwargs['steps_ahead'] = max(steps_ahead)
+ kwargs['parameters'] = benchmark_methods_parameters[bm]
+
+ if not distributed:
+ try:
+ job = experiment_method(method, None, None, None, None, train, test, ct, **kwargs)
+ synthesis_method(dataset, tag, job, conn)
+ except Exception as ex:
+ print('EXCEPTION! ', method, benchmark_methods_parameters[bm])
+ traceback.print_exc()
+ else:
+ job = cluster.submit(method, None, None, None, None, train, test, ct, **kwargs)
+ jobs.append(job)
+
+ if fts_methods is not None:
+ params = [ix_methods, orders, partitioners_methods, partitions, transformations]
+ for id, instance in enumerate(product(*params)):
+ fts_method = fts_methods[instance[0]]
+ kwargs['steps_ahead'] = max(steps_ahead)
+ if methods_parameters is not None:
+ kwargs['parameters'] = methods_parameters[instance[0]]
+ if not distributed:
+ try:
+ job = experiment_method(fts_method, instance[1], instance[2], instance[3], instance[4], train, test, ct, **kwargs)
+ synthesis_method(dataset, tag, job, conn)
+ except Exception as ex:
+ print('EXCEPTION! ', instance)
+ traceback.print_exc()
+ else:
+ job = cluster.submit(fts_method, instance[1], instance[2], instance[3], instance[4], train, test, ct, **kwargs)
+ job.id = id
+ jobs.append(job)
+
+ if distributed:
+ for job in jobs:
+ job()
+ if job.status == dispy.dispy.DispyJob.Finished and job is not None:
+ tmp = job.result
+ synthesis_method(dataset, tag, tmp, conn)
+ else:
+ print("status", job.status)
+ print("result", job.result)
+ print("stdout", job.stdout)
+ print("stderr", job.exception)
+
+ cluster.wait() # wait for all jobs to finish
+ dispy.stop_dispy_cluster(cluster, http_server)
+
+ conn.close()
+
+
+[docs]def sliding_window_benchmarks(data, windowsize, train=0.8, **kwargs):
+ """
+ Sliding window benchmarks for FTS forecasters.
+
+ For each data window, a train and test datasets will be splitted. For each train split, number of
+ partitions and partitioning method will be created a partitioner model. And for each partitioner, order,
+ steps ahead and FTS method a foreasting model will be trained.
+
+ Then all trained models are benchmarked on the test data and the metrics are stored on a sqlite3 database
+ (identified by the 'file' parameter) for posterior analysis.
+
+ All these process can be distributed on a dispy cluster, setting the atributed 'distributed' to true and
+ informing the list of dispy nodes on 'nodes' parameter.
+
+ The number of experiments is determined by 'windowsize' and 'inc' parameters.
+
+ :param data: test data
+ :param windowsize: size of sliding window
+ :param train: percentual of sliding window data used to train the models
+ :param kwargs: dict, optional arguments
+
+ :keyword benchmark_methods: a list with Non FTS models to benchmark. The default is None.
+ :keyword benchmark_methods_parameters: a list with Non FTS models parameters. The default is None.
+ :keyword benchmark_models: A boolean value indicating if external FTS methods will be used on benchmark. The default is False.
+ :keyword build_methods: A boolean value indicating if the default FTS methods will be used on benchmark. The default is True.
+ :keyword dataset: the dataset name to identify the current set of benchmarks results on database.
+ :keyword distributed: A boolean value indicating if the forecasting procedure will be distributed in a dispy cluster. . The default is False
+ :keyword file: file path to save the results. The default is benchmarks.db.
+ :keyword inc: a float on interval [0,1] indicating the percentage of the windowsize to move the window
+ :keyword methods: a list with FTS class names. The default depends on the forecasting type and contains the list of all FTS methods.
+ :keyword models: a list with prebuilt FTS objects. The default is None.
+ :keyword nodes: a list with the dispy cluster nodes addresses. The default is [127.0.0.1].
+ :keyword orders: a list with orders of the models (for high order models). The default is [1,2,3].
+ :keyword partitions: a list with the numbers of partitions on the Universe of Discourse. The default is [10].
+ :keyword partitioners_models: a list with prebuilt Universe of Discourse partitioners objects. The default is None.
+ :keyword partitioners_methods: a list with Universe of Discourse partitioners class names. The default is [partitioners.Grid.GridPartitioner].
+ :keyword progress: If true a progress bar will be displayed during the benchmarks. The default is False.
+ :keyword start: in the multi step forecasting, the index of the data where to start forecasting. The default is 0.
+ :keyword steps_ahead: a list with the forecasting horizons, i. e., the number of steps ahead to forecast. The default is 1.
+ :keyword tag: a name to identify the current set of benchmarks results on database.
+ :keyword type: the forecasting type, one of these values: point(default), interval or distribution. The default is point.
+ :keyword transformations: a list with data transformations do apply . The default is [None].
+ """
+
+ tag = __pop('tag', None, kwargs)
+ dataset = __pop('dataset', None, kwargs)
+
+ distributed = __pop('distributed', False, kwargs)
+
+ transformations = kwargs.get('transformations', [None])
+ progress = kwargs.get('progress', None)
+ type = kwargs.get("type", 'point')
+
+ orders = __pop("orders", [1,2,3], kwargs)
+
+ partitioners_models = __pop("partitioners_models", None, kwargs)
+ partitioners_methods = __pop("partitioners_methods", [Grid.GridPartitioner], kwargs)
+ partitions = __pop("partitions", [10], kwargs)
+
+ steps_ahead = __pop('steps_ahead', [1], kwargs)
+
+ methods = __pop('methods', None, kwargs)
+
+ models = __pop('models', None, kwargs)
+
+ pool = [] if models is None else models
+
+ if methods is None:
+ if type == 'point':
+ methods = get_point_methods()
+ elif type == 'interval':
+ methods = get_interval_methods()
+ elif type == 'distribution':
+ methods = get_probabilistic_methods()
+
+ build_methods = __pop("build_methods", True, kwargs)
+
+ if build_methods:
+ for method in methods:
+ mfts = method()
+
+ if mfts.is_high_order:
+ for order in orders:
+ if order >= mfts.min_order:
+ mfts = method()
+ mfts.order = order
+ pool.append(mfts)
+ else:
+ mfts.order = 1
+ pool.append(mfts)
+
+ benchmark_models = __pop("benchmark_models", False, kwargs)
+
+ if benchmark_models != False:
+
+ benchmark_methods = __pop("benchmark_methods", None, kwargs)
+ benchmark_methods_parameters = __pop("benchmark_methods_parameters", None, kwargs)
+
+ benchmark_pool = [] if ( benchmark_models is None or not isinstance(benchmark_models, list)) \
+ else benchmark_models
+
+ if benchmark_models is None and benchmark_methods is None:
+ if type == 'point'or type == 'partition':
+ benchmark_methods = get_benchmark_point_methods()
+ elif type == 'interval':
+ benchmark_methods = get_benchmark_interval_methods()
+ elif type == 'distribution':
+ benchmark_methods = get_benchmark_probabilistic_methods()
+
+ if benchmark_methods is not None:
+ for transformation in transformations:
+ for count, model in enumerate(benchmark_methods, start=0):
+ par = benchmark_methods_parameters[count]
+ mfts = model(**par)
+ mfts.append_transformation(transformation)
+ benchmark_pool.append(mfts)
+
+ if type == 'point':
+ experiment_method = run_point
+ synthesis_method = process_point_jobs
+ elif type == 'interval':
+ experiment_method = run_interval
+ synthesis_method = process_interval_jobs
+ elif type == 'distribution':
+ experiment_method = run_probabilistic
+ synthesis_method = process_probabilistic_jobs
+ else:
+ raise ValueError("Type parameter has a unkown value!")
+
+ if distributed:
+ import pyFTS.distributed.dispy as dispy
+
+ nodes = kwargs.get("nodes", ['127.0.0.1'])
+ cluster, http_server = dispy.start_dispy_cluster(experiment_method, nodes)
+
+ jobs = []
+
+ inc = __pop("inc", 0.1, kwargs)
+
+ if progress:
+ from tqdm import tqdm
+ _tdata = len(data) / (windowsize * inc)
+ _tasks = (len(partitioners_models) * len(orders) * len(partitions) * len(transformations) * len(steps_ahead))
+ _tbcmk = len(benchmark_pool)*len(steps_ahead)
+ progressbar = tqdm(total=_tdata*_tasks + _tdata*_tbcmk, desc="Benchmarks:")
+
+ file = kwargs.get('file', "benchmarks.db")
+
+ conn = bUtil.open_benchmark_db(file)
+
+ for ct, train, test in cUtil.sliding_window(data, windowsize, train, inc=inc, **kwargs):
+ if benchmark_models != False:
+ for model in benchmark_pool:
+ for step in steps_ahead:
+
+ kwargs['steps_ahead'] = step
+
+ if not distributed:
+ if progress:
+ progressbar.update(1)
+ try:
+ job = experiment_method(deepcopy(model), None, train, test, **kwargs)
+ synthesis_method(dataset, tag, job, conn)
+ except Exception as ex:
+ print('EXCEPTION! ', model.shortname, model.order)
+ traceback.print_exc()
+ else:
+ job = cluster.submit(deepcopy(model), None, train, test, **kwargs)
+ jobs.append(job)
+
+ partitioners_pool = []
+
+ if partitioners_models is None:
+
+ for transformation in transformations:
+
+ for partition in partitions:
+
+ for partitioner in partitioners_methods:
+
+ data_train_fs = partitioner(data=train, npart=partition, transformation=transformation)
+
+ partitioners_pool.append(data_train_fs)
+ else:
+ partitioners_pool = partitioners_models
+
+ for step in steps_ahead:
+
+ for partitioner in partitioners_pool:
+
+ for _id, model in enumerate(pool,start=0):
+
+ kwargs['steps_ahead'] = step
+
+ if not distributed:
+ if progress:
+ progressbar.update(1)
+ try:
+ job = experiment_method(deepcopy(model), deepcopy(partitioner), train, test, **kwargs)
+ synthesis_method(dataset, tag, job, conn)
+ except Exception as ex:
+ print('EXCEPTION! ',model.shortname, model.order, partitioner.name,
+ partitioner.partitions, str(partitioner.transformation))
+ traceback.print_exc()
+ else:
+ job = cluster.submit(deepcopy(model), deepcopy(partitioner), train, test, **kwargs)
+ job.id = id # associate an ID to identify jobs (if needed later)
+ jobs.append(job)
+
+ if progress:
+ progressbar.close()
+
+ if distributed:
+
+ for job in jobs:
+ if progress:
+ progressbar.update(1)
+ job()
+ if job.status == dispy.dispy.DispyJob.Finished and job is not None:
+ tmp = job.result
+ synthesis_method(dataset, tag, tmp, conn)
+ else:
+ print("status",job.status)
+ print("result",job.result)
+ print("stdout",job.stdout)
+ print("stderr",job.exception)
+
+ cluster.wait() # wait for all jobs to finish
+
+ dispy.stop_dispy_cluster(cluster, http_server)
+
+ conn.close()
+
+
+[docs]def run_point(mfts, partitioner, train_data, test_data, window_key=None, **kwargs):
+ """
+ Run the point forecasting benchmarks
+
+ :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.models import yu, chen, hofts, pwfts,ismailefendi,sadaei, song, cheng, hwang
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, naive, arima, quantreg
+ from pyFTS.common import Transformations
+
+ tmp = [song.ConventionalFTS, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS,
+ cheng.TrendWeightedFTS, sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, hwang.HighOrderFTS,
+ pwfts.ProbabilisticWeightedFTS]
+
+ tmp2 = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner]
+
+ tmp4 = [naive.Naive, arima.ARIMA, quantreg.QuantileRegression]
+
+ tmp3 = [Measures.get_point_statistics]
+
+ tmp5 = [Transformations.Differential]
+
+ indexer = kwargs.get('indexer', None)
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+
+ if mfts.benchmark_only:
+ _key = mfts.shortname + str(mfts.order if mfts.order is not None else "")
+ else:
+ pttr = str(partitioner.__module__).split('.')[-1]
+ _key = mfts.shortname + " n = " + str(mfts.order) + " " + pttr + " q = " + str(partitioner.partitions)
+ mfts.partitioner = partitioner
+ mfts.append_transformation(partitioner.transformation)
+
+ _key += str(steps_ahead)
+ _key += str(method) if method is not None else ""
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+
+ _start = time.time()
+ _rmse, _smape, _u = Measures.get_point_statistics(test_data, mfts, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ ret = {'key': _key, 'obj': mfts, 'rmse': _rmse, 'smape': _smape, 'u': _u, 'time': times, 'window': window_key,
+ 'steps': steps_ahead, 'method': method}
+
+ return ret
+
+
+[docs]def run_interval(mfts, partitioner, train_data, test_data, window_key=None, **kwargs):
+ """
+ Run the interval forecasting benchmarks
+
+ :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.models import hofts,ifts,pwfts
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, arima, quantreg
+
+ tmp = [hofts.HighOrderFTS, ifts.IntervalFTS, pwfts.ProbabilisticWeightedFTS]
+
+ tmp2 = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner]
+
+ tmp4 = [arima.ARIMA, quantreg.QuantileRegression]
+
+ tmp3 = [Measures.get_interval_statistics]
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+
+ if mfts.benchmark_only:
+ _key = mfts.shortname + str(mfts.order if mfts.order is not None else "") + str(mfts.alpha)
+ else:
+ pttr = str(partitioner.__module__).split('.')[-1]
+ _key = mfts.shortname + " n = " + str(mfts.order) + " " + pttr + " q = " + str(partitioner.partitions)
+ mfts.partitioner = partitioner
+ mfts.append_transformation(partitioner.transformation)
+
+ _key += str(steps_ahead)
+ _key += str(method) if method is not None else ""
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ _start = time.time()
+ #_sharp, _res, _cov, _q05, _q25, _q75, _q95, _w05, _w25
+ metrics = Measures.get_interval_statistics(test_data, mfts, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ ret = {'key': _key, 'obj': mfts, 'sharpness': metrics[0], 'resolution': metrics[1], 'coverage': metrics[2],
+ 'time': times,'Q05': metrics[3], 'Q25': metrics[4], 'Q75': metrics[5], 'Q95': metrics[6],
+ 'winkler05': metrics[7], 'winkler25': metrics[8],
+ 'window': window_key,'steps': steps_ahead, 'method': method}
+
+ return ret
+
+
+[docs]def run_probabilistic(mfts, partitioner, train_data, test_data, window_key=None, **kwargs):
+ """
+ Run the probabilistic forecasting benchmarks
+
+ :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 steps:
+ :param resolution:
+ :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
+ import numpy as np
+ from pyFTS.models import hofts, ifts, pwfts
+ from pyFTS.models.ensemble import ensemble
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, arima, quantreg, knn
+ from pyFTS.models.seasonal import SeasonalIndexer
+
+ tmp = [hofts.HighOrderFTS, ifts.IntervalFTS, pwfts.ProbabilisticWeightedFTS, arima.ARIMA,
+ ensemble.AllMethodEnsembleFTS, knn.KNearestNeighbors]
+
+ tmp2 = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner]
+
+ tmp3 = [Measures.get_distribution_statistics, SeasonalIndexer.SeasonalIndexer, SeasonalIndexer.LinearSeasonalIndexer]
+
+ indexer = kwargs.get('indexer', None)
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+
+ if mfts.benchmark_only:
+ _key = mfts.shortname + str(mfts.order if mfts.order is not None else "") + str(mfts.alpha)
+ else:
+ pttr = str(partitioner.__module__).split('.')[-1]
+ _key = mfts.shortname + " n = " + str(mfts.order) + " " + pttr + " q = " + str(partitioner.partitions)
+ mfts.partitioner = partitioner
+ mfts.append_transformation(partitioner.transformation)
+
+ _key += str(steps_ahead)
+ _key += str(method) if method is not None else ""
+
+ if mfts.has_seasonality:
+ mfts.indexer = indexer
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ _crps1, _t1, _brier = Measures.get_distribution_statistics(test_data, mfts, **kwargs)
+ _t1 += times
+
+ ret = {'key': _key, 'obj': mfts, 'crps': _crps1, 'time': _t1, 'brier': _brier, 'window': window_key,
+ 'steps': steps_ahead, 'method': method}
+
+ return ret
+
+
+def __build_model(fts_method, order, parameters, partitioner_method, partitions, train_data, transformation):
+ mfts = fts_method(**parameters)
+ if mfts.benchmark_only or mfts.is_wrapper:
+ pttr = ''
+ else:
+ fs = partitioner_method(npart=partitions, data=train_data, transformation=transformation)
+ pttr = str(fs.__module__).split('.')[-1]
+ if order > 1:
+ mfts = fts_method(partitioner=fs, order=order, **parameters)
+ else:
+ mfts.partitioner = fs
+
+ if transformation is not None:
+ mfts.append_transformation(transformation)
+ return mfts, pttr
+
+
+[docs]def mv_run_point2(mfts, train_data, test_data, window_key=None, **kwargs):
+ import time
+ from pyFTS.models import hofts, ifts, pwfts
+ from pyFTS.models.multivariate import mvfts, wmvfts, granular
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, arima, quantreg, BSTS, benchmarks
+
+ tmp = [hofts.HighOrderFTS, ifts.IntervalFTS, ifts.WeightedIntervalFTS, pwfts.ProbabilisticWeightedFTS]
+
+ tmp2 = [Grid.GridPartitioner, mvfts.MVFTS, wmvfts.WeightedMVFTS, granular.GranularWMVFTS]
+
+ tmp4 = [arima.ARIMA, quantreg.QuantileRegression, BSTS.ARIMA]
+
+ tmp3 = [Measures.get_interval_statistics]
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ if steps_ahead == 1:
+
+ _start = time.time()
+ _rmse, _smape, _u = Measures.get_point_statistics(test_data, mfts, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ ret = {'model': mfts.shortname, 'partitioner': None, 'order': mfts.order, 'partitions': None,
+ 'transformation': None,
+ 'size': len(mfts), 'time': times,
+ 'rmse': _rmse, 'smape': _smape, 'u': _u, 'window': window_key,
+ 'steps': steps_ahead, 'method': method}
+ else:
+ _start = time.time()
+ forecasts = mfts.predict(test_data, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ tmp_test = test_data[mfts.target_variable.data_label].values[mfts.order:mfts.order + steps_ahead]
+
+ eval = Measures.get_point_ahead_statistics(tmp_test, forecasts)
+
+ for key in eval.keys():
+ eval[key]["time"] = times
+ eval[key]["method"] = method
+
+ ret = {'model': mfts.shortname, 'partitioner': None, 'order': mfts.order, 'partitions': None,
+ 'transformation': None,
+ 'size': len(mfts), 'time': times,
+ 'window': window_key, 'steps': steps_ahead, 'method': method,
+ 'ahead_results': eval
+ }
+
+ return ret
+
+
+[docs]def run_point2(fts_method, order, partitioner_method, partitions, transformation, train_data, test_data, window_key=None, **kwargs):
+
+ import time
+ from pyFTS.models import yu, chen, hofts, pwfts,ismailefendi,sadaei, song, cheng, hwang
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, naive, arima, quantreg, benchmarks
+ from pyFTS.common import Transformations
+
+ tmp = [song.ConventionalFTS, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS,
+ cheng.TrendWeightedFTS, sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, hwang.HighOrderFTS,
+ pwfts.ProbabilisticWeightedFTS]
+
+ tmp2 = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner]
+
+ tmp4 = [naive.Naive, arima.ARIMA, quantreg.QuantileRegression]
+
+ tmp3 = [Measures.get_point_statistics]
+
+ tmp5 = [Transformations.Differential]
+
+ indexer = kwargs.get('indexer', None)
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+ parameters = kwargs.get('parameters', {})
+
+ mfts, pttr = benchmarks.__build_model(fts_method, order, parameters, partitioner_method, partitions, train_data,
+ transformation)
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ if steps_ahead == 1:
+
+ _start = time.time()
+ _rmse, _smape, _u = Measures.get_point_statistics(test_data, mfts, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ ret = {'model': mfts.shortname, 'partitioner': pttr, 'order': order, 'partitions': partitions,
+ 'transformation': '' if transformation is None else transformation.name,
+ 'size': len(mfts), 'time': times,
+ 'rmse': _rmse, 'smape': _smape, 'u': _u, 'window': window_key,
+ 'steps': steps_ahead, 'method': method}
+ else:
+ _start = time.time()
+ forecasts = mfts.predict(test_data, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ eval = Measures.get_point_ahead_statistics(test_data[mfts.order:mfts.order+steps_ahead], forecasts)
+
+ for key in eval.keys():
+ eval[key]["time"] = times
+ eval[key]["method"] = method
+
+ ret = {'model': mfts.shortname, 'partitioner': pttr, 'order': order, 'partitions': partitions,
+ 'transformation': '' if transformation is None else transformation.name,
+ 'size': len(mfts), 'time': times,
+ 'window': window_key, 'steps': steps_ahead, 'method': method,
+ 'ahead_results': eval
+ }
+
+ return ret
+
+
+[docs]def mv_run_interval2(mfts,train_data, test_data, window_key=None, **kwargs):
+ import time
+ from pyFTS.models import hofts,ifts,pwfts
+ from pyFTS.models.multivariate import mvfts, wmvfts, granular
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, arima, quantreg, BSTS, benchmarks
+
+ tmp = [hofts.HighOrderFTS, ifts.IntervalFTS, ifts.WeightedIntervalFTS, pwfts.ProbabilisticWeightedFTS]
+
+ tmp2 = [Grid.GridPartitioner, mvfts.MVFTS, wmvfts.WeightedMVFTS, granular.GranularWMVFTS ]
+
+ tmp4 = [arima.ARIMA, quantreg.QuantileRegression, BSTS.ARIMA]
+
+ tmp3 = [Measures.get_interval_statistics]
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+ parameters = kwargs.get('parameters',{})
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ if steps_ahead == 1:
+
+ _start = time.time()
+ metrics = Measures.get_interval_statistics(test_data, mfts, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ ret = {'model': mfts.shortname, 'partitioner': None, 'order': mfts.order, 'partitions': None,
+ 'transformation': None,
+ 'size': len(mfts), 'time': times,
+ 'sharpness': metrics[0], 'resolution': metrics[1], 'coverage': metrics[2],
+ 'time': times,'pinball05': metrics[3], 'pinball25': metrics[4], 'pinball75': metrics[5], 'pinball95': metrics[6],
+ 'winkler05': metrics[7], 'winkler25': metrics[8],
+ 'window': window_key,'steps': steps_ahead, 'method': method}
+ else:
+ _start = time.time()
+ intervals = mfts.predict(test_data, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ tmp_test = test_data[mfts.target_variable.data_label].values[mfts.order:mfts.order + steps_ahead]
+
+ eval = Measures.get_interval_ahead_statistics(tmp_test, intervals)
+
+ for key in eval.keys():
+ eval[key]["time"] = times
+ eval[key]["method"] = method
+
+ ret = {'model': mfts.shortname, 'partitioner': None, 'order': mfts.order, 'partitions': None,
+ 'transformation': None,
+ 'size': len(mfts), 'time': times,
+ 'window': window_key, 'steps': steps_ahead, 'method': method,
+ 'ahead_results': eval
+ }
+
+
+ return ret
+
+
+[docs]def run_interval2(fts_method, order, partitioner_method, partitions, transformation, train_data, test_data, window_key=None, **kwargs):
+ import time
+ from pyFTS.models import hofts,ifts,pwfts
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, arima, quantreg, BSTS, benchmarks
+
+ tmp = [hofts.HighOrderFTS, ifts.IntervalFTS, ifts.WeightedIntervalFTS, pwfts.ProbabilisticWeightedFTS]
+
+ tmp2 = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner]
+
+ tmp4 = [arima.ARIMA, quantreg.QuantileRegression, BSTS.ARIMA]
+
+ tmp3 = [Measures.get_interval_statistics]
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+ parameters = kwargs.get('parameters',{})
+
+ mfts, pttr = benchmarks.__build_model(fts_method, order, parameters, partitioner_method, partitions, train_data,
+ transformation)
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ if steps_ahead == 1:
+
+ _start = time.time()
+ metrics = Measures.get_interval_statistics(test_data, mfts, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ ret = {'model': mfts.shortname, 'partitioner': pttr, 'order': order, 'partitions': partitions,
+ 'transformation': '' if transformation is None else transformation.name,
+ 'size': len(mfts), 'time': times,
+ 'sharpness': metrics[0], 'resolution': metrics[1], 'coverage': metrics[2],
+ 'time': times,'pinball05': metrics[3], 'pinball25': metrics[4], 'pinball75': metrics[5], 'pinball95': metrics[6],
+ 'winkler05': metrics[7], 'winkler25': metrics[8],
+ 'window': window_key,'steps': steps_ahead, 'method': method}
+ else:
+ _start = time.time()
+ intervals = mfts.predict(test_data, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ eval = Measures.get_interval_ahead_statistics(test_data[mfts.order:mfts.order+steps_ahead], intervals)
+
+ for key in eval.keys():
+ eval[key]["time"] = times
+ eval[key]["method"] = method
+
+ ret = {'model': mfts.shortname, 'partitioner': pttr, 'order': order, 'partitions': partitions,
+ 'transformation': '' if transformation is None else transformation.name,
+ 'size': len(mfts), 'time': times,
+ 'window': window_key, 'steps': steps_ahead, 'method': method,
+ 'ahead_results': eval
+ }
+
+
+ return ret
+
+
+[docs]def mv_run_probabilistic2(mfts, train_data, test_data, window_key=None, **kwargs):
+ import time
+ from pyFTS.models import hofts, ifts, pwfts
+ from pyFTS.models.multivariate import mvfts, wmvfts, granular
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, arima, quantreg, BSTS, benchmarks
+
+ tmp = [hofts.HighOrderFTS, ifts.IntervalFTS, ifts.WeightedIntervalFTS, pwfts.ProbabilisticWeightedFTS]
+
+ tmp2 = [Grid.GridPartitioner, mvfts.MVFTS, wmvfts.WeightedMVFTS, granular.GranularWMVFTS]
+
+ tmp4 = [arima.ARIMA, quantreg.QuantileRegression, BSTS.ARIMA]
+
+ tmp3 = [Measures.get_interval_statistics]
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+ parameters = kwargs.get('parameters', {})
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ if steps_ahead == 1:
+
+ _crps1, _t1, _brier = Measures.get_distribution_statistics(test_data, mfts, **kwargs)
+ times += _t1
+
+ ret = {'model': mfts.shortname, 'partitioner': None, 'order': mfts.order, 'partitions': None,
+ 'transformation': None,
+ 'size': len(mfts), 'time': times,
+ 'crps': _crps1, 'brier': _brier, 'window': window_key,
+ 'steps': steps_ahead, 'method': method}
+ else:
+ _start = time.time()
+ distributions = mfts.predict(test_data, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ tmp_test = test_data[mfts.target_variable.data_label].values[mfts.order:mfts.order + steps_ahead]
+
+ eval = Measures.get_distribution_ahead_statistics(tmp_test, distributions)
+
+ for key in eval.keys():
+ eval[key]["time"] = times
+ eval[key]["method"] = method
+
+ ret = {'model': mfts.shortname, 'partitioner': None, 'order': mfts.order, 'partitions': None,
+ 'transformation': None,
+ 'size': len(mfts), 'time': times,
+ 'window': window_key, 'steps': steps_ahead, 'method': method,
+ 'ahead_results': eval
+ }
+
+ return ret
+
+
+
+[docs]def run_probabilistic2(fts_method, order, partitioner_method, partitions, transformation, train_data, test_data, window_key=None, **kwargs):
+ import time
+ import numpy as np
+ from pyFTS.models import hofts, ifts, pwfts
+ from pyFTS.models.ensemble import ensemble
+ from pyFTS.partitioners import Grid, Entropy, FCM
+ from pyFTS.benchmarks import Measures, arima, quantreg, knn, benchmarks
+ from pyFTS.models.seasonal import SeasonalIndexer
+
+ tmp = [hofts.HighOrderFTS, ifts.IntervalFTS, pwfts.ProbabilisticWeightedFTS, arima.ARIMA,
+ ensemble.AllMethodEnsembleFTS, knn.KNearestNeighbors]
+
+ tmp2 = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner]
+
+ tmp3 = [Measures.get_distribution_statistics, SeasonalIndexer.SeasonalIndexer, SeasonalIndexer.LinearSeasonalIndexer]
+
+ indexer = kwargs.get('indexer', None)
+
+ steps_ahead = kwargs.get('steps_ahead', 1)
+ method = kwargs.get('method', None)
+ parameters = kwargs.get('parameters', {})
+
+ mfts, pttr = benchmarks.__build_model(fts_method, order, parameters, partitioner_method, partitions, train_data,
+ transformation)
+ if mfts.has_seasonality:
+ mfts.indexer = indexer
+
+ _start = time.time()
+ mfts.fit(train_data, **kwargs)
+ _end = time.time()
+ times = _end - _start
+
+ if steps_ahead == 1:
+
+ _crps1, _t1, _brier = Measures.get_distribution_statistics(test_data, mfts, **kwargs)
+ times += _t1
+
+ ret = {'model': mfts.shortname, 'partitioner': pttr, 'order': order, 'partitions': partitions,
+ 'transformation': '' if transformation is None else transformation.name,
+ 'size': len(mfts), 'time': times,
+ 'crps': _crps1, 'brier': _brier, 'window': window_key,
+ 'steps': steps_ahead, 'method': method}
+ else:
+ _start = time.time()
+ distributions = mfts.predict(test_data, **kwargs)
+ _end = time.time()
+ times += _end - _start
+
+ eval = Measures.get_distribution_ahead_statistics(test_data[mfts.order:mfts.order+steps_ahead], distributions)
+
+ for key in eval.keys():
+ eval[key]["time"] = times
+ eval[key]["method"] = method
+
+ ret = {'model': mfts.shortname, 'partitioner': pttr, 'order': order, 'partitions': partitions,
+ 'transformation': '' if transformation is None else transformation.name,
+ 'size': len(mfts), 'time': times,
+ 'window': window_key, 'steps': steps_ahead, 'method': method,
+ 'ahead_results': eval
+ }
+
+ return ret
+
+
+[docs]def common_process_time_jobs(conn, data, job):
+ dta = deepcopy(data)
+ dta.append(job['steps'])
+ dta.append(job['method'])
+ for key in ["time"]:
+ if key in job:
+ data2 = deepcopy(dta)
+ data2.extend([key, job[key]])
+ bUtil.insert_benchmark(data2, conn)
+
+
+[docs]def common_process_point_jobs(conn, data, job):
+ dta = deepcopy(data)
+ dta.append(job['steps'])
+ dta.append(job['method'])
+ for key in ["rmse", "mape", "u", "time"]:
+ if key in job:
+ data2 = deepcopy(dta)
+ data2.extend([key, job[key]])
+ bUtil.insert_benchmark(data2, conn)
+
+
+[docs]def process_point_jobs(dataset, tag, job, conn):
+ """
+ Extract information from a dictionary with point benchmark results and save it on a database
+
+ :param dataset: the benchmark dataset name
+ :param tag: alias for the benchmark group being executed
+ :param job: a dictionary with the benchmark results
+ :param conn: a connection to a Sqlite database
+ :return:
+ """
+
+ data = bUtil.process_common_data(dataset, tag, 'point',job)
+
+ common_process_point_jobs(conn, data, job)
+
+
+[docs]def process_point_jobs2(dataset, tag, job, conn):
+ """
+ Extract information from a dictionary with point benchmark results and save it on a database
+
+ :param dataset: the benchmark dataset name
+ :param tag: alias for the benchmark group being executed
+ :param job: a dictionary with the benchmark results
+ :param conn: a connection to a Sqlite database
+ :return:
+ """
+
+ data = bUtil.process_common_data2(dataset, tag, 'point',job)
+
+ if job['steps'] == 1:
+ common_process_point_jobs(conn, data, job)
+ else:
+ for k in range(job['steps']):
+ j2 = job['ahead_results'][k]
+ common_process_point_jobs(conn, data, j2)
+
+
+[docs]def common_process_interval_jobs(conn, data, job):
+ dta = deepcopy(data)
+ dta.append(job['steps'])
+ dta.append(job['method'])
+ for key in ["sharpness","resolution","coverage","time","pinball05",
+ "pinball25","pinball75","pinball95", "winkler05", "winkler25"]:
+ if key in job:
+ data2 = deepcopy(dta)
+ data2.extend([key, job[key]])
+ bUtil.insert_benchmark(data2, conn)
+
+
+[docs]def process_interval_jobs(dataset, tag, job, conn):
+ """
+ Extract information from an dictionary with interval benchmark results and save it on a database
+
+ :param dataset: the benchmark dataset name
+ :param tag: alias for the benchmark group being executed
+ :param job: a dictionary with the benchmark results
+ :param conn: a connection to a Sqlite database
+ :return:
+ """
+
+ data = bUtil.process_common_data(dataset, tag, 'interval', job)
+
+ common_process_interval_jobs(conn, data, job)
+
+
+[docs]def process_interval_jobs2(dataset, tag, job, conn):
+
+ data = bUtil.process_common_data2(dataset, tag, 'interval', job)
+
+ if job['steps'] == 1:
+ common_process_interval_jobs(conn, data, job)
+ else:
+ for k in range(job['steps']):
+ j2 = job['ahead_results'][k]
+ common_process_interval_jobs(conn, data, j2)
+
+
+[docs]def common_process_probabilistic_jobs(conn, data, job):
+ dta = deepcopy(data)
+ dta.append(job['steps'])
+ dta.append(job['method'])
+ for key in ["crps","time","brier"]:
+ if key in job:
+ data2 = deepcopy(dta)
+ data2.extend([key, job[key]])
+ bUtil.insert_benchmark(data2, conn)
+
+
+[docs]def process_probabilistic_jobs(dataset, tag, job, conn):
+ """
+ Extract information from an dictionary with probabilistic benchmark results and save it on a database
+
+ :param dataset: the benchmark dataset name
+ :param tag: alias for the benchmark group being executed
+ :param job: a dictionary with the benchmark results
+ :param conn: a connection to a Sqlite database
+ :return:
+ """
+
+ data = bUtil.process_common_data(dataset, tag, 'density', job)
+
+ common_process_probabilistic_jobs(conn, data, job)
+
+
+[docs]def process_probabilistic_jobs2(dataset, tag, job, conn):
+ """
+ Extract information from an dictionary with probabilistic benchmark results and save it on a database
+
+ :param dataset: the benchmark dataset name
+ :param tag: alias for the benchmark group being executed
+ :param job: a dictionary with the benchmark results
+ :param conn: a connection to a Sqlite database
+ :return:
+ """
+
+ data = bUtil.process_common_data2(dataset, tag, 'density', job)
+
+ if job['steps'] == 1:
+ common_process_probabilistic_jobs(conn,data,job)
+ else:
+ for k in range(job['steps']):
+ j2 = job['ahead_results'][k]
+ common_process_probabilistic_jobs(conn, data, j2)
+
+
+[docs]def print_point_statistics(data, models, externalmodels = None, externalforecasts = None, indexers=None):
+ """
+ Run point benchmarks on given models and data and print the results
+
+ :param data: test data
+ :param models: a list of FTS models to benchmark
+ :param externalmodels: a list with benchmark models (façades for other methods)
+ :param externalforecasts:
+ :param indexers:
+ :return:
+ """
+ ret = "Model & Order & RMSE & SMAPE & Theil's U \\\\ \n"
+ for count,model in enumerate(models,start=0):
+ _rmse, _smape, _u = Measures.get_point_statistics(data, model, indexers)
+ ret += model.shortname + " & "
+ ret += str(model.order) + " & "
+ ret += str(_rmse) + " & "
+ ret += str(_smape)+ " & "
+ ret += str(_u)
+ #ret += str(round(Measures.TheilsInequality(np.array(data[fts.order:]), np.array(forecasts[:-1])), 4))
+ ret += " \\\\ \n"
+ if externalmodels is not None:
+ l = len(externalmodels)
+ for k in np.arange(0,l):
+ ret += externalmodels[k] + " & "
+ ret += " 1 & "
+ ret += str(round(Measures.rmse(data, externalforecasts[k][:-1]), 2)) + " & "
+ ret += str(round(Measures.smape(data, externalforecasts[k][:-1]), 2))+ " & "
+ ret += str(round(Measures.UStatistic(data, externalforecasts[k][:-1]), 2))
+ ret += " \\\\ \n"
+ print(ret)
+
+
+[docs]def print_interval_statistics(original, models):
+ """
+ Run interval benchmarks on given models and data and print the results
+
+ :param data: test data
+ :param models: a list of FTS models to benchmark
+ :return:
+ """
+ ret = "Model & Order & Sharpness & Resolution & Coverage & .05 & .25 & .75 & .95 \\\\ \n"
+ for fts in models:
+ _sharp, _res, _cov, _q5, _q25, _q75, _q95 = Measures.get_interval_statistics(original, fts)
+ ret += fts.shortname + " & "
+ ret += str(fts.order) + " & "
+ ret += str(_sharp) + " & "
+ ret += str(_res) + " & "
+ ret += str(_cov) + " &"
+ ret += str(_q5) + " &"
+ ret += str(_q25) + " &"
+ ret += str(_q75) + " &"
+ ret += str(_q95) + "\\\\ \n"
+ print(ret)
+
+
+[docs]def print_distribution_statistics(original, models, steps, resolution):
+ """
+ Run probabilistic benchmarks on given models and data and print the results
+
+ :param data: test data
+ :param models: a list of FTS models to benchmark
+ :return:
+ """
+ ret = "Model & Order & Interval & Distribution \\\\ \n"
+ for fts in models:
+ _crps1, _crps2, _t1, _t2 = Measures.get_distribution_statistics(original, fts, steps, resolution)
+ ret += fts.shortname + " & "
+ ret += str(fts.order) + " & "
+ ret += str(_crps1) + " & "
+ ret += str(_crps2) + " \\\\ \n"
+ print(ret)
+
+
+[docs]def plot_point(axis, points, order, label, color='red', ls='-', linewidth=1):
+ mi = min(points) * 0.95
+ ma = max(points) * 1.05
+ for k in np.arange(0, order):
+ points.insert(0, None)
+ axis.plot(points, color=color, label=label, ls=ls,linewidth=linewidth)
+ return [mi, ma]
+
+
+
+[docs]def plot_compared_series(original, models, colors, typeonlegend=False, save=False, file=None, tam=[20, 5],
+ points=True, intervals=True, linewidth=1.5):
+ """
+ Plot the forecasts of several one step ahead models, by point or by interval
+
+ :param original: Original time series data (list)
+ :param models: List of models to compare
+ :param colors: List of models colors
+ :param typeonlegend: Add the type of forecast (point / interval) on legend
+ :param save: Save the picture on file
+ :param file: Filename to save the picture
+ :param tam: Size of the picture
+ :param points: True to plot the point forecasts, False otherwise
+ :param intervals: True to plot the interval forecasts, False otherwise
+ :param linewidth:
+ :return:
+ """
+
+ fig = plt.figure(figsize=tam)
+ ax = fig.add_subplot(111)
+
+ mi = []
+ ma = []
+
+ legends = []
+
+ ax.plot(original, color='black', label="Original", linewidth=linewidth*1.5)
+
+ for count, fts in enumerate(models, start=0):
+ try:
+ if fts.has_point_forecasting and points:
+ forecasts = fts.forecast(original)
+ if isinstance(forecasts, np.ndarray):
+ forecasts = forecasts.tolist()
+ mi.append(min(forecasts) * 0.95)
+ ma.append(max(forecasts) * 1.05)
+ for k in np.arange(0, fts.order):
+ forecasts.insert(0, None)
+ lbl = fts.shortname + str(fts.order if fts.is_high_order and not fts.benchmark_only else "")
+ if typeonlegend: lbl += " (Point)"
+ ax.plot(forecasts, color=colors[count], label=lbl, ls="-",linewidth=linewidth)
+
+ if fts.has_interval_forecasting and intervals:
+ forecasts = fts.forecast_interval(original)
+ lbl = fts.shortname + " " + str(fts.order if fts.is_high_order and not fts.benchmark_only else "")
+ if not points and intervals:
+ ls = "-"
+ else:
+ ls = "--"
+ tmpmi, tmpma = Util.plot_interval(ax, forecasts, fts.order, label=lbl, typeonlegend=typeonlegend,
+ color=colors[count], ls=ls, linewidth=linewidth)
+ mi.append(tmpmi)
+ ma.append(tmpma)
+ except ValueError as ex:
+ print(fts.shortname)
+
+ handles0, labels0 = ax.get_legend_handles_labels()
+ lgd = ax.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))
+ legends.append(lgd)
+
+ # ax.set_title(fts.name)
+ ax.set_ylim([min(mi), max(ma)])
+ ax.set_ylabel('F(T)')
+ ax.set_xlabel('T')
+ ax.set_xlim([0, len(original)])
+
+ #Util.show_and_save_image(fig, file, save, lgd=legends)
+
+
+[docs]def plotCompared(original, forecasts, labels, title):
+ fig = plt.figure(figsize=[13, 6])
+ ax = fig.add_subplot(111)
+ ax.plot(original, color='k', label="Original")
+ for c in range(0, len(forecasts)):
+ ax.plot(forecasts[c], label=labels[c])
+ handles0, labels0 = ax.get_legend_handles_labels()
+ ax.legend(handles0, labels0)
+ ax.set_title(title)
+ ax.set_ylabel('F(T)')
+ ax.set_xlabel('T')
+ ax.set_xlim([0, len(original)])
+ ax.set_ylim([min(original), max(original)])
+
+
+[docs]def SelecaoSimples_MenorRMSE(original, parameters, modelo):
+ ret = []
+ errors = []
+ forecasted_best = []
+ print("Série Original")
+ fig = plt.figure(figsize=[20, 12])
+ fig.suptitle("Comparação de modelos ")
+ ax0 = fig.add_axes([0, 0.5, 0.65, 0.45]) # left, bottom, width, height
+ ax0.set_xlim([0, len(original)])
+ ax0.set_ylim([min(original), max(original)])
+ ax0.set_title('Série Temporal')
+ ax0.set_ylabel('F(T)')
+ ax0.set_xlabel('T')
+ ax0.plot(original, label="Original")
+ min_rmse = 100000.0
+ best = None
+ for p in parameters:
+ sets = Grid.GridPartitioner(data=original, npart=p).sets
+ fts = modelo(str(p) + " particoes")
+ fts.train(original, sets=sets)
+ # print(original)
+ forecasted = fts.forecast(original)
+ forecasted.insert(0, original[0])
+ # print(forecasted)
+ ax0.plot(forecasted, label=fts.name)
+ error = Measures.rmse(np.array(forecasted), np.array(original))
+ print(p, error)
+ errors.append(error)
+ if error < min_rmse:
+ min_rmse = error
+ best = fts
+ forecasted_best = forecasted
+ handles0, labels0 = ax0.get_legend_handles_labels()
+ ax0.legend(handles0, labels0)
+ ax1 = fig.add_axes([0.7, 0.5, 0.3, 0.45]) # left, bottom, width, height
+ ax1.set_title('Comparação dos Erros Quadráticos Médios')
+ ax1.set_ylabel('RMSE')
+ ax1.set_xlabel('Quantidade de Partições')
+ ax1.set_xlim([min(parameters), max(parameters)])
+ ax1.plot(parameters, errors)
+ ret.append(best)
+ ret.append(forecasted_best)
+ # Modelo diferencial
+ print("\nSérie Diferencial")
+ difffts = Transformations.differential(original)
+ errors = []
+ forecastedd_best = []
+ ax2 = fig.add_axes([0, 0, 0.65, 0.45]) # left, bottom, width, height
+ ax2.set_xlim([0, len(difffts)])
+ ax2.set_ylim([min(difffts), max(difffts)])
+ ax2.set_title('Série Temporal')
+ ax2.set_ylabel('F(T)')
+ ax2.set_xlabel('T')
+ ax2.plot(difffts, label="Original")
+ min_rmse = 100000.0
+ bestd = None
+ for p in parameters:
+ sets = Grid.GridPartitioner(data=difffts, npart=p)
+ fts = modelo(str(p) + " particoes")
+ fts.train(difffts, sets=sets)
+ forecasted = fts.forecast(difffts)
+ forecasted.insert(0, difffts[0])
+ ax2.plot(forecasted, label=fts.name)
+ error = Measures.rmse(np.array(forecasted), np.array(difffts))
+ print(p, error)
+ errors.append(error)
+ if error < min_rmse:
+ min_rmse = error
+ bestd = fts
+ forecastedd_best = forecasted
+ handles0, labels0 = ax2.get_legend_handles_labels()
+ ax2.legend(handles0, labels0)
+ ax3 = fig.add_axes([0.7, 0, 0.3, 0.45]) # left, bottom, width, height
+ ax3.set_title('Comparação dos Erros Quadráticos Médios')
+ ax3.set_ylabel('RMSE')
+ ax3.set_xlabel('Quantidade de Partições')
+ ax3.set_xlim([min(parameters), max(parameters)])
+ ax3.plot(parameters, errors)
+ ret.append(bestd)
+ ret.append(forecastedd_best)
+ return ret
+
+
+[docs]def compareModelsPlot(original, models_fo, models_ho):
+ fig = plt.figure(figsize=[13, 6])
+ fig.suptitle("Comparação de modelos ")
+ ax0 = fig.add_axes([0, 0, 1, 1]) # left, bottom, width, height
+ rows = []
+ for model in models_fo:
+ fts = model["model"]
+ ax0.plot(model["forecasted"], label=model["name"])
+ for model in models_ho:
+ fts = model["model"]
+ ax0.plot(model["forecasted"], label=model["name"])
+ handles0, labels0 = ax0.get_legend_handles_labels()
+ ax0.legend(handles0, labels0)
+
+
+[docs]def compareModelsTable(original, models_fo, models_ho):
+ fig = plt.figure(figsize=[12, 4])
+ fig.suptitle("Comparação de modelos ")
+ columns = ['Modelo', 'Ordem', 'Partições', 'RMSE', 'MAPE (%)']
+ rows = []
+ for model in models_fo:
+ fts = model["model"]
+ error_r = Measures.rmse(model["forecasted"], original)
+ error_m = round(Measures.mape(model["forecasted"], original) * 100, 2)
+ rows.append([model["name"], fts.order, len(fts.sets), error_r, error_m])
+ for model in models_ho:
+ fts = model["model"]
+ error_r = Measures.rmse(model["forecasted"][fts.order:], original[fts.order:])
+ error_m = round(Measures.mape(model["forecasted"][fts.order:], original[fts.order:]) * 100, 2)
+ rows.append([model["name"], fts.order, len(fts.sets), error_r, error_m])
+ ax1 = fig.add_axes([0, 0, 1, 1]) # left, bottom, width, height
+ ax1.set_xticks([])
+ ax1.set_yticks([])
+ ax1.table(cellText=rows,
+ colLabels=columns,
+ cellLoc='center',
+ bbox=[0, 0, 1, 1])
+ sup = "\\begin{tabular}{"
+ header = ""
+ body = ""
+ footer = ""
+
+ for c in columns:
+ sup = sup + "|c"
+ if len(header) > 0:
+ header = header + " & "
+ header = header + "\\textbf{" + c + "} "
+ sup = sup + "|} \\hline\n"
+ header = header + "\\\\ \\hline \n"
+
+ for r in rows:
+ lin = ""
+ for c in r:
+ if len(lin) > 0:
+ lin = lin + " & "
+ lin = lin + str(c)
+
+ body = body + lin + "\\\\ \\hline \n"
+
+ return sup + header + body + "\\end{tabular}"
+
+
+[docs]def simpleSearch_RMSE(train, test, model, partitions, orders, save=False, file=None, tam=[10, 15],
+ plotforecasts=False, elev=30, azim=144, intervals=False,parameters=None,
+ partitioner=Grid.GridPartitioner,transformation=None,indexer=None):
+ _3d = len(orders) > 1
+ ret = []
+ if _3d:
+ errors = np.array([[0 for k in range(len(partitions))] for kk in range(len(orders))])
+ else:
+ errors = []
+ forecasted_best = []
+ fig = plt.figure(figsize=tam)
+ # fig.suptitle("Comparação de modelos ")
+ if plotforecasts:
+ ax0 = fig.add_axes([0, 0.4, 0.9, 0.5]) # left, bottom, width, height
+ ax0.set_xlim([0, len(train)])
+ ax0.set_ylim([min(train) * 0.9, max(train) * 1.1])
+ ax0.set_title('Forecasts')
+ ax0.set_ylabel('F(T)')
+ ax0.set_xlabel('T')
+ min_rmse = 1000000.0
+ best = None
+
+ for pc, p in enumerate(partitions, start=0):
+
+ sets = partitioner(data=train, npart=p, transformation=transformation).sets
+ for oc, o in enumerate(orders, start=0):
+ fts = model("q = " + str(p) + " n = " + str(o))
+ fts.append_transformation(transformation)
+ fts.train(train, sets=sets, order=o, parameters=parameters)
+ if not intervals:
+ forecasted = fts.forecast(test)
+ if not fts.has_seasonality:
+ error = Measures.rmse(np.array(test[o:]), np.array(forecasted[:-1]))
+ else:
+ error = Measures.rmse(np.array(test[o:]), np.array(forecasted))
+ for kk in range(o):
+ forecasted.insert(0, None)
+ if plotforecasts: ax0.plot(forecasted, label=fts.name)
+ else:
+ forecasted = fts.forecast_interval(test)
+ error = 1.0 - Measures.rmse_interval(np.array(test[o:]), np.array(forecasted[:-1]))
+ if _3d:
+ errors[oc, pc] = error
+ else:
+ errors.append( error )
+ if error < min_rmse:
+ min_rmse = error
+ best = fts
+ forecasted_best = forecasted
+
+ # print(min_rmse)
+ if plotforecasts:
+ # handles0, labels0 = ax0.get_legend_handles_labels()
+ # ax0.legend(handles0, labels0)
+ ax0.plot(test, label="Original", linewidth=3.0, color="black")
+ if _3d: ax1 = Axes3D(fig, rect=[0, 1, 0.9, 0.9], elev=elev, azim=azim)
+ if _3d and not plotforecasts:
+ ax1 = Axes3D(fig, rect=[0, 1, 0.9, 0.9], elev=elev, azim=azim)
+ ax1.set_title('Error Surface')
+ ax1.set_ylabel('Model order')
+ ax1.set_xlabel('Number of partitions')
+ ax1.set_zlabel('RMSE')
+ X, Y = np.meshgrid(partitions, orders)
+ surf = ax1.plot_surface(X, Y, errors, rstride=1, cstride=1, antialiased=True)
+ else:
+ ax1 = fig.add_axes([0, 1, 0.9, 0.9])
+ ax1.set_title('Error Curve')
+ ax1.set_xlabel('Number of partitions')
+ ax1.set_ylabel('RMSE')
+ ax1.plot(partitions, errors)
+ ret.append(best)
+ ret.append(forecasted_best)
+ ret.append(min_rmse)
+
+ # plt.tight_layout()
+
+ cUtil.show_and_save_image(fig, file, save)
+
+ return ret
+
+
+
+[docs]def pftsExploreOrderAndPartitions(data,save=False, file=None):
+ fig, axes = plt.subplots(nrows=4, ncols=1, figsize=[6, 8])
+ data_fs1 = Grid.GridPartitioner(data=data, npart=10).sets
+ mi = []
+ ma = []
+
+ axes[0].set_title('Point Forecasts by Order')
+ axes[2].set_title('Interval Forecasts by Order')
+
+ for order in np.arange(1, 6):
+ fts = pwfts.ProbabilisticWeightedFTS("")
+ fts.shortname = "n = " + str(order)
+ fts.train(data, sets=data_fs1.sets, order=order)
+ point_forecasts = fts.forecast(data)
+ interval_forecasts = fts.forecast_interval(data)
+ lower = [kk[0] for kk in interval_forecasts]
+ upper = [kk[1] for kk in interval_forecasts]
+ mi.append(min(lower) * 0.95)
+ ma.append(max(upper) * 1.05)
+ for k in np.arange(0, order):
+ point_forecasts.insert(0, None)
+ lower.insert(0, None)
+ upper.insert(0, None)
+ axes[0].plot(point_forecasts, label=fts.shortname)
+ axes[2].plot(lower, label=fts.shortname)
+ axes[2].plot(upper)
+
+ axes[1].set_title('Point Forecasts by Number of Partitions')
+ axes[3].set_title('Interval Forecasts by Number of Partitions')
+
+ for partitions in np.arange(5, 11):
+ data_fs = Grid.GridPartitioner(data=data, npart=partitions).sets
+ fts = pwfts.ProbabilisticWeightedFTS("")
+ fts.shortname = "q = " + str(partitions)
+ fts.train(data, sets=data_fs.sets, order=1)
+ point_forecasts = fts.forecast(data)
+ interval_forecasts = fts.forecast_interval(data)
+ lower = [kk[0] for kk in interval_forecasts]
+ upper = [kk[1] for kk in interval_forecasts]
+ mi.append(min(lower) * 0.95)
+ ma.append(max(upper) * 1.05)
+ point_forecasts.insert(0, None)
+ lower.insert(0, None)
+ upper.insert(0, None)
+ axes[1].plot(point_forecasts, label=fts.shortname)
+ axes[3].plot(lower, label=fts.shortname)
+ axes[3].plot(upper)
+
+ for ax in axes:
+ ax.set_ylabel('F(T)')
+ ax.set_xlabel('T')
+ ax.plot(data, label="Original", color="black", linewidth=1.5)
+ handles, labels = ax.get_legend_handles_labels()
+ ax.legend(handles, labels, loc=2, bbox_to_anchor=(1, 1))
+ ax.set_ylim([min(mi), max(ma)])
+ ax.set_xlim([0, len(data)])
+
+ plt.tight_layout()
+
+ cUtil.show_and_save_image(fig, file, save)
+
+
+[docs]def train_test_time(data, windowsize, train=0.8, **kwargs):
+ import time
+
+ tag = __pop('tag', None, kwargs)
+ steps = __pop('steps', 0, kwargs)
+ dataset = __pop('dataset', None, kwargs)
+
+ partitions = __pop('partitions', 10, kwargs)
+
+ fts_methods = __pop('methods', [], kwargs)
+
+ file = kwargs.get('file', "benchmarks.db")
+
+ inc = __pop("inc", 0.1, kwargs)
+
+ conn = bUtil.open_benchmark_db(file)
+
+ for ct, train, test in cUtil.sliding_window(data, windowsize, train, inc=inc, **kwargs):
+ partitioner = Grid.GridPartitioner(data=train, npart=partitions)
+ for id, fts_method in enumerate(fts_methods):
+ print(dataset, fts_method, ct)
+ times = []
+ model = fts_method(partitioner = partitioner, **kwargs)
+ _start = time.time()
+ model.fit(train, **kwargs)
+ _end = time.time()
+ times.append( _end - _start )
+ _start = time.time()
+ model.predict(train, **kwargs)
+ _end = time.time()
+ times.append(_end - _start)
+ for ct, method in enumerate(['train','test']):
+ job = {
+ 'steps': steps, 'method': method, 'time': times[ct],
+ 'model': model.shortname, 'transformation': None,
+ 'order': model.order, 'partitioner': partitioner.name,
+ 'partitions': partitions, 'size': len(model)
+ }
+
+ data = bUtil.process_common_data2(dataset, tag, 'train', job)
+ common_process_time_jobs(conn, data, job)
+
+
+ conn.close()
+
+
+[docs]def distributed_model_train_test_time(models, data, windowsize, train=0.8, **kwargs):
+ """
+ Assess the train and test times for a given list of configured models and save the results on a database.
+
+ :param models: A list of FTS models already configured, but not yet trained,
+ :param data: time series data, including train and test data
+ :param windowsize: Train/test data windows
+ :param train: Percent of data window that will be used to train the models
+ :param kwargs:
+ :return:
+ """
+ import time
+
+ tag = __pop('tag', None, kwargs)
+ num_batches = kwargs.get('num_batches', 1)
+ dataset = __pop('dataset', None, kwargs)
+
+ file = kwargs.get('file', "benchmarks.db")
+
+ inc = __pop("inc", 0.5, kwargs)
+
+ conn = bUtil.open_benchmark_db(file)
+
+ for ct, train, test in cUtil.sliding_window(data, windowsize, train, inc=inc, **kwargs):
+ for id, model in enumerate(models):
+ print(dataset, model, ct)
+
+ model.fit(train, **kwargs)
+
+ for time in model.__dict__['training_time']:
+ job = {
+ 'steps': num_batches, 'method': 'train', 'time': time,
+ 'model': model.shortname, 'transformation': None,
+ 'order': model.order, 'partitioner': None,
+ 'partitions': None, 'size': len(model)
+ }
+ data = bUtil.process_common_data2(dataset, tag, 'train', job)
+ common_process_time_jobs(conn, data, job)
+
+ model.predict(train, **kwargs)
+
+ for time in model.__dict__['forecasting_time']:
+ job = {
+ 'steps': num_batches, 'method': 'test', 'time': time,
+ 'model': model.shortname, 'transformation': None,
+ 'order': model.order, 'partitioner': None,
+ 'partitions': None, 'size': len(model)
+ }
+
+ data = bUtil.process_common_data2(dataset, tag, 'test', job)
+ common_process_time_jobs(conn, data, job)
+
+ conn.close()
+
+
+
Source code for pyFTS.benchmarks.knn
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+import numpy as np
+from statsmodels.tsa.tsatools import lagmat
+from pyFTS.common import fts
+from pyFTS.probabilistic import ProbabilityDistribution
+from sklearn.neighbors import KDTree
+from itertools import product
+from pyFTS.models.ensemble.ensemble import sampler
+
+[docs]class KNearestNeighbors(fts.FTS):
+ """
+ A façade for sklearn.neighbors
+ """
+ def __init__(self, **kwargs):
+ super(KNearestNeighbors, self).__init__(**kwargs)
+ self.name = "kNN"
+ self.shortname = "kNN"
+ self.detail = "K-Nearest Neighbors"
+ self.uod_clip = False
+ self.is_high_order = True
+ self.has_point_forecasting = True
+ self.has_interval_forecasting = True
+ self.has_probability_forecasting = True
+ self.benchmark_only = True
+ self.min_order = 1
+ self.alpha = kwargs.get("alpha", 0.05)
+ self.max_lag = self.order
+ self.lag = None
+ self.k = kwargs.get("k", 30)
+ self.uod = None
+ self.kdtree = None
+ self.values = None
+
+ def _prepare_x(self, data):
+ l = len(data)
+ X = []
+
+ if l == self.order:
+ l += 1
+
+ for t in np.arange(self.order, l):
+ X.append([data[t - k - 1] for k in np.arange(self.order)])
+
+ return X
+
+ def _prepare_xy(self, data):
+ l = len(data)
+ X = []
+ Y = []
+
+ for t in np.arange(self.order, l):
+ X.append([data[t - k - 1] for k in np.arange(self.order)])
+ Y.append(data[t])
+
+ return (X,Y)
+
+[docs] def train(self, data, **kwargs):
+ X,Y = self._prepare_xy(data)
+
+ self.kdtree = KDTree(np.array(X))
+ self.values = Y
+
+ self.shortname = "kNN({})-{}".format(self.order, self.alpha)
+
+[docs] def knn(self, sample):
+ X = self._prepare_x(sample)
+ _, ix = self.kdtree.query(np.array(X), self.k)
+
+ return [self.values[k] for k in ix.flatten() ]
+
+[docs] def forecast(self, data, **kwargs):
+ l = len(data)
+ ret = []
+ for k in np.arange(self.order, l+(1 if self.order == l else 0)):
+
+ sample = data[k-self.order : k]
+
+ forecasts = self.knn(sample)
+
+ ret.append(np.nanmean(forecasts))
+
+ return ret
+
+[docs] def forecast_interval(self, data, **kwargs):
+
+ alpha = kwargs.get('alpha',self.alpha)
+
+ ret = []
+ for k in np.arange(self.order, len(data)):
+
+ sample = data[k-self.order : k]
+
+ forecasts = self.knn(sample)
+
+ i = np.percentile(forecasts, [alpha*100, (1-alpha)*100]).tolist()
+ ret.append(i)
+
+ return ret
+
+[docs] def forecast_ahead_interval(self, data, steps, **kwargs):
+ alpha = kwargs.get('alpha', self.alpha)
+
+ ret = []
+
+ start = kwargs.get('start', self.order)
+
+ sample = [[k] for k in data[start - self.order: start]]
+
+ for k in np.arange(self.order, steps + self.order):
+ forecasts = []
+
+ lags = [sample[k - i - 1] for i in np.arange(0, self.order)]
+
+ # Trace the possible paths
+ for path in product(*lags):
+ forecasts.extend(self.knn(path))
+
+ sample.append(sampler(forecasts, np.arange(.1, 1, 0.1), bounds=True))
+
+ interval = np.percentile(forecasts, [alpha*100, (1-alpha)*100]).tolist()
+
+ ret.append(interval)
+
+ return ret
+
+[docs] def forecast_distribution(self, data, **kwargs):
+ ret = []
+
+ smooth = kwargs.get("smooth", "histogram")
+
+ uod = self.get_UoD()
+
+ for k in np.arange(self.order, len(data)):
+
+ sample = data[k-self.order : k]
+
+ forecasts = self.knn(sample)
+
+ dist = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, data=forecasts,
+ name="", **kwargs)
+ ret.append(dist)
+
+ return ret
+
+[docs] def forecast_ahead_distribution(self, data, steps, **kwargs):
+ smooth = kwargs.get("smooth", "histogram")
+
+ ret = []
+
+ start = kwargs.get('start', self.order)
+
+ uod = self.get_UoD()
+
+ sample = [[k] for k in data[start - self.order: start]]
+
+ for k in np.arange(self.order, steps + self.order):
+ forecasts = []
+
+ lags = [sample[k - i - 1] for i in np.arange(0, self.order)]
+
+ # Trace the possible paths
+ for path in product(*lags):
+ forecasts.extend(self.knn(path))
+
+ dist = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, data=forecasts,
+ name="", **kwargs)
+ ret.append(dist)
+
+ sample.append(sampler(forecasts, np.arange(.1, 1, 0.1), bounds=True))
+
+ return ret
+
+
+
Source code for pyFTS.benchmarks.naive
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+from pyFTS.common import fts
+
+
+[docs]class Naive(fts.FTS):
+ """Naïve Forecasting method"""
+ def __init__(self, **kwargs):
+ super(Naive, self).__init__(order=1, name="Naive",**kwargs)
+ self.name = "Naïve Model"
+ self.detail = "Naïve Model"
+ self.benchmark_only = True
+ self.is_high_order = False
+ self.uod_clip = False
+
+
+
+
Source code for pyFTS.benchmarks.quantreg
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+import numpy as np
+import pandas as pd
+from statsmodels.regression.quantile_regression import QuantReg
+from statsmodels.tsa.tsatools import lagmat
+from pyFTS.common import SortedCollection, fts
+from pyFTS.probabilistic import ProbabilityDistribution
+
+
+[docs]class QuantileRegression(fts.FTS):
+ """Façade for statsmodels.regression.quantile_regression"""
+ def __init__(self, **kwargs):
+ super(QuantileRegression, self).__init__(**kwargs)
+ self.name = "QAR"
+ self.detail = "Quantile Regression"
+ self.is_high_order = True
+ self.has_point_forecasting = True
+ self.has_interval_forecasting = True
+ self.has_probability_forecasting = True
+ self.uod_clip = False
+ self.benchmark_only = True
+ self.min_order = 1
+ self.alpha = kwargs.get("alpha", 0.05)
+ self.dist = kwargs.get("dist", False)
+ self.upper_qt = None
+ self.mean_qt = None
+ self.lower_qt = None
+ self.dist_qt = None
+
+[docs] def train(self, data, **kwargs):
+ if self.indexer is not None and isinstance(data, pd.DataFrame):
+ data = self.indexer.get_data(data)
+
+ lagdata, ndata = lagmat(data, maxlag=self.order, trim="both", original='sep')
+
+ mqt = QuantReg(ndata, lagdata).fit(0.5)
+ if self.alpha is not None:
+ uqt = QuantReg(ndata, lagdata).fit(1 - self.alpha)
+ lqt = QuantReg(ndata, lagdata).fit(self.alpha)
+
+ self.mean_qt = [k for k in mqt.params]
+ if self.alpha is not None:
+ self.upper_qt = [k for k in uqt.params]
+ self.lower_qt = [k for k in lqt.params]
+
+ if self.dist:
+ self.dist_qt = []
+ for alpha in np.arange(0.05,0.5,0.05):
+ lqt = QuantReg(ndata, lagdata).fit(alpha)
+ uqt = QuantReg(ndata, lagdata).fit(1 - alpha)
+ lo_qt = [k for k in lqt.params]
+ up_qt = [k for k in uqt.params]
+ self.dist_qt.append([lo_qt, up_qt])
+
+ self.shortname = "QAR({})-{}".format(self.order,self.alpha)
+
+[docs] def linearmodel(self,data,params):
+ #return params[0] + sum([ data[k] * params[k+1] for k in np.arange(0, self.order) ])
+ return sum([data[k] * params[k] for k in np.arange(0, self.order)])
+
+[docs] def point_to_interval(self, data, lo_params, up_params):
+ lo = self.linearmodel(data, lo_params)
+ up = self.linearmodel(data, up_params)
+ return [lo, up]
+
+[docs] def interval_to_interval(self, data, lo_params, up_params):
+ lo = self.linearmodel([k[0] for k in data], lo_params)
+ up = self.linearmodel([k[1] for k in data], up_params)
+ return [lo, up]
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ l = len(ndata)
+
+ ret = []
+
+ for k in np.arange(self.order, l+1): #+1 to forecast one step ahead given all available lags
+ sample = ndata[k - self.order : k]
+
+ ret.append(self.linearmodel(sample, self.mean_qt))
+
+ return ret
+
+[docs] def forecast_interval(self, ndata, **kwargs):
+
+ l = len(ndata)
+
+ ret = []
+
+ for k in np.arange(self.order , l):
+ sample = ndata[k - self.order: k]
+ ret.append(self.point_to_interval(sample, self.lower_qt, self.upper_qt))
+
+ return ret
+
+[docs] def forecast_ahead_interval(self, ndata, steps, **kwargs):
+
+ smoothing = kwargs.get("smoothing", 0.01)
+
+ l = len(ndata)
+
+ ret = []
+
+ nmeans = self.forecast_ahead(ndata, steps, **kwargs)
+
+ for k in np.arange(0, self.order):
+ nmeans.insert(k,ndata[k])
+
+ for k in np.arange(self.order, steps+self.order):
+ intl = self.point_to_interval(nmeans[k - self.order: k], self.lower_qt, self.upper_qt)
+
+ tmpk = k-self.order
+
+ ret.append([intl[0]*(1 - (tmpk*smoothing)), intl[1]*(1 + (tmpk*smoothing))])
+
+ return ret[-steps:]
+
+[docs] def forecast_distribution(self, ndata, **kwargs):
+
+ ret = []
+
+ l = len(ndata)
+
+ for k in np.arange(self.order, l + 1):
+ dist = ProbabilityDistribution.ProbabilityDistribution(type="histogram",
+ uod=[self.original_min, self.original_max])
+ intervals = []
+ for qt in self.dist_qt:
+ sample = ndata[k - self.order: k]
+ intl = self.point_to_interval(sample, qt[0], qt[1])
+ intervals.append(intl)
+
+ dist.append_interval(intervals)
+
+ ret.append(dist)
+
+ return ret
+
+[docs] def forecast_ahead_distribution(self, ndata, steps, **kwargs):
+ smoothing = kwargs.get("smoothing", 0.01)
+
+ l = len(ndata)
+
+ ret = []
+
+ nmeans = self.forecast_ahead(ndata, steps, **kwargs)
+
+ for k in np.arange(0, self.order):
+ nmeans.insert(k, ndata[k])
+
+ for k in np.arange(self.order, steps + self.order):
+ dist = ProbabilityDistribution.ProbabilityDistribution(type="histogram",
+ uod=[self.original_min, self.original_max])
+
+ intervals = [[nmeans[self.order], nmeans[self.order]]]
+ for qt in self.dist_qt:
+ intl1 = self.point_to_interval(nmeans[k - self.order: k], qt[0], qt[1])
+ tmpk = k - self.order
+ intl2 = [intl1[0] * (1 - (tmpk * smoothing)), intl1[1] * (1 + (tmpk * smoothing))]
+ intervals.append(intl2)
+ dist.append_interval(intervals)
+
+ ret.append(dist)
+
+ return ret
+
+
Source code for pyFTS.common.Util
+"""
+Common facilities for pyFTS
+"""
+
+import time
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import matplotlib.cm as cmx
+import matplotlib.colors as pltcolors
+from pyFTS.probabilistic import ProbabilityDistribution
+from pyFTS.common import Transformations
+
+
+[docs]def plot_compared_intervals_ahead(original, models, colors, distributions, time_from, time_to, intervals = True,
+ save=False, file=None, tam=[20, 5], resolution=None,
+ cmap='Blues', linewidth=1.5):
+ """
+ Plot the forecasts of several one step ahead models, by point or by interval
+
+ :param original: Original time series data (list)
+ :param models: List of models to compare
+ :param colors: List of models colors
+ :param distributions: True to plot a distribution
+ :param time_from: index of data poit to start the ahead forecasting
+ :param time_to: number of steps ahead to forecast
+ :param interpol: Fill space between distribution plots
+ :param save: Save the picture on file
+ :param file: Filename to save the picture
+ :param tam: Size of the picture
+ :param resolution:
+ :param cmap: Color map to be used on distribution plot
+ :param option: Distribution type to be passed for models
+ :return:
+ """
+ fig = plt.figure(figsize=tam)
+ ax = fig.add_subplot(111)
+
+ cm = plt.get_cmap(cmap)
+ cNorm = pltcolors.Normalize(vmin=0, vmax=1)
+ scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm)
+
+ if resolution is None: resolution = (max(original) - min(original)) / 100
+
+ mi = []
+ ma = []
+
+ for count, fts in enumerate(models, start=0):
+ if fts.has_probability_forecasting and distributions[count]:
+ density = fts.forecast_ahead_distribution(original[time_from - fts.order:time_from], time_to,
+ resolution=resolution)
+
+ #plot_density_scatter(ax, cmap, density, fig, resolution, time_from, time_to)
+ plot_density_rectange(ax, cm, density, fig, resolution, time_from, time_to)
+
+ if fts.has_interval_forecasting and intervals:
+ forecasts = fts.forecast_ahead_interval(original[time_from - fts.order:time_from], time_to)
+ lower = [kk[0] for kk in forecasts]
+ upper = [kk[1] for kk in forecasts]
+ mi.append(min(lower))
+ ma.append(max(upper))
+ for k in np.arange(0, time_from - fts.order):
+ lower.insert(0, None)
+ upper.insert(0, None)
+ ax.plot(lower, color=colors[count], label=fts.shortname, linewidth=linewidth)
+ ax.plot(upper, color=colors[count], linewidth=linewidth*1.5)
+
+ ax.plot(original, color='black', label="Original", linewidth=linewidth*1.5)
+ handles0, labels0 = ax.get_legend_handles_labels()
+ if True in distributions:
+ lgd = ax.legend(handles0, labels0, loc=2)
+ else:
+ lgd = ax.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))
+ _mi = min(mi)
+ if _mi < 0:
+ _mi *= 1.1
+ else:
+ _mi *= 0.9
+ _ma = max(ma)
+ if _ma < 0:
+ _ma *= 0.9
+ else:
+ _ma *= 1.1
+
+ ax.set_ylim([_mi, _ma])
+ ax.set_ylabel('F(T)')
+ ax.set_xlabel('T')
+ ax.set_xlim([0, len(original)])
+
+ show_and_save_image(fig, file, save, lgd=lgd)
+
+
+
+[docs]def plot_density_rectange(ax, cmap, density, fig, resolution, time_from, time_to):
+ """
+ Auxiliar function to plot_compared_intervals_ahead
+ """
+ from matplotlib.patches import Rectangle
+ from matplotlib.collections import PatchCollection
+ patches = []
+ colors = []
+ for x in density.index:
+ for y in density.columns:
+ s = Rectangle((time_from + x, y), 1, resolution, fill=True, lw = 0)
+ patches.append(s)
+ colors.append(density[y][x]*5)
+ pc = PatchCollection(patches=patches, match_original=True)
+ pc.set_clim([0, 1])
+ pc.set_cmap(cmap)
+ pc.set_array(np.array(colors))
+ ax.add_collection(pc)
+ cb = fig.colorbar(pc, ax=ax)
+ cb.set_label('Density')
+
+
+[docs]def plot_probability_distributions(pmfs, lcolors, tam=[15, 7]):
+ fig = plt.figure(figsize=tam)
+ ax = fig.add_subplot(111)
+
+ for k,m in enumerate(pmfs,start=0):
+ m.plot(ax, color=lcolors[k])
+
+ handles0, labels0 = ax.get_legend_handles_labels()
+ ax.legend(handles0, labels0)
+
+
+[docs]def plot_distribution(ax, cmap, probabilitydist, fig, time_from, reference_data=None):
+ """
+ Plot forecasted ProbabilityDistribution objects on a matplotlib axis
+
+ :param ax: matplotlib axis
+ :param cmap: matplotlib colormap name
+ :param probabilitydist: list of ProbabilityDistribution objects
+ :param fig: matplotlib figure
+ :param time_from: starting time (on x axis) to begin the plots
+ :param reference_data:
+ :return:
+ """
+ from matplotlib.patches import Rectangle
+ from matplotlib.collections import PatchCollection
+ patches = []
+ colors = []
+ for ct, dt in enumerate(probabilitydist):
+ disp = 0.0
+ if reference_data is not None:
+ disp = reference_data[time_from+ct]
+
+ for y in dt.bins:
+ s = Rectangle((time_from+ct, y+disp), 1, dt.resolution, fill=True, lw = 0)
+ patches.append(s)
+ colors.append(dt.density(y))
+ scale = Transformations.Scale()
+ colors = scale.apply(colors)
+ pc = PatchCollection(patches=patches, match_original=True)
+ pc.set_clim([0, 1])
+ pc.set_cmap(cmap)
+ pc.set_array(np.array(colors))
+ ax.add_collection(pc)
+ cb = fig.colorbar(pc, ax=ax)
+ cb.set_label('Density')
+
+
+[docs]def plot_distribution2(probabilitydist, data, **kwargs):
+ """
+ Plot distributions in y-axis over the time (x-axis)
+
+ :param probabilitydist: the forecasted probability distributions to plot
+ :param data: the original test sample
+ :keyword start_at: the time index (inside of data) to start to plot the probability distributions
+ :keyword ax: a matplotlib axis. If no value was provided a new axis is created.
+ :keyword cmap: a matplotlib colormap name, the default value is 'Blues'
+ :keyword quantiles: the list of quantiles intervals to plot, e. g. [.05, .25, .75, .95]
+ :keyword median: a boolean value indicating if the median value will be plot.
+ """
+ import matplotlib.colorbar as cbar
+ import matplotlib.cm as cm
+
+ ax = kwargs.get('ax',None)
+ if ax is None:
+ fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[15, 5])
+
+ l = len(probabilitydist)
+
+ cmap = kwargs.get('cmap','Blues')
+ cmap = plt.get_cmap(cmap)
+
+ start_at = kwargs.get('start_at',0)
+
+ x = [k + start_at for k in range(l + 1)]
+
+ qt = kwargs.get('quantiles',None)
+
+ if qt is None:
+ qt = [round(k, 2) for k in np.arange(.05, 1., .05)]
+ qt.insert(0, .01)
+ qt.append(.99)
+
+ lq = len(qt)
+
+ normal = plt.Normalize(min(qt), max(qt))
+ scalarMap = cm.ScalarMappable(norm=normal, cmap=cmap)
+
+ for ct in np.arange(1, int(lq / 2) + 1):
+ try:
+ y = [[data[start_at], data[start_at]]]
+ for pd in probabilitydist:
+ qts = pd.quantile([qt[ct - 1], qt[-ct]])
+ y.append(qts)
+
+ ax.fill_between(x, [k[0] for k in y], [k[1] for k in y],
+ facecolor=scalarMap.to_rgba(ct / lq))
+ except:
+ pass
+
+ if kwargs.get('median',True):
+ y = [data[start_at]]
+ for pd in probabilitydist:
+ qts = pd.quantile([.5])
+ y.append(qts[0])
+
+ ax.plot(x, y, color='red', label='Median')
+
+ cax, _ = cbar.make_axes(ax)
+ cb = cbar.ColorbarBase(cax, cmap=cmap, norm=normal)
+ cb.set_label('Density')
+
+
+[docs]def plot_distribution_tiled(distributions,data=None,rows=5,cols=5,index=None,axis=None,size=[10,20]):
+ """
+ Plot one distribution individually in each axis, with probability in y-axis and UoD on x-axis
+
+ :param distributions:
+ :param data:
+ :param rows:
+ :param cols:
+ :param index:
+ :param axis:
+ :param size:
+ :return:
+ """
+
+ if axis is None:
+ fig, axis = plt.subplots(nrows=rows, ncols=cols, figsize=size)
+
+ for ct in range(rows*cols):
+ col = ct % cols
+ row = ct // cols
+ if index is None:
+ ix = ct
+ else:
+ ix =index[ct]
+ forecast = distributions[ix]
+ forecast.plot(axis=axis[row][col])
+ if data is not None:
+ axis[row][col].axvline(data[ix])
+ axis[row][col].set_title('t+{}'.format(ix))
+ axis[row][col].set_xlabel(None)
+
+ plt.tight_layout()
+
+
+[docs]def plot_interval(axis, intervals, order, label, color='red', typeonlegend=False, ls='-', linewidth=1):
+ """
+ Plot forecasted intervals on matplotlib
+
+ :param axis: matplotlib axis
+ :param intervals: list of forecasted intervals
+ :param order: order of the model that create the forecasts
+ :param label: figure label
+ :param color: matplotlib color name
+ :param typeonlegend:
+ :param ls: matplotlib line style
+ :param linewidth: matplotlib width
+ :return:
+ """
+ lower = [kk[0] for kk in intervals]
+ upper = [kk[1] for kk in intervals]
+ mi = min(lower) * 0.95
+ ma = max(upper) * 1.05
+ for k in np.arange(0, order+1):
+ lower.insert(0, None)
+ upper.insert(0, None)
+ if typeonlegend: label += " (Interval)"
+ axis.plot(lower, color=color, label=label, ls=ls,linewidth=linewidth)
+ axis.plot(upper, color=color, ls=ls,linewidth=linewidth)
+ return [mi, ma]
+
+
+[docs]def plot_interval2(intervals, data, **kwargs):
+ """
+ Plot forecasted intervals on matplotlib
+
+ :param intervals: list of forecasted intervals
+ :param data: the original test sample
+ :keyword start_at: the time index (inside of data) to start to plot the intervals
+ :keyword label: figure label
+ :keyword color: matplotlib color name
+ :keyword typeonlegend:
+ :keyword ls: matplotlib line style
+ :keyword linewidth: matplotlib width
+ """
+
+ l = len(intervals)
+
+ nintervals = intervals
+
+ start_at = kwargs.get('start_at', 1)
+
+ ax = kwargs.get('ax', None)
+ if ax is None:
+ fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[15, 5])
+
+ for k in np.arange(0, start_at):
+ nintervals.insert(0, [None,None])
+
+ nintervals.insert(start_at, [data[start_at], data[start_at]])
+
+ lower = [kk[0] for kk in nintervals]
+ upper = [kk[1] for kk in nintervals]
+
+ typeonlegend = kwargs.get('typeonlegend', False)
+ color = kwargs.get('color', 'red')
+ label = kwargs.get('label','')
+ linewidth = kwargs.get('linewidth', 1)
+
+ ls = kwargs.get('ls','-')
+
+ if typeonlegend: label += " (Interval)"
+ ax.plot(lower, color=color, label=label, ls=ls,linewidth=linewidth)
+ ax.plot(upper, color=color, ls=ls,linewidth=linewidth)
+
+
+[docs]def plot_rules(model, size=[5, 5], axis=None, rules_by_axis=None, columns=1):
+ """
+ Plot the FLRG rules of a FTS model on a matplotlib axis
+
+ :param model: FTS model
+ :param size: figure size
+ :param axis: matplotlib axis
+ :param rules_by_axis: number of rules plotted by column
+ :param columns: number of columns
+ :return:
+ """
+ if axis is None and rules_by_axis is None:
+ rows = 1
+ elif axis is None and rules_by_axis is not None:
+ rows = (((len(model.flrgs.keys())//rules_by_axis)) // columns)+1
+
+ fig, axis = plt.subplots(nrows=rows, ncols=columns, figsize=size)
+
+ if rules_by_axis is None:
+ draw_sets_on_axis(axis, model, size)
+
+ _lhs = model.partitioner.ordered_sets if not model.is_high_order else model.flrgs.keys()
+
+ for ct, key in enumerate(_lhs):
+
+ xticks = []
+ xtickslabels = []
+
+ if rules_by_axis is None:
+ ax = axis
+ else:
+ colcount = (ct // rules_by_axis) % columns
+ rowcount = (ct // rules_by_axis) // columns
+
+ if rows > 1 and columns > 1:
+ ax = axis[rowcount, colcount]
+ elif columns > 1:
+ ax = axis[rowcount]
+ else:
+ ax = axis
+
+ if ct % rules_by_axis == 0:
+ draw_sets_on_axis(ax, model, size)
+
+ if not model.is_high_order:
+ if key in model.flrgs:
+ x = (ct % rules_by_axis) + 1
+ flrg = model.flrgs[key]
+ y = model.sets[key].centroid
+ ax.plot([x],[y],'o')
+ xticks.append(x)
+ xtickslabels.append(key)
+ for rhs in flrg.RHS:
+ dest = model.sets[rhs].centroid
+ ax.arrow(x+.1, y, 0.8, dest - y, #length_includes_head=True,
+ head_width=0.1, head_length=0.1, shape='full', overhang=0,
+ fc='k', ec='k')
+ else:
+ flrg = model.flrgs[key]
+ x = (ct%rules_by_axis)*model.order + 1
+ for ct2, lhs in enumerate(flrg.LHS):
+ y = model.sets[lhs].centroid
+ ax.plot([x+ct2], [y], 'o')
+ xticks.append(x+ct2)
+ xtickslabels.append(lhs)
+ for ct2 in range(1, model.order):
+ fs1 = flrg.LHS[ct2-1]
+ fs2 = flrg.LHS[ct2]
+ y = model.sets[fs1].centroid
+ dest = model.sets[fs2].centroid
+ ax.plot([x+ct2-1,x+ct2], [y,dest],'-')
+
+ y = model.sets[flrg.LHS[-1]].centroid
+ for rhs in flrg.RHS:
+ dest = model.sets[rhs].centroid
+ ax.arrow(x + model.order -1 + .1, y, 0.8, dest - y, # length_includes_head=True,
+ head_width=0.1, head_length=0.1, shape='full', overhang=0,
+ fc='k', ec='k')
+
+
+ ax.set_xticks(xticks)
+ ax.set_xticklabels(xtickslabels)
+ ax.set_xlim([0,rules_by_axis*model.order+1])
+
+ plt.tight_layout()
+ plt.show()
+
+
+[docs]def draw_sets_on_axis(axis, model, size):
+ if axis is None:
+ fig, axis = plt.subplots(nrows=1, ncols=1, figsize=size)
+ for ct, key in enumerate(model.partitioner.ordered_sets):
+ fs = model.sets[key]
+ axis.plot([0, 1, 0], fs.parameters, label=fs.name)
+ axis.axhline(fs.centroid, c="lightgray", alpha=0.5)
+ axis.set_xlim([0, len(model.partitioner.ordered_sets)])
+ axis.set_xticks(range(0, len(model.partitioner.ordered_sets)))
+ tmp = ['']
+ tmp.extend(model.partitioner.ordered_sets)
+ axis.set_xticklabels(tmp)
+ axis.set_ylim([model.partitioner.min, model.partitioner.max])
+ axis.set_yticks([model.sets[k].centroid for k in model.partitioner.ordered_sets])
+ axis.set_yticklabels([str(round(model.sets[k].centroid, 1)) + " - " + k
+ for k in model.partitioner.ordered_sets])
+
+
+current_milli_time = lambda: int(round(time.time() * 1000))
+
+
+[docs]def uniquefilename(name):
+ if '.' in name:
+ tmp = name.split('.')
+ return tmp[0] + str(current_milli_time()) + '.' + tmp[1]
+ else:
+ return name + str(current_milli_time())
+
+
+[docs]def show_and_save_image(fig, file, flag, lgd=None):
+ """
+ Show and image and save on file
+
+ :param fig: Matplotlib Figure object
+ :param file: filename to save the picture
+ :param flag: if True the image will be saved
+ :param lgd: legend
+ """
+ plt.show()
+ if flag:
+ if lgd is not None:
+ fig.savefig(file, additional_artists=lgd,bbox_inches='tight') #bbox_extra_artists=(lgd,), )
+ else:
+ fig.savefig(file)
+ plt.close(fig)
+
+
+
+
+
+[docs]def sliding_window(data, windowsize, train=0.8, inc=0.1, **kwargs):
+ """
+ Sliding window method of cross validation for time series
+
+ :param data: the entire dataset
+ :param windowsize: window size
+ :param train: percentual of the window size will be used for training the models
+ :param inc: percentual of data used for slide the window
+ :return: window count, training set, test set
+ """
+
+ multivariate = True if isinstance(data, pd.DataFrame) else False
+
+ l = len(data) if not multivariate else len(data.index)
+ ttrain = int(round(windowsize * train, 0))
+ ic = int(round(windowsize * inc, 0))
+
+ progressbar = kwargs.get('progress', None)
+
+ rng = np.arange(0,l-windowsize+ic,ic)
+
+ if progressbar:
+ from tqdm import tqdm
+ rng = tqdm(rng)
+
+ for count in rng:
+ if count + windowsize > l:
+ _end = l
+ else:
+ _end = count + windowsize
+ if multivariate:
+ yield (count, data.iloc[count: count + ttrain], data.iloc[count + ttrain: _end])
+ else:
+ yield (count, data[count : count + ttrain], data[count + ttrain : _end] )
+
+
+[docs]def persist_obj(obj, file):
+ """
+ Persist an object on filesystem. This function depends on Dill package
+
+ :param obj: object on memory
+ :param file: file name to store the object
+ """
+ import dill
+ try:
+ with open(file, 'wb') as _file:
+ dill.dump(obj, _file)
+ except Exception as ex:
+ print("File {} could not be saved due exception {}".format(file, ex))
+
+
+[docs]def load_obj(file):
+ """
+ Load to memory an object stored filesystem. This function depends on Dill package
+
+ :param file: file name where the object is stored
+ :return: object
+ """
+ import dill
+ with open(file, 'rb') as _file:
+ obj = dill.load(_file)
+ return obj
+
+
+[docs]def persist_env(file):
+ """
+ Persist an entire environment on file. This function depends on Dill package
+
+ :param file: file name to store the environment
+ """
+ import dill
+ dill.dump_session(file)
+
+
+
+
+
+
+
Source code for pyFTS.common.fts
+import numpy as np
+import pandas as pd
+from pyFTS.common import FuzzySet, SortedCollection, tree, Util
+
+
+[docs]class FTS(object):
+ """
+ Fuzzy Time Series object model
+ """
+ def __init__(self, **kwargs):
+ """
+ Create a Fuzzy Time Series model
+ """
+ self.flrgs = {}
+ """The list of Fuzzy Logical Relationship Groups - FLRG"""
+ self.order = kwargs.get('order',1)
+ """A integer with the model order (number of past lags are used on forecasting)"""
+ self.shortname = kwargs.get('name',"")
+ """A string with a short name or alias for the model"""
+ self.name = kwargs.get('name',"")
+ """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
+ """In high order models, this integer value indicates the minimal order supported for the model, default: 1"""
+ self.has_seasonality = False
+ """A boolean value indicating if the model supports seasonal indexers, default: False"""
+ self.has_point_forecasting = True
+ """A boolean value indicating if the model supports point forecasting, default: True"""
+ self.has_interval_forecasting = False
+ """A boolean value indicating if the model supports interval forecasting, default: False"""
+ self.has_probability_forecasting = False
+ """A boolean value indicating if the model support probabilistic forecasting, default: False"""
+ self.is_multivariate = False
+ """A boolean value indicating if the model support multivariate time series (Pandas DataFrame), default: False"""
+ self.is_clustered = False
+ """A boolean value indicating if the model support multivariate time series (Pandas DataFrame), but works like
+ a monovariate method, default: False"""
+ self.dump = False
+ self.transformations = []
+ """A list with the data transformations (common.Transformations) applied on model pre and post processing, default: []"""
+ self.transformations_param = []
+ """A list with the specific parameters for each data transformation"""
+ self.original_max = 0
+ """A float with the upper limit of the Universe of Discourse, the maximal value found on training data"""
+ self.original_min = 0
+ """A float with the lower limit of the Universe of Discourse, the minimal value found on training data"""
+ self.partitioner = kwargs.get("partitioner", None)
+ """A pyFTS.partitioners.Partitioner object with the Universe of Discourse partitioner used on the model. This is a mandatory dependecy. """
+ if self.partitioner != None:
+ self.sets = self.partitioner.sets
+ self.auto_update = False
+ """A boolean value indicating that model is incremental"""
+ self.benchmark_only = False
+ """A boolean value indicating a façade for external (non-FTS) model used on benchmarks or ensembles."""
+ self.indexer = kwargs.get("indexer", None)
+ """An pyFTS.models.seasonal.Indexer object for indexing the time series data"""
+ self.uod_clip = kwargs.get("uod_clip", True)
+ """Flag indicating if the test data will be clipped inside the training Universe of Discourse"""
+ self.alpha_cut = kwargs.get("alpha_cut", 0.0)
+ """A float with the minimal membership to be considered on fuzzyfication process"""
+ self.lags = kwargs.get("lags", None)
+ """The list of lag indexes for high order models"""
+ self.max_lag = self.order
+ """A integer indicating the largest lag used by the model. This value also indicates the minimum number of past lags
+ needed to forecast a single step ahead"""
+ self.log = pd.DataFrame([],columns=["Datetime","Operation","Value"])
+ """"""
+ self.is_time_variant = False
+ """A boolean value indicating if this model is time variant"""
+ self.standard_horizon = kwargs.get("standard_horizon", 1)
+ """Standard forecasting horizon (Default: 1)"""
+
+
+[docs] 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.partitioner.sets:
+ fset = self.partitioner.sets[f]
+ if best["membership"] <= fset.membership(data):
+ best["fuzzyset"] = fset.name
+ best["membership"] = fset.membership(data)
+
+ return best
+
+[docs] def clip_uod(self, ndata):
+ if self.uod_clip and self.partitioner is not None:
+ ndata = np.clip(ndata, self.partitioner.min, self.partitioner.max)
+ elif self.uod_clip:
+ ndata = np.clip(ndata, self.original_min, self.original_max)
+ return ndata
+
+[docs] def predict(self, data, **kwargs):
+ """
+ Forecast using trained model
+
+ :param data: time series with minimal length to the order of the model
+
+ :keyword type: the forecasting type, one of these values: point(default), interval, distribution or multivariate.
+ :keyword steps_ahead: The forecasting path H, i. e., tell the model to forecast from t+1 to t+H.
+ :keyword step_to: The forecasting step H, i. e., tell the model to forecast to t+H for each input sample
+ :keyword start_at: in the multi step forecasting, the index of the data where to start forecasting (default value: 0)
+ :keyword distributed: boolean, indicate if the forecasting procedure will be distributed in a dispy cluster (default value: False)
+ :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. (default value: False)
+ :keyword generators: for multivariate methods on multi step ahead forecasting, generators is a dict where the keys
+ are the dataframe columun 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 or trained FTS
+ models that accept the actual values and forecast new ones.
+
+ :return: a numpy array with the forecasted data
+ """
+ import copy
+
+ kw = copy.deepcopy(kwargs)
+
+ if self.is_multivariate:
+ ndata = data
+ else:
+ ndata = self.apply_transformations(data)
+
+ ndata = self.clip_uod(ndata)
+
+ if 'distributed' in kw:
+ distributed = kw.pop('distributed')
+ else:
+ distributed = False
+
+ if 'type' in kw:
+ type = kw.pop("type")
+ else:
+ type = 'point'
+
+ if distributed is None or distributed == False:
+
+ steps_ahead = kw.get("steps_ahead", None)
+
+ step_to = kw.get("step_to", None)
+
+ if (steps_ahead == None and step_to == None) or (steps_ahead == 1 or step_to ==1):
+ if type == 'point':
+ ret = self.forecast(ndata, **kw)
+ elif type == 'interval':
+ ret = self.forecast_interval(ndata, **kw)
+ elif type == 'distribution':
+ ret = self.forecast_distribution(ndata, **kw)
+ elif type == 'multivariate':
+ ret = self.forecast_multivariate(ndata, **kw)
+ elif step_to == None and steps_ahead > 1:
+ if type == 'point':
+ ret = self.forecast_ahead(ndata, steps_ahead, **kw)
+ elif type == 'interval':
+ ret = self.forecast_ahead_interval(ndata, steps_ahead, **kw)
+ elif type == 'distribution':
+ ret = self.forecast_ahead_distribution(ndata, steps_ahead, **kw)
+ elif type == 'multivariate':
+ ret = self.forecast_ahead_multivariate(ndata, steps_ahead, **kw)
+ elif step_to > 1:
+ if type == 'point':
+ ret = self.forecast_step(ndata, step_to, **kw)
+ else:
+ raise NotImplementedError('This model only perform point step ahead forecasts!')
+
+ if not ['point', 'interval', 'distribution', 'multivariate'].__contains__(type):
+ raise ValueError('The argument \'type\' has an unknown value.')
+
+ else:
+
+ if distributed == 'dispy':
+ from pyFTS.distributed import dispy
+
+ nodes = kw.pop("nodes", ['127.0.0.1'])
+ num_batches = kw.pop('num_batches', 10)
+
+ ret = dispy.distributed_predict(self, kw, nodes, ndata, num_batches, **kw)
+
+ elif distributed == 'spark':
+ from pyFTS.distributed import spark
+
+ ret = spark.distributed_predict(data=ndata, model=self, **kw)
+
+ if not self.is_multivariate:
+ kw['type'] = type
+ ret = self.apply_inverse_transformations(ret, params=[data[self.max_lag - 1:]], **kw)
+
+ if 'statistics' in kw:
+ kwargs['statistics'] = kw['statistics']
+
+ return ret
+
+[docs] def forecast(self, data, **kwargs):
+ """
+ Point forecast one step ahead
+
+ :param data: time series data with the minimal length equal to the max_lag of the model
+ :param kwargs: model specific parameters
+ :return: a list with the forecasted values
+ """
+ raise NotImplementedError('This model do not perform one step ahead point forecasts!')
+
+[docs] def forecast_interval(self, data, **kwargs):
+ """
+ Interval forecast one step ahead
+
+ :param data: time series data with the minimal length equal to the max_lag of the model
+ :param kwargs: model specific parameters
+ :return: a list with the prediction intervals
+ """
+ raise NotImplementedError('This model do not perform one step ahead interval forecasts!')
+
+[docs] def forecast_distribution(self, data, **kwargs):
+ """
+ Probabilistic forecast one step ahead
+
+ :param data: time series data with the minimal length equal to the max_lag of the model
+ :param kwargs: model specific parameters
+ :return: a list with probabilistic.ProbabilityDistribution objects representing the forecasted Probability Distributions
+ """
+ raise NotImplementedError('This model do not perform one step ahead distribution forecasts!')
+
+[docs] def forecast_multivariate(self, data, **kwargs):
+ """
+ Multivariate forecast one step ahead
+
+ :param data: Pandas dataframe with one column for each variable and with the minimal length equal to the max_lag of the model
+ :param kwargs: model specific parameters
+ :return: a Pandas Dataframe object representing the forecasted values for each variable
+ """
+ raise NotImplementedError('This model do not perform one step ahead multivariate forecasts!')
+
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+ """
+ Point forecast from 1 to H steps ahead, where H is given by the steps parameter
+
+ :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 (default: 1)
+ :keyword start_at: in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+ :return: a list with the forecasted values
+ """
+
+ if len(data) < self.max_lag:
+ return data
+
+ if isinstance(data, np.ndarray):
+ data = data.tolist()
+
+ start = kwargs.get('start_at',0)
+
+ ret = data[:start+self.max_lag]
+ for k in np.arange(start+self.max_lag, steps+start+self.max_lag):
+ tmp = self.forecast(ret[k-self.max_lag:k], **kwargs)
+
+ if isinstance(tmp,(list, np.ndarray)):
+ tmp = tmp[-1]
+
+ ret.append(tmp)
+ data.append(tmp)
+
+ return ret[-steps:]
+
+[docs] def forecast_ahead_interval(self, data, steps, **kwargs):
+ """
+ Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
+
+ :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
+ :keyword start_at: in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+ :return: a list with the forecasted intervals
+ """
+ raise NotImplementedError('This model do not perform multi step ahead interval forecasts!')
+
+[docs] def forecast_ahead_distribution(self, data, steps, **kwargs):
+ """
+ Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
+
+ :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
+ :keyword start_at: in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+ :return: a list with the forecasted Probability Distributions
+ """
+ raise NotImplementedError('This model do not perform multi step ahead distribution forecasts!')
+
+[docs] def forecast_ahead_multivariate(self, data, steps, **kwargs):
+ """
+ Multivariate forecast n step ahead
+
+ :param data: Pandas dataframe with one column for each variable and with the minimal length equal to the max_lag of the model
+ :param steps: the number of steps ahead to forecast
+ :keyword start_at: in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+ :return: a Pandas Dataframe object representing the forecasted values for each variable
+ """
+ raise NotImplementedError('This model do not perform one step ahead multivariate forecasts!')
+
+[docs] def forecast_step(self, data, step, **kwargs):
+ """
+ Point forecast for H steps ahead, where H is given by the step parameter
+
+ :param data: time series data with the minimal length equal to the max_lag of the model
+ :param step: the forecasting horizon (default: 1)
+ :keyword start_at: in the multi step forecasting, the index of the data where to start forecasting (default: 0)
+ :return: a list with the forecasted values
+ """
+
+ l = len(data)
+
+ ret = []
+
+ if l < self.max_lag:
+ return data
+
+ if isinstance(data, np.ndarray):
+ data = data.tolist()
+
+ start = kwargs.get('start_at',0)
+
+ for k in np.arange(start+self.max_lag, l):
+ sample = data[k-self.max_lag:k]
+ tmp = self.forecast_ahead(sample, step, **kwargs)
+
+ if isinstance(tmp,(list, np.ndarray)):
+ tmp = tmp[-1]
+
+ ret.append(tmp)
+
+ return ret
+
+[docs] def train(self, data, **kwargs):
+ """
+ Method specific parameter fitting
+
+ :param data: training time series data
+ :param kwargs: Method specific parameters
+
+ """
+ pass
+
+[docs] def fit(self, ndata, **kwargs):
+ """
+ Fit the model's parameters based on the training data.
+
+ :param ndata: training time series data
+ :param kwargs:
+
+ :keyword num_batches: split the training data in num_batches to save memory during the training process
+ :keyword save_model: save final model on disk
+ :keyword batch_save: save the model between each batch
+ :keyword file_path: path to save the model
+ :keyword distributed: boolean, indicate if the training procedure will be distributed in a dispy cluster
+ :keyword nodes: a list with the dispy cluster nodes addresses
+
+ """
+
+ import datetime, copy
+
+ kw = copy.deepcopy(kwargs)
+
+ if self.is_multivariate:
+ data = ndata
+ else:
+ data = self.apply_transformations(ndata)
+
+ self.original_min = np.nanmin(data)
+ self.original_max = np.nanmax(data)
+
+ if 'partitioner' in kw:
+ self.partitioner = kw.pop('partitioner')
+
+ if not self.is_multivariate and not self.is_wrapper and not self.benchmark_only:
+ if self.partitioner is None:
+ raise Exception("Fuzzy sets were not provided for the model. Use 'partitioner' parameter. ")
+
+ if 'order' in kw:
+ self.order = kw.pop('order')
+
+ dump = kw.get('dump', None)
+
+ num_batches = kw.pop('num_batches', None)
+
+ save = kw.get('save_model', False) # save model on disk
+
+ batch_save = kw.get('batch_save', False) #save model between batches
+
+ file_path = kw.get('file_path', None)
+
+ distributed = kw.pop('distributed', False)
+
+ if distributed is not None and distributed:
+ if num_batches is None:
+ num_batches = 10
+
+ if distributed == 'dispy':
+ from pyFTS.distributed import dispy
+ nodes = kw.pop('nodes', False)
+ train_method = kwargs.get('train_method', dispy.simple_model_train)
+ dispy.distributed_train(self, train_method, nodes, type(self), data, num_batches, {},
+ **kw)
+ elif distributed == 'spark':
+ from pyFTS.distributed import spark
+ url = kwargs.get('url', 'spark://127.0.0.1:7077')
+ app = kwargs.get('app', 'pyFTS')
+
+ spark.distributed_train(self, data, url=url, app=app)
+ else:
+
+ if dump == 'time':
+ print("[{0: %H:%M:%S}] Start training".format(datetime.datetime.now()))
+
+ if num_batches is not None and not self.is_wrapper:
+ n = len(data)
+ batch_size = int(n / num_batches)
+ bcount = 1
+
+ rng = range(self.order, n, batch_size)
+
+ if dump == 'tqdm':
+ from tqdm import tqdm
+
+ rng = tqdm(rng)
+
+ for ct in rng:
+ if dump == 'time':
+ print("[{0: %H:%M:%S}] Starting batch ".format(datetime.datetime.now()) + str(bcount))
+ if self.is_multivariate:
+ mdata = data.iloc[ct - self.order:ct + batch_size]
+ else:
+ mdata = data[ct - self.order : ct + batch_size]
+
+ self.train(mdata, **kw)
+
+ if batch_save:
+ Util.persist_obj(self,file_path)
+
+ if dump == 'time':
+ print("[{0: %H:%M:%S}] Finish batch ".format(datetime.datetime.now()) + str(bcount))
+
+ bcount += 1
+
+ else:
+ self.train(data, **kw)
+
+ if dump == 'time':
+ print("[{0: %H:%M:%S}] Finish training".format(datetime.datetime.now()))
+
+ if save:
+ Util.persist_obj(self, file_path)
+
+
+[docs] def clone_parameters(self, model):
+ """
+ Import the parameters values from other model
+
+ :param model: a model to clone the parameters
+ """
+
+ self.order = model.order
+ self.partitioner = model.partitioner
+ self.lags = model.lags
+ self.shortname = model.shortname
+ self.name = model.name
+ self.detail = model.detail
+ self.is_high_order = model.is_high_order
+ self.min_order = model.min_order
+ self.has_seasonality = model.has_seasonality
+ self.has_point_forecasting = model.has_point_forecasting
+ self.has_interval_forecasting = model.has_interval_forecasting
+ self.has_probability_forecasting = model.has_probability_forecasting
+ self.is_multivariate = model.is_multivariate
+ self.dump = model.dump
+ self.transformations = model.transformations
+ self.transformations_param = model.transformations_param
+ self.original_max = model.original_max
+ self.original_min = model.original_min
+ self.auto_update = model.auto_update
+ self.benchmark_only = model.benchmark_only
+ self.indexer = model.indexer
+
+[docs] def append_rule(self, flrg):
+ """
+ Append FLRG rule to the model
+
+ :param flrg: rule
+ :return:
+ """
+
+ if flrg.get_key() not in self.flrgs:
+ self.flrgs[flrg.get_key()] = flrg
+ else:
+ if isinstance(flrg.RHS, (list, set)):
+ for k in flrg.RHS:
+ self.flrgs[flrg.get_key()].append_rhs(k)
+ elif isinstance(flrg.RHS, dict):
+ for key, value in flrg.RHS.items():
+ self.flrgs[flrg.get_key()].append_rhs(key, count=value)
+ else:
+ self.flrgs[flrg.get_key()].append_rhs(flrg.RHS)
+
+[docs] def merge(self, model):
+ """
+ Merge the FLRG rules from other model
+
+ :param model: source model
+ :return:
+ """
+
+ for key, flrg in model.flrgs.items():
+ self.append_rule(flrg)
+
+[docs] def append_transformation(self, transformation):
+ if transformation is not None:
+ self.transformations.append(transformation)
+
+[docs] def apply_transformations(self, data, params=None, updateUoD=False, **kwargs):
+ """
+ Apply the data transformations for data preprocessing
+
+ :param data: input data
+ :param params: transformation parameters
+ :param updateUoD:
+ :param kwargs:
+ :return: preprocessed data
+ """
+
+ ndata = data
+ if updateUoD:
+ if min(data) < 0:
+ self.original_min = min(data) * 1.1
+ else:
+ self.original_min = min(data) * 0.9
+
+ if max(data) > 0:
+ self.original_max = max(data) * 1.1
+ else:
+ self.original_max = max(data) * 0.9
+
+ if len(self.transformations) > 0:
+ if params is None:
+ params = [ None for k in self.transformations]
+
+ for c, t in enumerate(self.transformations, start=0):
+ ndata = t.apply(ndata, params[c], )
+
+ return ndata
+
+[docs] def apply_inverse_transformations(self, data, params=None, **kwargs):
+ """
+ Apply the data transformations for data postprocessing
+
+ :param data: input data
+ :param params: transformation parameters
+ :param updateUoD:
+ :param kwargs:
+ :return: postprocessed data
+ """
+ if len(self.transformations) > 0:
+ if params is None:
+ params = [None for k in self.transformations]
+
+ for c, t in enumerate(reversed(self.transformations), start=0):
+ ndata = t.inverse(data, params[c], **kwargs)
+
+ return ndata
+ else:
+ return data
+
+[docs] def get_UoD(self):
+ """
+ Returns the interval of the known bounds of the universe of discourse (UoD), i. e.,
+ the known minimum and maximum values of the time series.
+
+ :return: A set with the lower and the upper bounds of the UoD
+ """
+ if self.partitioner is not None:
+ return (self.partitioner.min, self.partitioner.max)
+ else:
+ return (self.original_min, self.original_max)
+
+[docs] def offset(self):
+ """
+ Returns the number of lags to skip in the input test data in order to synchronize it with
+ the forecasted values given by the predict function. This is necessary due to the order of the
+ model, among other parameters.
+
+ :return: An integer with the number of lags to skip
+ """
+ if self.is_high_order:
+ return self.max_lag
+ else:
+ return 1
+
+ def __str__(self):
+ """
+ String representation of the model
+
+ :return: a string containing the name of the model and the learned rules
+ (if the model was already trained)
+ """
+
+ tmp = self.name + ":\n"
+ if self.partitioner.type == 'common':
+ for r in sorted(self.flrgs, key=lambda key: self.flrgs[key].get_midpoint(self.partitioner.sets)):
+ tmp = "{0}{1}\n".format(tmp, str(self.flrgs[r]))
+ else:
+ for r in self.flrgs:
+ tmp = "{0}{1}\n".format(tmp, str(self.flrgs[r]))
+ return tmp
+
+ def __len__(self):
+ """
+ The length (number of rules) of the model
+
+ :return: number of rules
+ """
+ return len(self.flrgs)
+
+[docs] def len_total(self):
+ """
+ Total length of the model, adding the number of terms in all rules
+
+ :return:
+ """
+ return sum([len(k) for k in self.flrgs])
+
+[docs] def reset_calculated_values(self):
+ """
+ Reset all pre-calculated values on the FLRG's
+
+ :return:
+ """
+
+ for flrg in self.flrgs.keys():
+ self.flrgs[flrg].reset_calculated_values()
+
+
+
+
+
+
+
+
+
Source code for pyFTS.distributed.dispy
+import dispy as dispy, dispy.httpd, logging
+from pyFTS.common import Util
+import numpy as np
+
+
+[docs]def start_dispy_cluster(method, nodes):
+ """
+ Start a new Dispy cluster on 'nodes' to execute the method 'method'
+
+ :param method: function to be executed on each cluster node
+ :param nodes: list of node names or IP's.
+ :return: the dispy cluster instance and the http_server for monitoring
+ """
+
+ cluster = dispy.JobCluster(method, nodes=nodes, loglevel=logging.DEBUG, ping_interval=1000)
+
+ http_server = dispy.httpd.DispyHTTPServer(cluster)
+
+ return cluster, http_server
+
+
+[docs]def stop_dispy_cluster(cluster, http_server):
+ """
+ Stop a dispy cluster and http_server
+
+ :param cluster:
+ :param http_server:
+ :return:
+ """
+ #cluster.wait() # wait for all jobs to finish
+
+ cluster.print_status()
+
+ http_server.shutdown() # this waits until browser gets all updates
+ cluster.close()
+
+
+[docs]def get_number_of_cpus(cluster):
+ cpus = 0
+ for dispy_node in cluster.status().nodes:
+ cpus += dispy_node.cpus
+
+ return cpus
+
+
+[docs]def simple_model_train(model, data, parameters):
+ import time
+ """
+ Cluster function that receives a FTS instance 'model' and train using the 'data' and 'parameters'
+
+ :param model: a FTS instance
+ :param data: training dataset
+ :param parameters: parameters for the training process
+ :return: the trained model
+ """
+ _start = time.time()
+ model.train(data, **parameters)
+ _end = time.time()
+ model.__dict__['training_time'] = _end - _start
+ return model
+
+
+[docs]def distributed_train(model, train_method, nodes, fts_method, data, num_batches=10,
+ train_parameters={}, **kwargs):
+ import dispy, dispy.httpd, datetime
+
+ batch_save = kwargs.get('batch_save', False) # save model between batches
+
+ batch_save_interval = kwargs.get('batch_save_interval', 1)
+
+ file_path = kwargs.get('file_path', None)
+
+ cluster, http_server = start_dispy_cluster(train_method, nodes)
+
+ print("[{0: %H:%M:%S}] Distrituted Train Started with {1} CPU's"
+ .format(datetime.datetime.now(), get_number_of_cpus(cluster)))
+
+ jobs = []
+ n = len(data)
+ batch_size = int(n / num_batches)
+ bcount = 1
+ for ct in range(model.order, n, batch_size):
+ if model.is_multivariate:
+ ndata = data.iloc[ct - model.order:ct + batch_size]
+ else:
+ ndata = data[ct - model.order: ct + batch_size]
+
+ tmp_model = fts_method()
+
+ tmp_model.clone_parameters(model)
+
+ job = cluster.submit(tmp_model, ndata, train_parameters)
+ job.id = bcount # associate an ID to identify jobs (if needed later)
+ jobs.append(job)
+
+ bcount += 1
+
+ for job in jobs:
+ print("[{0: %H:%M:%S}] Processing batch ".format(datetime.datetime.now()) + str(job.id))
+ tmp = job()
+ if job.status == dispy.DispyJob.Finished and tmp is not None:
+ model.merge(tmp)
+ if 'training_time' not in model.__dict__:
+ model.__dict__['training_time'] = []
+ model.__dict__['training_time'].append(tmp.__dict__['training_time'])
+
+ if batch_save and (job.id % batch_save_interval) == 0:
+ Util.persist_obj(model, file_path)
+
+ else:
+ print(job.exception)
+ print(job.stdout)
+
+ print("[{0: %H:%M:%S}] Finished batch ".format(datetime.datetime.now()) + str(job.id))
+
+ print("[{0: %H:%M:%S}] Distrituted Train Finished".format(datetime.datetime.now()))
+
+ stop_dispy_cluster(cluster, http_server)
+
+ return model
+
+
+[docs]def simple_model_predict(model, data, parameters):
+ import time
+ _start = time.time()
+ forecasts = model.predict(data, **parameters)
+ _stop = time.time()
+ return forecasts, _stop - _start
+
+
+[docs]def distributed_predict(model, parameters, nodes, data, num_batches, **kwargs):
+ import dispy, dispy.httpd
+
+ cluster, http_server = start_dispy_cluster(simple_model_predict, nodes)
+
+ jobs = []
+ n = len(data)
+ batch_size = int(n / num_batches)
+ bcount = 1
+ for ct in range(model.order, n, batch_size):
+ if model.is_multivariate:
+ ndata = data.iloc[ct - model.order:ct + batch_size]
+ else:
+ ndata = data[ct - model.order: ct + batch_size]
+
+ job = cluster.submit(model, ndata, parameters)
+ job.id = bcount # associate an ID to identify jobs (if needed later)
+ jobs.append(job)
+
+ bcount += 1
+
+ ret = []
+
+ for job in jobs:
+ tmp = job()
+ if job.status == dispy.DispyJob.Finished and tmp is not None:
+ if job.id < batch_size:
+ ret.extend(tmp[0][:-1])
+ else:
+ ret.extend(tmp[0])
+
+ if 'forecasting_time' not in model.__dict__:
+ model.__dict__['forecasting_time'] = []
+ model.__dict__['forecasting_time'].append(tmp[1])
+
+ else:
+ print(job.exception)
+ print(job.stdout)
+
+ stop_dispy_cluster(cluster, http_server)
+
+ return ret
+
Source code for pyFTS.hyperparam.Evolutionary
+"""
+Distributed Evolutionary Hyperparameter Optimization (DEHO) for MVFTS
+"""
+
+import numpy as np
+import pandas as pd
+import math
+import time
+from functools import reduce
+from operator import itemgetter
+
+import random
+from pyFTS.common import Util
+from pyFTS.benchmarks import Measures
+from pyFTS.partitioners import Grid, Entropy # , Huarng
+from pyFTS.common import Membership
+from pyFTS.models import hofts, ifts, pwfts
+from pyFTS.hyperparam import Util as hUtil
+
+
+__measures = ['f1', 'f2', 'rmse', 'size']
+
+
+[docs]def genotype(mf, npart, partitioner, order, alpha, lags, f1, f2):
+ """
+ Create the individual genotype
+
+ :param mf: membership function
+ :param npart: number of partitions
+ :param partitioner: partitioner method
+ :param order: model order
+ :param alpha: alpha-cut
+ :param lags: array with lag indexes
+ :param f1: accuracy fitness value
+ :param f2: parsimony fitness value
+ :return: the genotype, a dictionary with all hyperparameters
+ """
+ ind = dict(mf=mf, npart=npart, partitioner=partitioner, order=order,
+ alpha=alpha, lags=lags, f1=f1, f2=f2)
+ return ind
+
+
+[docs]def random_genotype(**kwargs):
+ """
+ Create random genotype
+
+ :return: the genotype, a dictionary with all hyperparameters
+ """
+ order = random.randint(1, 3)
+ lags = [k for k in np.arange(1, order+1)]
+ return genotype(
+ random.randint(1, 4),
+ random.randint(10, 100),
+ random.randint(1, 2),
+ order,
+ random.uniform(0, .5),
+ lags,
+ None,
+ None
+ )
+
+
+#
+[docs]def initial_population(n, **kwargs):
+ """
+ Create a random population of size n
+
+ :param n: the size of the population
+ :return: a list with n random individuals
+ """
+
+ create_random_individual = kwargs.get('random_individual', random_genotype)
+
+ pop = []
+ for i in range(n):
+ pop.append(create_random_individual(**kwargs))
+ return pop
+
+
+[docs]def phenotype(individual, train, fts_method, parameters={}, **kwargs):
+ """
+ Instantiate the genotype, creating a fitted model with the genotype hyperparameters
+
+ :param individual: a genotype
+ :param train: the training dataset
+ :param fts_method: the FTS method
+ :param parameters: dict with model specific arguments for fit method.
+ :return: a fitted FTS model
+ """
+ from pyFTS.models import hofts, ifts, pwfts
+
+ 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:
+ partitioner = Entropy.EntropyPartitioner(data=train, npart=individual['npart'], func=mf)
+
+ model = fts_method(partitioner=partitioner,
+ lags=individual['lags'],
+ alpha_cut=individual['alpha'],
+ order=individual['order'])
+
+ model.fit(train, **parameters)
+
+ return model
+
+
+[docs]def evaluate(dataset, individual, **kwargs):
+ """
+ Evaluate an individual using a sliding window cross validation over the dataset.
+
+ :param dataset: Evaluation dataset
+ :param individual: genotype to be tested
+ :param window_size: The length of scrolling window for train/test on dataset
+ :param train_rate: The train/test split ([0,1])
+ :param increment_rate: The increment of the scrolling window, relative to the window_size ([0,1])
+ :param parameters: dict with model specific arguments for fit method.
+ :return: a tuple (len_lags, rmse) with the parsimony fitness value and the accuracy fitness value
+ """
+ from pyFTS.models import hofts, ifts, pwfts
+ from pyFTS.common import Util
+ from pyFTS.benchmarks import Measures
+ from pyFTS.hyperparam.Evolutionary import phenotype, __measures
+ import numpy as np
+
+ window_size = kwargs.get('window_size', 800)
+ train_rate = kwargs.get('train_rate', .8)
+ increment_rate = kwargs.get('increment_rate', .2)
+ fts_method = kwargs.get('fts_method', hofts.WeightedHighOrderFTS)
+ parameters = kwargs.get('parameters',{})
+
+ if individual['f1'] is not None and individual['f2'] is not None:
+ return { key: individual[key] for key in __measures }
+
+ errors = []
+ lengths = []
+
+ for count, train, test in Util.sliding_window(dataset, window_size, train=train_rate, inc=increment_rate):
+
+ try:
+
+ model = phenotype(individual, train, fts_method=fts_method, parameters=parameters)
+
+ forecasts = model.predict(test)
+
+ rmse = Measures.rmse(test[model.max_lag:], forecasts[:-1])
+ lengths.append(len(model))
+
+ errors.append(rmse)
+
+ except:
+ lengths.append(np.nan)
+ errors.append(np.nan)
+
+ try:
+ _lags = sum(model.lags) * 100
+
+ _rmse = np.nanmean(errors)
+ _len = np.nanmean(lengths)
+
+ f1 = np.nansum([.6 * _rmse, .4 * np.nanstd(errors)])
+ f2 = np.nansum([.4 * _len, .6 * _lags])
+
+ return {'f1': f1, 'f2': f2, 'rmse': _rmse, 'size': _len }
+ except:
+ return {'f1': np.inf, 'f2': np.inf, 'rmse': np.inf, 'size': np.inf}
+
+
+[docs]def tournament(population, objective, **kwargs):
+ """
+ Simple tournament selection strategy.
+
+ :param population: the population
+ :param objective: the objective to be considered on tournament
+ :return:
+ """
+ n = len(population) - 1
+
+ r1 = random.randint(0, n) if n > 2 else 0
+ r2 = random.randint(0, n) if n > 2 else 1
+ ix = r1 if population[r1][objective] < population[r2][objective] else r2
+ return population[ix]
+
+
+[docs]def double_tournament(population, **kwargs):
+ """
+ Double tournament selection strategy.
+
+ :param population:
+ :return:
+ """
+
+ ancestor1 = tournament(population, 'f1')
+ ancestor2 = tournament(population, 'f1')
+
+ selected = tournament([ancestor1, ancestor2], 'f2')
+
+ return selected
+
+
+[docs]def lag_crossover2(best, worst):
+ """
+ Cross over two lag genes
+
+ :param best: best genotype
+ :param worst: worst genotype
+ :return: a tuple (order, lags)
+ """
+ order = int(round(.7 * best['order'] + .3 * worst['order']))
+ lags = []
+
+ min_order = min(best['order'], worst['order'])
+
+ max_order = best if best['order'] > min_order else worst
+
+ for k in np.arange(0, order):
+ if k < min_order:
+ lags.append(int(round(.7 * best['lags'][k] + .3 * worst['lags'][k])))
+ else:
+ lags.append(max_order['lags'][k])
+
+ for k in range(1, order):
+ while lags[k - 1] >= lags[k]:
+ lags[k] += random.randint(1, 10)
+
+ return order, lags
+
+
+[docs]def crossover(population, **kwargs):
+ """
+ Crossover operation between two parents
+
+ :param population: the original population
+ :return: a genotype
+ """
+ import random
+
+ n = len(population) - 1
+
+ r1, r2 = 0, 0
+ while r1 == r2:
+ r1 = random.randint(0, n)
+ r2 = random.randint(0, n)
+
+ if population[r1]['f1'] < population[r2]['f1']:
+ best = population[r1]
+ worst = population[r2]
+ else:
+ best = population[r2]
+ worst = population[r1]
+
+ npart = int(round(.7 * best['npart'] + .3 * worst['npart']))
+ alpha = float(.7 * best['alpha'] + .3 * worst['alpha'])
+
+ rnd = random.uniform(0, 1)
+ mf = best['mf'] if rnd < .7 else worst['mf']
+
+ rnd = random.uniform(0, 1)
+ partitioner = best['partitioner'] if rnd < .7 else worst['partitioner']
+
+ order, lags = lag_crossover2(best, worst)
+
+ descendent = genotype(mf, npart, partitioner, order, alpha, lags, None, None)
+
+ return descendent
+
+
+[docs]def mutation_lags(lags, order):
+ """
+ Mutation operation for lags gene
+
+ :param lags:
+ :param order:
+ :return:
+ """
+ try:
+ l = len(lags)
+ new = []
+ for lag in np.arange(order):
+ if lag < l:
+ new.append( min(50, max(1, int(lags[lag] + np.random.randint(-5, 5)))) )
+ else:
+ new.append( new[-1] + np.random.randint(1, 5) )
+
+ if order > 1:
+ for k in np.arange(1, order):
+ while new[k] <= new[k - 1]:
+ new[k] = int(new[k] + np.random.randint(1, 5))
+
+ return new
+ except Exception as ex:
+ print(lags, order, new, lag)
+
+
+[docs]def mutation(individual, **kwargs):
+ """
+ Mutation operator
+
+ :param individual: an individual genotype
+ :param pmut: individual probability o
+ :return:
+ """
+
+ individual['npart'] = min(50, max(3, int(individual['npart'] + np.random.normal(0, 4))))
+ individual['alpha'] = min(.5, max(0, individual['alpha'] + np.random.normal(0, .5)))
+ individual['mf'] = random.randint(1, 2)
+ individual['partitioner'] = random.randint(1, 2)
+ individual['order'] = min(5, max(1, int(individual['order'] + np.random.normal(0, 1))))
+ # Chama a função mutation_lags
+ individual['lags'] = mutation_lags( individual['lags'], individual['order'])
+
+ individual['f1'] = None
+ individual['f2'] = None
+
+ return individual
+
+
+[docs]def elitism(population, new_population, **kwargs):
+ """
+ Elitism operation, always select the best individual of the population and discard the worst
+
+ :param population:
+ :param new_population:
+ :return:
+ """
+ population = sorted(population, key=itemgetter('f1'))
+ best = population[0]
+
+ new_population = sorted(new_population, key=itemgetter('f1'))
+ if new_population[0]["f1"] > best["f1"]:
+ new_population.insert(0,best)
+ elif new_population[0]["f1"] == best["f1"] and new_population[0]["f2"] > best["f2"]:
+ new_population.insert(0, best)
+
+ return new_population
+
+
+[docs]def GeneticAlgorithm(dataset, **kwargs):
+ """
+ Genetic algoritm for Distributed Evolutionary Hyperparameter Optimization (DEHO)
+
+ :param dataset: The time series to optimize the FTS
+ :keyword ngen: An integer value with the maximum number of generations, default value: 30
+ :keyword mgen: An integer value with the maximum number of generations without improvement to stop, default value 7
+ :keyword npop: An integer value with the population size, default value: 20
+ :keyword pcross: A float value between 0 and 1 with the probability of crossover, default: .5
+ :keyword psel: A float value between 0 and 1 with the probability of selection, default: .5
+ :keyword pmut: A float value between 0 and 1 with the probability of mutation, default: .3
+ :keyword fts_method: The FTS method to optimize
+ :keyword parameters: dict with model specific arguments for fts_method
+ :keyword elitism: A boolean value indicating if the best individual must always survive to next population
+ :keyword initial_operator: a function that receives npop and return a random population with size npop
+ :keyword evalutation_operator: a function that receives a dataset and an individual and return its fitness
+ :keyword selection_operator: a function that receives the whole population and return a selected individual
+ :keyword crossover_operator: a function that receives the whole population and return a descendent individual
+ :keyword mutation_operator: a function that receives one individual and return a changed individual
+ :keyword window_size: An integer value with the the length of scrolling window for train/test on dataset
+ :keyword train_rate: A float value between 0 and 1 with the train/test split ([0,1])
+ :keyword increment_rate: A float value between 0 and 1 with the the increment of the scrolling window,
+ relative to the window_size ([0,1])
+ :keyword collect_statistics: A boolean value indicating to collect statistics for each generation
+ :keyword distributed: A value indicating it the execution will be local and sequential (distributed=False),
+ or parallel and distributed (distributed='dispy' or distributed='spark')
+ :keyword cluster: If distributed='dispy' the list of cluster nodes, else if distributed='spark' it is the master node
+ :return: the best genotype
+ """
+
+ statistics = []
+
+ ngen = kwargs.get('ngen',30)
+ mgen = kwargs.get('mgen', 7)
+ npop = kwargs.get('npop',20)
+ psel = kwargs.get('psel', .5)
+ pcross = kwargs.get('pcross',.5)
+ pmut = kwargs.get('pmut',.3)
+ distributed = kwargs.get('distributed', False)
+
+ initial_operator = kwargs.get('initial_operator', initial_population)
+ evaluation_operator = kwargs.get('evaluation_operator', evaluate)
+ selection_operator = kwargs.get('selection_operator', double_tournament)
+ crossover_operator = kwargs.get('crossover_operator', crossover)
+ mutation_operator = kwargs.get('mutation_operator', mutation)
+
+ _elitism = kwargs.get('elitism', True)
+
+ elitism_operator = kwargs.get('elitism_operator', elitism)
+
+ if distributed == 'dispy':
+ cluster = kwargs.pop('cluster', None)
+
+ collect_statistics = kwargs.get('collect_statistics', True)
+
+ no_improvement_count = 0
+
+ new_population = []
+
+ population = initial_operator(npop, **kwargs)
+
+ last_best = population[0]
+ best = population[1]
+
+ print("Evaluating initial population {}".format(time.time()))
+ if not distributed:
+ for individual in population:
+ ret = evaluation_operator(dataset, individual, **kwargs)
+ for key in __measures:
+ individual[key] = ret[key]
+ elif distributed=='dispy':
+ from pyFTS.distributed import dispy as dUtil
+ import dispy
+ jobs = []
+ for ct, individual in enumerate(population):
+ job = cluster.submit(dataset, individual, **kwargs)
+ job.id = ct
+ jobs.append(job)
+ for job in jobs:
+ result = job()
+ if job.status == dispy.DispyJob.Finished and result is not None:
+ for key in __measures:
+ population[job.id][key] = result[key]
+ else:
+ print(job.exception)
+ print(job.stdout)
+
+ for i in range(ngen):
+ print("GENERATION {} {}".format(i, time.time()))
+
+ generation_statistics = {}
+
+ # Selection
+ for j in range(int(npop * psel)):
+ new_population.append(selection_operator(population, **kwargs))
+
+ # Crossover
+ new = []
+ for j in range(int(npop * pcross)):
+ new.append(crossover_operator(new_population, **kwargs))
+
+ new_population.extend(new)
+
+ # Mutation
+ for ct, individual in enumerate(new_population):
+ rnd = random.uniform(0, 1)
+ if rnd < pmut:
+ new_population[ct] = mutation_operator(individual, **kwargs)
+
+ # Evaluation
+ if collect_statistics:
+ stats = {}
+ for key in __measures:
+ stats[key] = []
+
+ if not distributed:
+ for individual in new_population:
+ ret = evaluation_operator(dataset, individual, **kwargs)
+ for key in __measures:
+ individual[key] = ret[key]
+ if collect_statistics: stats[key].append(ret[key])
+
+ elif distributed == 'dispy':
+ jobs = []
+
+ for ct, individual in enumerate(new_population):
+ job = cluster.submit(dataset, individual, **kwargs)
+ job.id = ct
+ jobs.append(job)
+ for job in jobs:
+ print('job id {}'.format(job.id))
+ result = job()
+ if job.status == dispy.DispyJob.Finished and result is not None:
+ for key in __measures:
+ new_population[job.id][key] = result[key]
+ if collect_statistics: stats[key].append(result[key])
+ else:
+ print(job.exception)
+ print(job.stdout)
+
+
+ if collect_statistics:
+ mean_stats = {key: np.nanmedian(stats[key]) for key in __measures }
+
+ generation_statistics['population'] = mean_stats
+
+ # Elitism
+ if _elitism:
+ population = elitism_operator(population, new_population, **kwargs)
+
+ population = population[:npop]
+
+ new_population = []
+
+ last_best = best
+
+ best = population[0]
+
+ if collect_statistics:
+ generation_statistics['best'] = {key: best[key] for key in __measures }
+
+ statistics.append(generation_statistics)
+
+ if last_best['f1'] <= best['f1'] and last_best['f2'] <= best['f2']:
+ no_improvement_count += 1
+ print("WITHOUT IMPROVEMENT {}".format(no_improvement_count))
+ pmut += .05
+ else:
+ no_improvement_count = 0
+ pcross = kwargs.get('pcross', .5)
+ pmut = kwargs.get('pmut', .3)
+ print(best)
+
+ if no_improvement_count == mgen:
+ break
+
+ return best, statistics
+
+
+[docs]def process_experiment(fts_method, result, datasetname, conn):
+ """
+ Persist the results of an DEHO execution in sqlite database (best hyperparameters) and json file (generation statistics)
+
+ :param fts_method:
+ :param result:
+ :param datasetname:
+ :param conn:
+ :return:
+ """
+
+ log_result(conn, datasetname, fts_method, result['individual'])
+ persist_statistics(datasetname, result['statistics'])
+ return result['individual']
+
+
+[docs]def persist_statistics(datasetname, statistics):
+ import json
+ with open('statistics_{}.json'.format(datasetname), 'w') as file:
+ file.write(json.dumps(statistics))
+
+
+[docs]def log_result(conn, datasetname, fts_method, result):
+ metrics = ['rmse', 'size', 'time']
+ for metric in metrics:
+ record = (datasetname, 'Evolutive', fts_method, None, result['mf'],
+ result['order'], result['partitioner'], result['npart'],
+ result['alpha'], str(result['lags']), metric, result[metric])
+
+ print(record)
+
+ hUtil.insert_hyperparam(record, conn)
+
+
+[docs]def execute(datasetname, dataset, **kwargs):
+ """
+ Batch execution of Distributed Evolutionary Hyperparameter Optimization (DEHO) for monovariate methods
+
+ :param datasetname:
+ :param dataset: The time series to optimize the FTS
+ :keyword file:
+ :keyword experiments:
+ :keyword distributed:
+ :keyword ngen: An integer value with the maximum number of generations, default value: 30
+ :keyword mgen: An integer value with the maximum number of generations without improvement to stop, default value 7
+ :keyword npop: An integer value with the population size, default value: 20
+ :keyword pcross: A float value between 0 and 1 with the probability of crossover, default: .5
+ :keyword psel: A float value between 0 and 1 with the probability of selection, default: .5
+ :keyword pmut: A float value between 0 and 1 with the probability of mutation, default: .3
+ :keyword fts_method: The FTS method to optimize
+ :keyword parameters: dict with model specific arguments for fts_method
+ :keyword elitism: A boolean value indicating if the best individual must always survive to next population
+ :keyword initial_operator: a function that receives npop and return a random population with size npop
+ :keyword random_individual: create an random genotype
+ :keyword evalutation_operator: a function that receives a dataset and an individual and return its fitness
+ :keyword selection_operator: a function that receives the whole population and return a selected individual
+ :keyword crossover_operator: a function that receives the whole population and return a descendent individual
+ :keyword mutation_operator: a function that receives one individual and return a changed individual
+ :keyword window_size: An integer value with the the length of scrolling window for train/test on dataset
+ :keyword train_rate: A float value between 0 and 1 with the train/test split ([0,1])
+ :keyword increment_rate: A float value between 0 and 1 with the the increment of the scrolling window,
+ relative to the window_size ([0,1])
+ :keyword collect_statistics: A boolean value indicating to collect statistics for each generation
+ :keyword distributed: A value indicating it the execution will be local and sequential (distributed=False),
+ or parallel and distributed (distributed='dispy' or distributed='spark')
+ :keyword cluster: If distributed='dispy' the list of cluster nodes, else if distributed='spark' it is the master node
+ :return: the best genotype
+ """
+
+ file = kwargs.get('file', 'hyperparam.db')
+
+ conn = hUtil.open_hyperparam_db(file)
+
+ experiments = kwargs.get('experiments', 30)
+
+ distributed = kwargs.get('distributed', False)
+
+ fts_method = kwargs.get('fts_method', hofts.WeightedHighOrderFTS)
+ shortname = str(fts_method.__module__).split('.')[-1]
+
+ if distributed == 'dispy':
+ from pyFTS.distributed import dispy as dUtil
+ nodes = kwargs.get('nodes', ['127.0.0.1'])
+ cluster, http_server = dUtil.start_dispy_cluster(evaluate, nodes=nodes)
+ kwargs['cluster'] = cluster
+
+ ret = []
+ for i in np.arange(experiments):
+ print("Experiment {}".format(i))
+
+ start = time.time()
+ ret, statistics = GeneticAlgorithm(dataset, **kwargs)
+ end = time.time()
+ ret['time'] = end - start
+ experiment = {'individual': ret, 'statistics': statistics}
+
+ ret = process_experiment(shortname, experiment, datasetname, conn)
+
+ if distributed == 'dispy':
+ dUtil.stop_dispy_cluster(cluster, http_server)
+
+ return ret
+
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
+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 cluster_method(individual, dataset, **kwargs):
+ from pyFTS.common import Util, Membership
+ from pyFTS.models import hofts
+ from pyFTS.partitioners import Grid, Entropy
+ from pyFTS.benchmarks import Measures
+ import numpy as np
+
+ 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
+
+ window_size = kwargs.get('window_size', 800)
+ train_rate = kwargs.get('train_rate', .8)
+ increment_rate = kwargs.get('increment_rate', .2)
+ parameters = kwargs.get('parameters', {})
+
+ errors = []
+ sizes = []
+
+ for count, train, test in Util.sliding_window(dataset, window_size, train=train_rate, inc=increment_rate):
+
+ 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.WeightedHighOrderFTS(partitioner=partitioner,
+ lags=individual['lags'],
+ alpha_cut=individual['alpha'],
+ order=individual['order'])
+ model.fit(train)
+
+ forecasts = model.predict(test)
+
+ #rmse, mape, u = Measures.get_point_statistics(test, model)
+ rmse = Measures.rmse(test[model.max_lag:], forecasts)
+
+ size = len(model)
+
+ errors.append(rmse)
+ sizes.append(size)
+
+ return {'parameters': individual, 'rmse': np.nanmean(errors), 'size': np.nanmean(size)}
+
+
+[docs]def process_jobs(jobs, datasetname, conn):
+ from pyFTS.distributed import dispy as dUtil
+ import dispy
+ for ct, job in enumerate(jobs):
+ print("Processing job {}".format(ct))
+ result = job()
+ if job.status == dispy.DispyJob.Finished and result is not None:
+ print("Processing result of {}".format(result))
+
+ metrics = {'rmse': result['rmse'], 'size': result['size']}
+
+ for metric in metrics.keys():
+
+ param = result['parameters']
+
+ record = (datasetname, 'GridSearch', 'WHOFTS', None, param['mf'],
+ param['order'], param['partitioner'], param['npart'],
+ param['alpha'], str(param['lags']), metric, metrics[metric])
+
+
+ hUtil.insert_hyperparam(record, conn)
+
+ else:
+ print(job.exception)
+ print(job.stdout)
+
+
+[docs]def execute(hyperparams, datasetname, dataset, **kwargs):
+ from pyFTS.distributed import dispy as dUtil
+ import dispy
+
+ 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
+
+ print("Evaluation order: \n {}".format(index))
+
+ hp_values = [
+ [v for v in hyperparams[hp]]
+ for hp in keys_sorted
+ ]
+
+ print("Evaluation values: \n {}".format(hp_values))
+
+ cluster, http_server = dUtil.start_dispy_cluster(cluster_method, nodes=nodes)
+ file = kwargs.get('file', 'hyperparam.db')
+
+ conn = hUtil.open_hyperparam_db(file)
+
+ 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']]
+ count = 0
+ for lag1 in lags: # o é o lag1
+ _lags = [lag1]
+ count += 1
+ if order > 1:
+ for lag2 in lags: # o é o lag1
+ _lags2 = [lag1, lag1+lag2]
+ count += 1
+ if order > 2:
+ for lag3 in lags: # o é o lag1
+ count += 1
+ _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))
+
+ if count > 10:
+ jobs = []
+
+ for ind in individuals:
+ print("Testing individual {}".format(ind))
+ job = cluster.submit(ind, dataset, **kwargs)
+ jobs.append(job)
+
+ process_jobs(jobs, datasetname, conn)
+
+ count = 0
+
+ individuals = []
+
+ dUtil.stop_dispy_cluster(cluster, http_server)
+
Source code for pyFTS.models.chen
+"""
+First Order Conventional Fuzzy Time Series by Chen (1996)
+
+S.-M. Chen, “Forecasting enrollments based on fuzzy time series,” Fuzzy Sets Syst., vol. 81, no. 3, pp. 311–319, 1996.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts, flrg
+
+
+[docs]class ConventionalFLRG(flrg.FLRG):
+ """First Order Conventional Fuzzy Logical Relationship Group"""
+ def __init__(self, LHS, **kwargs):
+ super(ConventionalFLRG, self).__init__(1, **kwargs)
+ self.LHS = LHS
+ self.RHS = set()
+
+
+
+
+
+ def __str__(self):
+ tmp = str(self.LHS) + " -> "
+ tmp2 = ""
+ for c in sorted(self.RHS, key=lambda s: s):
+ if len(tmp2) > 0:
+ tmp2 = tmp2 + ","
+ tmp2 = tmp2 + str(c)
+ return tmp + tmp2
+
+
+[docs]class ConventionalFTS(fts.FTS):
+ """Conventional Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(ConventionalFTS, self).__init__(order=1, **kwargs)
+ self.name = "Conventional FTS"
+ self.detail = "Chen"
+ self.shortname = "CFTS"
+ self.flrgs = {}
+
+[docs] def generate_flrg(self, flrs):
+ for flr in flrs:
+ if flr.LHS in self.flrgs:
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+ else:
+ self.flrgs[flr.LHS] = ConventionalFLRG(flr.LHS)
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+
+[docs] def train(self, data, **kwargs):
+
+ tmpdata = self.partitioner.fuzzyfy(data, method='maximum', mode='sets')
+ flrs = FLR.generate_non_recurrent_flrs(tmpdata, steps=self.standard_horizon)
+ self.generate_flrg(flrs)
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ explain = kwargs.get('explain',False)
+
+ l = len(ndata) if not explain else 1
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ actual = FuzzySet.get_maximum_membership_fuzzyset(ndata[k], self.partitioner.sets)
+
+ if explain:
+ print("Fuzzyfication:\n\n {} -> {} \n".format(ndata[k], actual.name))
+
+ if actual.name not in self.flrgs:
+ ret.append(actual.centroid)
+
+ if explain:
+ print("Rules:\n\n {} -> {} (Naïve)\t Midpoint: {} \n\n".format(actual.name, actual.name,actual.centroid))
+
+ else:
+ _flrg = self.flrgs[actual.name]
+
+ mp = _flrg.get_midpoint(self.partitioner.sets)
+
+ ret.append(mp)
+
+ if explain:
+ print("Rules:\n\n {} \t Midpoint: {} \n".format(str(_flrg), mp))
+
+ print("Deffuzyfied value: {} \n".format(mp))
+
+ return ret
+
Source code for pyFTS.models.cheng
+"""
+Trend Weighted Fuzzy Time Series by Cheng, Chen and Wu (2009)
+
+C.-H. Cheng, Y.-S. Chen, and Y.-L. Wu, “Forecasting innovation diffusion of products using trend-weighted fuzzy time-series model,”
+Expert Syst. Appl., vol. 36, no. 2, pp. 1826–1832, 2009.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts
+from pyFTS.models import yu
+
+
+[docs]class TrendWeightedFLRG(yu.WeightedFLRG):
+ """
+ First Order Trend Weighted Fuzzy Logical Relationship Group
+ """
+ def __init__(self, LHS, **kwargs):
+ super(TrendWeightedFLRG, self).__init__(LHS, **kwargs)
+ self.w = None
+
+[docs] def weights(self, sets):
+ if self.w is None:
+ count_nochange = 0.0
+ count_up = 0.0
+ count_down = 0.0
+ weights = []
+
+ for c in self.RHS:
+ tmp = 0
+ if sets[self.LHS].centroid == sets[c].centroid:
+ count_nochange += 1.0
+ tmp = count_nochange
+ elif sets[self.LHS].centroid > sets[c].centroid:
+ count_down += 1.0
+ tmp = count_down
+ else:
+ count_up += 1.0
+ tmp = count_up
+ weights.append(tmp)
+
+ tot = sum(weights)
+ self.w = np.array([k / tot for k in weights])
+ return self.w
+
+
+[docs]class TrendWeightedFTS(yu.WeightedFTS):
+ """First Order Trend Weighted Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(TrendWeightedFTS, self).__init__(**kwargs)
+ self.shortname = "TWFTS"
+ self.name = "Trend Weighted FTS"
+ self.detail = "Cheng"
+ self.is_high_order = False
+
+[docs] def generate_FLRG(self, flrs):
+ for flr in flrs:
+ if flr.LHS in self.flrgs:
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+ else:
+ self.flrgs[flr.LHS] = TrendWeightedFLRG(flr.LHS)
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+
Source code for pyFTS.models.ensemble.ensemble
+"""
+EnsembleFTS wraps several FTS methods to ensemble their forecasts, providing point,
+interval and probabilistic forecasting.
+
+Silva, P. C. L et al. Probabilistic Forecasting with Seasonal Ensemble Fuzzy Time-Series
+XIII Brazilian Congress on Computational Intelligence, 2017. Rio de Janeiro, Brazil.
+"""
+
+
+import numpy as np
+import pandas as pd
+from pyFTS.common import SortedCollection, fts, tree
+from pyFTS.models import chen, cheng, hofts, hwang, ismailefendi, sadaei, song, yu
+from pyFTS.probabilistic import ProbabilityDistribution
+from pyFTS.partitioners import Grid
+import scipy.stats as st
+from itertools import product
+
+
+[docs]def sampler(data, quantiles, bounds=False):
+ ret = []
+ for qt in quantiles:
+ ret.append(np.nanpercentile(data, q=qt * 100))
+ if bounds:
+ ret.insert(0, min(data))
+ ret.append(max(data))
+ return ret
+
+
+[docs]class EnsembleFTS(fts.FTS):
+ """
+ Ensemble FTS
+ """
+ def __init__(self, **kwargs):
+ super(EnsembleFTS, self).__init__(**kwargs)
+ 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
+ self.is_high_order = True
+ self.models = []
+ """A list of FTS models, the ensemble components"""
+ self.parameters = []
+ """A list with the parameters for each component model"""
+ self.alpha = kwargs.get("alpha", 0.05)
+ """The quantiles """
+ self.point_method = kwargs.get('point_method', 'mean')
+ """The method used to mix the several model's forecasts into a unique point forecast. Options: mean, median, quantile, exponential"""
+ self.interval_method = kwargs.get('interval_method', 'quantile')
+ """The method used to mix the several model's forecasts into a interval forecast. Options: quantile, extremum, normal"""
+
+[docs] def append_model(self, model):
+ """
+ Append a new trained model to the ensemble
+
+ :param model: FTS model
+
+ """
+ self.models.append(model)
+ if model.order > self.order:
+ self.order = model.order
+
+ if model.is_multivariate:
+ self.is_multivariate = True
+
+ if model.has_seasonality:
+ self.has_seasonality = True
+
+ if model.original_min < self.original_min:
+ self.original_min = model.original_min
+ elif model.original_max > self.original_max:
+ self.original_max = model.original_max
+
+
+
+
+
+
+[docs] def get_models_forecasts(self,data):
+ tmp = []
+ for model in self.models:
+ if model.is_multivariate or model.has_seasonality:
+ forecast = model.forecast(data)
+ else:
+
+ if isinstance(data, pd.DataFrame) and self.indexer is not None:
+ data = self.indexer.get_data(data)
+
+ sample = data[-model.order:]
+ forecast = model.predict(sample)
+ if isinstance(forecast, (list,np.ndarray)) and len(forecast) > 0:
+ forecast = forecast[-1]
+ elif isinstance(forecast, (list,np.ndarray)) and len(forecast) == 0:
+ forecast = np.nan
+ if isinstance(forecast, list):
+ tmp.extend(forecast)
+ else:
+ tmp.append(forecast)
+ return tmp
+
+[docs] def get_point(self,forecasts, **kwargs):
+ if self.point_method == 'mean':
+ ret = np.nanmean(forecasts)
+ elif self.point_method == 'median':
+ ret = np.nanpercentile(forecasts, 50)
+ elif self.point_method == 'quantile':
+ alpha = kwargs.get("alpha",0.05)
+ ret = np.nanpercentile(forecasts, alpha*100)
+ elif self.point_method == 'exponential':
+ l = len(self.models)
+ if l == 1:
+ return forecasts[0]
+ w = np.array([np.exp(-(l - k)) for k in range(l)])
+ w = w / np.nansum(w)
+ ret = np.nansum([w[k] * forecasts[k] for k in range(l)])
+
+ return ret
+
+[docs] def get_interval(self, forecasts):
+ ret = []
+ if self.interval_method == 'extremum':
+ ret.append([min(forecasts), max(forecasts)])
+ elif self.interval_method == 'quantile':
+ qt_lo = np.nanpercentile(forecasts, q=self.alpha * 100)
+ qt_up = np.nanpercentile(forecasts, q=(1-self.alpha) * 100)
+ ret.append([qt_lo, qt_up])
+ elif self.interval_method == 'normal':
+ mu = np.nanmean(forecasts)
+ sigma = np.sqrt(np.nanvar(forecasts))
+ ret.append(mu + st.norm.ppf(self.alpha) * sigma)
+ ret.append(mu + st.norm.ppf(1 - self.alpha) * sigma)
+
+ return ret
+
+[docs] def get_distribution_interquantile(self,forecasts, alpha):
+ size = len(forecasts)
+ qt_lower = int(np.ceil(size * alpha)) - 1
+ qt_upper = int(np.ceil(size * (1- alpha))) - 1
+
+ ret = sorted(forecasts)[qt_lower : qt_upper]
+
+ return ret
+
+[docs] def forecast(self, data, **kwargs):
+
+ if "method" in kwargs:
+ self.point_method = kwargs.get('method','mean')
+
+ l = len(data)
+ ret = []
+
+ for k in np.arange(self.order, l+1):
+ sample = data[k - self.max_lag : k]
+ tmp = self.get_models_forecasts(sample)
+ point = self.get_point(tmp)
+ ret.append(point)
+
+ return ret
+
+[docs] def forecast_interval(self, data, **kwargs):
+
+ if "method" in kwargs:
+ self.interval_method = kwargs.get('method','quantile')
+
+ self.alpha = kwargs.get('alpha', self.alpha)
+
+ l = len(data)
+
+ ret = []
+
+ for k in np.arange(self.order, l+1):
+ sample = data[k - self.order : k]
+ tmp = self.get_models_forecasts(sample)
+ interval = self.get_interval(tmp)
+ if len(interval) == 1:
+ interval = interval[-1]
+ ret.append(interval)
+
+ return ret
+
+[docs] def forecast_ahead_interval(self, data, steps, **kwargs):
+
+ if 'method' in kwargs:
+ self.interval_method = kwargs.get('method','quantile')
+
+ self.alpha = kwargs.get('alpha', self.alpha)
+
+ ret = []
+
+ start = kwargs.get('start_at', self.order)
+
+ sample = [[k] for k in data[start: start+self.order]]
+
+ for k in np.arange(self.order, steps + self.order):
+ forecasts = []
+
+ lags = []
+ for i in np.arange(0, self.order):
+ lags.append(sample[i - self.order])
+
+ # Trace the possible paths
+ for path in product(*lags):
+ forecasts.extend(self.get_models_forecasts(path))
+
+ sample.append(sampler(forecasts, np.arange(.1, 1, 0.1), bounds=True))
+
+ interval = self.get_interval(forecasts)
+
+ if len(interval) == 1:
+ interval = interval[0]
+
+ ret.append(interval)
+
+ return ret[-steps:]
+
+[docs] def forecast_distribution(self, data, **kwargs):
+ ret = []
+
+ smooth = kwargs.get("smooth", "KDE")
+ alpha = kwargs.get("alpha", None)
+
+ uod = self.get_UoD()
+
+ for k in np.arange(self.order, len(data)):
+
+ sample = data[k-self.order : k]
+
+ forecasts = self.get_models_forecasts(sample)
+
+ if alpha is None:
+ forecasts = np.ravel(forecasts).tolist()
+ else:
+ forecasts = self.get_distribution_interquantile(np.ravel(forecasts).tolist(), alpha)
+
+ dist = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, data=forecasts,
+ name="", **kwargs)
+
+ ret.append(dist)
+
+ return ret
+
+[docs] def forecast_ahead_distribution(self, data, steps, **kwargs):
+ if 'method' in kwargs:
+ self.point_method = kwargs.get('method','mean')
+
+ smooth = kwargs.get("smooth", "histogram")
+ alpha = kwargs.get("alpha", None)
+
+ ret = []
+
+ start = kwargs.get('start_at', self.order)
+
+ uod = self.get_UoD()
+
+ sample = [[k] for k in data[start: start+self.order]]
+
+ for k in np.arange(self.order, steps+self.order):
+ forecasts = []
+
+ lags = []
+ for i in np.arange(0, self.order):
+ lags.append(sample[i - self.order])
+
+ # Trace the possible paths
+ for path in product(*lags):
+ forecasts.extend(self.get_models_forecasts(path))
+
+ sample.append(sampler(forecasts, np.arange(.1, 1, 0.1), bounds=True))
+
+ if alpha is None:
+ forecasts = np.ravel(forecasts).tolist()
+ else:
+ forecasts = self.get_distribution_interquantile(np.ravel(forecasts).tolist(), alpha)
+
+ dist = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, data=forecasts,
+ name="", **kwargs)
+
+ ret.append(dist)
+
+ return ret[-steps:]
+
+
+[docs]class SimpleEnsembleFTS(EnsembleFTS):
+ '''
+ An homogeneous FTS method ensemble with variations on partitionings and orders.
+ '''
+ def __init__(self, **kwargs):
+ super(SimpleEnsembleFTS, self).__init__(**kwargs)
+ self.method = kwargs.get('fts_method', hofts.WeightedHighOrderFTS)
+ """FTS method class that will be used on internal models"""
+ self.partitioner_method = kwargs.get('partitioner_method', Grid.GridPartitioner)
+ """UoD partitioner class that will be used on internal methods"""
+ self.partitions = kwargs.get('partitions', np.arange(15,35,10))
+ """Possible variations of number of partitions on internal models"""
+ self.orders = kwargs.get('orders', [1,2,3])
+ """Possible variations of order on internal models"""
+ self.uod_clip = False
+
+ self.shortname = kwargs.get('name', 'EnsembleFTS-' + str(self.method.__module__).split('.')[-1])
+
+[docs] def train(self, data, **kwargs):
+ for k in self.partitions:
+ fs = self.partitioner_method(data=data, npart=k)
+
+ for order in self.orders:
+ tmp = self.method(partitioner=fs, order=order)
+
+ tmp.fit(data)
+
+ self.append_model(tmp)
+
+
+[docs]class AllMethodEnsembleFTS(EnsembleFTS):
+ """
+ Creates an EnsembleFTS with all point forecast methods, sharing the same partitioner
+ """
+ def __init__(self, **kwargs):
+ super(AllMethodEnsembleFTS, self).__init__(**kwargs)
+ self.min_order = 3
+ self.shortname ="Ensemble FTS"
+
+[docs] def set_transformations(self, model):
+ for t in self.transformations:
+ model.append_transformation(t)
+
+[docs] def train(self, data, **kwargs):
+ fo_methods = [song.ConventionalFTS, chen.ConventionalFTS, yu.WeightedFTS, cheng.TrendWeightedFTS,
+ sadaei.ExponentialyWeightedFTS, ismailefendi.ImprovedWeightedFTS]
+
+ ho_methods = [hofts.HighOrderFTS, hwang.HighOrderFTS]
+
+ for method in fo_methods:
+ model = method(partitioner=self.partitioner)
+ self.set_transformations(model)
+ model.fit(data, **kwargs)
+ self.append_model(model)
+
+ for method in ho_methods:
+ for o in np.arange(1, self.order+1):
+ model = method(partitioner=self.partitioner)
+ if model.min_order >= o:
+ model.order = o
+ self.set_transformations(model)
+ model.fit(data, **kwargs)
+ self.append_model(model)
+
+
+
+
+
Source code for pyFTS.models.ensemble.multiseasonal
+"""
+Silva, P. C. L et al. Probabilistic Forecasting with Seasonal Ensemble Fuzzy Time-Series
+XIII Brazilian Congress on Computational Intelligence, 2017. Rio de Janeiro, Brazil.
+"""
+
+import numpy as np
+from pyFTS.common import Util as cUtil
+from pyFTS.models.ensemble import ensemble
+from pyFTS.models.seasonal import cmsfts
+from pyFTS.probabilistic import ProbabilityDistribution
+from copy import deepcopy
+from joblib import Parallel, delayed
+import multiprocessing
+
+
+[docs]def train_individual_model(partitioner, train_data, indexer):
+ pttr = str(partitioner.__module__).split('.')[-1]
+ diff = "_diff" if partitioner.transformation is not None else ""
+ _key = "msfts_" + pttr + str(partitioner.partitions) + diff + "_" + indexer.name
+
+ print(_key)
+
+ model = cmsfts.ContextualMultiSeasonalFTS(_key, indexer=indexer)
+ model.append_transformation(partitioner.transformation)
+ model.train(train_data, partitioner.sets, order=1)
+
+ cUtil.persist_obj(model, "models/"+_key+".pkl")
+
+ return model
+
+
+[docs]class SeasonalEnsembleFTS(ensemble.EnsembleFTS):
+ def __init__(self, name, **kwargs):
+ super(SeasonalEnsembleFTS, self).__init__(name="Seasonal Ensemble FTS", **kwargs)
+ self.min_order = 1
+ self.indexers = []
+ self.partitioners = []
+ self.is_multivariate = True
+ self.has_seasonality = True
+ self.has_probability_forecasting = True
+
+[docs] def update_uod(self, data):
+ self.original_max = max(self.indexer.get_data(data))
+ self.original_min = min(self.indexer.get_data(data))
+
+[docs] def train(self, data, **kwargs):
+ self.original_max = max(self.indexer.get_data(data))
+ self.original_min = min(self.indexer.get_data(data))
+
+ num_cores = multiprocessing.cpu_count()
+
+ pool = {}
+ count = 0
+ for ix in self.indexers:
+ for pt in self.partitioners:
+ pool[count] = {'ix': ix, 'pt': pt}
+ count += 1
+
+ results = Parallel(n_jobs=num_cores)(
+ delayed(train_individual_model)(deepcopy(pool[m]['pt']), data, deepcopy(pool[m]['ix']))
+ for m in pool.keys())
+
+ for tmp in results:
+ self.append_model(tmp)
+
+ cUtil.persist_obj(self, "models/"+self.name+".pkl")
+
+[docs] def forecast_distribution(self, data, **kwargs):
+
+ ret = []
+
+ smooth = kwargs.get("smooth", "KDE")
+ alpha = kwargs.get("alpha", None)
+
+ uod = self.get_UoD()
+
+ for k in data.index:
+
+ tmp = self.get_models_forecasts(data.ix[k])
+
+ if alpha is None:
+ tmp = np.ravel(tmp).tolist()
+ else:
+ tmp = self.get_distribution_interquantile( np.ravel(tmp).tolist(), alpha)
+
+ name = str(self.indexer.get_index(data.ix[k]))
+
+ dist = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, data=tmp,
+ name=name, **kwargs)
+
+ ret.append(dist)
+
+ return ret
+
Source code for pyFTS.models.hofts
+"""
+High Order FTS
+
+Severiano, S. A. Jr; Silva, P. C. L.; Sadaei, H. J.; Guimarães, F. G. Very Short-term Solar Forecasting
+using Fuzzy Time Series. 2017 IEEE International Conference on Fuzzy Systems. DOI10.1109/FUZZ-IEEE.2017.8015732
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts, flrg
+from itertools import product
+
+
+[docs]class HighOrderFLRG(flrg.FLRG):
+ """Conventional High Order Fuzzy Logical Relationship Group"""
+ def __init__(self, order, **kwargs):
+ super(HighOrderFLRG, self).__init__(order, **kwargs)
+ self.LHS = []
+ self.RHS = {}
+ self.strlhs = ""
+
+
+
+[docs] def append_lhs(self, c):
+ if isinstance(c,(tuple,list)):
+ for k in c:
+ self.LHS.append(k)
+ else:
+ self.LHS.append(c)
+
+ def __str__(self):
+ tmp = ""
+ for c in sorted(self.RHS):
+ if len(tmp) > 0:
+ tmp = tmp + ","
+ tmp = tmp + c
+ return self.get_key() + " -> " + tmp
+
+
+ def __len__(self):
+ 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):
+ count = kwargs.get('count',1.0)
+ if fset not in self.RHS:
+ self.RHS[fset] = count
+ else:
+ self.RHS[fset] += count
+ self.count += count
+
+
+
+[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):
+ if self.midpoint is None:
+ mp = np.array([sets[c].centroid for c in self.RHS.keys()])
+ self.midpoint = mp.dot(self.weights())
+
+ return self.midpoint
+
+[docs] def get_lower(self, sets):
+ if self.lower is None:
+ lw = np.array([sets[s].lower for s in self.RHS.keys()])
+ self.lower = lw.dot(self.weights())
+ return self.lower
+
+[docs] def get_upper(self, sets):
+ if self.upper is None:
+ up = np.array([sets[s].upper for s in self.RHS.keys()])
+ self.upper = up.dot(self.weights())
+ return self.upper
+
+ 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):
+ super(HighOrderFTS, self).__init__(**kwargs)
+ self.name = "High Order FTS"
+ self.shortname = "HOFTS"
+ self.detail = "Severiano, Silva, Sadaei and Guimarães"
+ self.is_high_order = True
+ self.min_order = 1
+ self.order= kwargs.get("order", self.min_order)
+ self.configure_lags(**kwargs)
+
+[docs] def configure_lags(self, **kwargs):
+ if "order" in kwargs:
+ self.order = kwargs.get("order", self.min_order)
+
+ if "lags" in kwargs:
+ self.lags = kwargs.get("lags", None)
+
+ if self.lags is not None:
+ self.max_lag = max(self.lags)
+ else:
+ self.max_lag = self.order
+ self.lags = np.arange(1, self.order+1)
+
+[docs] def generate_lhs_flrg(self, sample, explain=False):
+
+ nsample = [self.partitioner.fuzzyfy(k, mode="sets", alpha_cut=self.alpha_cut)
+ for k in sample]
+
+ if explain:
+ self.append_log("Fuzzyfication","{} -> {}".format(sample, nsample))
+
+ 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 = sample[o - 1]
+ lags.append(lhs)
+
+ if explain:
+ self.append_log("Ordering Lags", "Lag {} Value {}".format(o, lhs))
+
+ # Trace the possible paths
+ for path in product(*lags):
+ flrg = HighOrderFLRG(self.order)
+
+ for lhs in path:
+ flrg.append_lhs(lhs)
+
+ flrgs.append(flrg)
+
+ return flrgs
+
+[docs] def generate_flrg(self, data):
+ _tmp_steps = self.standard_horizon - 1
+ l = len(data)
+ for k in np.arange(self.max_lag, l - _tmp_steps):
+
+ if self.dump: print("FLR: " + str(k))
+
+ sample = data[k - self.max_lag: k]
+
+ rhs = self.partitioner.fuzzyfy(data[k+_tmp_steps], mode="sets", alpha_cut=self.alpha_cut)
+
+ flrgs = self.generate_lhs_flrg(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 generate_flrg_fuzzyfied(self, data):
+ _tmp_steps = self.standard_horizon - 1
+ 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+_tmp_steps]
+
+ 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)
+ if not kwargs.get('fuzzyfied',False):
+ self.generate_flrg(data)
+ else:
+ self.generate_flrg_fuzzyfied(data)
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ explain = kwargs.get('explain', False)
+
+ fuzzyfied = kwargs.get('fuzzyfied', False)
+
+ mode = kwargs.get('mode', 'mean')
+
+ ret = []
+
+ l = len(ndata) if not explain else self.max_lag + 1
+
+ if l < self.max_lag:
+ return ndata
+ elif l == self.max_lag:
+ l += 1
+
+ for k in np.arange(self.max_lag, l):
+
+ sample = ndata[k - self.max_lag: k]
+
+ if not fuzzyfied:
+ flrgs = self.generate_lhs_flrg(sample, explain)
+ else:
+ flrgs = self.generate_lhs_flrg_fuzzyfied(sample, explain)
+
+ midpoints = []
+ memberships = []
+ for flrg in flrgs:
+
+ if flrg.get_key() not in self.flrgs:
+ if len(flrg.LHS) > 0:
+ mp = self.partitioner.sets[flrg.LHS[-1]].centroid
+ mv = self.partitioner.sets[flrg.LHS[-1]].membership(sample[-1]) if not fuzzyfied else None
+ midpoints.append(mp)
+ memberships.append(mv)
+
+ if explain:
+ self.append_log("Rule Matching", "{} -> {} (Naïve) Midpoint: {}".format(str(flrg.LHS), flrg.LHS[-1],
+ mp))
+ else:
+ flrg = self.flrgs[flrg.get_key()]
+ mp = flrg.get_midpoint(self.partitioner.sets)
+ mv = flrg.get_membership(sample, self.partitioner.sets) if not fuzzyfied else None
+ midpoints.append(mp)
+ memberships.append(mv)
+
+ if explain:
+ self.append_log("Rule Matching", "{}, Midpoint: {} Membership: {}".format(flrg.get_key(), mp, mv))
+
+ if mode == "mean" or fuzzyfied:
+ final = np.nanmean(midpoints)
+ if explain: self.append_log("Deffuzyfication", "By Mean: {}".format(final))
+ else:
+ final = np.dot(midpoints, memberships)/np.nansum(memberships)
+ if explain: self.append_log("Deffuzyfication", "By Memberships: {}".format(final))
+
+ ret.append(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.append(sample[o-1])
+
+ if explain:
+ print("\t (Lag {}) {} \n".format(o, sample[o-1]))
+
+ # Trace the possible paths
+ for path in product(*lags):
+ flrg = WeightedHighOrderFLRG(self.order)
+
+ for lhs in path:
+ flrg.append_lhs(lhs)
+
+ flrgs.append(flrg)
+
+ return flrgs
+
Source code for pyFTS.models.hwang
+"""
+High Order Fuzzy Time Series by Hwang, Chen and Lee (1998)
+
+Jeng-Ren Hwang, Shyi-Ming Chen, and Chia-Hoang Lee, “Handling forecasting problems using fuzzy time series,”
+Fuzzy Sets Syst., no. 100, pp. 217–228, 1998.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, Transformations, fts
+
+
+[docs]class HighOrderFTS(fts.FTS):
+ def __init__(self, **kwargs):
+ super(HighOrderFTS, self).__init__(**kwargs)
+ self.is_high_order = True
+ self.min_order = 2
+ self.name = "Hwang High Order FTS"
+ self.shortname = "Hwang"
+ self.detail = "Hwang"
+ self.configure_lags(**kwargs)
+
+[docs] def configure_lags(self, **kwargs):
+ if "order" in kwargs:
+ self.order = kwargs.get("order", 2)
+
+ self.max_lag = self.order
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ l = len(self.sets)
+
+ cn = np.array([0.0 for k in range(l)])
+ ow = np.array([[0.0 for k in range(l)] for z in range(self.order - 1)])
+ rn = np.array([[0.0 for k in range(l)] for z in range(self.order - 1)])
+ ft = np.array([0.0 for k in range(l)])
+
+ ret = []
+
+ for t in np.arange(self.order-1, len(ndata)):
+
+ for ix in range(l):
+ s = self.partitioner.ordered_sets[ix]
+ cn[ix] = self.sets[s].membership( FuzzySet.grant_bounds(ndata[t], self.sets, self.partitioner.ordered_sets))
+ for w in np.arange(self.order-1):
+ ow[w, ix] = self.sets[s].membership(FuzzySet.grant_bounds(ndata[t - w], self.sets, self.partitioner.ordered_sets))
+ rn[w, ix] = ow[w, ix] * cn[ix]
+ ft[ix] = max(ft[ix], rn[w, ix])
+ mft = max(ft)
+ out = 0.0
+ count = 0.0
+ for ix in range(l):
+ s = self.partitioner.ordered_sets[ix]
+ if ft[ix] == mft:
+ out = out + self.sets[s].centroid
+ count += 1.0
+ ret.append(out / count)
+
+ return ret
+
+[docs] def train(self, data, **kwargs):
+
+ if self.sets == None:
+ self.sets = self.partitioner.sets
+
+ self.configure_lags(**kwargs)
+
Source code for pyFTS.models.ifts
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+"""
+High Order Interval Fuzzy Time Series
+
+SILVA, Petrônio CL; SADAEI, Hossein Javedani; GUIMARÃES, Frederico Gadelha. Interval Forecasting with Fuzzy Time Series.
+In: Computational Intelligence (SSCI), 2016 IEEE Symposium Series on. IEEE, 2016. p. 1-8.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts, tree
+from pyFTS.models import hofts
+
+
+[docs]class IntervalFTS(hofts.HighOrderFTS):
+ """
+ High Order Interval Fuzzy Time Series
+ """
+ def __init__(self, **kwargs):
+ super(IntervalFTS, self).__init__(**kwargs)
+ self.shortname = "IFTS"
+ self.name = "Interval FTS"
+ self.detail = "Silva, P.; Guimarães, F.; Sadaei, H. (2016)"
+ self.flrgs = {}
+ self.has_point_forecasting = False
+ self.has_interval_forecasting = True
+ self.is_high_order = True
+ self.min_order = 1
+
+[docs] def get_upper(self, flrg):
+ ret = np.nan
+ if len(flrg.LHS) > 0:
+ if flrg.get_key() in self.flrgs:
+ tmp = self.flrgs[flrg.get_key()]
+ ret = tmp.get_upper(self.partitioner.sets)
+ else:
+ ret = self.partitioner.sets[flrg.LHS[-1]].upper
+ return ret
+
+[docs] def get_lower(self, flrg):
+ ret = np.nan
+ if len(flrg.LHS) > 0:
+ if flrg.get_key() in self.flrgs:
+ tmp = self.flrgs[flrg.get_key()]
+ ret = tmp.get_lower(self.partitioner.sets)
+ else:
+ ret = self.partitioner.sets[flrg.LHS[-1]].lower
+ return ret
+
+[docs] def get_sequence_membership(self, data, fuzzySets):
+ mb = [fuzzySets[k].membership(data[k]) for k in np.arange(0, len(data))]
+ return mb
+
+[docs] def forecast_interval(self, ndata, **kwargs):
+
+ ret = []
+
+ l = len(ndata)
+
+ if l < self.order:
+ return ndata
+
+ for k in np.arange(self.max_lag, l+1):
+
+ sample = ndata[k - self.max_lag: k]
+
+ flrgs = self.generate_lhs_flrg(sample)
+
+ up = []
+ lo = []
+ affected_flrgs_memberships = []
+
+ for flrg in flrgs:
+ if len(flrg.LHS) > 0:
+
+ mv = flrg.get_membership(sample, self.partitioner.sets)
+ up.append(mv * self.get_upper(flrg))
+ lo.append(mv * self.get_lower(flrg))
+ affected_flrgs_memberships.append(mv)
+
+ # gerar o intervalo
+ norm = np.nansum(affected_flrgs_memberships)
+ lo_ = np.nansum(lo) / norm
+ up_ = np.nansum(up) / norm
+ ret.append([lo_, up_])
+
+ return ret
+
+[docs] def forecast_ahead_interval(self, data, steps, **kwargs):
+ start = kwargs.get('start_at', 0)
+ ret = [[x, x] for x in data[start:start+self.max_lag]]
+ for k in np.arange(self.max_lag, self.max_lag + steps):
+ interval_lower = self.clip_uod(self.forecast_interval([x[0] for x in ret[k - self.max_lag: k]])[0])
+ interval_upper = self.clip_uod(self.forecast_interval([x[1] for x in ret[k - self.max_lag: k]])[0])
+ interval = [np.nanmin(interval_lower), np.nanmax(interval_upper)]
+ ret.append(interval)
+
+ return ret[-steps:]
+
+
+[docs]class WeightedIntervalFTS(hofts.WeightedHighOrderFTS):
+ """
+ Weighted High Order Interval Fuzzy Time Series
+ """
+ def __init__(self, **kwargs):
+ super(WeightedIntervalFTS, self).__init__(**kwargs)
+ self.shortname = "WIFTS"
+ self.name = "Weighted Interval FTS"
+ self.detail = "Silva, P.; Guimarães, F.; Sadaei, H. (2016)"
+ self.flrgs = {}
+ self.has_point_forecasting = False
+ self.has_interval_forecasting = True
+ self.is_high_order = True
+ self.min_order = 1
+
+[docs] def get_upper(self, flrg):
+ ret = np.nan
+ if len(flrg.LHS) > 0:
+ if flrg.get_key() in self.flrgs:
+ tmp = self.flrgs[flrg.get_key()]
+ ret = tmp.get_upper(self.partitioner.sets)
+ else:
+ ret = self.partitioner.sets[flrg.LHS[-1]].upper
+ return ret
+
+[docs] def get_lower(self, flrg):
+ ret = np.nan
+ if len(flrg.LHS) > 0:
+ if flrg.get_key() in self.flrgs:
+ tmp = self.flrgs[flrg.get_key()]
+ ret = tmp.get_lower(self.partitioner.sets)
+ else:
+ ret = self.partitioner.sets[flrg.LHS[-1]].lower
+ return ret
+
+[docs] def get_sequence_membership(self, data, fuzzySets):
+ mb = [fuzzySets[k].membership(data[k]) for k in np.arange(0, len(data))]
+ return mb
+
+[docs] def forecast_interval(self, ndata, **kwargs):
+ ret = []
+
+ l = len(ndata)
+
+ if l < self.order:
+ return ndata
+
+ for k in np.arange(self.max_lag, l+1):
+
+ sample = ndata[k - self.max_lag: k]
+
+ flrgs = self.generate_lhs_flrg(sample)
+
+ up = []
+ lo = []
+ affected_flrgs_memberships = []
+
+ for flrg in flrgs:
+ if len(flrg.LHS) > 0:
+
+ mv = flrg.get_membership(sample, self.partitioner.sets)
+ up.append(mv * self.get_upper(flrg))
+ lo.append(mv * self.get_lower(flrg))
+ affected_flrgs_memberships.append(mv)
+
+ # gerar o intervalo
+ norm = np.nansum(affected_flrgs_memberships)
+ lo_ = np.nansum(lo) / norm
+ up_ = np.nansum(up) / norm
+ ret.append([lo_, up_])
+
+ return ret
+
+[docs] def forecast_ahead_interval(self, data, steps, **kwargs):
+ start = kwargs.get('start_at', 0)
+ ret = [[x, x] for x in data[start:start + self.max_lag]]
+ for k in np.arange(self.max_lag, self.max_lag + steps):
+ interval_lower = self.clip_uod(self.forecast_interval([x[0] for x in ret[k - self.max_lag: k]])[0])
+ interval_upper = self.clip_uod(self.forecast_interval([x[1] for x in ret[k - self.max_lag: k]])[0])
+ interval = [np.nanmin(interval_lower), np.nanmax(interval_upper)]
+ ret.append(interval)
+
+ return ret[-steps:]
+
+
+
Source code for pyFTS.models.incremental.IncrementalEnsemble
+'''
+Time Variant/Incremental Ensemble of FTS methods
+'''
+
+
+import numpy as np
+import pandas as pd
+from pyFTS.common import FuzzySet, FLR, fts, flrg
+from pyFTS.partitioners import Grid
+from pyFTS.models import hofts
+from pyFTS.models.ensemble import ensemble
+
+
+[docs]class IncrementalEnsembleFTS(ensemble.EnsembleFTS):
+ """
+ Time Variant/Incremental Ensemble of FTS methods
+ """
+ def __init__(self, **kwargs):
+ super(IncrementalEnsembleFTS, self).__init__(**kwargs)
+ self.shortname = "IncrementalEnsembleFTS"
+ self.name = "Incremental Ensemble FTS"
+
+ self.order = kwargs.get('order',1)
+
+ self.partitioner_method = kwargs.get('partitioner_method', Grid.GridPartitioner)
+ """The partitioner method to be called when a new model is build"""
+ self.partitioner_params = kwargs.get('partitioner_params', {'npart': 10})
+ """The partitioner method parameters"""
+
+ 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.window_length = kwargs.get('window_length', 100)
+ """The memory window length"""
+
+ self.batch_size = kwargs.get('batch_size', 10)
+ """The batch interval between each retraining"""
+
+ self.num_models = kwargs.get('num_models', 5)
+ """The number of models to hold in the ensemble"""
+
+ self.point_method = kwargs.get('point_method', 'exponential')
+
+ self.is_high_order = True
+ self.uod_clip = False
+ self.max_lag = self.window_length + self.order
+
+
+
+[docs] def train(self, data, **kwargs):
+
+ partitioner = self.partitioner_method(data=data, **self.partitioner_params)
+ model = self.fts_method(partitioner=partitioner, **self.fts_params)
+ if model.is_high_order:
+ model = self.fts_method(partitioner=partitioner, order=self.order, **self.fts_params)
+ model.fit(data, **kwargs)
+ self.append_model(model)
+ if len(self.models) > self.num_models:
+ self.models.pop(0)
+
+[docs] def forecast(self, data, **kwargs):
+ l = len(data)
+ no_update = kwargs.get('no_update', False)
+ if no_update:
+ ret = []
+ for k in np.arange(self.order, l+1):
+ sample = data[k-self.order: k]
+ tmp = self.get_models_forecasts(sample)
+ point = self.get_point(tmp)
+ ret.append(point)
+ return ret
+
+ data_window = []
+
+ ret = []
+
+ for k in np.arange(self.max_lag, l):
+
+ k2 = k - self.max_lag
+
+ data_window.append(data[k2])
+
+ if k2 >= self.window_length:
+ data_window.pop(0)
+
+ if k % self.batch_size == 0 and k2 >= self.window_length:
+ self.train(data_window, **kwargs)
+
+ if len(self.models) > 0:
+ sample = data[k2: k]
+ tmp = self.get_models_forecasts(sample)
+ point = self.get_point(tmp)
+ ret.append(point)
+
+ return ret
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+ if len(data) < self.order:
+ return data
+
+ if isinstance(data, np.ndarray):
+ data = data.tolist()
+
+ start = kwargs.get('start_at',0)
+
+ ret = data[:start+self.order]
+ for k in np.arange(start+self.order, steps+start+self.order):
+ tmp = self.forecast(ret[k-self.order:k], no_update=True, **kwargs)
+
+ if isinstance(tmp,(list, np.ndarray)):
+ tmp = tmp[-1]
+
+ ret.append(tmp)
+ data.append(tmp)
+
+ return ret[-steps:]
+
+
+
+
+
+
+
Source code for pyFTS.models.incremental.TimeVariant
+"""
+Meta model that wraps another FTS method and continously retrain it using a data window with
+the most recent data
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts, flrg
+from pyFTS.partitioners import Grid
+
+
+[docs]class Retrainer(fts.FTS):
+ """
+ Meta model for incremental/online learning that retrain its internal model after
+ data windows controlled by the parameter 'batch_size', using as the training data a
+ window of recent lags, whose size is controlled by the parameter 'window_length'.
+ """
+ def __init__(self, **kwargs):
+ super(Retrainer, self).__init__(**kwargs)
+
+ self.partitioner_method = kwargs.get('partitioner_method', Grid.GridPartitioner)
+ """The partitioner method to be called when a new model is build"""
+ self.partitioner_params = kwargs.get('partitioner_params', {'npart': 10})
+ """The partitioner method parameters"""
+ self.partitioner = None
+ """The most recent trained partitioner"""
+
+ self.fts_method = kwargs.get('fts_method', None)
+ """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.window_length = kwargs.get('window_length',100)
+ """The memory window length"""
+ self.auto_update = False
+ """If true the model is updated at each time and not recreated"""
+ self.batch_size = kwargs.get('batch_size', 10)
+ """The batch interval between each retraining"""
+ self.is_high_order = True
+ self.is_time_variant = True
+ self.uod_clip = False
+ self.max_lag = self.window_length + self.order
+ self.is_wrapper = True
+
+[docs] def train(self, data, **kwargs):
+ self.partitioner = self.partitioner_method(data=data, **self.partitioner_params)
+ self.model = self.fts_method(partitioner=self.partitioner, **self.fts_params)
+ if self.model.is_high_order:
+ self.model.order = self.model = self.fts_method(partitioner=self.partitioner,
+ order=self.order, **self.fts_params)
+ self.model.fit(data, **kwargs)
+ self.shortname = "TimeVariant - " + self.model.shortname
+
+[docs] def forecast(self, data, **kwargs):
+ l = len(data)
+
+ no_update = kwargs.get('no_update',False)
+
+ if no_update:
+ return self.model.predict(data, **kwargs)
+
+ horizon = self.window_length + self.order
+
+ ret = []
+
+ for k in np.arange(horizon, l+1):
+ _train = data[k - horizon: k - self.order]
+ _test = data[k - self.order: k]
+
+ if k % self.batch_size == 0 or self.model is None:
+ if self.auto_update:
+ self.model.train(_train)
+ else:
+ self.train(_train, **kwargs)
+
+ ret.extend(self.model.predict(_test, **kwargs))
+
+ return ret
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+ if len(data) < self.order:
+ return data
+
+ if isinstance(data, np.ndarray):
+ data = data.tolist()
+
+ start = kwargs.get('start_at',0)
+
+ ret = data[:start+self.order]
+ for k in np.arange(start+self.order, steps+start+self.order):
+ tmp = self.forecast(ret[k-self.order:k], no_update=True, **kwargs)
+
+ if isinstance(tmp,(list, np.ndarray)):
+ tmp = tmp[-1]
+
+ ret.append(tmp)
+ data.append(tmp)
+
+ return ret[-steps:]
+
+
+
+ def __str__(self):
+ """String representation of the model"""
+
+ return str(self.model)
+
+ def __len__(self):
+ """
+ The length (number of rules) of the model
+
+ :return: number of rules
+ """
+ return len(self.model)
+
Source code for pyFTS.models.ismailefendi
+"""
+First Order Improved Weighted Fuzzy Time Series by Efendi, Ismail and Deris (2013)
+
+R. Efendi, Z. Ismail, and M. M. Deris, “Improved weight Fuzzy Time Series as used in the exchange rates forecasting of
+US Dollar to Ringgit Malaysia,” Int. J. Comput. Intell. Appl., vol. 12, no. 1, p. 1350005, 2013.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts, flrg
+
+
+[docs]class ImprovedWeightedFLRG(flrg.FLRG):
+ """First Order Improved Weighted Fuzzy Logical Relationship Group"""
+ def __init__(self, LHS, **kwargs):
+ super(ImprovedWeightedFLRG, self).__init__(1, **kwargs)
+ self.LHS = LHS
+ self.RHS = {}
+ self.rhs_counts = {}
+ self.count = 0.0
+ self.w = None
+
+[docs] def append_rhs(self, c, **kwargs):
+ count = kwargs.get('count', 1.0)
+ if c not in self.RHS:
+ self.RHS[c] = c
+ self.rhs_counts[c] = count
+ else:
+ self.rhs_counts[c] += count
+ self.count += count
+
+[docs] def weights(self):
+ if self.w is None:
+ self.w = np.array([self.rhs_counts[c] / self.count for c in self.RHS.keys()])
+ return self.w
+
+ def __str__(self):
+ tmp = self.LHS + " -> "
+ tmp2 = ""
+ for c in sorted(self.RHS.keys()):
+ if len(tmp2) > 0:
+ tmp2 = tmp2 + ","
+ tmp2 = tmp2 + c + "(" + str(round(self.rhs_counts[c] / self.count, 3)) + ")"
+ return tmp + tmp2
+
+ def __len__(self):
+ return len(self.RHS)
+
+
+[docs]class ImprovedWeightedFTS(fts.FTS):
+ """First Order Improved Weighted Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(ImprovedWeightedFTS, self).__init__(order=1, name="IWFTS", **kwargs)
+ self.name = "Improved Weighted FTS"
+ self.detail = "Ismail & Efendi"
+
+[docs] def generate_flrg(self, flrs):
+ for flr in flrs:
+ if flr.LHS in self.flrgs:
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+ else:
+ self.flrgs[flr.LHS] = ImprovedWeightedFLRG(flr.LHS)
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+
+[docs] def train(self, ndata, **kwargs):
+
+ tmpdata = self.partitioner.fuzzyfy(ndata, method='maximum', mode='sets')
+ flrs = FLR.generate_recurrent_flrs(tmpdata)
+ self.generate_flrg(flrs)
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ explain = kwargs.get('explain', False)
+
+ if self.partitioner is not None:
+ ordered_sets = self.partitioner.ordered_sets
+ else:
+ ordered_sets = FuzzySet.set_ordered(self.partitioner.sets)
+
+ ndata = np.array(ndata)
+
+ l = len(ndata) if not explain else 1
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ actual = FuzzySet.get_maximum_membership_fuzzyset(ndata[k], self.partitioner.sets, ordered_sets)
+
+ if explain:
+ print("Fuzzyfication:\n\n {} -> {} \n".format(ndata[k], actual.name))
+
+ if actual.name not in self.flrgs:
+ ret.append(actual.centroid)
+
+ if explain:
+ print("Rules:\n\n {} -> {} (Naïve)\t Midpoint: {} \n\n".format(actual.name, actual.name,actual.centroid))
+
+ else:
+ flrg = self.flrgs[actual.name]
+ mp = flrg.get_midpoints(self.partitioner.sets)
+
+ final = mp.dot(flrg.weights())
+
+ ret.append(final)
+
+ if explain:
+ print("Rules:\n\n {} \n\n ".format(str(flrg)))
+ print("Midpoints: \n\n {}\n\n".format(mp))
+
+ print("Deffuzyfied value: {} \n".format(final))
+
+ return ret
+
Source code for pyFTS.models.multivariate.cmvfts
+
+import numpy as np
+import pandas as pd
+from pyFTS.common import FuzzySet, FLR, fts, flrg
+from pyFTS.models import hofts
+from pyFTS.models.multivariate import mvfts, grid, common
+from types import LambdaType
+
+
+[docs]class ClusteredMVFTS(mvfts.MVFTS):
+ """
+ Meta model for high order, clustered multivariate FTS
+ """
+ def __init__(self, **kwargs):
+ super(ClusteredMVFTS, self).__init__(**kwargs)
+
+ 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.is_clustered = True
+
+ self.order = kwargs.get("order", 2)
+ self.lags = kwargs.get("lags", None)
+ self.alpha_cut = kwargs.get('alpha_cut', 0.0)
+
+ self.shortname = "ClusteredMVFTS"
+ self.name = "Clustered Multivariate FTS"
+
+ self.pre_fuzzyfy = kwargs.get('pre_fuzzyfy', True)
+ self.fuzzyfy_mode = kwargs.get('fuzzyfy_mode', 'sets')
+
+[docs] def fuzzyfy(self,data):
+ ndata = []
+ for index, row in data.iterrows() if isinstance(data, pd.DataFrame) else enumerate(data):
+ data_point = self.format_data(row)
+ ndata.append(self.partitioner.fuzzyfy(data_point, mode=self.fuzzyfy_mode))
+
+ return ndata
+
+[docs] def train(self, data, **kwargs):
+
+ self.fts_params['order'] = self.order
+
+ self.model = self.fts_method(partitioner=self.partitioner, **self.fts_params)
+
+ ndata = self.apply_transformations(data)
+
+ ndata = self.check_data(ndata)
+
+ self.model.train(ndata, fuzzyfied=self.pre_fuzzyfy)
+
+ self.partitioner.prune()
+
+[docs] def check_data(self, data):
+ if self.pre_fuzzyfy:
+ ndata = self.fuzzyfy(data)
+ else:
+ ndata = [self.format_data(k) for k in data.to_dict('records')]
+
+ return ndata
+
+[docs] def forecast(self, data, **kwargs):
+
+ ndata1 = self.apply_transformations(data)
+
+ ndata = self.check_data(ndata1)
+
+ pre_fuzz = kwargs.get('pre_fuzzyfy', self.pre_fuzzyfy)
+
+ ret = self.model.forecast(ndata, fuzzyfied=pre_fuzz, **kwargs)
+
+ ret = self.target_variable.apply_inverse_transformations(ret,
+ params=data[self.target_variable.data_label].values)
+
+ return ret
+
+[docs] def forecast_interval(self, data, **kwargs):
+
+ if not self.model.has_interval_forecasting:
+ raise Exception("The internal method does not support interval forecasting!")
+
+ data = self.check_data(data)
+
+ pre_fuzz = kwargs.get('pre_fuzzyfy', self.pre_fuzzyfy)
+
+ return self.model.forecast_interval(data, fuzzyfied=pre_fuzz, **kwargs)
+
+
+
+[docs] def forecast_distribution(self, data, **kwargs):
+
+ if not self.model.has_probability_forecasting:
+ raise Exception("The internal method does not support probabilistic forecasting!")
+
+ data = self.check_data(data)
+
+ pre_fuzz = kwargs.get('pre_fuzzyfy', self.pre_fuzzyfy)
+
+ return self.model.forecast_distribution(data, fuzzyfied=pre_fuzz, **kwargs)
+
+[docs] def forecast_ahead_distribution(self, data, steps, **kwargs):
+
+ generators = kwargs.get('generators', None)
+
+ if generators is None:
+ raise Exception('You must provide parameter \'generators\'! generators is a dict where the keys' +
+ ' are the dataframe column 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 or trained FTS models that accept the actual values and '
+ 'forecast new ones.')
+
+ ndata = self.apply_transformations(data)
+
+ start = kwargs.get('start_at', 0)
+
+ ret = []
+ sample = ndata.iloc[start: start + self.max_lag]
+ for k in np.arange(0, steps):
+ tmp = self.forecast_distribution(sample.iloc[-self.max_lag:], **kwargs)[0]
+
+ ret.append(tmp)
+
+ new_data_point = {}
+
+ for data_label in generators.keys():
+ if data_label != self.target_variable.data_label:
+ if isinstance(generators[data_label], LambdaType):
+ last_data_point = sample.iloc[-1]
+ new_data_point[data_label] = generators[data_label](last_data_point[data_label])
+
+ elif isinstance(generators[data_label], fts.FTS):
+ gen_model = generators[data_label]
+ last_data_point = sample.iloc[-gen_model.order:]
+
+ if not gen_model.is_multivariate:
+ last_data_point = last_data_point[data_label].values
+
+ new_data_point[data_label] = gen_model.forecast(last_data_point)[0]
+
+ new_data_point[self.target_variable.data_label] = tmp.expected_value()
+
+ sample = sample.append(new_data_point, ignore_index=True)
+
+ return ret[-steps:]
+
+[docs] def forecast_multivariate(self, data, **kwargs):
+
+ ndata = self.check_data(data)
+
+ generators = kwargs.get('generators', {})
+
+ already_processed_cols = []
+
+ ret = {}
+
+ ret[self.target_variable.data_label] = self.model.forecast(ndata, fuzzyfied=self.pre_fuzzyfy, **kwargs)
+
+ for var in self.explanatory_variables:
+ if var.data_label not in already_processed_cols:
+ if var.data_label in generators:
+ if isinstance(generators[var.data_label], LambdaType):
+ fx = generators[var.data_label]
+ if len(data[var.data_label].values) > self.order:
+ ret[var.data_label] = [fx(k) for k in data[var.data_label].values[self.order:]]
+ else:
+ ret[var.data_label] = [fx(data[var.data_label].values[-1])]
+ elif isinstance(generators[var.data_label], fts.FTS):
+ model = generators[var.data_label]
+ if not model.is_multivariate:
+ ret[var.data_label] = model.forecast(data[var.data_label].values)
+ else:
+ ret[var.data_label] = model.forecast(data)
+ elif self.target_variable.name != var.name:
+ self.target_variable = var
+ self.partitioner.change_target_variable(var)
+ self.model.partitioner = self.partitioner
+ self.model.reset_calculated_values()
+ ret[var.data_label] = self.model.forecast(ndata, fuzzyfied=self.pre_fuzzyfy, **kwargs)
+
+ already_processed_cols.append(var.data_label)
+
+ return pd.DataFrame(ret, columns=ret.keys())
+
+[docs] def forecast_ahead_multivariate(self, data, steps, **kwargs):
+
+ ndata = self.apply_transformations(data)
+
+ start = kwargs.get('start_at', 0)
+
+ ret = ndata.iloc[start:self.order+start]
+
+ for k in np.arange(0, steps):
+ sample = ret.iloc[k:self.order+k]
+ tmp = self.forecast_multivariate(sample, **kwargs)
+ ret = ret.append(tmp, ignore_index=True)
+
+ return ret
+
+ def __str__(self):
+ """String representation of the model"""
+ return str(self.model)
+
+ def __len__(self):
+ """
+ The length (number of rules) of the model
+
+ :return: number of rules
+ """
+ return len(self.model)
+
+
Source code for pyFTS.models.multivariate.granular
+from pyFTS.models.multivariate import cmvfts, grid
+from pyFTS.models import hofts
+
+
+[docs]class GranularWMVFTS(cmvfts.ClusteredMVFTS):
+ """
+ Granular multivariate weighted high order FTS
+ """
+
+ def __init__(self, **kwargs):
+ super(GranularWMVFTS, self).__init__(**kwargs)
+
+ self.fts_method = kwargs.get('fts_method', hofts.WeightedHighOrderFTS)
+ self.model = None
+ """The most recent trained model"""
+ self.knn = kwargs.get('knn', 2)
+ self.order = kwargs.get("order", 2)
+ self.shortname = "FIG-FTS"
+ self.name = "Fuzzy Information Granular FTS"
+ self.mode = kwargs.get('mode','sets')
+
+[docs] def train(self, data, **kwargs):
+ self.partitioner = grid.IncrementalGridCluster(
+ explanatory_variables=self.explanatory_variables,
+ target_variable=self.target_variable,
+ neighbors=self.knn)
+ super(GranularWMVFTS, self).train(data, mode=self.mode, **kwargs)
+
+
Source code for pyFTS.models.multivariate.mvfts
+from pyFTS.common import fts, FuzzySet, FLR, Membership
+from pyFTS.partitioners import Grid
+from pyFTS.models.multivariate import FLR as MVFLR, common, flrg as mvflrg
+from itertools import product
+from types import LambdaType
+from copy import deepcopy
+
+import numpy as np
+import pandas as pd
+
+
+[docs]def product_dict(**kwargs):
+ """
+ Code by Seth Johnson
+ :param kwargs:
+ :return:
+ """
+ keys = kwargs.keys()
+ vals = kwargs.values()
+ for instance in product(*vals):
+ yield dict(zip(keys, instance))
+
+
+[docs]class MVFTS(fts.FTS):
+ """
+ Multivariate extension of Chen's ConventionalFTS method
+ """
+ def __init__(self, **kwargs):
+ super(MVFTS, self).__init__(**kwargs)
+ self.explanatory_variables = kwargs.get('explanatory_variables',[])
+ self.target_variable = kwargs.get('target_variable',None)
+ self.flrgs = {}
+ self.is_multivariate = True
+ self.shortname = "MVFTS"
+ self.name = "Multivariate FTS"
+ self.uod_clip = False
+
+[docs] def append_transformation(self, transformation, **kwargs):
+ if not transformation.is_multivariate:
+ raise Exception('The transformation is not multivariate')
+ self.transformations.append(transformation)
+ self.transformations_param.append(kwargs)
+
+[docs] def append_variable(self, var):
+ """
+ Append a new endogenous variable to the model
+
+ :param var: variable object
+ :return:
+ """
+ self.explanatory_variables.append(var)
+
+[docs] def format_data(self, data):
+ ndata = {}
+ for var in self.explanatory_variables:
+ ndata[var.name] = var.partitioner.extractor(data[var.data_label])
+
+ return ndata
+
+[docs] def apply_transformations(self, data, params=None, updateUoD=False, **kwargs):
+ ndata = data.copy(deep=True)
+ for ct, transformation in enumerate(self.transformations):
+ ndata = transformation.apply(ndata, **self.transformations_param[ct])
+
+ for var in self.explanatory_variables:
+ try:
+ values = ndata[var.data_label].values #if isinstance(ndata, pd.DataFrame) else ndata[var.data_label]
+ if self.uod_clip and var.partitioner.type == 'common':
+ ndata[var.data_label] = np.clip(values,
+ var.partitioner.min, var.partitioner.max)
+
+ ndata[var.data_label] = var.apply_transformations(values)
+ except:
+ pass
+
+ return ndata
+
+[docs] def generate_lhs_flrs(self, data):
+ flrs = []
+ lags = {}
+ for vc, var in enumerate(self.explanatory_variables):
+ data_point = data[var.name]
+ lags[var.name] = common.fuzzyfy_instance(data_point, var, tuples=False)
+
+ for path in product_dict(**lags):
+ flr = MVFLR.FLR()
+
+ flr.LHS = path
+
+ #for var, fset in path.items():
+ # flr.set_lhs(var, fset)
+
+ if len(flr.LHS.keys()) == len(self.explanatory_variables):
+ flrs.append(flr)
+
+ return flrs
+
+[docs] def generate_flrs(self, data):
+ flrs = []
+ for ct in np.arange(1, len(data.index)):
+ ix = data.index[ct-1]
+ data_point = self.format_data( data.loc[ix] )
+
+ tmp_flrs = self.generate_lhs_flrs(data_point)
+
+ target_ix = data.index[ct]
+ target_point = data[self.target_variable.data_label][target_ix]
+ target = common.fuzzyfy_instance(target_point, self.target_variable)
+
+ for flr in tmp_flrs:
+ for v, s in target:
+ new_flr = deepcopy(flr)
+ new_flr.set_rhs(s)
+ flrs.append(new_flr)
+
+ return flrs
+
+[docs] def generate_flrg(self, flrs):
+ for flr in flrs:
+ flrg = mvflrg.FLRG(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)
+
+[docs] def train(self, data, **kwargs):
+
+ ndata = self.apply_transformations(data)
+
+ flrs = self.generate_flrs(ndata)
+ self.generate_flrg(flrs)
+
+[docs] def forecast(self, data, **kwargs):
+ ret = []
+ ndata = self.apply_transformations(data)
+ c = 0
+ for index, row in ndata.iterrows() if isinstance(ndata, pd.DataFrame) else enumerate(ndata):
+ data_point = self.format_data(row)
+ flrs = self.generate_lhs_flrs(data_point)
+ mvs = []
+ mps = []
+ for flr in flrs:
+ flrg = mvflrg.FLRG(lhs=flr.LHS)
+ if flrg.get_key() not in self.flrgs:
+ #Naïve approach is applied when no rules were found
+ if self.target_variable.name in flrg.LHS:
+ fs = flrg.LHS[self.target_variable.name]
+ fset = self.target_variable.partitioner.sets[fs]
+ mp = fset.centroid
+ mv = fset.membership(data_point[self.target_variable.name])
+ mvs.append(mv)
+ mps.append(mp)
+ else:
+ mvs.append(0.)
+ mps.append(0.)
+ else:
+ _flrg = self.flrgs[flrg.get_key()]
+ mvs.append(_flrg.get_membership(data_point, self.explanatory_variables))
+ mps.append(_flrg.get_midpoint(self.target_variable.partitioner.sets))
+
+ mv = np.array(mvs)
+ mp = np.array(mps)
+
+ ret.append(np.dot(mv,mp.T)/np.nansum(mv))
+
+ ret = self.target_variable.apply_inverse_transformations(ret,
+ params=data[self.target_variable.data_label].values)
+ return ret
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+ generators = kwargs.get('generators',None)
+
+ if generators is None:
+ raise Exception('You must provide parameter \'generators\'! generators is a dict where the keys' +
+ ' are the dataframe column 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 or trained FTS models that accept the actual values and '
+ 'forecast new ones.')
+
+ ndata = self.apply_transformations(data)
+
+ start = kwargs.get('start_at', 0)
+
+ ndata = ndata.iloc[start: start + self.max_lag]
+ ret = []
+ for k in np.arange(0, steps):
+ sample = ndata.iloc[-self.max_lag:]
+ tmp = self.forecast(sample, **kwargs)
+
+ if isinstance(tmp, (list, np.ndarray)):
+ tmp = tmp[-1]
+
+ ret.append(tmp)
+
+ new_data_point = {}
+
+ for data_label in generators.keys():
+ if data_label != self.target_variable.data_label:
+ if isinstance(generators[data_label], LambdaType):
+ last_data_point = ndata.loc[ndata.index[-1]]
+ new_data_point[data_label] = generators[data_label](last_data_point[data_label])
+ elif isinstance(generators[data_label], fts.FTS):
+ gen_model = generators[data_label]
+ last_data_point = sample.iloc[-gen_model.order:]
+
+ if not gen_model.is_multivariate:
+ last_data_point = last_data_point[data_label].values
+
+ new_data_point[data_label] = gen_model.forecast(last_data_point)[0]
+
+ new_data_point[self.target_variable.data_label] = tmp
+
+ ndata = ndata.append(new_data_point, ignore_index=True)
+
+ return ret[-steps:]
+
+[docs] def forecast_interval(self, data, **kwargs):
+ ret = []
+ ndata = self.apply_transformations(data)
+ c = 0
+ for index, row in ndata.iterrows() if isinstance(ndata, pd.DataFrame) else enumerate(ndata):
+ data_point = self.format_data(row)
+ flrs = self.generate_lhs_flrs(data_point)
+ mvs = []
+ ups = []
+ los = []
+ for flr in flrs:
+ flrg = mvflrg.FLRG(lhs=flr.LHS)
+ if flrg.get_key() not in self.flrgs:
+ #Naïve approach is applied when no rules were found
+ if self.target_variable.name in flrg.LHS:
+ fs = flrg.LHS[self.target_variable.name]
+ fset = self.target_variable.partitioner.sets[fs]
+ up = fset.upper
+ lo = fset.lower
+ mv = fset.membership(data_point[self.target_variable.name])
+ mvs.append(mv)
+ ups.append(up)
+ los.append(lo)
+ else:
+ mvs.append(0.)
+ ups.append(0.)
+ los.append(0.)
+ else:
+ _flrg = self.flrgs[flrg.get_key()]
+ mvs.append(_flrg.get_membership(data_point, self.explanatory_variables))
+ ups.append(_flrg.get_upper(self.target_variable.partitioner.sets))
+ los.append(_flrg.get_lower(self.target_variable.partitioner.sets))
+
+ mv = np.array(mvs)
+ up = np.dot(mv, np.array(ups).T) / np.nansum(mv)
+ lo = np.dot(mv, np.array(los).T) / np.nansum(mv)
+
+ ret.append([lo, up])
+
+ ret = self.target_variable.apply_inverse_transformations(ret,
+ params=data[self.target_variable.data_label].values)
+ return ret
+
+[docs] def forecast_ahead_interval(self, data, steps, **kwargs):
+ generators = kwargs.get('generators', None)
+
+ if generators is None:
+ raise Exception('You must provide parameter \'generators\'! generators is a dict where the keys' +
+ ' are the dataframe column 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 or trained FTS models that accept the actual values and '
+ 'forecast new ones.')
+
+ ndata = self.apply_transformations(data)
+
+ start = kwargs.get('start_at', 0)
+
+ ret = []
+ ix = ndata.index[start: start + self.max_lag]
+ lo = ndata.loc[ix] #[ndata.loc[k] for k in ix]
+ up = ndata.loc[ix] #[ndata.loc[k] for k in ix]
+ for k in np.arange(0, steps):
+ tmp_lo = self.forecast_interval(lo[-self.max_lag:], **kwargs)[0]
+ tmp_up = self.forecast_interval(up[-self.max_lag:], **kwargs)[0]
+
+ ret.append([min(tmp_lo), max(tmp_up)])
+
+ new_data_point_lo = {}
+ new_data_point_up = {}
+
+ for data_label in generators.keys():
+ if data_label != self.target_variable.data_label:
+ if isinstance(generators[data_label], LambdaType):
+ last_data_point_lo = lo.loc[lo.index[-1]]
+ new_data_point_lo[data_label] = generators[data_label](last_data_point_lo[data_label])
+ last_data_point_up = up.loc[up.index[-1]]
+ new_data_point_up[data_label] = generators[data_label](last_data_point_up[data_label])
+ elif isinstance(generators[data_label], fts.FTS):
+ model = generators[data_label]
+ last_data_point_lo = lo.loc[lo.index[-model.order:]]
+ last_data_point_up = up.loc[up.index[-model.order:]]
+
+ if not model.is_multivariate:
+ last_data_point_lo = last_data_point_lo[data_label].values
+ last_data_point_up = last_data_point_up[data_label].values
+
+ new_data_point_lo[data_label] = model.forecast(last_data_point_lo)[0]
+ new_data_point_up[data_label] = model.forecast(last_data_point_up)[0]
+
+ new_data_point_lo[self.target_variable.data_label] = min(tmp_lo)
+ new_data_point_up[self.target_variable.data_label] = max(tmp_up)
+
+ lo = lo.append(new_data_point_lo, ignore_index=True)
+ up = up.append(new_data_point_up, ignore_index=True)
+
+ return ret[-steps:]
+
+[docs] def clone_parameters(self, model):
+ super(MVFTS, self).clone_parameters(model)
+
+ self.explanatory_variables = model.explanatory_variables
+ self.target_variable = model.target_variable
+
+ def __str__(self):
+ _str = self.name + ":\n"
+ for k in self.flrgs.keys():
+ _str += str(self.flrgs[k]) + "\n"
+
+ return _str
+
+
+
Source code for pyFTS.models.multivariate.variable
+import pandas as pd
+from pyFTS.common import fts, FuzzySet, FLR, Membership, tree
+from pyFTS.partitioners import Grid
+from pyFTS.models.multivariate import FLR as MVFLR
+
+
+[docs]class Variable:
+ """
+ A variable of a fuzzy time series multivariate model. Each variable contains its own
+ transformations and partitioners.
+ """
+ def __init__(self, name, **kwargs):
+ """
+
+ :param name:
+ :param \**kwargs: See below
+
+ :Keyword Arguments:
+ * *alias* -- Alternative name for the variable
+ """
+ self.name = name
+ """A string with the name of the variable"""
+ self.alias = kwargs.get('alias', self.name)
+ """A string with the alias of the variable"""
+ self.data_label = kwargs.get('data_label', self.name)
+ """A string with the column name on DataFrame"""
+ self.type = kwargs.get('type', 'common')
+ self.data_type = kwargs.get('data_type', None)
+ """The type of the data column on Pandas Dataframe"""
+ self.mask = kwargs.get('mask', None)
+ """The mask for format the data column on Pandas Dataframe"""
+ self.transformation = kwargs.get('transformation', None)
+ """Pre processing transformation for the variable"""
+ self.transformation_params = kwargs.get('transformation_params', None)
+ self.partitioner = None
+ """UoD partitioner for the variable data"""
+ self.alpha_cut = kwargs.get('alpha_cut', 0.0)
+ """Minimal membership value to be considered on fuzzyfication process"""
+
+
+ if kwargs.get('data', None) is not None:
+ self.build(**kwargs)
+
+[docs] def build(self, **kwargs):
+ """
+
+ :param kwargs:
+ :return:
+ """
+ fs = kwargs.get('partitioner', Grid.GridPartitioner)
+ mf = kwargs.get('func', Membership.trimf)
+ np = kwargs.get('npart', 10)
+ data = kwargs.get('data', None)
+ kw = kwargs.get('partitioner_specific', {})
+ self.partitioner = fs(data=data[self.data_label].values, npart=np, func=mf,
+ transformation=self.transformation, prefix=self.alias,
+ variable=self.name, **kw)
+
+ self.partitioner.name = self.name + " " + self.partitioner.name
+
+[docs] def apply_transformations(self, data, **kwargs):
+
+ if kwargs.get('params', None) is not None:
+ self.transformation_params = kwargs.get('params', None)
+
+ if self.transformation is not None:
+ return self.transformation.apply(data, self.transformation_params)
+
+ return data
+
+[docs] def apply_inverse_transformations(self, data, **kwargs):
+
+ if kwargs.get('params', None) is not None:
+ self.transformation_params = kwargs.get('params', None)
+
+ if self.transformation is not None:
+ return self.transformation.inverse(data, self.transformation_params)
+
+ return data
+
+ def __str__(self):
+ return self.name
+
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):
+ count = kwargs.get('count', 1.0)
+ if fset not in self.RHS:
+ self.RHS[fset] = count
+ else:
+ self.RHS[fset] += count
+ self.count += count
+
+[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):
+ if self.midpoint is None:
+ mp = np.array([sets[c].centroid for c in self.RHS.keys()])
+ self.midpoint = mp.dot(self.weights())
+
+ return self.midpoint
+
+[docs] def get_lower(self, sets):
+ if self.lower is None:
+ lw = np.array([sets[s].lower for s in self.RHS.keys()])
+ self.lower = lw.dot(self.weights())
+ return self.lower
+
+[docs] def get_upper(self, sets):
+ if self.upper is None:
+ up = np.array([sets[s].upper for s in self.RHS.keys()])
+ self.upper = up.dot(self.weights())
+ return self.upper
+
+ 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.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)
+
Source code for pyFTS.models.nonstationary.cvfts
+import numpy as np
+from pyFTS.models import hofts
+from pyFTS.models.nonstationary import common,nsfts
+from pyFTS.common import FLR, flrg, tree
+
+
+[docs]class HighOrderNonstationaryFLRG(hofts.HighOrderFTS):
+ """Conventional High Order Fuzzy Logical Relationship Group"""
+ def __init__(self, order, **kwargs):
+ super(HighOrderNonstationaryFLRG, self).__init__(order, **kwargs)
+ self.LHS = []
+ self.RHS = {}
+ self.strlhs = ""
+
+
+
+
+
+ def __str__(self):
+ tmp = ""
+ for c in sorted(self.RHS):
+ if len(tmp) > 0:
+ tmp = tmp + ","
+ tmp = tmp + c
+ return self.get_key() + " -> " + tmp
+
+
+ def __len__(self):
+ return len(self.RHS)
+
+
+[docs]class ConditionalVarianceFTS(hofts.HighOrderFTS):
+ def __init__(self, **kwargs):
+ super(ConditionalVarianceFTS, self).__init__(**kwargs)
+ self.name = "Conditional Variance FTS"
+ self.shortname = "CVFTS "
+ self.detail = ""
+ self.flrgs = {}
+ self.is_high_order = False
+ if self.partitioner is not None:
+ self.append_transformation(self.partitioner.transformation)
+
+ self.min_stack = [0,0,0]
+ self.max_stack = [0,0,0]
+ self.uod_clip = False
+ self.order = 1
+ self.min_order = 1
+ self.max_lag = 1
+ self.inputs = []
+ self.forecasts = []
+ self.residuals = []
+ self.variance_residual = 0.
+ self.mean_residual = 0.
+ self.memory_window = kwargs.get("memory_window",5)
+ self.sets = {}
+
+[docs] def train(self, ndata, **kwargs):
+
+ tmpdata = common.fuzzySeries(ndata, self.sets,
+ self.partitioner.ordered_sets,
+ method='fuzzy', const_t=0)
+ flrs = FLR.generate_non_recurrent_flrs(tmpdata)
+ 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()
+
+
+[docs] def generate_flrg(self, flrs, **kwargs):
+ for flr in flrs:
+ if flr.LHS.name in self.flrgs:
+ self.flrgs[flr.LHS.name].append_rhs(flr.RHS.name)
+ else:
+ self.flrgs[flr.LHS.name] = nsfts.ConventionalNonStationaryFLRG(flr.LHS.name)
+ self.flrgs[flr.LHS.name].append_rhs(flr.RHS.name)
+
+
+ def _smooth(self, a):
+ return .1 * a[0] + .3 * a[1] + .6 * a[2]
+
+[docs] def perturbation_factors(self, data, **kwargs):
+ npart = len(self.partitioner.sets)
+ _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, npart)
+
+ 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, npart) for w in translate]
+
+ scale = [abs(location[0] - location[2])]
+ scale.extend([abs(location[k - 1] - location[k + 1]) for k in np.arange(1, npart)])
+ scale.append(abs(location[-1] - location[-3]))
+
+ perturb = [[location[k], scale[k]] for k in np.arange(npart)]
+
+ return perturb
+
+[docs] def perturbation_factors__old(self, data):
+ npart = len(self.partitioner.sets)
+ _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)
+
+ location = np.linspace(_min, _max, npart)
+ scale = [abs(location[0] - location[2])]
+ scale.extend([abs(location[k-1] - location[k+1]) for k in np.arange(1, npart)])
+ scale.append(abs(location[-1] - location[-3]))
+
+ perturb = [[location[k], scale[k]] for k in np.arange(0, npart)]
+
+ return perturb
+
+ def _fsset_key(self, ix):
+ return self.partitioner.ordered_sets[ix]
+
+ def _affected_sets(self, sample, perturb):
+
+ affected_sets = [[ct, self.sets[self._fsset_key(ct)].membership(sample, perturb[ct])]
+ for ct in np.arange(len(self.partitioner.sets))
+ if self.sets[self._fsset_key(ct)].membership(sample, perturb[ct]) > 0.0]
+
+ if len(affected_sets) == 0:
+
+ if sample < self.partitioner.lower_set().get_lower(perturb[0]):
+ affected_sets.append([0, 1])
+ elif sample > self.partitioner.upper_set().get_upper(perturb[-1]):
+ affected_sets.append([len(self.sets) - 1, 1])
+
+ return affected_sets
+
+[docs] def forecast(self, ndata, **kwargs):
+ l = len(ndata)
+
+ ret = []
+
+ no_update = kwargs.get("no_update",False)
+
+ for k in np.arange(0, l):
+
+ sample = ndata[k]
+
+ if not no_update:
+ perturb = self.perturbation_factors(sample)
+ else:
+ perturb = [[0, 1] for k in np.arange(len(self.partitioner.sets))]
+
+ affected_sets = self._affected_sets(sample, perturb)
+
+ numerator = []
+ denominator = []
+
+ if len(affected_sets) == 1:
+ ix = affected_sets[0][0]
+ aset = self.partitioner.ordered_sets[ix]
+ if aset in self.flrgs:
+ numerator.append(self.flrgs[aset].get_midpoint(self.sets, perturb[ix]))
+ else:
+ fuzzy_set = self.sets[aset]
+ numerator.append(fuzzy_set.get_midpoint(perturb[ix]))
+ denominator.append(1)
+ else:
+ for aset in affected_sets:
+ ix = aset[0]
+ fs = self.partitioner.ordered_sets[ix]
+ tdisp = perturb[ix]
+ if fs in self.flrgs:
+ numerator.append(self.flrgs[fs].get_midpoint(self.sets, tdisp) * aset[1])
+ else:
+ fuzzy_set = self.sets[fs]
+ numerator.append(fuzzy_set.get_midpoint(tdisp) * aset[1])
+ denominator.append(aset[1])
+
+ if sum(denominator) > 0:
+ pto = sum(numerator) /sum(denominator)
+ else:
+ pto = sum(numerator)
+
+ 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
+
+
+[docs] def forecast_interval(self, ndata, **kwargs):
+ l = len(ndata)
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ sample = ndata[k]
+
+ perturb = self.perturbation_factors(sample)
+
+ affected_sets = self._affected_sets(sample, perturb)
+
+ upper = []
+ lower = []
+
+ if len(affected_sets) == 1:
+ ix = affected_sets[0][0]
+ aset = self.partitioner.ordered_sets[ix]
+ if aset in self.flrgs:
+ lower.append(self.flrgs[aset].get_lower(perturb[ix]))
+ upper.append(self.flrgs[aset].get_upper(perturb[ix]))
+ else:
+ fuzzy_set = self.sets[aset]
+ lower.append(fuzzy_set.get_lower(perturb[ix]))
+ upper.append(fuzzy_set.get_upper(perturb[ix]))
+ else:
+ for aset in affected_sets:
+ ix = aset[0]
+ fs = self.partitioner.ordered_sets[ix]
+ tdisp = perturb[ix]
+ if fs in self.flrgs:
+ lower.append(self.flrgs[fs].get_lower(tdisp) * aset[1])
+ upper.append(self.flrgs[fs].get_upper(tdisp) * aset[1])
+ else:
+ fuzzy_set = self.sets[fs]
+ lower.append(fuzzy_set.get_lower(tdisp) * aset[1])
+ upper.append(fuzzy_set.get_upper(tdisp) * aset[1])
+
+ itvl = [sum(lower), sum(upper)]
+
+ ret.append(itvl)
+
+ return ret
+
Source code for pyFTS.models.nonstationary.honsfts
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts
+from pyFTS.models import hofts
+from pyFTS.models.nonstationary import common, flrg, nsfts
+from itertools import product
+
+
+[docs]class HighOrderNonStationaryFLRG(flrg.NonStationaryFLRG):
+ """First Order NonStationary Fuzzy Logical Relationship Group"""
+ def __init__(self, order, **kwargs):
+ super(HighOrderNonStationaryFLRG, self).__init__(order, **kwargs)
+ self.LHS = []
+ self.RHS = {}
+ self.count = 0.0
+ self.strlhs = ""
+ self.w = None
+
+[docs] def append_rhs(self, fset, **kwargs):
+ count = kwargs.get('count',1.0)
+ if fset not in self.RHS:
+ self.RHS[fset] = count
+ else:
+ self.RHS[fset] += count
+ self.count += count
+
+
+
+[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, perturb):
+ mp = np.array([sets[c].get_midpoint(perturb) for c in self.RHS.keys()])
+ midpoint = mp.dot(self.weights())
+ return midpoint
+
+[docs] def get_lower(self, sets, perturb):
+ lw = np.array([sets[s].get_lower(perturb) for s in self.RHS.keys()])
+ lower = lw.dot(self.weights())
+ return lower
+
+[docs] def get_upper(self, sets, perturb):
+ up = np.array([sets[s].get_upper(perturb) for s in self.RHS.keys()])
+ upper = up.dot(self.weights())
+ return upper
+
+ 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 HighOrderNonStationaryFTS(nsfts.NonStationaryFTS):
+ """NonStationaryFTS Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(HighOrderNonStationaryFTS, self).__init__(**kwargs)
+ self.name = "High Order Non Stationary FTS"
+ self.shortname = "HONSFTS"
+ self.detail = ""
+ self.flrgs = {}
+ self.is_high_order = True
+ self.order = kwargs.get("order",2)
+ self.configure_lags(**kwargs)
+
+[docs] def configure_lags(self, **kwargs):
+ if "order" in kwargs:
+ self.order = kwargs.get("order", self.min_order)
+
+ if "lags" in kwargs:
+ self.lags = kwargs.get("lags", None)
+
+ if self.lags is not None:
+ self.max_lag = max(self.lags)
+ else:
+ self.max_lag = self.order
+ self.lags = np.arange(1, self.order + 1)
+
+[docs] def train(self, data, **kwargs):
+
+ self.generate_flrg(data)
+
+ if self.method == 'conditional':
+ self.forecasts = self.forecast(data, no_update=True)
+ self.residuals = np.array(data[self.order:]) - np.array(self.forecasts)
+
+ 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(data[-self.memory_window:]).tolist()
+
+[docs] def generate_flrg(self, data, **kwargs):
+ 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 = [key for key in self.partitioner.ordered_sets
+ if self.partitioner.sets[key].membership(data[k], [0,1]) > 0.0]
+
+ if len(rhs) == 0:
+ rhs = [common.check_bounds(data[k], self.partitioner, [0,1]).name]
+
+ lags = []
+
+ for o in np.arange(0, self.order):
+ tdisp = [0,1]
+ lhs = [key for key in self.partitioner.ordered_sets
+ if self.partitioner.sets[key].membership(sample[o], tdisp) > 0.0]
+
+ if len(lhs) == 0:
+ lhs = [common.check_bounds(sample[o], self.partitioner, tdisp).name]
+
+ lags.append(lhs)
+
+ # Trace the possible paths
+ for path in product(*lags):
+ flrg = HighOrderNonStationaryFLRG(self.order)
+
+ for c, e in enumerate(path, start=0):
+ flrg.append_lhs(e)
+
+ 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)
+
+ def _affected_flrgs(self, sample, perturb):
+
+ affected_flrgs = []
+ affected_flrgs_memberships = []
+
+ lags = []
+
+ for ct, dat in enumerate(sample):
+ affected_sets = [key for ct, key in enumerate(self.partitioner.ordered_sets)
+ if self.partitioner.sets[key].membership(dat, perturb[ct]) > 0.0]
+
+ if len(affected_sets) == 0:
+
+ if dat < self.partitioner.lower_set().get_lower(perturb[0]):
+ affected_sets.append(self.partitioner.lower_set().name)
+ elif dat > self.partitioner.upper_set().get_upper(perturb[-1]):
+ affected_sets.append(self.partitioner.upper_set().name)
+
+ lags.append(affected_sets)
+
+ # Build the tree with all possible paths
+
+ # Trace the possible paths
+ for path in product(*lags):
+
+ flrg = HighOrderNonStationaryFLRG(self.order)
+
+ for kk in path:
+ flrg.append_lhs(kk)
+
+ affected_flrgs.append(flrg)
+ mv = []
+ for ct, dat in enumerate(sample):
+ fset = self.partitioner.sets[flrg.LHS[ct]]
+ ix = self.partitioner.ordered_sets.index(flrg.LHS[ct])
+ tmp = fset.membership(dat, perturb[ix])
+
+ mv.append(tmp)
+
+ affected_flrgs_memberships.append(np.prod(mv))
+
+ return [affected_flrgs, affected_flrgs_memberships]
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ explain = kwargs.get('explain', False)
+
+ time_displacement = kwargs.get("time_displacement", 0)
+
+ window_size = kwargs.get("window_size", 1)
+
+ no_update = kwargs.get("no_update", False)
+
+ ret = []
+
+ l = len(ndata) if not explain else self.max_lag + 1
+
+ if l < self.max_lag:
+ return ndata
+ elif l == self.max_lag:
+ l += 1
+
+ for k in np.arange(self.max_lag, l):
+
+ sample = ndata[k - self.max_lag: k]
+
+ if self.method == 'unconditional':
+ perturb = common.window_index(k + time_displacement, window_size)
+ elif self.method == 'conditional':
+ if no_update:
+ perturb = [[0, 1] for k in np.arange(self.partitioner.partitions)]
+ else:
+ perturb = self.conditional_perturbation_factors(sample[-1])
+
+ affected_flrgs, affected_flrgs_memberships = self._affected_flrgs(sample, perturb)
+
+ tmp = []
+
+ perturb2 = perturb[0]
+ if len(affected_flrgs) == 0:
+ tmp.append(common.check_bounds(sample[-1], self.partitioner.sets, perturb2))
+ elif len(affected_flrgs) == 1:
+ flrg = affected_flrgs[0]
+ if flrg.get_key() in self.flrgs:
+ tmp.append(self.flrgs[flrg.get_key()].get_midpoint(self.partitioner.sets, perturb2))
+ else:
+ fset = self.partitioner.sets[flrg.LHS[-1]]
+ ix = self.partitioner.ordered_sets.index(flrg.LHS[-1])
+ tmp.append(fset.get_midpoint(perturb[ix]))
+ else:
+ for ct, aset in enumerate(affected_flrgs):
+ if aset.get_key() in self.flrgs:
+
+ tmp.append(self.flrgs[aset.get_key()].get_midpoint(self.partitioner.sets, perturb2) *
+ affected_flrgs_memberships[ct])
+ else:
+ fset = self.partitioner.sets[aset.LHS[-1]]
+ ix = self.partitioner.ordered_sets.index(aset.LHS[-1])
+ tmp.append(fset.get_midpoint(perturb[ix])*affected_flrgs_memberships[ct])
+ pto = sum(tmp)
+
+ ret.append(pto)
+
+ if self.method == 'conditional' and not no_update:
+ self.forecasts.append(pto)
+ self.residuals.append(self.inputs[-1] - self.forecasts[-1])
+ self.inputs.extend(sample)
+
+ for g in range(self.order):
+ self.inputs.pop(0)
+ self.forecasts.pop(0)
+ self.residuals.pop(0)
+
+ return ret
+
+ def __str__(self):
+ tmp = self.name + ":\n"
+ for r in self.flrgs:
+ tmp = "{0}{1}\n".format(tmp, str(self.flrgs[r]))
+ return tmp
+
Source code for pyFTS.models.nonstationary.nsfts
+import numpy as np
+from pyFTS.common import FLR, fts
+from pyFTS.models.nonstationary import common, flrg
+
+
+[docs]class ConventionalNonStationaryFLRG(flrg.NonStationaryFLRG):
+ """First Order NonStationary Fuzzy Logical Relationship Group"""
+
+ def __init__(self, LHS, **kwargs):
+ super(ConventionalNonStationaryFLRG, self).__init__(1, **kwargs)
+ self.LHS = LHS
+ self.RHS = set()
+
+
+
+
+
+ def __str__(self):
+ tmp = self.LHS + " -> "
+ tmp2 = ""
+ for c in sorted(self.RHS):
+ if len(tmp2) > 0:
+ tmp2 = tmp2 + ","
+ tmp2 = tmp2 + c
+ return tmp + tmp2
+
+
+[docs]class WeightedNonStationaryFLRG(flrg.NonStationaryFLRG):
+ """First Order NonStationary Fuzzy Logical Relationship Group"""
+
+ def __init__(self, LHS, **kwargs):
+ super(WeightedNonStationaryFLRG, self).__init__(1, **kwargs)
+ self.LHS = LHS
+ self.RHS = {}
+ self.count = 0.0
+ self.strlhs = ""
+ self.w = None
+
+
+
+[docs] def append_rhs(self, c, **kwargs):
+ if c not in self.RHS:
+ self.RHS[c] = 1
+ else:
+ self.RHS[c] += 1
+ self.count += 1
+
+[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, perturb):
+ mp = np.array([sets[c].get_midpoint(perturb) for c in self.RHS.keys()])
+ midpoint = mp.dot(self.weights())
+ return midpoint
+
+ 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 NonStationaryFTS(fts.FTS):
+ """NonStationaryFTS Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(NonStationaryFTS, self).__init__(**kwargs)
+ self.name = "Non Stationary FTS"
+ self.shortname = "NSFTS"
+ self.detail = ""
+ self.flrgs = {}
+ self.method = kwargs.get('method','conditional')
+ self.is_high_order = False
+ if self.partitioner is not None:
+ self.append_transformation(self.partitioner.transformation)
+
+ if self.method == 'conditional':
+ self.min_stack = [0, 0, 0]
+ self.max_stack = [0, 0, 0]
+ self.uod_clip = False
+ self.order = 1
+ self.min_order = 1
+ self.max_lag = 1
+ self.inputs = []
+ self.forecasts = []
+ self.residuals = []
+ self.variance_residual = 0.
+ self.mean_residual = 0.
+ self.memory_window = kwargs.get("memory_window", 5)
+
+[docs] def generate_flrg(self, flrs, **kwargs):
+ for flr in flrs:
+ if flr.LHS.name in self.flrgs:
+ self.flrgs[flr.LHS.name].append_rhs(flr.RHS.name)
+ else:
+ self.flrgs[flr.LHS.name] = ConventionalNonStationaryFLRG(flr.LHS.name)
+ self.flrgs[flr.LHS.name].append_rhs(flr.RHS.name)
+
+ def _smooth(self, a):
+ return .1 * a[0] + .3 * a[1] + .6 * a[2]
+
+[docs] def train(self, data, **kwargs):
+
+ if self.method == 'unconditional':
+ window_size = kwargs.get('parameters', 1)
+ tmpdata = common.fuzzySeries(data, self.partitioner.sets,
+ self.partitioner.ordered_sets,
+ window_size, method='fuzzy')
+ else:
+ tmpdata = common.fuzzySeries(data, self.partitioner.sets,
+ self.partitioner.ordered_sets,
+ method='fuzzy', const_t=0)
+
+ flrs = FLR.generate_non_recurrent_flrs(tmpdata)
+ self.generate_flrg(flrs)
+
+ if self.method == 'conditional':
+ self.forecasts = self.forecast(data, no_update=True)
+ self.residuals = np.array(data[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(data[-self.memory_window:]).tolist()
+
+[docs] def conditional_perturbation_factors(self, data, **kwargs):
+ npart = len(self.partitioner.sets)
+ _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, npart)
+
+ 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, npart) for w in translate]
+
+ scale = [abs(location[0] - location[2])]
+ scale.extend([abs(location[k - 1] - location[k + 1]) for k in np.arange(1, npart)])
+ scale.append(abs(location[-1] - location[-3]))
+
+ perturb = [[location[k], scale[k]] for k in np.arange(npart)]
+
+ return perturb
+
+ def _affected_sets(self, sample, perturb):
+
+ if self.method == 'conditional':
+
+ affected_sets = [[ct, self.partitioner.sets[key].membership(sample, perturb[ct])]
+ for ct, key in enumerate(self.partitioner.ordered_sets)
+ if self.partitioner.sets[key].membership(sample, perturb[ct]) > 0.0]
+
+ if len(affected_sets) == 0:
+ if sample < self.partitioner.lower_set().get_lower(perturb[0]):
+ affected_sets.append([0, 1])
+ elif sample > self.partitioner.upper_set().get_upper(perturb[-1]):
+ affected_sets.append([len(self.sets) - 1, 1])
+
+ else:
+ affected_sets = [[ct, self.partitioner.sets[key].membership(sample, perturb)]
+ for ct, key in enumerate(self.partitioner.ordered_sets)
+ if self.partitioner.sets[key].membership(sample, perturb) > 0.0]
+
+ if len(affected_sets) == 0:
+
+ if sample < self.partitioner.lower_set().get_lower(perturb):
+ affected_sets.append([0, 1])
+ elif sample > self.partitioner.upper_set().get_upper(perturb):
+ affected_sets.append([len(self.sets) - 1, 1])
+
+ return affected_sets
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ time_displacement = kwargs.get("time_displacement",0)
+
+ window_size = kwargs.get("window_size", 1)
+
+ no_update = kwargs.get("no_update", False)
+
+ l = len(ndata)
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ sample = ndata[k]
+
+ if self.method == 'unconditional':
+ perturb = common.window_index(k + time_displacement, window_size)
+ elif self.method == 'conditional':
+ if not no_update:
+ perturb = self.conditional_perturbation_factors(sample)
+ else:
+ perturb = [[0, 1] for k in np.arange(len(self.partitioner.sets))]
+
+ affected_sets = self._affected_sets(sample, perturb)
+
+ numerator = []
+ denominator = []
+
+ if len(affected_sets) == 1:
+ ix = affected_sets[0][0]
+ aset = self.partitioner.ordered_sets[ix]
+ if aset in self.flrgs:
+ numerator.append(self.flrgs[aset].get_midpoint(self.partitioner.sets, perturb[ix]))
+ else:
+ fuzzy_set = self.partitioner.sets[aset]
+ numerator.append(fuzzy_set.get_midpoint(perturb[ix]))
+ denominator.append(1)
+ else:
+ for aset in affected_sets:
+ ix = aset[0]
+ fs = self.partitioner.ordered_sets[ix]
+ tdisp = perturb[ix]
+ if fs in self.flrgs:
+ numerator.append(self.flrgs[fs].get_midpoint(self.partitioner.sets, tdisp) * aset[1])
+ else:
+ fuzzy_set = self.partitioner.sets[fs]
+ numerator.append(fuzzy_set.get_midpoint(tdisp) * aset[1])
+ denominator.append(aset[1])
+
+ if sum(denominator) > 0:
+ pto = sum(numerator) / sum(denominator)
+ else:
+ pto = sum(numerator)
+
+ ret.append(pto)
+
+ if self.method == 'conditional' and 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
+
+[docs] def forecast_interval(self, ndata, **kwargs):
+
+ time_displacement = kwargs.get("time_displacement", 0)
+
+ window_size = kwargs.get("window_size", 1)
+
+ l = len(ndata)
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ # print("input: " + str(ndata[k]))
+
+ tdisp = common.window_index(k + time_displacement, window_size)
+
+ affected_sets = [[self.partitioner.sets[key], self.partitioner.sets[key].membership(ndata[k], tdisp)]
+ for key in self.partitioner.ordered_sets
+ if self.partitioner.sets[key].membership(ndata[k], tdisp) > 0.0]
+
+ if len(affected_sets) == 0:
+ affected_sets.append([common.check_bounds(ndata[k], self.partitioner, tdisp), 1.0])
+
+ upper = []
+ lower = []
+
+ if len(affected_sets) == 1:
+ aset = affected_sets[0][0]
+ if aset.name in self.flrgs:
+ lower.append(self.flrgs[aset.name].get_lower(tdisp))
+ upper.append(self.flrgs[aset.name].get_upper(tdisp))
+ else:
+ lower.append(aset.get_lower(tdisp))
+ upper.append(aset.get_upper(tdisp))
+ else:
+ for aset in affected_sets:
+ if aset[0].name in self.flrgs:
+ lower.append(self.flrgs[aset[0].name].get_lower(tdisp) * aset[1])
+ upper.append(self.flrgs[aset[0].name].get_upper(tdisp) * aset[1])
+ else:
+ lower.append(aset[0].get_lower(tdisp) * aset[1])
+ upper.append(aset[0].get_upper(tdisp) * aset[1])
+
+
+ ret.append([sum(lower), sum(upper)])
+
+ return ret
+
+ def __str__(self):
+ tmp = self.name + ":\n"
+ for r in self.flrgs:
+ tmp = "{0}{1}\n".format(tmp, str(self.flrgs[r]))
+ return tmp
+
+
+[docs]class WeightedNonStationaryFTS(NonStationaryFTS):
+ """Weighted NonStationaryFTS Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(WeightedNonStationaryFTS, self).__init__(**kwargs)
+ self.name = "Weighted Non Stationary FTS"
+ self.shortname = "WNSFTS"
+
+[docs] def train(self, data, **kwargs):
+
+ if self.method == 'unconditional':
+ window_size = kwargs.get('parameters', 1)
+ tmpdata = common.fuzzySeries(data, self.partitioner.sets,
+ self.partitioner.ordered_sets,
+ window_size, method='fuzzy')
+ else:
+ tmpdata = common.fuzzySeries(data, self.partitioner.sets,
+ self.partitioner.ordered_sets,
+ method='fuzzy', const_t=0)
+
+ flrs = FLR.generate_recurrent_flrs(tmpdata)
+ self.generate_flrg(flrs)
+
+ if self.method == 'conditional':
+ self.forecasts = self.forecast(data, no_update=True)
+ self.residuals = np.array(data[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(data[-self.memory_window:]).tolist()
+
+[docs] def generate_flrg(self, flrs, **kwargs):
+ for flr in flrs:
+ if flr.LHS.name in self.flrgs:
+ self.flrgs[flr.LHS.name].append_rhs(flr.RHS.name)
+ else:
+ self.flrgs[flr.LHS.name] = WeightedNonStationaryFLRG(flr.LHS.name)
+ self.flrgs[flr.LHS.name].append_rhs(flr.RHS.name)
+
Source code for pyFTS.models.nonstationary.util
+import numpy as np
+import pandas as pd
+import matplotlib as plt
+import matplotlib.colors as pltcolors
+import matplotlib.pyplot as plt
+from pyFTS.common import Membership, Util
+
+
+[docs]def plot_sets(partitioner, start=0, end=10, step=1, tam=[5, 5], colors=None,
+ save=False, file=None, axes=None, data=None, window_size = 1, only_lines=False, legend=True):
+
+ range = np.arange(start,end,step)
+ ticks = []
+ if axes is None:
+ fig, axes = plt.subplots(nrows=1, ncols=1, figsize=tam)
+
+ for ct, key in enumerate(partitioner.ordered_sets):
+ fset = partitioner.sets[key]
+ if not only_lines:
+ for t in range:
+ tdisp = t - (t % window_size)
+ fset.membership(0, tdisp)
+ param = fset.perturbated_parameters[str(tdisp)]
+
+ if fset.mf == Membership.trimf:
+ if t == start:
+ line = axes.plot([t, t+1, t], param, label=fset.name)
+ fset.metadata['color'] = line[0].get_color()
+ else:
+ axes.plot([t, t + 1, t], param,c=fset.metadata['color'])
+
+ ticks.extend(["t+"+str(t),""])
+ else:
+ tmp = []
+ for t in range:
+ tdisp = t - (t % window_size)
+ fset.membership(0, tdisp)
+ param = fset.perturbated_parameters[str(tdisp)]
+ tmp.append(np.polyval(param, tdisp))
+ axes.plot(range, tmp, ls="--", c="blue")
+
+ axes.set_ylabel("Universe of Discourse")
+ axes.set_xlabel("Time")
+ plt.xticks([k for k in range], ticks, rotation='vertical')
+
+ if legend:
+ handles0, labels0 = axes.get_legend_handles_labels()
+ lgd = axes.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))
+
+ if data is not None:
+ axes.plot(np.arange(start, start + len(data), 1), data,c="black")
+
+ if file is not None:
+ plt.tight_layout()
+ Util.show_and_save_image(fig, file, save)
+
+
+[docs]def plot_sets_conditional(model, data, step=1, size=[5, 5], colors=None,
+ save=False, file=None, axes=None, fig=None):
+ range = np.arange(0, len(data), step)
+ ticks = []
+ if axes is None:
+ fig, axes = plt.subplots(nrows=1, ncols=1, figsize=size)
+
+ for t in range:
+ model.forecast([data[t]])
+ perturb = model.conditional_perturbation_factors(data[t])
+
+ for ct, key in enumerate(model.partitioner.ordered_sets):
+ set = model.partitioner.sets[key]
+ set.perturbate_parameters(perturb[ct])
+ param = set.perturbated_parameters[str(perturb[ct])]
+
+ if set.mf == Membership.trimf:
+ if t == 0:
+ line = axes.plot([t, t+1, t], param, label=set.name)
+ set.metadata['color'] = line[0].get_color()
+ else:
+ axes.plot([t, t + 1, t], param,c=set.metadata['color'])
+
+ #ticks.extend(["t+"+str(t),""])
+
+ axes.set_ylabel("Universe of Discourse")
+ axes.set_xlabel("Time")
+ #plt.xticks([k for k in range], ticks, rotation='vertical')
+
+ handles0, labels0 = axes.get_legend_handles_labels()
+ lgd = axes.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))
+
+ if data is not None:
+ axes.plot(np.arange(0, len(data), 1), data,c="black")
+
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
Source code for pyFTS.models.pwfts
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+
+import numpy as np
+import pandas as pd
+import math
+from operator import itemgetter
+from pyFTS.common import FLR, FuzzySet
+from pyFTS.models import hofts, ifts
+from pyFTS.probabilistic import ProbabilityDistribution
+from itertools import product
+
+
+[docs]class ProbabilisticWeightedFLRG(hofts.HighOrderFLRG):
+ """High Order Probabilistic Weighted Fuzzy Logical Relationship Group"""
+ def __init__(self, order):
+ super(ProbabilisticWeightedFLRG, self).__init__(order)
+ self.RHS = {}
+ self.frequency_count = 0.0
+ self.Z = None
+
+[docs] def get_membership(self, data, sets):
+ if isinstance(data, (np.ndarray, list, tuple, set)):
+ return np.nanprod([sets[key].membership(data[count])
+ for count, key in enumerate(self.LHS, start=0)])
+ else:
+ return sets[self.LHS[0]].membership(data)
+
+[docs] def append_rhs(self, c, **kwargs):
+ count = kwargs.get('count', 1.0)
+ self.frequency_count += count
+ if c in self.RHS:
+ self.RHS[c] += count
+ else:
+ self.RHS[c] = count
+
+[docs] def lhs_conditional_probability(self, x, sets, norm, uod, nbins):
+ pk = self.frequency_count / norm
+
+ tmp = pk * (self.get_membership(x, sets) / self.partition_function(sets, uod, nbins=nbins))
+
+ return tmp
+
+[docs] def lhs_conditional_probability_fuzzyfied(self, lhs_mv, sets, norm, uod, nbins):
+ pk = self.frequency_count / norm
+
+ tmp = pk * (lhs_mv / self.partition_function(sets, uod, nbins=nbins))
+
+ return tmp
+
+
+
+[docs] def rhs_conditional_probability(self, x, sets, uod, nbins):
+ total = 0.0
+ for rhs in self.RHS.keys():
+ set = sets[rhs]
+ wi = self.rhs_unconditional_probability(rhs)
+ mv = set.membership(x) / set.partition_function(uod, nbins=nbins)
+ total += wi * mv
+
+ return total
+
+[docs] def partition_function(self, sets, uod, nbins=100):
+ if self.Z is None:
+ self.Z = 0.0
+ for k in np.linspace(uod[0], uod[1], nbins):
+ for key in self.LHS:
+ self.Z += sets[key].membership(k)
+
+ return self.Z
+
+[docs] def get_midpoint(self, sets):
+ '''Return the expectation of the PWFLRG, the weighted sum'''
+ if self.midpoint is None:
+ self.midpoint = np.nansum(np.array([self.rhs_unconditional_probability(s) * sets[s].centroid
+ for s in self.RHS.keys()]))
+
+ return self.midpoint
+
+[docs] def get_upper(self, sets):
+ if self.upper is None:
+ self.upper = np.nansum(np.array([self.rhs_unconditional_probability(s) * sets[s].upper
+ for s in self.RHS.keys()]))
+
+ return self.upper
+
+[docs] def get_lower(self, sets):
+ if self.lower is None:
+ self.lower = np.nansum(np.array([self.rhs_unconditional_probability(s) * sets[s].lower
+ for s in self.RHS.keys()]))
+
+ return self.lower
+
+ def __str__(self):
+ tmp2 = ""
+ for c in sorted(self.RHS.keys()):
+ if len(tmp2) > 0:
+ tmp2 = tmp2 + ", "
+ tmp2 = tmp2 + "(" + str(round(self.RHS[c] / self.frequency_count, 3)) + ")" + c
+ return self.get_key() + " -> " + tmp2
+
+
+[docs]class ProbabilisticWeightedFTS(ifts.IntervalFTS):
+ """High Order Probabilistic Weighted Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(ProbabilisticWeightedFTS, self).__init__(**kwargs)
+ self.shortname = "PWFTS"
+ self.name = "Probabilistic FTS"
+ self.detail = "Silva, P.; Guimarães, F.; Sadaei, H."
+ self.flrgs = {}
+ 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.min_order = 1
+ self.auto_update = kwargs.get('update',False)
+ self.configure_lags(**kwargs)
+
+[docs] def train(self, data, **kwargs):
+
+ self.configure_lags(**kwargs)
+
+ if not kwargs.get('fuzzyfied',False):
+ self.generate_flrg2(data)
+ else:
+ self.generate_flrg_fuzzyfied(data)
+
+[docs] def generate_flrg2(self, data):
+ fuzz = []
+ l = len(data)
+ for k in np.arange(0, l):
+ fuzz.append(self.partitioner.fuzzyfy(data[k], mode='both', method='fuzzy',
+ alpha_cut=self.alpha_cut))
+
+ self.generate_flrg_fuzzyfied(fuzz)
+
+[docs] def generate_flrg_fuzzyfied(self, data):
+ l = len(data)
+ for k in np.arange(self.max_lag, l):
+ sample = data[k - self.max_lag: k]
+ set_sample = []
+ for instance in sample:
+ set_sample.append([k for k, v in instance])
+
+ flrgs = self.generate_lhs_flrg_fuzzyfied(set_sample)
+
+ for flrg in flrgs:
+
+ if flrg.get_key() not in self.flrgs:
+ self.flrgs[flrg.get_key()] = flrg;
+
+ lhs_mv = self.pwflrg_lhs_memberhip_fuzzyfied(flrg, sample)
+
+ mvs = []
+ inst = data[k]
+ for set, mv in inst:
+ self.flrgs[flrg.get_key()].append_rhs(set, count=lhs_mv * mv)
+ mvs.append(mv)
+
+ tmp_fq = np.nansum([lhs_mv * kk for kk in mvs if kk > 0])
+
+ self.global_frequency_count += tmp_fq
+
+[docs] def pwflrg_lhs_memberhip_fuzzyfied(self, flrg, sample):
+ vals = []
+ for ct in range(len(flrg.LHS)): # fuzz in enumerate(sample):
+ vals.append([mv for fset, mv in sample[ct] if fset == flrg.LHS[ct]])
+
+ return np.nanprod(vals)
+
+[docs] def generate_lhs_flrg(self, sample, explain=False):
+ if not isinstance(sample, (tuple, list, np.ndarray)):
+ sample = [sample]
+
+ nsample = [self.partitioner.fuzzyfy(k, 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 = sample[o - 1]
+ lags.append( lhs )
+
+ if explain:
+ print("\t (Lag {}) {} -> {} \n".format(o, sample[o-1], lhs))
+
+ # Trace the possible paths
+ for path in product(*lags):
+ flrg = ProbabilisticWeightedFLRG(self.order)
+
+ for lhs in path:
+ flrg.append_lhs(lhs)
+
+ flrgs.append(flrg)
+
+ return flrgs
+
+[docs] def generate_flrg(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]
+
+ flrgs = self.generate_lhs_flrg(sample)
+
+ for flrg in flrgs:
+
+ lhs_mv = flrg.get_membership(sample, self.partitioner.sets)
+
+ if flrg.get_key() not in self.flrgs:
+ self.flrgs[flrg.get_key()] = flrg;
+
+ fuzzyfied = self.partitioner.fuzzyfy(data[k], mode='both', method='fuzzy',
+ alpha_cut=self.alpha_cut)
+
+ mvs = []
+ for set, mv in fuzzyfied:
+ self.flrgs[flrg.get_key()].append_rhs(set, count=lhs_mv * mv)
+ mvs.append(mv)
+
+ tmp_fq = np.nansum([lhs_mv*kk for kk in mvs if kk > 0])
+
+ self.global_frequency_count += tmp_fq
+
+
+
+
+
+[docs] def add_new_PWFLGR(self, flrg):
+ if flrg.get_key() not in self.flrgs:
+ tmp = ProbabilisticWeightedFLRG(self.order)
+ for fs in flrg.LHS: tmp.append_lhs(fs)
+ tmp.append_rhs(flrg.LHS[-1])
+ self.flrgs[tmp.get_key()] = tmp;
+ self.global_frequency_count += 1
+
+[docs] def flrg_lhs_unconditional_probability(self, flrg):
+ if flrg.get_key() in self.flrgs:
+ return self.flrgs[flrg.get_key()].frequency_count / self.global_frequency_count
+ else:
+ return 1.0
+ #self.add_new_PWFLGR(flrg)
+ #return self.flrg_lhs_unconditional_probability(flrg)
+
+[docs] def flrg_lhs_conditional_probability(self, x, flrg):
+ mv = flrg.get_membership(x, self.partitioner.sets)
+ pb = self.flrg_lhs_unconditional_probability(flrg)
+ return mv * pb
+
+[docs] def flrg_lhs_conditional_probability_fuzzyfied(self, x, flrg):
+ mv = self.pwflrg_lhs_memberhip_fuzzyfied(flrg, x)
+ pb = self.flrg_lhs_unconditional_probability(flrg)
+ return mv * pb
+
+[docs] def get_midpoint(self, flrg):
+ if flrg.get_key() in self.flrgs:
+ tmp = self.flrgs[flrg.get_key()]
+ ret = tmp.get_midpoint(self.partitioner.sets) #sum(np.array([tmp.rhs_unconditional_probability(s) * self.setsDict[s].centroid for s in tmp.RHS]))
+ else:
+ if len(flrg.LHS) > 0:
+ pi = 1 / len(flrg.LHS)
+ ret = np.nansum(np.array([pi * self.partitioner.sets[s].centroid for s in flrg.LHS]))
+ else:
+ ret = np.nan
+ return ret
+
+[docs] def flrg_rhs_conditional_probability(self, x, flrg):
+
+ if flrg.get_key() in self.flrgs:
+ _flrg = self.flrgs[flrg.get_key()]
+ cond = []
+ for s in _flrg.RHS.keys():
+ _set = self.partitioner.sets[s]
+ tmp = _flrg.rhs_unconditional_probability(s) * (_set.membership(x) / _set.partition_function(uod=self.get_UoD()))
+ cond.append(tmp)
+ ret = np.nansum(np.array(cond))
+ else:
+ pi = 1 / len(flrg.LHS)
+ ret = np.nansum(np.array([pi * self.partitioner.sets[s].membership(x) for s in flrg.LHS]))
+ return ret
+
+[docs] def get_upper(self, flrg):
+ if flrg.get_key() in self.flrgs:
+ tmp = self.flrgs[flrg.get_key()]
+ ret = tmp.get_upper(self.partitioner.sets)
+ else:
+ ret = 0
+ return ret
+
+[docs] def get_lower(self, flrg):
+ if flrg.get_key() in self.flrgs:
+ tmp = self.flrgs[flrg.get_key()]
+ ret = tmp.get_lower(self.partitioner.sets)
+ else:
+ ret = 0
+ return ret
+
+[docs] def forecast(self, data, **kwargs):
+ method = kwargs.get('method','heuristic')
+
+ l = len(data)+1
+
+ ret = []
+
+ for k in np.arange(self.max_lag, l):
+ sample = data[k - self.max_lag: k]
+
+ if method == 'heuristic':
+ ret.append(self.point_heuristic(sample, **kwargs))
+ elif method == 'expected_value':
+ ret.append(self.point_expected_value(sample, **kwargs))
+ else:
+ raise ValueError("Unknown point forecasting method!")
+
+ if self.auto_update and k > self.order+1: self.update_model(data[k - self.order - 1 : k])
+
+ return ret
+
+[docs] def point_heuristic(self, sample, **kwargs):
+
+ explain = kwargs.get('explain', False)
+ fuzzyfied = kwargs.get('fuzzyfied', False)
+
+ if explain:
+ print("Fuzzyfication \n")
+
+ if not fuzzyfied:
+ flrgs = self.generate_lhs_flrg(sample, explain)
+ else:
+ fsets = self.get_sets_from_both_fuzzyfication(sample)
+ flrgs = self.generate_lhs_flrg_fuzzyfied(fsets, explain)
+
+ mp = []
+ norms = []
+
+ if explain:
+ print("Rules:\n")
+
+ for flrg in flrgs:
+ if not fuzzyfied:
+ norm = self.flrg_lhs_conditional_probability(sample, flrg)
+ else:
+ norm = self.flrg_lhs_conditional_probability_fuzzyfied(sample, flrg)
+
+ if norm == 0:
+ norm = self.flrg_lhs_unconditional_probability(flrg)
+
+ if explain:
+ print("\t {} \t Midpoint: {}\t Norm: {}\n".format(str(self.flrgs[flrg.get_key()]),
+ self.get_midpoint(flrg), norm))
+ mp.append(norm * self.get_midpoint(flrg))
+ norms.append(norm)
+
+ norm = np.nansum(norms)
+
+ final = np.nansum(mp) / norm if norm != 0 else 0
+
+ if explain:
+ print("Deffuzyfied value: {} \n".format(final))
+ return final
+
+[docs] def get_sets_from_both_fuzzyfication(self, sample):
+ return [[k for k, v in inst] for inst in sample]
+
+[docs] def point_expected_value(self, sample, **kwargs):
+ explain = kwargs.get('explain', False)
+
+ dist = self.forecast_distribution(sample, **kwargs)[0]
+
+ final = dist.expected_value()
+ return final
+
+[docs] def forecast_interval(self, ndata, **kwargs):
+
+ method = kwargs.get('method','heuristic')
+ alpha = kwargs.get('alpha', 0.05)
+
+ l = len(ndata)
+
+ ret = []
+
+ for k in np.arange(self.max_lag - 1, l):
+
+ sample = ndata[k - (self.max_lag - 1): k + 1]
+
+ if method == 'heuristic':
+ ret.append(self.interval_heuristic(sample, **kwargs))
+ elif method == 'quantile':
+ ret.append(self.interval_quantile(sample, alpha, **kwargs))
+ else:
+ raise ValueError("Unknown interval forecasting method!")
+
+ return ret
+
+[docs] def interval_quantile(self, ndata, alpha, **kwargs):
+ dist = self.forecast_distribution(ndata, **kwargs)
+ itvl = dist[0].quantile([alpha, 1.0 - alpha])
+ return itvl
+
+[docs] def interval_heuristic(self, sample, **kwargs):
+ fuzzyfied = kwargs.get('fuzzyfied', False)
+
+ if not fuzzyfied:
+ flrgs = self.generate_lhs_flrg(sample)
+ else:
+ fsets = self.get_sets_from_both_fuzzyfication(sample)
+ flrgs = self.generate_lhs_flrg_fuzzyfied(fsets)
+
+ up = []
+ lo = []
+ norms = []
+ for flrg in flrgs:
+ if not fuzzyfied:
+ norm = self.flrg_lhs_conditional_probability(sample, flrg)
+ else:
+ norm = self.flrg_lhs_conditional_probability_fuzzyfied(sample, flrg)
+
+ if norm == 0:
+ norm = self.flrg_lhs_unconditional_probability(flrg)
+ up.append(norm * self.get_upper(flrg))
+ lo.append(norm * self.get_lower(flrg))
+ norms.append(norm)
+
+ # gerar o intervalo
+ norm = np.nansum(norms)
+ if norm == 0:
+ return [0, 0]
+ else:
+ lo_ = np.nansum(lo) / norm
+ up_ = np.nansum(up) / norm
+ return [lo_, up_]
+
+[docs] def forecast_distribution(self, ndata, **kwargs):
+
+ smooth = kwargs.get("smooth", "none")
+
+ from_distribution = kwargs.get('from_distribution', False)
+
+ fuzzyfied = kwargs.get('fuzzyfied', False)
+
+ l = len(ndata)
+ uod = self.get_UoD()
+
+ if 'bins' in kwargs:
+ _bins = kwargs.pop('bins')
+ nbins = len(_bins)
+ else:
+ nbins = kwargs.get("num_bins", 100)
+ _bins = np.linspace(uod[0], uod[1], nbins)
+
+ ret = []
+
+ for k in np.arange(self.max_lag - 1, l):
+ sample = ndata[k - (self.max_lag - 1): k + 1]
+
+ if from_distribution:
+ dist = self.forecast_distribution_from_distribution(sample,smooth,uod,_bins)
+ else:
+
+ if not fuzzyfied:
+ flrgs = self.generate_lhs_flrg(sample)
+ else:
+ fsets = self.get_sets_from_both_fuzzyfication(sample)
+ flrgs = self.generate_lhs_flrg_fuzzyfied(fsets)
+
+ if 'type' in kwargs:
+ kwargs.pop('type')
+
+ dist = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, bins=_bins, **kwargs)
+
+ for bin in _bins:
+ num = []
+ den = []
+ for s in flrgs:
+ if s.get_key() in self.flrgs:
+ flrg = self.flrgs[s.get_key()]
+ wi = flrg.rhs_conditional_probability(bin, self.partitioner.sets, uod, nbins)
+ if not fuzzyfied:
+ pk = flrg.lhs_conditional_probability(sample, self.partitioner.sets, self.global_frequency_count, uod, nbins)
+ else:
+ lhs_mv = self.pwflrg_lhs_memberhip_fuzzyfied(flrg, sample)
+ pk = flrg.lhs_conditional_probability_fuzzyfied(lhs_mv, self.partitioner.sets,
+ self.global_frequency_count, uod, nbins)
+
+ num.append(wi * pk)
+ den.append(pk)
+ else:
+ num.append(0.0)
+ den.append(0.000000001)
+ pf = np.nansum(num) / np.nansum(den)
+
+ dist.set(bin, pf)
+
+ ret.append(dist)
+
+ return ret
+
+ def __check_point_bounds(self, point):
+ lower_set = self.partitioner.lower_set()
+ upper_set = self.partitioner.upper_set()
+ return point <= lower_set.lower or point >= upper_set.upper
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+
+ l = len(data)
+
+ fuzzyfied = kwargs.get('fuzzyfied', False)
+
+ start = kwargs.get('start_at', 0)
+
+ if isinstance(data, np.ndarray):
+ data = data.tolist()
+
+ ret = data[start: start+self.max_lag]
+
+ for k in np.arange(self.max_lag, steps+self.max_lag):
+
+ if self.__check_point_bounds(ret[-1]) and not fuzzyfied:
+ ret.append(ret[-1])
+ else:
+ mp = self.forecast(ret[k - self.max_lag: k], **kwargs)
+ ret.append(mp[0])
+
+ return ret[-steps:]
+
+ def __check_interval_bounds(self, interval):
+ if len(self.transformations) > 0:
+ lower_set = self.partitioner.lower_set()
+ upper_set = self.partitioner.upper_set()
+ return interval[0] <= lower_set.lower and interval[1] >= upper_set.upper
+ elif len(self.transformations) == 0:
+ return interval[0] <= self.original_min and interval[1] >= self.original_max
+
+[docs] def forecast_ahead_interval(self, data, steps, **kwargs):
+
+ start = kwargs.get('start_at', 0)
+
+ if 'fuzzyfied' in kwargs:
+ fuzzyfied = kwargs.pop('fuzzyfied')
+ else:
+ fuzzyfied = False
+
+ sample = data[start: start + self.max_lag]
+
+ if not fuzzyfied:
+ ret = [[k, k] for k in sample]
+ else:
+ ret = []
+ for k in sample:
+ kv = self.partitioner.defuzzyfy(k, mode='both')
+ ret.append([kv, kv])
+
+ ret.append(self.forecast_interval(sample, **kwargs)[0])
+
+ for k in np.arange(start + self.max_lag, steps + start + self.max_lag):
+
+ if len(ret) > 0 and self.__check_interval_bounds(ret[-1]):
+ ret.append(ret[-1])
+ else:
+ lower = self.forecast_interval([ret[x][0] for x in np.arange(k - self.max_lag, k)], **kwargs)
+ upper = self.forecast_interval([ret[x][1] for x in np.arange(k - self.max_lag, k)], **kwargs)
+
+ ret.append([np.min(lower), np.max(upper)])
+
+ return ret[-steps:]
+
+[docs] def forecast_ahead_distribution(self, ndata, steps, **kwargs):
+
+ ret = []
+
+ if 'type' in kwargs:
+ kwargs.pop('type')
+
+ smooth = kwargs.get("smooth", "none")
+
+ uod = self.get_UoD()
+
+ if 'bins' in kwargs:
+ _bins = kwargs.pop('bins')
+ nbins = len(_bins)
+ else:
+ nbins = kwargs.get("num_bins", 100)
+ _bins = np.linspace(uod[0], uod[1], nbins)
+
+ start = kwargs.get('start_at', 0)
+
+ if 'fuzzyfied' in kwargs:
+ fuzzyfied = kwargs.pop('fuzzyfied')
+ else:
+ fuzzyfied = False
+
+ if not fuzzyfied:
+ sample = ndata[start: start + self.max_lag]
+ else:
+ sample = []
+ for k in ndata[start: start + self.max_lag]:
+ kv = self.partitioner.defuzzyfy(k, mode='both')
+ sample.append(kv)
+
+ for dat in sample:
+ if not isinstance(dat, ProbabilityDistribution.ProbabilityDistribution):
+ tmp = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, bins=_bins, **kwargs)
+ tmp.set(dat, 1.0)
+ ret.append(tmp)
+ else:
+ ret.append(dat)
+
+ dist = self.forecast_distribution_from_distribution(ret, smooth,uod,_bins,**kwargs)
+
+ ret.append(dist)
+
+ for k in np.arange(start + self.max_lag, steps + start + self.max_lag):
+ dist = self.forecast_distribution_from_distribution(ret[k-self.max_lag:], smooth, uod, _bins, **kwargs)
+ ret.append(dist)
+
+ return ret[-steps:]
+
+[docs] def forecast_distribution_from_distribution(self, previous_dist, smooth, uod, bins, **kwargs):
+ dist = ProbabilityDistribution.ProbabilityDistribution(smooth, uod=uod, bins=bins, **kwargs)
+
+ lags = []
+
+ # Find all bins of past distributions with probability greater than zero
+
+ for ct, lag in enumerate(self.lags):
+ dd = previous_dist[-lag]
+ vals = [float(v) for v in dd.bins if np.round(dd.density(v), 4) > 0.0]
+ lags.append(sorted(vals))
+
+ # Trace all possible combinations between the bins of past distributions
+
+ for path in product(*lags):
+
+ # get the combined probabilities for this path
+ pk = np.prod([previous_dist[-lag].density(path[ct])
+ for ct, lag in enumerate(self.lags)])
+
+ d = self.forecast_distribution(path)[0]
+
+ for bin in bins:
+ dist.set(bin, dist.density(bin) + pk * d.density(bin))
+
+ return dist
+
+ def __str__(self):
+ tmp = self.name + ":\n"
+ for r in sorted(self.flrgs.keys()):
+ p = round(self.flrgs[r].frequency_count / self.global_frequency_count, 3)
+ tmp = tmp + "(" + str(p) + ") " + str(self.flrgs[r]) + "\n"
+ return tmp
+
+
+[docs]def visualize_distributions(model, **kwargs):
+ import matplotlib.pyplot as plt
+ from matplotlib import gridspec
+ import seaborn as sns
+
+ ordered_sets = model.partitioner.ordered_sets
+ ftpg_keys = sorted(model.flrgs.keys(), key=lambda x: model.flrgs[x].get_midpoint(model.sets))
+
+ lhs_probs = [model.flrg_lhs_unconditional_probability(model.flrgs[k])
+ for k in ftpg_keys]
+
+ mat = np.zeros((len(ftpg_keys), len(ordered_sets)))
+ for row, w in enumerate(ftpg_keys):
+ for col, k in enumerate(ordered_sets):
+ if k in model.flrgs[w].RHS:
+ mat[row, col] = model.flrgs[w].rhs_unconditional_probability(k)
+
+ size = kwargs.get('size', (5,10))
+
+ fig = plt.figure(figsize=size)
+
+ gs = gridspec.GridSpec(1, 2, width_ratios=[1, 4])
+ ax1 = plt.subplot(gs[0])
+ sns.barplot(x='y', y='x', color='darkblue', data={'x': ftpg_keys, 'y': lhs_probs}, ax=ax1)
+ ax1.set_ylabel("LHS Probabilities")
+
+ ind_sets = range(len(ordered_sets))
+ ax = plt.subplot(gs[1])
+ sns.heatmap(mat, cmap='Blues', ax=ax, yticklabels=False)
+ ax.set_title("RHS probabilities")
+ ax.set_xticks(ind_sets)
+ ax.set_xticklabels(ordered_sets)
+ ax.grid(True)
+ ax.xaxis.set_tick_params(rotation=90)
+
Source code for pyFTS.models.sadaei
+"""
+First Order Exponentialy Weighted Fuzzy Time Series by Sadaei et al. (2013)
+
+H. J. Sadaei, R. Enayatifar, A. H. Abdullah, and A. Gani, “Short-term load forecasting using a hybrid model with a
+refined exponentially weighted fuzzy time series and an improved harmony search,” Int. J. Electr. Power Energy Syst., vol. 62, no. from 2005, pp. 118–129, 2014.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet,FLR,fts, flrg
+
+default_c = 1.1
+
+
+[docs]class ExponentialyWeightedFLRG(flrg.FLRG):
+ """First Order Exponentialy Weighted Fuzzy Logical Relationship Group"""
+ def __init__(self, LHS, **kwargs):
+ super(ExponentialyWeightedFLRG, self).__init__(1, **kwargs)
+ self.LHS = LHS
+ self.RHS = []
+ self.count = 0.0
+ self.c = kwargs.get("c",default_c)
+ self.w = None
+
+[docs] def append_rhs(self, c, **kwargs):
+ count = kwargs.get('count', 1.0)
+ self.RHS.append(c)
+ self.count += count
+
+[docs] def weights(self):
+ if self.w is None:
+ wei = [self.c ** k for k in np.arange(0.0, self.count, 1.0)]
+ tot = sum(wei)
+ self.w = np.array([k / tot for k in wei])
+ return self.w
+
+ def __str__(self):
+ tmp = self.LHS + " -> "
+ tmp2 = ""
+ cc = 0
+ wei = [self.c ** k for k in np.arange(0.0, self.count, 1.0)]
+ tot = sum(wei)
+ for c in sorted(self.RHS):
+ if len(tmp2) > 0:
+ tmp2 = tmp2 + ","
+ tmp2 = tmp2 + c + "(" + str(wei[cc] / tot) + ")"
+ cc = cc + 1
+ return tmp + tmp2
+
+ def __len__(self):
+ return len(self.RHS)
+
+
+[docs]class ExponentialyWeightedFTS(fts.FTS):
+ """First Order Exponentialy Weighted Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(ExponentialyWeightedFTS, self).__init__(order=1, name="EWFTS", **kwargs)
+ self.name = "Exponentialy Weighted FTS"
+ self.detail = "Sadaei"
+ self.c = kwargs.get('c', default_c)
+
+[docs] def generate_flrg(self, flrs, c):
+ for flr in flrs:
+ if flr.LHS in self.flrgs:
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+ else:
+ self.flrgs[flr.LHS] = ExponentialyWeightedFLRG(flr.LHS, c=c);
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+
+[docs] def train(self, data, **kwargs):
+ tmpdata = self.partitioner.fuzzyfy(data, method='maximum', mode='sets')
+ flrs = FLR.generate_recurrent_flrs(tmpdata)
+ self.generate_flrg(flrs, self.c)
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ explain = kwargs.get('explain', False)
+
+ if self.partitioner is not None:
+ ordered_sets = self.partitioner.ordered_sets
+ else:
+ ordered_sets = FuzzySet.set_ordered(self.partitioner.sets)
+
+ data = np.array(ndata)
+
+ l = len(ndata)
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ actual = FuzzySet.get_maximum_membership_fuzzyset(ndata[k], self.partitioner.sets, ordered_sets)
+
+ if explain:
+ print("Fuzzyfication:\n\n {} -> {} \n".format(ndata[k], actual.name))
+
+ if actual.name not in self.flrgs:
+ ret.append(actual.centroid)
+
+ if explain:
+ print("Rules:\n\n {} -> {} (Naïve)\t Midpoint: {} \n\n".format(actual.name, actual.name,actual.centroid))
+
+ else:
+ flrg = self.flrgs[actual.name]
+ mp = flrg.get_midpoints(self.partitioner.sets)
+
+ final = mp.dot(flrg.weights())
+
+ ret.append(final)
+
+ if explain:
+ print("Rules:\n\n {} \n\n ".format(str(flrg)))
+ print("Midpoints: \n\n {}\n\n".format(mp))
+
+ print("Deffuzyfied value: {} \n".format(final))
+
+ return ret
+
Source code for pyFTS.models.seasonal.cmsfts
+import numpy as np
+from pyFTS.common import FuzzySet, FLR
+from pyFTS.models.seasonal import sfts
+from pyFTS.models import chen
+
+
+[docs]class ContextualSeasonalFLRG(sfts.SeasonalFLRG):
+ """
+ Contextual Seasonal Fuzzy Logical Relationship Group
+ """
+ def __init__(self, seasonality):
+ super(ContextualSeasonalFLRG, self).__init__(seasonality)
+ self.RHS = {}
+
+[docs] def append_rhs(self, flr, **kwargs):
+ if flr.LHS in self.RHS:
+ self.RHS[flr.LHS].append_rhs(flr.RHS)
+ else:
+ self.RHS[flr.LHS] = chen.ConventionalFLRG(flr.LHS)
+ self.RHS[flr.LHS].append_rhs(flr.RHS)
+
+ def __str__(self):
+ tmp = str(self.LHS) + ": \n "
+ tmp2 = "\t"
+ for r in sorted(self.RHS):
+ tmp2 += str(self.RHS[r]) + "\n\t"
+ return tmp + tmp2 + "\n"
+
+
+[docs]class ContextualMultiSeasonalFTS(sfts.SeasonalFTS):
+ """
+ Contextual Multi-Seasonal Fuzzy Time Series
+ """
+ def __init__(self, **kwargs):
+ super(ContextualMultiSeasonalFTS, self).__init__(**kwargs)
+ self.name = "Contextual Multi Seasonal FTS"
+ self.shortname = "CMSFTS "
+ self.detail = ""
+ self.seasonality = 1
+ self.has_seasonality = True
+ self.has_point_forecasting = True
+ self.is_high_order = True
+ self.is_multivariate = True
+ self.order = 1
+ self.flrgs = {}
+
+[docs] def generate_flrg(self, flrs):
+ for flr in flrs:
+
+ if str(flr.index) not in self.flrgs:
+ self.flrgs[str(flr.index)] = ContextualSeasonalFLRG(flr.index)
+
+ self.flrgs[str(flr.index)].append_rhs(flr)
+
+[docs] def train(self, data, **kwargs):
+ if kwargs.get('sets', None) is not None:
+ self.sets = kwargs.get('sets', None)
+ if kwargs.get('parameters', None) is not None:
+ self.seasonality = kwargs.get('parameters', None)
+ flrs = FLR.generate_indexed_flrs(self.sets, self.indexer, data,
+ transformation=self.partitioner.transformation,
+ alpha_cut=self.alpha_cut)
+ self.generate_flrg(flrs)
+
+[docs] def get_midpoints(self, flrg, data):
+ ret = []
+ for d in data:
+ if d in flrg.RHS:
+ ret.extend([self.sets[s].centroid for s in flrg.RHS[d].RHS])
+ else:
+ ret.extend([self.sets[d].centroid])
+
+ return np.array(ret)
+
+[docs] def forecast(self, data, **kwargs):
+ ordered_sets = FuzzySet.set_ordered(self.sets)
+
+ ret = []
+
+ index = self.indexer.get_season_of_data(data)
+ ndata = self.indexer.get_data(data)
+
+ for k in np.arange(0, len(data)):
+
+ if str(index[k]) in self.flrgs:
+
+ flrg = self.flrgs[str(index[k])]
+
+ d = FuzzySet.get_fuzzysets(ndata[k], self.sets, ordered_sets, alpha_cut=self.alpha_cut)
+
+ mp = self.get_midpoints(flrg, d)
+
+ ret.append(sum(mp) / len(mp))
+ else:
+ ret.append(np.nan)
+
+ return ret
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+ ret = []
+ for i in steps:
+ flrg = self.flrgs[str(i)]
+
+ mp = self.get_midpoints(flrg)
+
+ ret.append(sum(mp) / len(mp))
+
+ return ret
+
+
+
Source code for pyFTS.models.seasonal.msfts
+import numpy as np
+from pyFTS.common import FLR
+from pyFTS.models.seasonal import sfts
+
+
+[docs]class MultiSeasonalFTS(sfts.SeasonalFTS):
+ """
+ Multi-Seasonal Fuzzy Time Series
+ """
+ def __init__(self, name, indexer, **kwargs):
+ super(MultiSeasonalFTS, self).__init__("MSFTS")
+ self.name = "Multi Seasonal FTS"
+ self.shortname = "MSFTS " + name
+ self.detail = ""
+ self.seasonality = 1
+ self.has_seasonality = True
+ self.has_point_forecasting = True
+ self.is_high_order = False
+ self.is_multivariate = True
+ self.indexer = indexer
+ self.flrgs = {}
+
+[docs] def generate_flrg(self, flrs):
+ for flr in flrs:
+
+ if str(flr.index) not in self.flrgs:
+ self.flrgs[str(flr.index)] = sfts.SeasonalFLRG(flr.index)
+
+ self.flrgs[str(flr.index)].append_rhs(flr.RHS)
+
+[docs] def train(self, data, **kwargs):
+ if kwargs.get('sets', None) is not None:
+ self.sets = kwargs.get('sets', None)
+ if kwargs.get('parameters', None) is not None:
+ self.seasonality = kwargs.get('parameters', None)
+ #ndata = self.indexer.set_data(data,self.doTransformations(self.indexer.get_data(data)))
+ flrs = FLR.generate_indexed_flrs(self.sets, self.indexer, data)
+ self.generate_flrg(flrs)
+
+[docs] def forecast(self, data, **kwargs):
+
+ ret = []
+
+ index = self.indexer.get_season_of_data(data)
+ ndata = self.indexer.get_data(data)
+
+ for k in np.arange(0, len(index)):
+
+ flrg = self.flrgs[str(index[k])]
+
+ mp = self.getMidpoints(flrg)
+
+ ret.append(sum(mp) / len(mp))
+
+ return ret
+
+[docs] def forecast_ahead(self, data, steps, **kwargs):
+ ret = []
+ for i in steps:
+ flrg = self.flrgs[str(i)]
+
+ mp = self.getMidpoints(flrg)
+
+ ret.append(sum(mp) / len(mp))
+
+ return ret
+
Source code for pyFTS.models.seasonal.sfts
+"""
+Simple First Order Seasonal Fuzzy Time Series implementation of Song (1999) based of Conventional FTS by Chen (1996)
+
+Q. Song, “Seasonal forecasting in fuzzy time series,” Fuzzy sets Syst., vol. 107, pp. 235–236, 1999.
+
+S.-M. Chen, “Forecasting enrollments based on fuzzy time series,” Fuzzy Sets Syst., vol. 81, no. 3, pp. 311–319, 1996.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, flrg, fts
+
+
+[docs]class SeasonalFLRG(flrg.FLRG):
+ """First Order Seasonal Fuzzy Logical Relationship Group"""
+ def __init__(self, seasonality):
+ super(SeasonalFLRG, self).__init__(1)
+ self.LHS = seasonality
+ self.RHS = []
+
+
+
+
+
+ def __str__(self):
+ tmp = str(self.LHS) + " -> "
+ tmp2 = ""
+ for c in sorted(self.RHS, key=lambda s: str(s)):
+ if len(tmp2) > 0:
+ tmp2 = tmp2 + ","
+ tmp2 = tmp2 + str(c)
+ return tmp + tmp2
+
+ def __len__(self):
+ return len(self.RHS)
+
+
+[docs]class SeasonalFTS(fts.FTS):
+ """First Order Seasonal Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(SeasonalFTS, self).__init__(**kwargs)
+ self.name = "Seasonal FTS"
+ self.shortname = "SFTS"
+ self.order = 1
+ self.seasonality = 1
+ self.has_seasonality = True
+ self.has_point_forecasting = True
+ self.is_high_order = False
+ self.flrgs = {}
+
+[docs] def generate_flrg(self, flrs):
+
+ for ct, flr in enumerate(flrs, start=1):
+
+ season = self.indexer.get_season_by_index(ct)[0]
+
+ ss = str(season)
+
+ if ss not in self.flrgs:
+ self.flrgs[ss] = SeasonalFLRG(season)
+
+ #print(season)
+ self.flrgs[ss].append_rhs(flr.RHS)
+
+[docs] def get_midpoints(self, flrg):
+ ret = np.array([self.sets[s].centroid for s in flrg.RHS])
+ return ret
+
+[docs] def train(self, data, **kwargs):
+ if kwargs.get('sets', None) is not None:
+ self.sets = kwargs.get('sets', None)
+ tmpdata = FuzzySet.fuzzyfy_series_old(data, self.sets)
+ flrs = FLR.generate_non_recurrent_flrs(tmpdata)
+ self.generate_flrg(flrs)
+
+[docs] def forecast(self, data, **kwargs):
+
+ l = len(data)
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ season = self.indexer.get_season_by_index(k)[0]
+
+ flrg = self.flrgs[str(season)]
+
+ mp = self.get_midpoints(flrg)
+
+ ret.append(np.percentile(mp, 50))
+
+ return ret
+
+ def __str__(self):
+ """String representation of the model"""
+
+ tmp = self.name + ":\n"
+ for r in self.flrgs:
+ tmp = tmp + str(self.flrgs[r]) + "\n"
+ return tmp
+
Source code for pyFTS.models.song
+"""
+First Order Traditional Fuzzy Time Series method by Song & Chissom (1993)
+
+Q. Song and B. S. Chissom, “Fuzzy time series and its models,” Fuzzy Sets Syst., vol. 54, no. 3, pp. 269–277, 1993.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts
+
+
+[docs]class ConventionalFTS(fts.FTS):
+ """Traditional Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(ConventionalFTS, self).__init__(order=1, name="FTS", **kwargs)
+ self.name = "Traditional FTS"
+ self.detail = "Song & Chissom"
+ if self.sets is not None and self.partitioner is not None:
+ self.sets = self.partitioner.sets
+
+ self.R = None
+
+ if self.sets is not None:
+ l = len(self.sets)
+ self.R = np.zeros((l,l))
+
+[docs] def flr_membership_matrix(self, flr):
+ ordered_set = FuzzySet.set_ordered(self.sets)
+ centroids = [self.sets[k].centroid for k in ordered_set]
+ lm = [self.sets[flr.LHS].membership(k) for k in centroids]
+ rm = [self.sets[flr.RHS].membership(k) for k in centroids]
+
+ l = len(ordered_set)
+ r = np.zeros((l, l))
+ for k in range(0,l):
+ for l in range(0, l):
+ r[k][l] = min(lm[k], rm[l])
+
+ return r
+
+[docs] def operation_matrix(self, flrs):
+ l = len(self.sets)
+ if self.R is None or len(self.R) == 0 :
+ self.R = np.zeros((l, l))
+ for k in flrs:
+ mm = self.flr_membership_matrix(k)
+ for k in range(0, l):
+ for l in range(0, l):
+ self.R[k][l] = max(self.R[k][l], mm[k][l])
+
+
+[docs] def train(self, data, **kwargs):
+
+ tmpdata = self.partitioner.fuzzyfy(data, method='maximum', mode='sets')
+ flrs = FLR.generate_non_recurrent_flrs(tmpdata)
+ self.operation_matrix(flrs)
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ if self.partitioner is not None:
+ ordered_sets = self.partitioner.ordered_sets
+ else:
+ ordered_sets = FuzzySet.set_ordered(self.sets)
+
+ l = len(ndata)
+ npart = len(self.sets)
+
+ ret = []
+
+ for k in np.arange(0, l):
+ mv = FuzzySet.fuzzyfy_instance(ndata[k], self.sets)
+
+ r = [max([ min(self.R[i][j], mv[j]) for j in np.arange(0,npart) ]) for i in np.arange(0,npart)]
+
+ fs = np.ravel(np.argwhere(r == max(r)))
+
+ if len(fs) == 1:
+ ret.append(self.sets[ordered_sets[fs[0]]].centroid)
+ else:
+ mp = [self.sets[ordered_sets[s]].centroid for s in fs]
+
+ ret.append( sum(mp)/len(mp))
+
+ return ret
+
+ def __str__(self):
+ tmp = self.name + ":\n"
+ return tmp + str(self.R)
+
Source code for pyFTS.models.yu
+"""
+First Order Weighted Fuzzy Time Series by Yu(2005)
+
+H.-K. Yu, “Weighted fuzzy time series models for TAIEX forecasting,”
+Phys. A Stat. Mech. its Appl., vol. 349, no. 3, pp. 609–624, 2005.
+"""
+
+import numpy as np
+from pyFTS.common import FuzzySet, FLR, fts, flrg
+from pyFTS.models import chen
+
+
+[docs]class WeightedFLRG(flrg.FLRG):
+ """First Order Weighted Fuzzy Logical Relationship Group"""
+ def __init__(self, LHS, **kwargs):
+ super(WeightedFLRG, self).__init__(1, **kwargs)
+ self.LHS = LHS
+ self.RHS = []
+ self.count = 1.0
+ self.w = None
+
+[docs] def append_rhs(self, c, **kwargs):
+ count = kwargs.get('count', 1.0)
+ self.RHS.append(c)
+ self.count += count
+
+[docs] def weights(self, sets):
+ if self.w is None:
+ tot = sum(np.arange(1.0, self.count, 1.0))
+ self.w = np.array([k / tot for k in np.arange(1.0, self.count, 1.0)])
+ return self.w
+
+ def __str__(self):
+ tmp = self.LHS + " -> "
+ tmp2 = ""
+ cc = 1.0
+ tot = sum(np.arange(1.0, self.count, 1.0))
+ for c in sorted(self.RHS):
+ if len(tmp2) > 0:
+ tmp2 = tmp2 + ","
+ tmp2 = tmp2 + c + "(" + str(round(cc / tot, 3)) + ")"
+ cc = cc + 1.0
+ return tmp + tmp2
+
+
+[docs]class WeightedFTS(fts.FTS):
+ """First Order Weighted Fuzzy Time Series"""
+ def __init__(self, **kwargs):
+ super(WeightedFTS, self).__init__(order=1, name="WFTS", **kwargs)
+ self.name = "Weighted FTS"
+ self.detail = "Yu"
+
+[docs] def generate_FLRG(self, flrs):
+ for flr in flrs:
+ if flr.LHS in self.flrgs:
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+ else:
+ self.flrgs[flr.LHS] = WeightedFLRG(flr.LHS);
+ self.flrgs[flr.LHS].append_rhs(flr.RHS)
+
+[docs] def train(self, ndata, **kwargs):
+ tmpdata = self.partitioner.fuzzyfy(ndata, method='maximum', mode='sets')
+ flrs = FLR.generate_recurrent_flrs(tmpdata)
+ self.generate_FLRG(flrs)
+
+[docs] def forecast(self, ndata, **kwargs):
+
+ explain = kwargs.get('explain', False)
+
+ if self.partitioner is not None:
+ ordered_sets = self.partitioner.ordered_sets
+ else:
+ ordered_sets = FuzzySet.set_ordered(self.partitioner.sets)
+
+ ndata = np.array(ndata)
+
+ l = len(ndata) if not explain else 1
+
+ ret = []
+
+ for k in np.arange(0, l):
+
+ actual = FuzzySet.get_maximum_membership_fuzzyset(ndata[k], self.partitioner.sets, ordered_sets)
+
+ if explain:
+ print("Fuzzyfication:\n\n {} -> {} \n\n".format(ndata[k], actual.name))
+
+ if actual.name not in self.flrgs:
+ ret.append(actual.centroid)
+
+ if explain:
+ print("Rules:\n\n {} -> {} (Naïve)\t Midpoint: {} \n\n".format(actual.name, actual.name,actual.centroid))
+
+ else:
+ flrg = self.flrgs[actual.name]
+ mp = flrg.get_midpoints(self.partitioner.sets)
+
+ final = mp.dot(flrg.weights(self.partitioner.sets))
+
+ ret.append(final)
+
+ if explain:
+ print("Rules:\n\n {} \n\n ".format(str(flrg)))
+ print("Midpoints: \n\n {}\n\n".format(mp))
+
+ print("Deffuzyfied value: {} \n".format(final))
+
+ return ret
+
Source code for pyFTS.partitioners.Huarng
+"""
+K. H. Huarng, “Effective lengths of intervals to improve forecasting in fuzzy time series,”
+Fuzzy Sets Syst., vol. 123, no. 3, pp. 387–394, Nov. 2001.
+"""
+
+import numpy as np
+import math
+import random as rnd
+import functools, operator
+from pyFTS.common import FuzzySet, Membership, Transformations
+
+from pyFTS.partitioners import partitioner
+
+[docs]class HuarngPartitioner(partitioner.Partitioner):
+ """Huarng Empirical Partitioner"""
+ def __init__(self, **kwargs):
+ super(HuarngPartitioner, self).__init__(name="Huarng", **kwargs)
+
+[docs] def build(self, data):
+ diff = Transformations.Differential(1)
+ data2 = diff.apply(data)
+ davg = np.abs( np.mean(data2) / 2 )
+
+ if davg <= 1.0:
+ base = 0.1
+ elif 1 < davg <= 10:
+ base = 1.0
+ elif 10 < davg <= 100:
+ base = 10
+ else:
+ base = 100
+
+ sets = {}
+
+ kwargs = {'type': self.type, 'variable': self.variable}
+
+ dlen = self.max - self.min
+ npart = math.ceil(dlen / base)
+ partition = math.ceil(self.min)
+ for c in range(npart):
+ _name = self.get_name(c)
+ if self.membership_function == Membership.trimf:
+ sets[_name] = FuzzySet.FuzzySet(_name, Membership.trimf,
+ [partition - base, partition, partition + base], partition, **kwargs)
+ elif self.membership_function == Membership.gaussmf:
+ sets[_name] = FuzzySet.FuzzySet(_name, Membership.gaussmf,
+ [partition, base/2], partition)
+ elif self.membership_function == Membership.trapmf:
+ sets[_name] = FuzzySet.FuzzySet(_name, Membership.trapmf,
+ [partition - base, partition - (base/2),
+ partition + (base / 2), partition + base], partition, **kwargs)
+
+ partition += base
+
+ return sets
+
Source code for pyFTS.partitioners.Util
+"""
+Facility methods for pyFTS partitioners module
+"""
+
+import numpy as np
+import pandas as pd
+import matplotlib as plt
+import matplotlib.colors as pltcolors
+import matplotlib.pyplot as plt
+#from mpl_toolkits.mplot3d import Axes3D
+
+from pyFTS.benchmarks import Measures
+from pyFTS.common import Membership, Util
+from pyFTS.partitioners import Grid,Huarng,FCM,Entropy
+
+all_methods = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner, Huarng.HuarngPartitioner]
+
+mfs = [Membership.trimf, Membership.gaussmf, Membership.trapmf]
+
+
+[docs]def plot_sets(data, sets, titles, size=[12, 10], save=False, file=None, axis=None):
+ num = len(sets)
+
+ if axis is None:
+ fig, axes = plt.subplots(nrows=num, ncols=1,figsize=size)
+ for k in np.arange(0,num):
+ ticks = []
+ x = []
+ ax = axes[k] if axis is None else axis
+ ax.set_title(titles[k])
+ ax.set_ylim([0, 1.1])
+ for key in sets[k].keys():
+ s = sets[k][key]
+ if s.mf == Membership.trimf:
+ ax.plot(s.parameters,[0,1,0])
+ elif s.mf == Membership.gaussmf:
+ tmpx = [ kk for kk in np.arange(s.lower, s.upper)]
+ tmpy = [s.membership(kk) for kk in np.arange(s.lower, s.upper)]
+ ax.plot(tmpx, tmpy)
+ elif s.mf == Membership.trapmf:
+ ax.plot(s.parameters, [0, 1, 1, 0])
+ ticks.append(str(round(s.centroid, 0)) + '\n' + s.name)
+ x.append(s.centroid)
+ ax.xaxis.set_ticklabels(ticks)
+ ax.xaxis.set_ticks(x)
+
+ if axis is None:
+ plt.tight_layout()
+
+ Util.show_and_save_image(fig, file, save)
+
+
+[docs]def plot_partitioners(data, objs, tam=[12, 10], save=False, file=None, axis=None):
+ sets = [k.sets for k in objs]
+ titles = [k.name for k in objs]
+ plot_sets(data, sets, titles, tam, save, file, axis)
+
+
+[docs]def explore_partitioners(data, npart, methods=None, mf=None, transformation=None,
+ size=[12, 10], save=False, file=None):
+ """
+ Create partitioners for the mf membership functions and npart partitions and show the partitioning images.
+ :data: Time series data
+ :npart: Maximum number of partitions of the universe of discourse
+ :methods: A list with the partitioning methods to be used
+ :mf: A list with the membership functions to be used
+ :transformation: a transformation to be used in partitioner
+ :size: list, the size of the output image [width, height]
+ :save: boolean, if the image will be saved on disk
+ :file: string, the file path to save the image
+ :return: the list of the built partitioners
+ """
+ if methods is None:
+ methods = all_methods
+
+ if mf is None:
+ mf = mfs
+
+ objs = []
+
+ for p in methods:
+ for m in mf:
+ obj = p(data=data, npart=npart, func=m, transformation=transformation)
+ obj.name = obj.name + " - " + obj.membership_function.__name__
+ objs.append(obj)
+
+ plot_partitioners(data, objs, size, save, file)
+
+ return objs
+
Source code for pyFTS.partitioners.parallel_util
+from copy import deepcopy
+from joblib import Parallel, delayed
+import multiprocessing
+import numpy as np
+
+from pyFTS.common import Membership, Util
+from pyFTS.partitioners import Grid,Huarng,FCM,Entropy
+from pyFTS.partitioners import Util
+
+
+[docs]def explore_partitioners(data, npart, methods=None, mf=None, tam=[12, 10], save=False, file=None):
+ all_methods = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitioner]
+ mfs = [Membership.trimf, Membership.gaussmf, Membership.trapmf]
+
+ if methods is None:
+ methods = all_methods
+
+ if mf is None:
+ mf = mfs
+
+ num_cores = multiprocessing.cpu_count()
+
+ objs = []
+ for method in methods:
+ print(str(method))
+ tmp = Parallel(n_jobs=num_cores)(delayed(method)(deepcopy(data), npart, m) for m in mf)
+ objs.append(tmp)
+
+ objs = np.ravel(objs).tolist()
+
+ Util.plot_partitioners(data, objs, tam, save, file)
+
+
Source code for pyFTS.probabilistic.ProbabilityDistribution
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+from pyFTS.common import FuzzySet,SortedCollection,tree
+from pyFTS.probabilistic import kde
+
+
+[docs]def from_point(x,**kwargs):
+ """
+ Create a probability distribution from a scalar value
+
+ :param x: scalar value
+ :param kwargs: common parameters of the distribution
+ :return: the ProbabilityDistribution object
+ """
+ tmp = ProbabilityDistribution(**kwargs)
+ tmp.set(x, 1.0)
+ return tmp
+
+
+[docs]class ProbabilityDistribution(object):
+ """
+ Represents a discrete or continous probability distribution
+ If type is histogram, the PDF is discrete
+ If type is KDE the PDF is continuous
+ """
+ def __init__(self, type = "KDE", **kwargs):
+ self.uod = kwargs.get("uod", None)
+ """Universe of discourse"""
+
+ self.data = []
+
+ data = kwargs.get("data", None)
+
+ self.type = type
+ """
+ If type is histogram, the PDF is discrete
+ If type is KDE the PDF is continuous
+ """
+
+ self.bins = kwargs.get("bins", None)
+ """Number of bins on a discrete PDF"""
+ self.labels = kwargs.get("bins_labels", None)
+ """Bins labels on a discrete PDF"""
+
+ if self.type == "KDE":
+ self.kde = kde.KernelSmoothing(h=kwargs.get("h", 0.5), kernel=kwargs.get("kernel", "epanechnikov"))
+
+ if data is not None and self.uod is None:
+ _min = np.nanmin(data)
+ _min = _min * .7 if _min > 0 else _min * 1.3
+ _max = np.nanmax(data)
+ _max = _max * 1.3 if _max > 0 else _max * .7
+ self.uod = [_min, _max]
+
+ self.nbins = kwargs.get("num_bins", 100)
+
+ if self.bins is None:
+ self.bins = np.linspace(int(self.uod[0]), int(self.uod[1]), int(self.nbins)).tolist()
+ self.labels = [str(k) for k in self.bins]
+
+ if self.uod is not None:
+ self.resolution = (self.uod[1] - self.uod[0]) / self.nbins
+
+ self.bin_index = SortedCollection.SortedCollection(iterable=sorted(self.bins))
+ self.quantile_index = None
+ self.distribution = {}
+ self.cdf = None
+ self.qtl = None
+ self.count = 0
+ for k in self.bins: self.distribution[k] = 0
+
+ if data is not None:
+ self.append(data)
+
+ self.name = kwargs.get("name", "")
+
+[docs] def set(self, value, density):
+ """
+ Assert a probability 'density' for a certain value 'value', such that P(value) = density
+
+ :param value: A value in the universe of discourse from the distribution
+ :param density: The probability density to assign to the value
+ """
+ k = self.bin_index.find_ge(value)
+ self.distribution[k] = density
+
+[docs] def append(self, values):
+ """
+ Increment the frequency count for the values
+
+ :param values: A list of values to account the frequency
+ """
+ if self.type == "histogram":
+ for k in values:
+ v = self.bin_index.find_ge(k)
+ self.distribution[v] += 1
+ self.count += 1
+ else:
+ self.data.extend(values)
+ self.distribution = {}
+ dens = self.density(self.bins)
+ for v,d in enumerate(dens):
+ self.distribution[self.bins[v]] = d
+
+[docs] def append_interval(self, intervals):
+ """
+ Increment the frequency count for all values inside an interval
+
+ :param intervals: A list of intervals do increment the frequency
+ """
+ if self.type == "histogram":
+ for interval in intervals:
+ for k in self.bin_index.inside(interval[0], interval[1]):
+ self.distribution[k] += 1
+ self.count += 1
+
+[docs] def density(self, values):
+ """
+ Return the probability densities for the input values
+
+ :param values: List of values to return the densities
+ :return: List of probability densities for the input values
+ """
+ ret = []
+ scalar = False
+
+ if not isinstance(values, list):
+ values = [values]
+ scalar = True
+
+ for k in values:
+ if self.type == "histogram":
+ v = self.bin_index.find_ge(k)
+ ret.append(self.distribution[v] / (self.count + 1e-5))
+ elif self.type == "KDE":
+ v = self.kde.probability(k, data=self.data)
+ ret.append(v)
+ else:
+ v = self.bin_index.find_ge(k)
+ ret.append(self.distribution[v])
+
+ if scalar:
+ return ret[0]
+
+ return ret
+
+[docs] def differential_offset(self, value):
+ """
+ Auxiliary function for probability distributions of differentiated data
+
+ :param value:
+ :return:
+ """
+ nbins = []
+ dist = {}
+
+ for k in self.bins:
+ nk = k+value
+ nbins.append(nk)
+ dist[nk] = self.distribution[k]
+
+ self.bins = nbins
+ self.distribution = dist
+ self.labels = [str(k) for k in self.bins]
+
+ self.bin_index = SortedCollection.SortedCollection(iterable=sorted(self.bins))
+ self.quantile_index = None
+ self.cdf = None
+ self.qtl = None
+
+[docs] def expected_value(self):
+ """
+ Return the expected value of the distribution, as E[X] = ∑ x * P(x)
+
+ :return: The expected value of the distribution
+ """
+ return np.nansum([v * self.distribution[v] for v in self.bins])
+
+[docs] def build_cdf_qtl(self):
+ ret = 0.0
+ self.cdf = {}
+ self.qtl = {}
+ for k in sorted(self.bins):
+ ret += self.density(k)
+ if k not in self.cdf:
+ self.cdf[k] = ret
+
+ if str(ret) not in self.qtl:
+ self.qtl[str(ret)] = []
+
+ self.qtl[str(ret)].append(k)
+
+ _keys = [float(k) for k in sorted(self.qtl.keys())]
+
+ self.quantile_index = SortedCollection.SortedCollection(iterable=_keys)
+
+[docs] def cumulative(self, values):
+ """
+ Return the cumulative probability densities for the input values,
+ such that F(x) = P(X <= x)
+
+ :param values: A list of input values
+ :return: The cumulative probability densities for the input values
+ """
+ if self.cdf is None:
+ self.build_cdf_qtl()
+
+ if isinstance(values, list):
+ ret = []
+ for val in values:
+ try:
+ k = self.bin_index.find_ge(val)
+ #ret.append(self.cdf[k])
+ ret.append(self.cdf[val])
+ except:
+ ret.append(np.nan)
+ else:
+ try:
+ k = self.bin_index.find_ge(values)
+ return self.cdf[k]
+ except:
+ return np.nan
+
+[docs] def quantile(self, values):
+ """
+ Return the Universe of Discourse values in relation to the quantile input values,
+ such that Q(tau) = min( {x | F(x) >= tau })
+
+ :param values: input values
+ :return: The list of the quantile values for the input values
+ """
+ if self.qtl is None:
+ self.build_cdf_qtl()
+
+ if isinstance(values, list):
+ ret = []
+ for val in values:
+ try:
+ k = self.quantile_index.find_ge(val)
+ ret.append(self.qtl[str(k)][0])
+ except:
+ ret.append(np.nan)
+ else:
+ try:
+ k = self.quantile_index.find_ge(values)
+ ret = self.qtl[str(k)]
+ except:
+ return np.nan
+
+ return ret
+
+[docs] def entropy(self):
+ """
+ Return the entropy of the probability distribution, H(P) = E[ -ln P(X) ] = - ∑ P(x) log ( P(x) )
+
+ :return:the entropy of the probability distribution
+ """
+ h = -np.nansum([self.distribution[k] * np.log(self.distribution[k]) if self.distribution[k] > 0 else 0
+ for k in self.bins])
+ return h
+
+[docs] def crossentropy(self,q):
+ """
+ Cross entropy between the actual probability distribution and the informed one,
+ H(P,Q) = - ∑ P(x) log ( Q(x) )
+
+ :param q: a probabilistic.ProbabilityDistribution object
+ :return: Cross entropy between this probability distribution and the given distribution
+ """
+ h = -np.nansum([self.distribution[k] * np.log(q.distribution[k]) if self.distribution[k] > 0 else 0
+ for k in self.bins])
+ return h
+
+[docs] def kullbackleiblerdivergence(self,q):
+ """
+ Kullback-Leibler divergence between the actual probability distribution and the informed one.
+ DKL(P || Q) = - ∑ P(x) log( P(X) / Q(x) )
+
+ :param q: a probabilistic.ProbabilityDistribution object
+ :return: Kullback-Leibler divergence
+ """
+ h = np.nansum([self.distribution[k] * np.log(self.distribution[k]/q.distribution[k]) if self.distribution[k] > 0 else 0
+ for k in self.bins])
+ return h
+
+[docs] def empiricalloglikelihood(self):
+ """
+ Empirical Log Likelihood of the probability distribution, L(P) = ∑ log( P(x) )
+
+ :return:
+ """
+ _s = 0
+ for k in self.bins:
+ if self.distribution[k] > 0:
+ _s += np.log(self.distribution[k])
+ return _s
+
+[docs] def pseudologlikelihood(self, data):
+ """
+ Pseudo log likelihood of the probability distribution with respect to data
+
+ :param data:
+ :return:
+ """
+
+ densities = self.density(data)
+
+ _s = 0
+ for k in densities:
+ if k > 0:
+ _s += np.log(k)
+ return _s
+
+[docs] def averageloglikelihood(self, data):
+ """
+ Average log likelihood of the probability distribution with respect to data
+
+ :param data:
+ :return:
+ """
+
+ densities = self.density(data)
+
+ _s = 0
+ for k in densities:
+ if k > 0:
+ _s += np.log(k)
+ return _s / len(data)
+
+[docs] def plot(self,axis=None,color="black",tam=[10, 6], title = None):
+
+ if axis is None:
+ fig = plt.figure(figsize=tam)
+ axis = fig.add_subplot(111)
+
+ if self.type == "histogram":
+ ys = [self.distribution[k]/self.count for k in self.bins]
+ else:
+ ys = [self.distribution[k] for k in self.bins]
+ yp = [0 for k in self.data]
+ axis.plot(self.data, yp, c="red")
+
+ if title is None:
+ title = self.name
+ axis.plot(self.bins, ys, c=color)
+ axis.set_title(title)
+
+ axis.set_xlabel('Universe of Discourse')
+ axis.set_ylabel('Probability')
+
+ def __str__(self):
+ ret = ""
+ for k in sorted(self.bins):
+ ret += str(round(k,2)) + ':\t'
+ if self.type == "histogram":
+ ret += str(round(self.distribution[k] / self.count,3))
+ elif self.type == "KDE":
+ ret += str(round(self.density(k),3))
+ else:
+ ret += str(round(self.distribution[k], 6))
+ ret += '\n'
+ return ret
+
Source code for pyFTS.probabilistic.kde
+# -*- coding: utf8 -*-
+
+"""
+Kernel Density Estimation
+"""
+
+from pyFTS.common import Transformations
+import numpy as np
+
+
+[docs]class KernelSmoothing(object):
+ """Kernel Density Estimation"""
+ def __init__(self, **kwargs):
+ self.h = kwargs.get('h',.5)
+ """Width parameter"""
+ self.kernel = kwargs.get("kernel", "epanechnikov")
+ """Kernel function"""
+ self.data = kwargs.get("data",None)
+ self.transf = Transformations.Scale(min=0,max=1)
+
+ if self.data is not None:
+ self.data = self.transf.apply(self.data)
+
+[docs] def kernel_function(self, u):
+ """
+ Apply the kernel
+
+ :param u:
+ :return:
+ """
+ if self.kernel == "epanechnikov":
+ tmp = (3/4)*(1.0 - u**2)
+ return tmp if tmp > 0 else 0
+ elif self.kernel == "gaussian":
+ return (1.0/np.sqrt(2*np.pi))*np.exp(-0.5*u**2)
+ elif self.kernel == "uniform":
+ return 0.5
+ elif self.kernel == "triangular":
+ tmp = 1.0 - np.abs(u)
+ return tmp if tmp > 0 else 0
+ elif self.kernel == "logistic":
+ return 1.0/(np.exp(u)+2+np.exp(-u))
+ elif self.kernel == "cosine":
+ return (np.pi/4.0)*np.cos((np.pi/2.0)*u)
+ elif self.kernel == "sigmoid":
+ return (2.0/np.pi)*(1.0/(np.exp(u)+np.exp(-u)))
+ elif self.kernel == "tophat":
+ return 1 if np.abs(u) < 0.5 else 0
+ elif self.kernel == "exponential":
+ return 0.5 * np.exp(-np.abs(u))
+
+[docs] def probability(self, x, **kwargs):
+ """
+ Probability of the point x on data
+
+ :param x:
+ :param data:
+ :return:
+ """
+
+ if self.data is None:
+ self.data = kwargs.get('data',None)
+ self.data = self.transf.apply(self.data)
+
+ l = len(self.data)
+
+ nx = self.transf.apply(x)
+ p = sum([self.kernel_function((nx - k)/self.h) for k in self.data]) / l*self.h
+
+ return p
+
A
B
|
|