import numpy as np from sklearn import datasets def FCM(X, c_clusters=3, m=2, eps=1e-2): # 随机二维数组shape(150,3),初始化隶属度矩阵 membership_mat = np.random.random((len(X), c_clusters)) # 使Xi的隶属度总和为1,即Xi隶属于每个类别的数值求和为1 membership_mat = np.divide(membership_mat, np.sum(membership_mat, axis=1)[:, np.newaxis]) while True: # 超参数m=2 working_membership_mat = membership_mat ** m # 根据公式计算聚类中心点Centroids.shape->(3,4) C_j Centroids = np.divide(np.dot(working_membership_mat.T, X), np.sum(working_membership_mat.T, axis=1)[:, np.newaxis]) # 该矩阵保存所有实点到每个聚类中心的欧式距离 n_c_distance_mat = np.zeros((len(X), c_clusters)) # shape->(150,3) for i, x in enumerate(X): for j, c in enumerate(Centroids): n_c_distance_mat[i][j] = np.linalg.norm(x - c, 2) # 计算l2范数(欧氏距离) new_membership_mat = np.zeros((len(X), c_clusters)) # 更新模糊矩阵U for i, x in enumerate(X): for j, c in enumerate(Centroids): new_membership_mat[i][j] = 1. / np.sum((n_c_distance_mat[i][j] / n_c_distance_mat[i]) ** (2 / (m - 1))) # 聚类到隶属度变化<eps时,退出循环。 if np.sum(abs(new_membership_mat - membership_mat)) < eps: break membership_mat = new_membership_mat return np.argmax(new_membership_mat, axis=1) if __name__ == '__main__': iris = datasets.load_iris() print(FCM(iris.data))
123456789101112131415161718192021222324252627282930313233343536373839404142434445