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