From 71cbb84574caa03de88d3605f2b9b2b7d7daf276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=C3=B4nio=20C=C3=A2ndido?= Date: Thu, 28 Sep 2017 10:16:28 -0300 Subject: [PATCH] Seasonal models refactoring; Composite fuzzy sets; Seasonal fuzzy set --- pyFTS/common/Composite.py | 39 +++++++++++++++ pyFTS/nonstationary/common.py | 33 ++++++++++-- pyFTS/nonstationary/nsfts.py | 12 +++++ .../{models => }/seasonal/SeasonalIndexer.py | 40 ++------------- pyFTS/{models => }/seasonal/__init__.py | 0 pyFTS/{models => seasonal}/cmsfts.py | 0 pyFTS/seasonal/common.py | 50 +++++++++++++++++++ pyFTS/{models => seasonal}/msfts.py | 0 pyFTS/{ => seasonal}/sfts.py | 0 9 files changed, 134 insertions(+), 40 deletions(-) create mode 100644 pyFTS/common/Composite.py create mode 100644 pyFTS/nonstationary/nsfts.py rename pyFTS/{models => }/seasonal/SeasonalIndexer.py (83%) rename pyFTS/{models => }/seasonal/__init__.py (100%) rename pyFTS/{models => seasonal}/cmsfts.py (100%) create mode 100644 pyFTS/seasonal/common.py rename pyFTS/{models => seasonal}/msfts.py (100%) rename pyFTS/{ => seasonal}/sfts.py (100%) diff --git a/pyFTS/common/Composite.py b/pyFTS/common/Composite.py new file mode 100644 index 0000000..f087ab0 --- /dev/null +++ b/pyFTS/common/Composite.py @@ -0,0 +1,39 @@ +""" +Composite Fuzzy Sets +""" + +import numpy as np +from pyFTS import * +from pyFTS.common import Membership, FuzzySet + + +class FuzzySet(FuzzySet.FuzzySet): + """ + Composite Fuzzy Set + """ + def __init__(self, name): + """ + Create an empty composite fuzzy set + :param name: fuzzy set name + """ + super(FuzzySet, self).__init__(self, name=name, mf=None, parameters=None, centroid=None) + self.mf = [] + self.parameters = [] + + 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 min([self.mf[ct](x, self.parameters[ct]) for ct in np.arange(0, len(self.mf))]) + + def append(self, mf, parameters): + """ + Adds a new function to composition + :param mf: + :param parameters: + :return: + """ + self.mf.append(mf) + self.parameters.append(parameters) \ No newline at end of file diff --git a/pyFTS/nonstationary/common.py b/pyFTS/nonstationary/common.py index 6fafbfb..cbffd59 100644 --- a/pyFTS/nonstationary/common.py +++ b/pyFTS/nonstationary/common.py @@ -1,10 +1,33 @@ +""" +Non Stationary Fuzzy Sets + +GARIBALDI, Jonathan M.; JAROSZEWSKI, Marcin; MUSIKASUWAN, Salang. Nonstationary fuzzy sets. +IEEE Transactions on Fuzzy Systems, v. 16, n. 4, p. 1072-1086, 2008. +""" + import numpy as np from pyFTS import * from pyFTS.common import FuzzySet, Membership -class NonStationaryMembershipFunction(object): +class MembershipFunction(object): + """ + Non Stationary Membership Function + """ def __init__(self, name, mf, parameters, **kwargs): + """ + Non Stationary Membership Function + :param name: + :param mf: + :param parameters: + :param kwargs: + - location: Pertubation function that affects the location of the membership function + - location_params: Parameters for location pertubation function + - width: Pertubation function that affects the width of the membership function + - width_params: Parameters for width pertubation function + - noise: Pertubation function that adds noise on the membership function + - noise_params: Parameters for noise pertubation function + """ self.mf = mf self.parameters = parameters self.location = kwargs.get("location", None) @@ -73,12 +96,9 @@ class NonStationaryMembershipFunction(object): return tmp -class NonStationaryFuzzySet(FuzzySet.FuzzySet): +class FuzzySet(FuzzySet.FuzzySet): """ Non Stationary Fuzzy Sets - - GARIBALDI, Jonathan M.; JAROSZEWSKI, Marcin; MUSIKASUWAN, Salang. Nonstationary fuzzy sets. - IEEE Transactions on Fuzzy Systems, v. 16, n. 4, p. 1072-1086, 2008. """ def __init__(self, name, mf, **kwargs): @@ -89,4 +109,7 @@ class NonStationaryFuzzySet(FuzzySet.FuzzySet): """ super(FuzzySet, self).__init__(name=name, mf=mf, parameters=None, centroid=None) + def membership(self, x, t): + return self.mf.membership(x,t) + diff --git a/pyFTS/nonstationary/nsfts.py b/pyFTS/nonstationary/nsfts.py new file mode 100644 index 0000000..32f03bf --- /dev/null +++ b/pyFTS/nonstationary/nsfts.py @@ -0,0 +1,12 @@ +import numpy as np +from pyFTS.common import FuzzySet, FLR +from pyFTS import fts, sfts + + +class NonStationaryFTS(sfts.SeasonalFTS): + """NonStationaryFTS Fuzzy Time Series""" + def __init__(self, name, **kwargs): + super(NonStationaryFTS, self).__init__(1, "NSFTS " + name, **kwargs) + self.name = "Non Stationary FTS" + self.detail = "" + self.flrgs = {} \ No newline at end of file diff --git a/pyFTS/models/seasonal/SeasonalIndexer.py b/pyFTS/seasonal/SeasonalIndexer.py similarity index 83% rename from pyFTS/models/seasonal/SeasonalIndexer.py rename to pyFTS/seasonal/SeasonalIndexer.py index 037dc9b..7b20f4b 100644 --- a/pyFTS/models/seasonal/SeasonalIndexer.py +++ b/pyFTS/seasonal/SeasonalIndexer.py @@ -1,6 +1,7 @@ import numpy as np import pandas as pd from enum import Enum +from pyFTS.seasonal import common class SeasonalIndexer(object): @@ -124,17 +125,6 @@ class DataFrameSeasonalIndexer(SeasonalIndexer): return data -class DateTime(Enum): - year = 1 - month = 2 - day_of_month = 3 - day_of_year = 4 - day_of_week = 5 - hour = 6 - minute = 7 - second = 8 - - class DateTimeSeasonalIndexer(SeasonalIndexer): def __init__(self,date_field, index_fields, index_seasons, data_fields,**kwargs): super(DateTimeSeasonalIndexer, self).__init__(len(index_seasons), **kwargs) @@ -143,29 +133,6 @@ class DateTimeSeasonalIndexer(SeasonalIndexer): self.data_fields = data_fields self.date_field = date_field - def strip_datepart(self, date, date_part, resolution): - if date_part == DateTime.year: - tmp = date.year - elif date_part == DateTime.month: - tmp = date.month - elif date_part == DateTime.day_of_year: - tmp = date.timetuple().tm_yday - elif date_part == DateTime.day_of_month: - tmp = date.day - elif date_part == DateTime.day_of_week: - tmp = date.weekday() - elif date_part == DateTime.hour: - tmp = date.hour - elif date_part == DateTime.minute: - tmp = date.minute - elif date_part == DateTime.second: - tmp = date.second - - if resolution is None: - return tmp - else: - return tmp // resolution - def get_season_of_data(self, data): ret = [] @@ -175,7 +142,10 @@ class DateTimeSeasonalIndexer(SeasonalIndexer): date = data[self.date_field][ix] season = [] for c, f in enumerate(self.fields, start=0): - season.append(self.strip_datepart(date, f, self.seasons[c])) + tmp = common.strip_datepart(date, f) + if self.seasons[c] is not None: + tmp = tmp // self.seasons[c] + season.append(tmp) ret.append(season) elif isinstance(data, pd.Series): diff --git a/pyFTS/models/seasonal/__init__.py b/pyFTS/seasonal/__init__.py similarity index 100% rename from pyFTS/models/seasonal/__init__.py rename to pyFTS/seasonal/__init__.py diff --git a/pyFTS/models/cmsfts.py b/pyFTS/seasonal/cmsfts.py similarity index 100% rename from pyFTS/models/cmsfts.py rename to pyFTS/seasonal/cmsfts.py diff --git a/pyFTS/seasonal/common.py b/pyFTS/seasonal/common.py new file mode 100644 index 0000000..07a5edb --- /dev/null +++ b/pyFTS/seasonal/common.py @@ -0,0 +1,50 @@ +import numpy as np +import pandas as pd +from enum import Enum +from pyFTS.common import FuzzySet + + +class DateTime(Enum): + year = 1 + month = 2 + day_of_month = 3 + day_of_year = 4 + day_of_week = 5 + hour = 6 + minute = 7 + second = 8 + + +def strip_datepart(self, date, date_part): + if date_part == DateTime.year: + tmp = date.year + elif date_part == DateTime.month: + tmp = date.month + elif date_part == DateTime.day_of_year: + tmp = date.timetuple().tm_yday + elif date_part == DateTime.day_of_month: + tmp = date.day + elif date_part == DateTime.day_of_week: + tmp = date.weekday() + elif date_part == DateTime.hour: + tmp = date.hour + elif date_part == DateTime.minute: + tmp = date.minute + elif date_part == DateTime.second: + tmp = date.second + + return tmp + + +class FuzzySet(FuzzySet.FuzzySet): + """ + Temporal/Seasonal Fuzzy Set + """ + + def __init__(self, datepart, name, mf, parameters, centroid): + super(FuzzySet, self).__init__(name, mf, parameters, centroid) + self.datepart = datepart + + def membership(self, x): + dp = strip_datepart(x, self.datepart) + return self.mf.membership(dp) \ No newline at end of file diff --git a/pyFTS/models/msfts.py b/pyFTS/seasonal/msfts.py similarity index 100% rename from pyFTS/models/msfts.py rename to pyFTS/seasonal/msfts.py diff --git a/pyFTS/sfts.py b/pyFTS/seasonal/sfts.py similarity index 100% rename from pyFTS/sfts.py rename to pyFTS/seasonal/sfts.py