该案例展示了如何利用进化算法进行仿k-means聚类(可称之为EA-KMeans算法)。
本案例采用与k-means类似的聚类方法,采用展开的聚类中心点坐标作为染色体的编码,基本流程大致如下:
1) 初始化种群染色体。
2) 迭代进化(循环第3步至第6步),直到满足终止条件。
3) 重组变异,然后根据得到的新染色体计算出对应的聚类中心点。
4) 计算各数据点到聚类中心点的欧式距离。
5) 把与各中心点关联的数据点的坐标平均值作为新的中心点,并以此更新种群的染色体。
6) 把各中心点到与其关联的数据点之间的距离之和作为待优化的目标函数值。
注意:导入的数据是以列为特征的,即每一列代表一个特征(如第一列代表x,第二列代表y......)。
import numpy as np
import geatpy as ea
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist
"""
该案例展示了如何利用进化算法进行仿k-means聚类(可称之为EA-KMeans算法)。
本案例采用与k-means类似的聚类方法,采用展开的聚类中心点坐标作为染色体的编码,基本流程大致如下:
1) 初始化种群染色体。
2) 迭代进化(循环第3步至第6步),直到满足终止条件。
3) 重组变异,然后根据得到的新染色体计算出对应的聚类中心点。
4) 计算各数据点到聚类中心点的欧式距离。
5) 把与各中心点关联的数据点的坐标平均值作为新的中心点,并以此更新种群的染色体。
6) 把各中心点到与其关联的数据点之间的距离之和作为待优化的目标函数值。
注意:导入的数据是以列为特征的,即每一列代表一个特征(如第一列代表x,第二列代表y......)。
"""
class MyProblem(ea.Problem):
def __init__(self):
self.datas = np.loadtxt('data.csv', delimiter=',')
self.k = 4
name = 'MyProblem'
M = 1
maxormins = [1]
Dim = self.datas.shape[1] * self.k
varTypes = [0] * Dim
lb = list(np.min(self.datas, 0)) * self.k
ub = list(np.max(self.datas, 0)) * self.k
lbin = [1] * Dim
ubin = [1] * Dim
ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)
def aimFunc(self, pop):
centers = pop.Phen.reshape(int(pop.sizes * self.k), int(pop.Phen.shape[1] / self.k))
dis = cdist(centers, self.datas, 'euclidean')
dis_split = dis.reshape(pop.sizes, self.k, self.datas.shape[0])
labels = np.argmin(dis_split, 1)[0]
uni_labels = np.unique(labels)
for i in range(len(uni_labels)):
centers[uni_labels[i], :] = np.mean(self.datas[np.where(labels == uni_labels[i])[0], :], 0)
pop.Chrom = centers.reshape(pop.sizes, self.k * centers.shape[1])
pop.Phen = pop.decoding()
dis = cdist(centers, self.datas, 'euclidean')
dis_split = dis.reshape(pop.sizes, self.k, self.datas.shape[0])
pop.ObjV = np.sum(np.min(dis_split, 1), 1, keepdims = True)
def draw(self, centers):
dis = cdist(centers, self.datas, 'euclidean')
dis_split = dis.reshape(1, self.k, self.datas.shape[0])
labels = np.argmin(dis_split, 1)[0]
colors = ['r','g','b','y']
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for i in range(self.k):
idx = np.where(labels == i)[0]
datas = self.datas[idx, :]
ax.scatter(datas[:, 0], datas[:, 1], datas[:, 2], c = colors[i])
plt.show()
源代码