diff --git a/common/FuzzySet.py b/common/FuzzySet.py index 65226f7..908eebd 100644 --- a/common/FuzzySet.py +++ b/common/FuzzySet.py @@ -1,5 +1,6 @@ import numpy as np from pyFTS import * +from pyFTS.common import Membership class FuzzySet: @@ -8,8 +9,12 @@ class FuzzySet: self.mf = mf self.parameters = parameters self.centroid = centroid - self.lower = min(parameters) - self.upper = max(parameters) + if self.mf == Membership.trimf: + self.lower = min(parameters) + self.upper = max(parameters) + elif self.mf == Membership.gaussmf: + self.lower = parameters[0] - parameters[1]*3 + self.upper = parameters[0] + parameters[1]*3 def membership(self, x): return self.mf(x, self.parameters) diff --git a/common/Membership.py b/common/Membership.py index 0a598d0..6827909 100644 --- a/common/Membership.py +++ b/common/Membership.py @@ -29,7 +29,8 @@ def trapmf(x, parameters): def gaussmf(x, parameters): - return math.exp(-0.5 * ((x - parameters[0]) / parameters[1]) ** 2) + return math.exp((-(x - parameters[0])**2)/(2 * parameters[1]**2)) + #return math.exp(-0.5 * ((x - parameters[0]) / parameters[1]) ** 2) def bellmf(x, parameters): diff --git a/partitioners/Entropy.py b/partitioners/Entropy.py new file mode 100644 index 0000000..6c6453c --- /dev/null +++ b/partitioners/Entropy.py @@ -0,0 +1,76 @@ +import numpy as np +import math +import random as rnd +import functools, operator +from pyFTS.common import FuzzySet, Membership + + +# C. H. Cheng, R. J. Chang, and C. A. Yeh, “Entropy-based and trapezoidal fuzzification-based fuzzy time series approach for forecasting IT project cost,” +# Technol. Forecast. Social Change, vol. 73, no. 5, pp. 524–542, Jun. 2006. + +def splitBelow(data,threshold): + return [k for k in data if k <= threshold] + +def splitAbove(data,threshold): + return [k for k in data if k > threshold] + +def PMF(data, threshold): + a = sum([1.0 for k in splitBelow(data,threshold)]) + b = sum([1.0 for k in splitAbove(data, threshold)]) + l = len(data) + return [a / l, b / l] + + +def entropy(data, threshold): + pmf = PMF(data, threshold) + return - sum([pmf[0] * math.log(pmf[0]), pmf[1] * math.log(pmf[1])]) + + +def informationGain(data, thres1, thres2): + return entropy(data, thres1) - entropy(data, thres2) + + +def bestSplit(data, npart): + if len(data) < 2: + return None + count = 2 + ndata = list(set(data)) + ndata.sort() + threshold = 0 + while informationGain(data, ndata[count - 1], ndata[count]) <= 0: + threshold = ndata[count] + count += 1 + + rem = npart % 2 + + if (npart - rem)/2 > 1: + p1 = splitBelow(data,threshold) + p2 = splitAbove(data,threshold) + + if len(p1) > len(p2): + np1 = (npart - rem)/2 + rem + np2 = (npart - rem)/2 + else: + np1 = (npart - rem) / 2 + np2 = (npart - rem) / 2 + rem + + return [ threshold, bestSplit(p1, np1 ), bestSplit(p2, np2 ) ] + + else: + return threshold + +def EntropyPartitionerTrimf(data, npart, prefix="A"): + dmax = max(data) + dmax += dmax * 0.10 + dmin = min(data) + dmin -= dmin * 0.10 + + sets = [dmin, bestSplit(data, npart), dmax] + + sets.sort() + for c in np.arange(1, len(sets) - 1): + sets.append(FuzzySet.FuzzySet(prefix + str(c), Membership.trimf, + [round(sets[c - 1], 3), round(sets[c], 3), + round(sets[c + 1], 3)],round(sets[c], 3))) + + return sets diff --git a/partitioners/Grid.py b/partitioners/Grid.py index 7c3c6f3..a34624d 100644 --- a/partitioners/Grid.py +++ b/partitioners/Grid.py @@ -23,3 +23,21 @@ def GridPartitionerTrimf(data, npart, names=None, prefix="A"): partition += partlen return sets + + +def GridPartitionerGaussmf(data, npart, names=None, prefix="A"): + sets = [] + dmax = max(data) + dmax += dmax * 0.10 + dmin = min(data) + dmin -= dmin * 0.10 + dlen = dmax - dmin + partlen = math.ceil(dlen / npart) + partition = math.ceil(dmin) + for c in range(npart): + sets.append( + FuzzySet.FuzzySet(prefix + str(c), Membership.gaussmf, [partition, partlen/3], + partition)) + partition += partlen + + return sets diff --git a/partitioners/Huarng.py b/partitioners/Huarng.py index 75d2bbb..491e752 100644 --- a/partitioners/Huarng.py +++ b/partitioners/Huarng.py @@ -12,8 +12,6 @@ def GridPartitionerTrimf(data, prefix="A"): data2 = Transformations.differential(data) davg = np.abs( np.mean(data2) / 2 ) - print(davg) - if davg <= 1.0: base = 0.1 elif 1 < davg <= 10: