pyFTS/partitioners/CMeans.py

100 lines
3.4 KiB
Python
Raw Normal View History

import numpy as np
import math
import random as rnd
import functools, operator
from pyFTS.common import FuzzySet, Membership
from pyFTS.partitioners import partitioner
def distancia(x, y):
if isinstance(x, list):
tmp = functools.reduce(operator.add, [(x[k] - y[k]) ** 2 for k in range(0, len(x))])
else:
tmp = (x - y) ** 2
return math.sqrt(tmp)
def c_means(k, dados, tam):
# Inicializa as centróides escolhendo elementos aleatórios dos conjuntos
centroides = [dados[rnd.randint(0, len(dados)-1)] for kk in range(0, k)]
grupos = [-1 for x in range(0, len(dados))]
it_semmodificacao = 0
# para cada instância
iteracoes = 0
while iteracoes < 1000 and it_semmodificacao < 10:
inst_count = 0
modificacao = False
for instancia in dados:
# verifica a distância para cada centroide
grupo_count = 0
dist = 10000
grupotmp = grupos[inst_count]
for grupo in centroides:
tmp = distancia(instancia, grupo)
if tmp < dist:
dist = tmp
# associa a a centroide de menor distância à instância
grupos[inst_count] = grupo_count
grupo_count = grupo_count + 1
if grupotmp != grupos[inst_count]:
modificacao = True
inst_count = inst_count + 1
if not modificacao:
it_semmodificacao = it_semmodificacao + 1
else:
it_semmodificacao = 0
# atualiza cada centroide com base nos valores médios de todas as instâncias à ela associadas
grupo_count = 0
for grupo in centroides:
total_inst = functools.reduce(operator.add, [1 for xx in grupos if xx == grupo_count], 0)
if total_inst > 0:
if tam > 1:
for count in range(0, tam):
soma = functools.reduce(operator.add,
[dados[kk][count] for kk in range(0, len(dados)) if
grupos[kk] == grupo_count])
centroides[grupo_count][count] = soma / total_inst
else:
soma = functools.reduce(operator.add,
[dados[kk] for kk in range(0, len(dados)) if grupos[kk] == grupo_count])
centroides[grupo_count] = soma / total_inst
grupo_count = grupo_count + 1
iteracoes = iteracoes + 1
2016-12-21 21:16:16 +04:00
return centroides
class CMeansPartitioner(partitioner.Partitioner):
def __init__(self, npart,data,func = Membership.trimf):
super(CMeansPartitioner, self).__init__("CMeans ",data,npart,func)
def build(self, data):
sets = []
dmax = max(data)
dmax += dmax * 0.10
dmin = min(data)
dmin -= dmin * 0.10
centroides = c_means(self.partitions, data, 1)
centroides.append(dmax)
centroides.append(dmin)
centroides = list(set(centroides))
centroides.sort()
for c in np.arange(1, len(centroides) - 1):
sets.append(FuzzySet.FuzzySet(self.prefix + str(c), Membership.trimf,
[round(centroides[c - 1], 3), round(centroides[c], 3), round(centroides[c + 1], 3)],
round(centroides[c], 3)))
return sets