Refactoring: Type Hints
This commit is contained in:
parent
ad3e857024
commit
cee6474034
@ -12,15 +12,15 @@ class FuzzySet(object):
|
||||
"""
|
||||
Create a Fuzzy Set
|
||||
"""
|
||||
self.name = name
|
||||
self.name : str = name
|
||||
"""The fuzzy set name"""
|
||||
self.mf = mf
|
||||
"""The membership function"""
|
||||
self.parameters = parameters
|
||||
self.parameters : list = parameters
|
||||
"""The parameters of the membership function"""
|
||||
self.centroid = centroid
|
||||
self.centroid : float = centroid
|
||||
"""The fuzzy set center of mass (or midpoint)"""
|
||||
self.alpha = alpha
|
||||
self.alpha : float = alpha
|
||||
"""The alpha cut value"""
|
||||
self.type = kwargs.get('type', 'common')
|
||||
"""The fuzzy set type (common, composite, nonstationary, etc)"""
|
||||
@ -170,7 +170,7 @@ def set_ordered(fuzzy_sets):
|
||||
return [k.name for k in sorted(tmp1, key=lambda x: x.centroid)]
|
||||
|
||||
|
||||
def fuzzyfy_instance(inst, fuzzy_sets, ordered_sets=None):
|
||||
def fuzzyfy_instance(inst, fuzzy_sets : dict , ordered_sets : list =None):
|
||||
"""
|
||||
Calculate the membership values for a data point given fuzzy sets
|
||||
|
||||
@ -191,7 +191,7 @@ def fuzzyfy_instance(inst, fuzzy_sets, ordered_sets=None):
|
||||
return mv
|
||||
|
||||
|
||||
def fuzzyfy_instances(data, fuzzy_sets, ordered_sets=None):
|
||||
def fuzzyfy_instances(data : list, fuzzy_sets : dict, ordered_sets=None) -> list:
|
||||
"""
|
||||
Calculate the membership values for a data point given fuzzy sets
|
||||
|
||||
@ -209,7 +209,7 @@ def fuzzyfy_instances(data, fuzzy_sets, ordered_sets=None):
|
||||
return ret
|
||||
|
||||
|
||||
def get_fuzzysets(inst, fuzzy_sets, ordered_sets=None, alpha_cut=0.0):
|
||||
def get_fuzzysets(inst, fuzzy_sets : dict, ordered_sets : list =None, alpha_cut : flota =0.0) -> list:
|
||||
"""
|
||||
Return the fuzzy sets which membership value for a inst is greater than the alpha_cut
|
||||
|
||||
@ -232,7 +232,7 @@ def get_fuzzysets(inst, fuzzy_sets, ordered_sets=None, alpha_cut=0.0):
|
||||
raise ex
|
||||
|
||||
|
||||
def get_maximum_membership_fuzzyset(inst, fuzzy_sets, ordered_sets=None):
|
||||
def get_maximum_membership_fuzzyset(inst, fuzzy_sets, ordered_sets=None) -> FuzzySet:
|
||||
"""
|
||||
Fuzzify a data point, returning the fuzzy set with maximum membership value
|
||||
|
||||
@ -248,7 +248,7 @@ def get_maximum_membership_fuzzyset(inst, fuzzy_sets, ordered_sets=None):
|
||||
return fuzzy_sets[key]
|
||||
|
||||
|
||||
def get_maximum_membership_fuzzyset_index(inst, fuzzy_sets):
|
||||
def get_maximum_membership_fuzzyset_index(inst, fuzzy_sets) -> int:
|
||||
"""
|
||||
Fuzzify a data point, returning the fuzzy set with maximum membership value
|
||||
|
||||
|
@ -15,6 +15,3 @@ from pyFTS.common.transformations.trend import LinearTrend
|
||||
from pyFTS.common.transformations.som import SOMTransformation
|
||||
from pyFTS.common.transformations.autoencoder import AutoencoderTransformation
|
||||
from pyFTS.common.transformations.normalization import Normalization
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from pyFTS.common import FuzzySet, SortedCollection, tree, Util
|
||||
from pyFTS.common import FuzzySet, Util
|
||||
from pyFTS.common.transformations import transformation
|
||||
from pyFTS.partitioners import partitioner
|
||||
from pyFTS.probabilistic import ProbabilityDistribution
|
||||
|
||||
|
||||
class FTS(object):
|
||||
@ -11,72 +14,72 @@ class FTS(object):
|
||||
"""
|
||||
Create a Fuzzy Time Series model
|
||||
"""
|
||||
self.flrgs = {}
|
||||
self.flrgs: dict = {}
|
||||
"""The list of Fuzzy Logical Relationship Groups - FLRG"""
|
||||
self.order = kwargs.get('order',1)
|
||||
self.order : int = kwargs.get('order',1)
|
||||
"""A integer with the model order (number of past lags are used on forecasting)"""
|
||||
self.shortname = kwargs.get('name',"")
|
||||
self.shortname : str = kwargs.get('name',"")
|
||||
"""A string with a short name or alias for the model"""
|
||||
self.name = kwargs.get('name',"")
|
||||
self.name : str = kwargs.get('name',"")
|
||||
"""A string with the model name"""
|
||||
self.detail = kwargs.get('name',"")
|
||||
self.detail : str = kwargs.get('name',"")
|
||||
"""A string with the model detailed information"""
|
||||
self.is_wrapper = False
|
||||
self.is_wrapper : bool = False
|
||||
"""Indicates that this model is a wrapper for other(s) method(s)"""
|
||||
self.is_high_order = False
|
||||
self.is_high_order : bool = False
|
||||
"""A boolean value indicating if the model support orders greater than 1, default: False"""
|
||||
self.min_order = 1
|
||||
self.min_order : int = 1
|
||||
"""In high order models, this integer value indicates the minimal order supported for the model, default: 1"""
|
||||
self.has_seasonality = False
|
||||
self.has_seasonality : bool = False
|
||||
"""A boolean value indicating if the model supports seasonal indexers, default: False"""
|
||||
self.has_point_forecasting = True
|
||||
self.has_point_forecasting : bool = True
|
||||
"""A boolean value indicating if the model supports point forecasting, default: True"""
|
||||
self.has_interval_forecasting = False
|
||||
self.has_interval_forecasting : bool = False
|
||||
"""A boolean value indicating if the model supports interval forecasting, default: False"""
|
||||
self.has_probability_forecasting = False
|
||||
self.has_probability_forecasting : bool = False
|
||||
"""A boolean value indicating if the model support probabilistic forecasting, default: False"""
|
||||
self.is_multivariate = False
|
||||
self.is_multivariate : bool = False
|
||||
"""A boolean value indicating if the model support multivariate time series (Pandas DataFrame), default: False"""
|
||||
self.is_clustered = False
|
||||
self.is_clustered : bool = 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 = []
|
||||
self.dump : bool = False
|
||||
self.transformations : list[transformation.Transformation] = []
|
||||
"""A list with the data transformations (common.Transformations) applied on model pre and post processing, default: []"""
|
||||
self.transformations_param = []
|
||||
self.transformations_param : list = []
|
||||
"""A list with the specific parameters for each data transformation"""
|
||||
self.original_max = 0
|
||||
self.original_max : float = 0.0
|
||||
"""A float with the upper limit of the Universe of Discourse, the maximal value found on training data"""
|
||||
self.original_min = 0
|
||||
self.original_min : float = 0.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)
|
||||
self.partitioner : partitioner.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
|
||||
self.auto_update : bool = False
|
||||
"""A boolean value indicating that model is incremental"""
|
||||
self.benchmark_only = False
|
||||
self.benchmark_only : bool = 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)
|
||||
self.uod_clip : bool = 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)
|
||||
self.alpha_cut : float = kwargs.get("alpha_cut", 0.0)
|
||||
"""A float with the minimal membership to be considered on fuzzyfication process"""
|
||||
self.lags = kwargs.get("lags", None)
|
||||
self.lags : list[int] = kwargs.get("lags", None)
|
||||
"""The list of lag indexes for high order models"""
|
||||
self.max_lag = self.order
|
||||
self.max_lag : int = 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.log : pd.DataFrame = pd.DataFrame([],columns=["Datetime","Operation","Value"])
|
||||
""""""
|
||||
self.is_time_variant = False
|
||||
self.is_time_variant : bool = False
|
||||
"""A boolean value indicating if this model is time variant"""
|
||||
self.standard_horizon = kwargs.get("standard_horizon", 1)
|
||||
self.standard_horizon : int = kwargs.get("standard_horizon", 1)
|
||||
"""Standard forecasting horizon (Default: 1)"""
|
||||
|
||||
|
||||
def fuzzy(self, data):
|
||||
def fuzzy(self, data) -> dict:
|
||||
"""
|
||||
Fuzzify a data point
|
||||
|
||||
@ -198,7 +201,7 @@ class FTS(object):
|
||||
|
||||
return ret
|
||||
|
||||
def forecast(self, data, **kwargs):
|
||||
def forecast(self, data, **kwargs) -> list:
|
||||
"""
|
||||
Point forecast one step ahead
|
||||
|
||||
@ -208,7 +211,7 @@ class FTS(object):
|
||||
"""
|
||||
raise NotImplementedError('This model do not perform one step ahead point forecasts!')
|
||||
|
||||
def forecast_interval(self, data, **kwargs):
|
||||
def forecast_interval(self, data, **kwargs) -> list:
|
||||
"""
|
||||
Interval forecast one step ahead
|
||||
|
||||
@ -218,7 +221,7 @@ class FTS(object):
|
||||
"""
|
||||
raise NotImplementedError('This model do not perform one step ahead interval forecasts!')
|
||||
|
||||
def forecast_distribution(self, data, **kwargs):
|
||||
def forecast_distribution(self, data, **kwargs) -> list[ProbabilityDistribution.ProbabilityDistribution]:
|
||||
"""
|
||||
Probabilistic forecast one step ahead
|
||||
|
||||
@ -228,7 +231,7 @@ class FTS(object):
|
||||
"""
|
||||
raise NotImplementedError('This model do not perform one step ahead distribution forecasts!')
|
||||
|
||||
def forecast_multivariate(self, data, **kwargs):
|
||||
def forecast_multivariate(self, data, **kwargs) -> pd.DataFrame:
|
||||
"""
|
||||
Multivariate forecast one step ahead
|
||||
|
||||
@ -239,7 +242,7 @@ class FTS(object):
|
||||
raise NotImplementedError('This model do not perform one step ahead multivariate forecasts!')
|
||||
|
||||
|
||||
def forecast_ahead(self, data, steps, **kwargs):
|
||||
def forecast_ahead(self, data, steps, **kwargs) -> list:
|
||||
"""
|
||||
Point forecast from 1 to H steps ahead, where H is given by the steps parameter
|
||||
|
||||
@ -269,7 +272,7 @@ class FTS(object):
|
||||
|
||||
return ret[-steps:]
|
||||
|
||||
def forecast_ahead_interval(self, data, steps, **kwargs):
|
||||
def forecast_ahead_interval(self, data, steps, **kwargs) -> list:
|
||||
"""
|
||||
Interval forecast from 1 to H steps ahead, where H is given by the steps parameter
|
||||
|
||||
@ -280,7 +283,7 @@ class FTS(object):
|
||||
"""
|
||||
raise NotImplementedError('This model do not perform multi step ahead interval forecasts!')
|
||||
|
||||
def forecast_ahead_distribution(self, data, steps, **kwargs):
|
||||
def forecast_ahead_distribution(self, data, steps, **kwargs) -> list[ProbabilityDistribution.ProbabilityDistribution]:
|
||||
"""
|
||||
Probabilistic forecast from 1 to H steps ahead, where H is given by the steps parameter
|
||||
|
||||
@ -291,7 +294,7 @@ class FTS(object):
|
||||
"""
|
||||
raise NotImplementedError('This model do not perform multi step ahead distribution forecasts!')
|
||||
|
||||
def forecast_ahead_multivariate(self, data, steps, **kwargs):
|
||||
def forecast_ahead_multivariate(self, data, steps, **kwargs) -> pd.DataFrame:
|
||||
"""
|
||||
Multivariate forecast n step ahead
|
||||
|
||||
@ -302,7 +305,7 @@ class FTS(object):
|
||||
"""
|
||||
raise NotImplementedError('This model do not perform one step ahead multivariate forecasts!')
|
||||
|
||||
def forecast_step(self, data, step, **kwargs):
|
||||
def forecast_step(self, data, step, **kwargs) -> list:
|
||||
"""
|
||||
Point forecast for H steps ahead, where H is given by the step parameter
|
||||
|
||||
@ -573,7 +576,7 @@ class FTS(object):
|
||||
else:
|
||||
return data
|
||||
|
||||
def get_UoD(self):
|
||||
def get_UoD(self) -> set:
|
||||
"""
|
||||
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.
|
||||
@ -585,7 +588,7 @@ class FTS(object):
|
||||
else:
|
||||
return (self.original_min, self.original_max)
|
||||
|
||||
def offset(self):
|
||||
def offset(self) -> int:
|
||||
"""
|
||||
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
|
||||
|
@ -9,7 +9,7 @@ import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
|
||||
def get_data():
|
||||
def get_data() -> np.ndarray:
|
||||
"""
|
||||
Get a simple univariate time series data.
|
||||
|
||||
@ -19,7 +19,7 @@ def get_data():
|
||||
dat = np.array(dat["Passengers"])
|
||||
return dat
|
||||
|
||||
def get_dataframe():
|
||||
def get_dataframe() -> pd.DataFrame:
|
||||
"""
|
||||
Get the complete multivariate time series data.
|
||||
|
||||
|
@ -16,7 +16,7 @@ class SignalEmulator(object):
|
||||
self.components = []
|
||||
"""Components of the signal"""
|
||||
|
||||
def stationary_gaussian(self, mu, sigma, **kwargs):
|
||||
def stationary_gaussian(self, mu:float, sigma:float, **kwargs):
|
||||
"""
|
||||
Creates a continuous Gaussian signal with mean mu and variance sigma.
|
||||
|
||||
@ -36,7 +36,7 @@ class SignalEmulator(object):
|
||||
'parameters': parameters, 'args': kwargs})
|
||||
return self
|
||||
|
||||
def incremental_gaussian(self, mu, sigma, **kwargs):
|
||||
def incremental_gaussian(self, mu:float, sigma:float, **kwargs):
|
||||
"""
|
||||
Creates an additive gaussian interference on a previous signal
|
||||
|
||||
|
@ -7,7 +7,7 @@ from pathlib import Path
|
||||
from urllib import request
|
||||
|
||||
|
||||
def get_dataframe(filename, url, sep=";", compression='infer'):
|
||||
def get_dataframe(filename: str, url: str, sep:str=";", compression:str='infer') -> pd.DataFrame:
|
||||
"""
|
||||
This method check if filename already exists, read the file and return its data.
|
||||
If the file don't already exists, it will be downloaded and decompressed.
|
||||
|
@ -9,7 +9,7 @@ from pyFTS.partitioners import partitioner
|
||||
|
||||
|
||||
class SingletonPartitioner(partitioner.Partitioner):
|
||||
"""Singleton Partitioner"""
|
||||
"""Singleton Partitioner: Create singleton fuzzy sets for each distinct value in UoD"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
"""
|
||||
@ -17,12 +17,12 @@ class SingletonPartitioner(partitioner.Partitioner):
|
||||
"""
|
||||
super(SingletonPartitioner, self).__init__(name="Singleton", **kwargs)
|
||||
|
||||
def build(self, data):
|
||||
def build(self, data : list):
|
||||
sets = {}
|
||||
|
||||
kwargs = {'type': self.type, 'variable': self.variable}
|
||||
|
||||
for count, instance in enumerate(data):
|
||||
for count, instance in enumerate(set(data)):
|
||||
_name = self.get_name(count)
|
||||
sets[_name] = FuzzySet.FuzzySet(_name, Membership.singleton, [instance], instance, **kwargs)
|
||||
|
||||
|
@ -18,7 +18,11 @@ all_methods = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.FCMPartitio
|
||||
mfs = [Membership.trimf, Membership.gaussmf, Membership.trapmf]
|
||||
|
||||
|
||||
def plot_sets(data, sets, titles, size=[12, 10], save=False, file=None, axis=None):
|
||||
def plot_sets(data, sets: dict, titles : list, size=[12, 10], save=False, file=None, axis=None):
|
||||
"""
|
||||
Plot all fuzzy sets in a Partitioner
|
||||
|
||||
"""
|
||||
num = len(sets)
|
||||
|
||||
if axis is None:
|
||||
@ -53,7 +57,7 @@ def plot_sets(data, sets, titles, size=[12, 10], save=False, file=None, axis=Non
|
||||
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)
|
||||
plot_sets(sets, titles, tam, save, file, axis)
|
||||
|
||||
|
||||
def explore_partitioners(data, npart, methods=None, mf=None, transformation=None,
|
||||
@ -84,6 +88,6 @@ def explore_partitioners(data, npart, methods=None, mf=None, transformation=None
|
||||
obj.name = obj.name + " - " + obj.membership_function.__name__
|
||||
objs.append(obj)
|
||||
|
||||
plot_partitioners(data, objs, size, save, file)
|
||||
plot_partitioners(objs, size, save, file)
|
||||
|
||||
return objs
|
||||
|
@ -28,5 +28,5 @@ def explore_partitioners(data, npart, methods=None, mf=None, tam=[12, 10], save=
|
||||
|
||||
objs = np.ravel(objs).tolist()
|
||||
|
||||
Util.plot_partitioners(data, objs, tam, save, file)
|
||||
Util.plot_partitioners(objs, tam, save, file)
|
||||
|
||||
|
@ -14,16 +14,17 @@ class Partitioner(object):
|
||||
"""
|
||||
Universe of Discourse partitioner scheme. Split data on several fuzzy sets
|
||||
"""
|
||||
self.name = kwargs.get('name',"")
|
||||
self.name : str = kwargs.get('name',"")
|
||||
"""partitioner name"""
|
||||
self.partitions = kwargs.get('npart', 10)
|
||||
self.partitions : int = kwargs.get('npart', 10)
|
||||
"""The number of universe of discourse partitions, i.e., the number of fuzzy sets that will be created"""
|
||||
self.sets = {}
|
||||
self.sets : dict = {}
|
||||
"""The fuzzy sets dictionary"""
|
||||
self.membership_function = kwargs.get('func', Membership.trimf)
|
||||
"""Fuzzy membership function (pyFTS.common.Membership)"""
|
||||
self.setnames = kwargs.get('names', None)
|
||||
self.setnames : list' = kwargs.get('names', None)
|
||||
"""list of partitions names. If None is given the partitions will be auto named with prefix"""
|
||||
self.prefix = kwargs.get('prefix', 'A')
|
||||
self.prefix : str'' = kwargs.get('prefix', 'A')
|
||||
"""prefix of auto generated partition names"""
|
||||
self.transformation = kwargs.get('transformation', None)
|
||||
"""data transformation to be applied on data"""
|
||||
@ -34,13 +35,13 @@ class Partitioner(object):
|
||||
"""The type of fuzzy sets that are generated by this partitioner"""
|
||||
self.ordered_sets = None
|
||||
"""A ordered list of the fuzzy sets names, sorted by their middle point"""
|
||||
self.kdtree = None
|
||||
self.kdtree : KDTree = None
|
||||
"""A spatial index to help in fuzzyfication"""
|
||||
self.margin = kwargs.get("margin", 0.1)
|
||||
self.margin : float = kwargs.get("margin", 0.1)
|
||||
"""The upper and lower exceeding margins for the known UoD. The default value is .1"""
|
||||
self.lower_margin = kwargs.get("lower_margin", self.margin)
|
||||
self.lower_margin : float = kwargs.get("lower_margin", self.margin)
|
||||
"""Specific lower exceeding margins for the known UoD. The default value is the self.margin parameter"""
|
||||
self.upper_margin = kwargs.get("lower_margin", self.margin)
|
||||
self.upper_margin : float = kwargs.get("lower_margin", self.margin)
|
||||
"""Specific upper exceeding margins for the known UoD. The default value is the self.margin parameter"""
|
||||
|
||||
if kwargs.get('preprocess',True):
|
||||
|
@ -8,6 +8,7 @@ from typing import Tuple
|
||||
|
||||
|
||||
class SOMPartitioner:
|
||||
"""Self Organized Map Partitioner"""
|
||||
def __init__(self,
|
||||
grid_dimension: Tuple,
|
||||
**kwargs):
|
||||
@ -19,8 +20,8 @@ class SOMPartitioner:
|
||||
|
||||
|
||||
# debug attributes
|
||||
self.name = 'Kohonen Self Organizing Maps FTS'
|
||||
self.shortname = 'SOM-FTS'
|
||||
self.name = 'Kohonen Self Organizing Map Partitioner'
|
||||
self.shortname = 'SOM-Partitioner'
|
||||
|
||||
def __repr__(self):
|
||||
status = "is trained" if self.is_trained else "not trained"
|
||||
|
Loading…
Reference in New Issue
Block a user