Source code for pyFTS.partitioners.CMeans

import numpy as np
import math
import random as rnd
import functools, operator
from pyFTS.common import FuzzySet, Membership
from pyFTS.partitioners import partitioner


[docs]def distance(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)
[docs]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 = distance(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 return centroides
[docs]class CMeansPartitioner(partitioner.Partitioner): def __init__(self, **kwargs): super(CMeansPartitioner, self).__init__(name="CMeans", **kwargs)
[docs] def build(self, data): sets = {} kwargs = {'type': self.type, 'variable': self.variable} centroides = c_means(self.partitions, data, 1) centroides.append(self.max) centroides.append(self.min) centroides = list(set(centroides)) centroides.sort() for c in np.arange(1, len(centroides) - 1): _name = self.get_name(c) sets[_name] = FuzzySet.FuzzySet(_name, Membership.trimf, [round(centroides[c - 1], 3), round(centroides[c], 3), round(centroides[c + 1], 3)], round(centroides[c], 3), **kwargs) return sets