模式识别(3)Kmeans和FCM

Kmeans和FCM

       Kmeans算法作为应用最广泛的基于划分的聚类算法之一,适用于处理大样本数据。是一种典型的基于相似性度量的方法,目标是根据输入参数K将数据集划分为K类。由于初始值,相似度,聚类均值计算策略的不同,因而有很多种K均值算法的变种。在数据接近球形分布的时候,K均值算法具有较好的聚类效果。
       K均值算法属于硬聚类算法,它把数据点划分到确切的某一聚类中。而模糊聚类则是软聚类,数据点可能归属于不止一个聚类,并且这些聚类与数据点通过一个成员水平联系起来。成员水平显示了数据点与某一聚类之间联系很密切。模糊聚类就是计算这些成员水平,按照成员水平来决定数据点属于哪一个或哪些聚类的过程。

一、问题描述

       1、查阅无监督聚类的评价标准有哪些?选择其中一个标准作为后续试验的验证指标。
       2、sonar和iris数据上分别验证两种聚类算法,同时,也可以先利用kmeans算法选择初始聚类中心,然后使用FCM聚类,观察其结果。

二、数据集说明

2.1 Iris数据集

       Iris数据集,是一个多分类问题,每个类的观察值数量是均等的,一共有150个观察值,4个输入变量和1个输出变量,其通过对鸢尾花的测量数据预测鸢尾花的品种。

2.2 Sonar数据集

       Sonar数据集提供了208组60维的声纳观测集数据,用来预测给定声纳从不同角度返回的强度预测目标是岩石还是矿井。其中R类代表岩石,M类代表矿井。

三、评价标准

       在有监督聚类算法中,由于数据是有标签的,我们可以将原始数据的准确标签和分类后得到的标签进行对比,以此来计算聚类结果的准确性,而且可以以此作为损失函数,使得分类的错误率越来越小,模型即可得到优化。
       但是在无监督学习中,由于数据本身是没有标签的,那么在聚类后我们只可以得到聚类的结果,并不知道结果是否正确,这是我们无法判断其准确率,由此我们需要一类可以评价无监督聚类结果的好坏的评价指标。由于不论是何种分类,其最终达到的目的都是使得“类内数据尽可能的紧密,类间的距离尽可能地大”,根据这个原则,我们提出了常用地四种评价指标。
       下面分别介绍四种评价指标,并举例说明其计算过程:
在这里插入图片描述
       x代表一类文档,o代表一类文档,方框代表一类文档,聚成了3个cluster。

3.1 纯度

       纯度:代表正确聚类地类别数占总类别数地比例。其计算公式如下:

在这里插入图片描述

       其中N代表总类别数, ω k ω_k ωk代表第k个聚类,C代表类别集合, C j C_j Cj表示第j类。其结算结果必然在0~1之间,完全错误时其值为0,完全正确时其值为1。
       根据上述例子,可计算得到其纯度为:
p u r i t y = ( 5 + 4 + 3 ) / 17 = 0.71 purity=(5+4+3)/17=0.71 purity=(5+4+3)/17=0.71

3.2 熵(Entropy)

       对于一个聚类i,首先计算P_ij,P_ij指的是聚类i中的成员属于类j地概率。
在这里插入图片描述

       其中m_i是在聚类i中所有成员地个数,m_ij是聚类i中成员属于j类的个数。
       每个聚类的entropy可以表示为
在这里插入图片描述

       其中L是类的个数,整个聚类划分的entropy为
在这里插入图片描述

       其中K是聚类的数目,m是整个聚类划分所涉及到的成员个数。
       例如上面的例子:
e 1 = − 1 / 6 l o g 2 ( 1 / 6 ) e1=-1/6log2(1/6) e1=1/6log2(1/6)
e 2 = − [ 1 / 6 l o g 2 ( 1 / 6 ) + 1 / 6 l o g 2 ( 1 / 6 ) ] e2=-[1/6log2(1/6)+1/6log2(1/6)] e2=[1/6log2(1/6)+1/6log2(1/6)]
e 3 = 2 / 5 l o g 2 ( 2 / 5 ) e3=2/5log2(2/5) e3=2/5log2(2/5)
       整个聚类划分的
e n t r o p y = ( 6 / 17 ) ∗ e 1 + ( 6 / 17 ) ∗ e 2 + 5 / 17 ∗ e 3 entropy=(6/17)*e1+(6/17)*e2+5/17*e3 entropy=(6/17)e1+(6/17)e2+5/17e3

3.3 兰德指数

R I = ( a + b ) / ( C 2 n ) RI=(a+b)/(C_2^n ) RI=(a+b)/(C2n)
       其中C表示实际类别信息,K表示聚类结果,a表示在C与K中都是同类别的元素对数,b表示在C与K中都是不同类别的元素对数。RI的取值为[0,1],值越大表示聚类结果与真实情况越吻合。
       RI越大表示聚类效果准确性越高 同时每个类内的纯度越高。为了实现“在聚类结果随机产生的情况下,指标应该接近零”,调整兰德系数(Adjusted rand index)被提出,它具有更高的区分度:
A R I = ( R I − E [ R I ] ) / ( m a x ⁡ ( R I ) − E [ R I ] ) ARI=(RI-E[RI])/(max⁡(RI)-E[RI]) ARI=(RIE[RI])/(max(RI)E[RI])
       ARI取值范围为[−1,1],值越大意味着聚类结果与真实情况越吻合。从广义的角度来讲,ARI衡量的是两个数据分布的吻合程度。

3.4 互信息

       互信息指的是两个随机变量之间的关联程度 如下公式计算:
在这里插入图片描述

四、Kmeans算法

4.1 原理概述

       K 均值聚类算法是应用最广泛的基于划分的聚类算法之一,适用于处理大样本数据。它是一种典型的基于相似性度量的方法,目标是根据输入参数 K 将数据集划分为 K 簇。由于初始值、相似度、聚类均值计算策略的不同,因而有很多种 K 均值算法的变种。在数据分布接近球体的情况下,K 均值算法具有较好的聚类效果。
       (1)选取K个初始聚类中心, z 1 ( 1 ) , z 2 ( 1 ) , … , z K ( 1 ) z_1 (1),z_2 (1),…,z_K (1) z1(1)z2(1)zK(1),其中括号内的序号为寻找聚类中心的迭代运算的次序号。聚类中心的向量值可任意设定,例如,可选开始的K个模式样本的向量值作为初始聚类中心。
       (2)根据最小距离标准将要分类的模式样本 X={x}分配给K个簇中心中的某一个 z j ( 1 ) z_j (1) zj(1),则 x 与各聚类中心的最小距离
D i ( t ) = m i n ‖ x − z j ‖ , j = 1 , 2 , ⋯ K D_i (t)=min{‖x-z_j ‖,j=1,2,⋯K} Di(t)=minxzj,j=1,2,K
x ∈ S j ( t ) x∈S_j (t) xSj(t),其中 t 表示迭代次数, S j S_j Sj表示第 j 个聚类簇,囚此其聚类中心是 z j z_j zj
       (3)计算各个聚类中心的新的向量值, z j ( t + 1 ) , j = 1 , 2 , … , K , z_j (t+1),j=1,2,…,K, zj(t+1)j=12K并计算各聚类簇中样本数据的均值向量
在这里插入图片描述
       其中, m j m_j mj为第 j 个聚类簇 S j S_j Sj的样本数目。最终的聚类准则函数为

在这里插入图片描述
       (4)若 z j ( t + 1 ) ≠ z j ( t ) , j = 1 , 2 , … , K , z_j (t+1)≠z_j (t),j=1,2,…,K, zj(t+1)=zj(t)j=12K则返回第二步,逐个重新分类模式样本,重复迭代操作;若 z j ( t + 1 ) = z j ( t ) , j = 1 , 2 , … , K , z_j (t+1)=z_j (t),j=1,2,…,K, zj(t+1)=zj(t)j=12K则算法收敛,计算结束。
在这里插入图片描述

4.2 算法实现:Iris数据集分类

  1. 读入文件,此时数据为字符串类型
  2. 读取的文件类型为字符串,所以需要编写一个从字符串获取我们需要的数据信息的函数
  3. 从读入的数据中创建样本空间向量集合
  4. 随机选取数据集中的K个点作为初始化的K个聚类中心(此问题中K=3)
  5. 计算每个点到各个聚类中心的距离并将其归到距离其最近的类中
  6. 根据归类后的数据重新计算聚类中心
  7. 检测新的聚类中心与上一次是否相同,若相同则说明已经找到目标聚类中心,迭代结束,跳出循环
  8. 判断每个聚类对应的真实标签,与真实标签对照,计算分类准确率并输出

       输出结果:
       12 次迭代后聚类中心: [5.006 3.428 1.462 0.246 5.88360656 2.74098361 4.38852459 1.43442623 6.85384615 3.07692308 5.71538462 2.05384615]
       分类准确率为: 0.8866666666666667
       其分类准确率的变化趋势如图:
在这里插入图片描述

4.3 算法实现:Sonar数据集分类

输出结果:
分类准确率为: 0.5432692307692307
其分类准确率的变化趋势如图:

在这里插入图片描述

五、FCM算法

5.1 原理概述

       K 均值算法属于硬聚类算法,它把数据点划分到确切的某一聚类中。而在模糊聚类亦称软聚类中,数据点则可能归属于不止一个聚类中,并且这些聚类与数据点通过一个成员水平(实际上类似于模糊集合中隶属度的概念)联系起来。成员水平显示了数据点与某一聚类之间的联系很密切。模糊聚类就是计算这些成员水平,按照成员水平来决定数据点属于哪一个或哪些聚类的过程。模糊C均值算法(Fuzzy C-Means,FCM)是模糊聚类算法中使用最广泛的算法之一。
       下面介绍隶属度函数的概念。隶属度函数是描述样本x隶属于集合 A 的程度的函数,记做 μ A ( x ) μ_A (x) μA(x),其自变量范围是所有样本点﹐值域范围为[0,1],即 0 ≤ μ A ( x ) ≤ 1 0≤μ_A (x)≤1 0μA(x)1。在 μ A ( x ) = l μ_A (x)=l μA(x)=l 时,样本 x 完全隶属于集合 A,这种情况相当于硬聚类集合概念中的x∈A。我们用定义在样本空间X={x}上的隶属度函数表示一个模糊
       集合A,或者叫作定义在论域X={x}上的一个模糊子集。对于有限个对象 x 1 , x 2 , ⋯ , x m x_1,x_2,⋯,x_m x1x2xm模糊集合可以表示为:
在这里插入图片描述
       利用模糊集的概念,一个样本隶属于哪一个聚类就不再是硬性的。该样本属于每个聚类的隶属度是区间[0,1]中的值。
       FCM 的目标函数是把m个样本 x i , i = 1 , 2 , … , m {x_i,i=1,2,…,m} xii=12m分为c个模糊集合,并给出每组的聚类中心,使得代价函数的值为最小。这里使用非相似性指标作为代价函数。FCM 加上归一化约束以后﹐样本数据属于所有类的隶属度的和总应等于1:
在这里插入图片描述
       FCM 的目标函数为:

在这里插入图片描述
       这里 u i j u_ij uij介于0,1之间; z j z_j zj为模糊集合 j 的聚类中心; d i j = ‖ c j − x i ‖ d_ij=‖c_j-x_i ‖ dij=cjxi
       为第i个数据与第 j 个聚类中心之间的欧氏距离,这里作为一个加权指数﹔U 为隶属矩阵。
       构建一个新的目标函数,也就是上式达到最小值的必要条件如下:

在这里插入图片描述
       其中,α为柔性参数,由上述两个条件可以看出,FCM 算法是一种简单的迭代算法。实践采用 FCM 确定聚类中心 z,和隶属矩阵 U 的步骤如下:
       (1)对隶属矩阵 U 使思(0;1)之间进行均匀分布的初始化,使其如下约束:
在这里插入图片描述
       (2)计算 c 个聚类中心 z ,j=1…c
       (3)计算代价函数。如果其结果小于某个阈值,或者与上一个成本函数值的变化小于某个阈值,则算法停止。
       (4)计算新的矩阵 U。返回步骤(2)。

5.2 算法实现:Iris数据集分类

       1,读入文件,此时数据为字符串类型
       2,读取的文件类型为字符串,所以需要编写一个从字符串获取我们需要的数据信息的函数
       3,从读入的数据中创建样本空间向量集合
       4,随机初始化数据集中每一个数据对K个聚类蔟的隶属度,组成隶属度矩阵U(此问题中K=3)
       5,根据隶属度矩阵计算K个聚类中心
       6,计算代价函数,并检测新的代价函数值与上一次值的差是否小于10^(-4),若足够小则说明已经找到目标聚类中心和隶属度矩阵,迭代结束,跳出循环。
       7,若未满足终止条件,则根据新的聚类中心更新隶属度矩阵U,继续迭代
       8,若满足终止条件,则跳出循环,判断每个聚类对应的真实标签,与真实标签对照,计算分类准确率并输出

       输出结果:
       20 次迭代后聚类中心: [5.0039648 3.41411326 1.48277577 0.25352849 6.77441494 3.05220857 5.64603834 2.05325944 5.88843895 2.76089151 4.36323081 1.39694357]
       第1蔟的实际标签为:0 第2蔟的实际标签为:2 第3蔟的实际标签为:1
       归1分类准确率为: 0.8933333333333333
       模糊分类准确率为: 0.8250662641523535

5.3 算法实现:Sonar数据集分类

       输出结果:
       第1蔟的实际标签为:0 第2蔟的实际标签为:1
       归1分类准确率为: 0.5528846153846154
       模糊分类准确率为: 0.5193918960896884

六、Kmeans算法在图像分割上的应用

       导入sklearn库中的图片,如图所示:
在这里插入图片描述
       其大小为:(768, 1024, 3),将其表现为矩阵格式:
在这里插入图片描述
       由于含有三个通道,所以我们选择其中一个通道来进行kmeans算法的应用,其第一个通道显示如图:
在这里插入图片描述
       分别选用K=2,3,5来对图像进行分割,并分别将原图像灰度化和分割后的图像灰度化,并将其进行对比:
                                                                      k=2
在这里插入图片描述
                                                                      k=3
在这里插入图片描述
                                                                      k=5
在这里插入图片描述
       将图像灰度化:
                                                                      k=2
在这里插入图片描述
                                                                      k=3
在这里插入图片描述
                                                                      k=5
在这里插入图片描述

文章的pdf文件:link

七、python代码

7.1 kmeans-Iris

import numpy as np
import numpy.linalg as lg
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random
import copy
# ---------------------------------读入文件---------------------------------------
path = r'bezdekIris.data'
f = open(path, 'r')
data = f.read()
data = data.split()
# ---------------------------------从str获取信息的函数-----------------------------
def get_data(datastr):
    species = {'Iris-setosa': 0, 'Iris-versicolor': 1, 'Iris-virginica': 2}
    datastr = datastr.split(',')
    data_part = list(map(float, datastr[:4]))
    label_part = species[datastr[4]]

    data_part = np.array(data_part)
    return data_part, label_part
# ---------------------------------创建样本空间向量集合----------------------------
Iris_data_list = []
Iris_label_list = []
for iris in data:
    iris_data, iris_label = get_data(iris)
    Iris_data_list.append(iris_data)
    Iris_label_list.append(iris_label)
# ----------------------------------初始化K个聚类中心-----------------------------
K = 3  # 聚类中心个数
z = []  # 存放K个聚类中心
while True:
    newz = random.choice(Iris_data_list)
    same_flag = False
    for i in z:
        if (i == newz).all():
            same_flag = True
    if not same_flag:
        z.append(newz)
    if len(z) == K:
        break
assert len(z) == K
print("初始聚类中心:", z)
# -----------------------------------迭代------------------------------------------
iterations_num = 0  # 迭代次数计数器
while True:
    z_old = copy.copy(z)
    clusters = [[] for i in range(K)]  # K个聚类蔟中包含的点
    for i in range(len(Iris_data_list)):
        distance = []  # 该点到K个中心的距离表
        for j in range(K):
            distance.append(lg.norm(Iris_data_list[i] - z[j]))
        nearest_zpoint = distance.index(min(distance))  # 找出距离其最近的聚类中心
        clusters[nearest_zpoint].append(i)
    same_flag = True
    for i in range(K):
        cluster_mean = np.zeros(len(z[i]))
        for j in range(len(clusters[i])):
            cluster_mean += Iris_data_list[clusters[i][j]]/len(clusters[i])
        z[i] = cluster_mean
        if (z[i] != z_old[i]).all():
            same_flag = False
    iterations_num += 1
    print(iterations_num, "次迭代后聚类中心:", '\n', z[0], '\n', z[1], '\n', z[2])
    # 计算分类准确率
    clusters_labels = []
    accuracy = 0
    for i in range(K):
        label_list = []
        for j in range(len(clusters[i])):
            label_list.append(Iris_label_list[clusters[i][j]])
        true_label = []
        for j in range(K):
            true_label.append(label_list.count(j))
        accuracy += max(true_label)  # 选取数量最大的标签作为其标签
        print(true_label.index(max(true_label)), end=' ')
        clusters_labels.append(true_label.index(max(true_label)))
    accuracy = accuracy/len(Iris_label_list)
    print("分类准确率为:", accuracy)
    if same_flag:
        if len(set(clusters_labels)) == K:
            print('已找到聚类结果')
        else:
            print('聚类结果错误!')
        break

7.2 kmeans-Sonar

import numpy as np
import numpy.linalg as lg
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random
import copy
# ---------------------------------读入文件---------------------------------------
path = r'sonar.all-data'
f = open(path, 'r')
data = f.read()
data = data.split()

# ---------------------------------从str获取信息的函数-----------------------------
def get_data(datastr):
    species = {'R': 0, 'M': 1}
    datastr = datastr.split(',')
    data_part = list(map(float, datastr[:60]))
    label_part = species[datastr[60]]
    data_part = np.array(data_part)
    return data_part, label_part
# ---------------------------------创建样本空间向量集合----------------------------
Sonar_data_list = []
Sonar_label_list = []
for sonar in data:
    sonar_data, sonar_label = get_data(sonar)
    Sonar_data_list.append(sonar_data)
    Sonar_label_list.append(sonar_label)
# ----------------------------------初始化K个聚类中心-----------------------------
K = 2  # 聚类中心个数
z = []  # 存放K个聚类中心
while True:
    newz = random.choice(Sonar_data_list)
    same_flag = False
    for i in z:
        if (i == newz).all():
            same_flag = True
    if not same_flag:
        z.append(newz)
    if len(z) == K:
        break
assert len(z) == K
print("初始聚类中心:", z)
# -----------------------------------迭代------------------------------------------
iterations_num = 0  # 迭代次数计数器
while True:
    z_old = copy.copy(z)
    clusters = [[] for i in range(K)]  # K个聚类蔟中包含的点
    for i in range(len(Sonar_data_list)):
        distance = []  # 该点到K个中心的距离表
        for j in range(K):
            distance.append(lg.norm(Sonar_data_list[i] - z[j]))
        nearest_zpoint = distance.index(min(distance))  # 找出距离其最近的聚类中心
        clusters[nearest_zpoint].append(i)
    same_flag = True
    for i in range(K):
        cluster_mean = np.zeros(len(z[i]))
        for j in range(len(clusters[i])):
            cluster_mean += Sonar_data_list[clusters[i][j]]/len(clusters[i])
        z[i] = cluster_mean
        if (z[i] != z_old[i]).all():
            same_flag = False
    iterations_num += 1
    print(iterations_num, "次迭代后聚类中心:", '\n', z[0], '\n', z[1])
    # 计算分类准确率
    accuracy = 0
    for i in range(K):
        label_list = []
        for j in range(len(clusters[i])):
            label_list.append(Sonar_label_list[clusters[i][j]])
        true_label = []
        for j in range(K):
            true_label.append(label_list.count(j))
        accuracy += max(true_label)  # 选取数量最大的标签作为其标签
        print(true_label.index(max(true_label)), end=' ')
    accuracy = accuracy/len(Sonar_label_list)
    print("分类准确率为:", accuracy)
    if same_flag:
        print('已找到聚类结果')
        break

7.3 FCM-Iris

import numpy as np
import numpy.linalg as lg
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random
import copy
# ---------------------------------读入文件---------------------------------------
path = r'bezdekIris.data'
f = open(path, 'r')
data = f.read()
data = data.split()
# ---------------------------------从str获取信息的函数-----------------------------
def get_data(datastr):
    species = {'Iris-setosa': 0, 'Iris-versicolor': 1, 'Iris-virginica': 2}
    datastr = datastr.split(',')
    data_part = list(map(float, datastr[:4]))
    label_part = species[datastr[4]]

    data_part = np.array(data_part)
    return data_part, label_part
# ---------------------------------创建样本空间向量集合----------------------------
Iris_data_list = []
Iris_label_list = []
for iris in data:
    iris_data, iris_label = get_data(iris)
    Iris_data_list.append(iris_data)
    Iris_label_list.append(iris_label)
# ----------------------------------初始化K个聚类中心-----------------------------
K = 3  # 聚类中心个数
z = [0, 0, 0]  # 存放K个聚类中心
# ----------------------------------初始化隶属矩阵U-------------------------------
U = np.random.rand(len(Iris_data_list), K)
for i in range(len(Iris_data_list)):
    U[i] = U[i]/sum(U[i])
# -----------------------------------迭代------------------------------------------
J = 0
a = 2  # 柔性参数
iterations_num = 0  # 迭代次数计数器
while True:
    z_old = copy.copy(z)
    U_old = copy.copy(U)
    J_old = J
    # 计算新聚类中心
    for j in range(K):
        sum_ux = 0
        sum_u = 0
        for i in range(len(Iris_data_list)):
            sum_ux += (U[i][j]**a) * Iris_data_list[i]
            sum_u += U[i][j]**a
        z[j] = sum_ux/sum_u
    iterations_num += 1
    print(iterations_num, "次迭代后聚类中心:", '\n', z[0], '\n', z[1], '\n', z[2])
    # 计算代价函数
    J = 0
    for j in range(K):
        for i in range(len(Iris_data_list)):
            J += (U[i][j]**a) * (lg.norm(z[j]-Iris_data_list[i])**2)
    # 终止条件
    if abs(J - J_old) < 0.0001:
        break
    # 计算新矩阵U
    for i in range(len(Iris_data_list)):
        for j in range(K):
            sum_ud = 0
            for k in range(K):
                sum_ud += ((lg.norm(z[j]-Iris_data_list[i])) / (lg.norm(z[k]-Iris_data_list[i]))) ** (2/(a-1))
            U[i][j] = 1/sum_ud
# 计算第几蔟的实际标签是什么
label_order = []
for i in range(K):
    K_list = [0]*K
    for j in range(len(Iris_data_list)):
        if np.argmax(U[j]) == i:
            K_list[Iris_label_list[j]] += 1
    label_order.append(K_list.index(max(K_list)))
assert len(set(label_order)) == K, '出现了两类相同蔟!'
# 输出判断结果
for i in range(K):
    print('第{}蔟的实际标签为:{}'.format(i+1, label_order[i]), end='  ')
print()
# 计算实际标签对应的是第几蔟
un_label_order = [0]*K
for i in range(K):
    un_label_order[label_order[i]] = i
accuracy1 = 0
for i in range(len(Iris_data_list)):
    if U[i][un_label_order[Iris_label_list[i]]] == max(U[i]):
        accuracy1 += 1
accuracy1 /= len(Iris_data_list)
print("归1分类准确率为:", accuracy1)
accuracy2 = 0
for i in range(len(Iris_data_list)):
    accuracy2 += U[i][un_label_order[Iris_label_list[i]]]
accuracy2 /= len(Iris_data_list)
print("模糊分类准确率为:", accuracy2)

7.4 FCM-Sonar

import numpy as np
import numpy.linalg as lg
import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import random
import copy
# ---------------------------------读入文件---------------------------------------
path = r'sonar.all-data'
f = open(path, 'r')
data = f.read()
data = data.split()
# ---------------------------------从str获取信息的函数-----------------------------
def get_data(datastr):
    species = {'R': 0, 'M': 1}
    datastr = datastr.split(',')
    data_part = list(map(float, datastr[:60]))
    label_part = species[datastr[60]]
    data_part = np.array(data_part)
    return data_part, label_part
# ---------------------------------创建样本空间向量集合----------------------------
Sonar_data_list = []
Sonar_label_list = []
for sonar in data:
    sonar_data, iris_label = get_data(sonar)
    Sonar_data_list.append(sonar_data)
    Sonar_label_list.append(iris_label)
# ---------------------------------初始化K个聚类中心------------------------------
K = 2  # 聚类中心个数
z = [0, 0]  # 存放K个聚类中心
# ----------------------------------初始化隶属矩阵U-------------------------------
U = np.random.rand(len(Sonar_data_list), K)
for i in range(len(Sonar_data_list)):
    U[i] = U[i]/sum(U[i])
# -----------------------------------迭代------------------------------------------
J = 0
a = 2  # 柔性参数
iterations_num = 0  # 迭代次数计数器
while True:
    z_old = copy.copy(z)
    U_old = copy.copy(U)
    J_old = J
    # 计算新聚类中心
    for j in range(K):
        sum_ux = 0
        sum_u = 0
        for i in range(len(Sonar_data_list)):
            sum_ux += (U[i][j]**a) * Sonar_data_list[i]
            sum_u += U[i][j]**a
        z[j] = sum_ux/sum_u
    iterations_num += 1
    print(iterations_num, "次迭代后聚类中心:", '\n', z[0], '\n', z[1])
    # 计算代价函数
    J = 0
    for j in range(K):
        for i in range(len(Sonar_data_list)):
            J += (U[i][j]**a) * (lg.norm(z[j]-Sonar_data_list[i])**2)
    # 终止条件
    if abs(J - J_old) < 0.0001:
        break
    # 计算新矩阵U
    for i in range(len(Sonar_data_list)):
        for j in range(K):
            sum_ud = 0
            for k in range(K):
                sum_ud += ((lg.norm(z[j]-Sonar_data_list[i])) / (lg.norm(z[k]-Sonar_data_list[i]))) ** (2/(a-1))
            U[i][j] = 1/sum_ud
# 计算第几蔟的实际标签是什么
label_order = []
for i in range(K):
    K_list = [0]*K
    for j in range(len(Sonar_data_list)):
        if np.argmax(U[j]) == i:
            K_list[Sonar_label_list[j]] += 1
    label_order.append(K_list.index(max(K_list)))
assert len(set(label_order)) == K, '出现了两类相同蔟!'
# 输出判断结果
for i in range(K):
    print('第{}蔟的实际标签为:{}'.format(i+1, label_order[i]), end='  ')
print()
# 计算实际标签对应的是第几蔟
un_label_order = [0]*K
for i in range(K):
    un_label_order[label_order[i]] = i
accuracy1 = 0
for i in range(len(Sonar_data_list)):
    if U[i][un_label_order[Sonar_label_list[i]]] == max(U[i]):
        accuracy1 += 1
accuracy1 /= len(Sonar_data_list)
print("归1分类准确率为:", accuracy1)
accuracy2 = 0
for i in range(len(Sonar_data_list)):
    accuracy2 += U[i][un_label_order[Sonar_label_list[i]]]
accuracy2 /= len(Sonar_data_list)
print("模糊分类准确率为:", accuracy2)

7.5 kmeans-图像分割

from scipy import misc
from sklearn.cluster import Kmeans
face = misc.face()
print(face.shape)
plt.subplot()
plt.imshow(face)
# 分别展示三个通道下的图片
print(face[:,:,0])
print(face[:,:,1])
print(face[:,:,2])
plt.figure(1)
plt.imshow(face[:,:,0])
plt.figure(2)
plt.imshow(face[:,:,1])
plt.figure(3)
plt.imshow(face[:,:,2])
a=face[:,:,1]
image=a.ravel()
print(image.shape)
image.resize(len(image),1)
print(image.shape)
kmeans = KMeans(n_clusters=2)
kmeans.fit(image)#进行聚类
pre = kmeans.predict(image)
pre.resize(768,1024)

plt.figure(1)
plt.subplot(1,2,1)
plt.imshow(a)
plt.subplot(1,2,2)
plt.imshow(pre)

plt.figure(2)
plt.subplot(1,2,1)
plt.imshow(a,cmap=plt.cm.gray)
plt.subplot(1,2,2)
plt.imshow(pre,cmap=plt.cm.gray)
kmeans = KMeans(n_clusters=3)
kmeans.fit(image)#进行聚类
pre = kmeans.predict(image)
pre.resize(768,1024)

plt.figure(1)
plt.subplot(1,2,1)
plt.imshow(a)
plt.subplot(1,2,2)
plt.imshow(pre)

plt.figure(2)
plt.subplot(1,2,1)
plt.imshow(a,cmap=plt.cm.gray)
plt.subplot(1,2,2)
plt.imshow(pre,cmap=plt.cm.gray)

kmeans = KMeans(n_clusters=5)
kmeans.fit(image)#进行聚类
pre = kmeans.predict(image)
pre.resize(768,1024)

plt.figure(1)
plt.subplot(1,2,1)
plt.imshow(a)
plt.subplot(1,2,2)
plt.imshow(pre)

plt.figure(2)
plt.subplot(1,2,1)
plt.imshow(a,cmap=plt.cm.gray)
plt.subplot(1,2,2)
plt.imshow(pre,cmap=plt.cm.gray)
  • 12
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值