Particionamento por entropia

This commit is contained in:
Petrônio Cândido de Lima e Silva 2016-12-26 18:25:59 -02:00
parent f3e46735b2
commit 2022c2a032
2 changed files with 39 additions and 18 deletions

View File

@ -8,12 +8,15 @@ 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,” # 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. 524542, Jun. 2006. # Technol. Forecast. Social Change, vol. 73, no. 5, pp. 524542, Jun. 2006.
def splitBelow(data,threshold): def splitBelow(data,threshold):
return [k for k in data if k <= threshold] return [k for k in data if k <= threshold]
def splitAbove(data,threshold): def splitAbove(data,threshold):
return [k for k in data if k > threshold] return [k for k in data if k > threshold]
def PMF(data, threshold): def PMF(data, threshold):
a = sum([1.0 for k in splitBelow(data,threshold)]) a = sum([1.0 for k in splitBelow(data,threshold)])
b = sum([1.0 for k in splitAbove(data, threshold)]) b = sum([1.0 for k in splitAbove(data, threshold)])
@ -23,6 +26,9 @@ def PMF(data, threshold):
def entropy(data, threshold): def entropy(data, threshold):
pmf = PMF(data, threshold) pmf = PMF(data, threshold)
if pmf[0] == 0 or pmf[1] == 0:
return 1
else:
return - sum([pmf[0] * math.log(pmf[0]), pmf[1] * math.log(pmf[1])]) return - sum([pmf[0] * math.log(pmf[0]), pmf[1] * math.log(pmf[1])])
@ -33,13 +39,19 @@ def informationGain(data, thres1, thres2):
def bestSplit(data, npart): def bestSplit(data, npart):
if len(data) < 2: if len(data) < 2:
return None return None
count = 2 count = 1
ndata = list(set(data)) ndata = list(set(data))
ndata.sort() ndata.sort()
l = len(ndata)
threshold = 0 threshold = 0
while informationGain(data, ndata[count - 1], ndata[count]) <= 0: try:
while count < l and informationGain(data, ndata[count - 1], ndata[count]) <= 0:
threshold = ndata[count] threshold = ndata[count]
count += 1 count += 1
except IndexError:
print(threshold)
print (ndata)
print (count)
rem = npart % 2 rem = npart % 2
@ -54,23 +66,31 @@ def bestSplit(data, npart):
np1 = (npart - rem) / 2 np1 = (npart - rem) / 2
np2 = (npart - rem) / 2 + rem np2 = (npart - rem) / 2 + rem
return [ threshold, bestSplit(p1, np1 ), bestSplit(p2, np2 ) ] tmp = [threshold]
for k in bestSplit(p1, np1 ): tmp.append(k)
for k in bestSplit(p2, np2 ): tmp.append(k)
return tmp
else: else:
return threshold return [threshold]
def EntropyPartitionerTrimf(data, npart, prefix="A"): def EntropyPartitionerTrimf(data, npart, prefix="A"):
sets = []
dmax = max(data) dmax = max(data)
dmax += dmax * 0.10 dmax += dmax * 0.10
dmin = min(data) dmin = min(data)
dmin -= dmin * 0.10 dmin -= dmin * 0.10
sets = [dmin, bestSplit(data, npart), dmax] partitions = bestSplit(data, npart)
partitions.append(dmin)
sets.sort() partitions.append(dmax)
for c in np.arange(1, len(sets) - 1): partitions = list(set(partitions))
partitions.sort()
for c in np.arange(1, len(partitions) - 1):
sets.append(FuzzySet.FuzzySet(prefix + str(c), Membership.trimf, sets.append(FuzzySet.FuzzySet(prefix + str(c), Membership.trimf,
[round(sets[c - 1], 3), round(sets[c], 3), [partitions[c - 1], partitions[c], partitions[c + 1]],partitions[c]))
round(sets[c + 1], 3)],round(sets[c], 3)))
return sets return sets

View File

@ -4,17 +4,18 @@ import matplotlib as plt
import matplotlib.colors as pltcolors import matplotlib.colors as pltcolors
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D from mpl_toolkits.mplot3d import Axes3D
from pyFTS.common import Membership from pyFTS.common import Membership
def plotSets(data, sets):
def plotSets(data, sets, titles):
num = len(sets) num = len(sets)
fig = plt.figure(figsize=[20, 10]) fig = plt.figure(figsize=[12, 10])
maxx = max(data) maxx = max(data)
minx = min(data) minx = min(data)
h = 1/num h = 1/num
for k in range(num): for k in range(num):
ax0 = fig.add_axes([0, (k+1)*h, 0.65, h]) # left, bottom, width, height ax0 = fig.add_axes([0, (k+1)*h, 0.65, h*0.7]) # left, bottom, width, height
ax0.set_title(titles[k])
ax0.set_ylim([0, 1]) ax0.set_ylim([0, 1])
ax0.set_xlim([minx, maxx]) ax0.set_xlim([minx, maxx])
for s in sets[k]: for s in sets[k]: