K均值算法


机器学习实验
采用K均值算法对样本进行聚类

一、选取([3, 3], [6, 2], [8, 5])三个点作为初始聚类中心

1、源代码

import pandas as pd
import numpy as np
import scipy.io as scio
import matplotlib.pyplot as plt

if __name__ == '__main__':
    data = scio.loadmat('ex7data2.mat')
    D = data['X']

    k=3
    avg_vec=[[3, 3], [6, 2], [8, 5]]  #均值向量
    center=[[[3,3]],[[6,2]],[[8,5]]]  #聚类中心点

    for times in range(0,10):
        C = []
        for i in range(0, k):
            C.append([])
        for j in range(0,len(D)):   #计算样本与均值向量的距离,加入距离最小的簇
            min_d=0 #最短距离
            min_sign=0    #簇标记
            for i in range(0,k):
                d= ((D[j][0] - avg_vec[i][0]) ** 2 + (D[j][1] - avg_vec[i][1]) ** 2) ** 0.5
                if i==0:
                    min_d=d
                    min_sign=i
                else:
                    if d<min_d:
                        min_d=d
                        min_sign=i
            C[min_sign].append(D[j])
        for i in range(0,k):    #计算新均值向量
            new_vec=[]
            for j in range(0,2):
                new_vec_value=0
                for m in range(0,len(C[i])):
                    new_vec_value+=C[i][m][j]
                new_vec_value/=len(C[i])
                new_vec.append(new_vec_value)
            for pos in range(0,2):
                if new_vec[pos]!=avg_vec[i][pos]:   #更新均值向量
                    avg_vec[i]=new_vec
            center[i].append(new_vec)   #记录每次迭代的聚类中心点


    #画图
    plt.title('EXP5', fontsize=20)
    plt.xlabel('x', fontsize=10)
    plt.ylabel('y', fontsize=10)
    for i in range(0,k):
        X=[]
        Y=[]
        for j in range(0,len(C[i])):
            X.append(C[i][j][0])
            Y.append(C[i][j][1])
        if i==0:
            plt.plot(X, Y, 'o', c='red', markersize=6)
        elif i==1:
            plt.plot(X, Y, 'o', c='green', markersize=6)
        else:
            plt.plot(X, Y, 'o', c='blue', markersize=6)
        #画聚类中心点折线图
        plt.plot([item[0] for item in center[i]],[item[1] for item in center[i]],c='black',marker='x')

    plt.show()

2、实验结果

在这里插入图片描述

二、随机取初始聚类中心点

1、源代码

import pandas as pd
import numpy as np
import scipy.io as scio
import matplotlib.pyplot as plt

if __name__ == '__main__':
    data = scio.loadmat('ex7data2.mat')
    D = data['X']

    k=3
    avg_vec=[]  #均值向量
    for i in np.random.randint(0,len(D),k):     #从D中随机选择k个样本作为初始均值向量
        avg_vec.append(D[i])

    while True:
        C=[]
        for i in range(0,k):
            C.append([])
        for j in range(0,len(D)):   #计算样本与均值向量的距离,加入距离最小的簇
            min_d=0 #最短距离
            min_sign=0    #簇标记
            for i in range(0,k):
                d= ((D[j][0] - avg_vec[i][0]) ** 2 + (D[j][1] - avg_vec[i][1]) ** 2) ** 0.5
                if i==0:
                    min_d=d
                    min_sign=i
                else:
                    if d<min_d:
                        min_d=d
                        min_sign=i
            C[min_sign].append(D[j])
        change=False    #判断均值向量是否更新
        for i in range(0,k):    #计算新均值向量
            new_vec=[]
            for j in range(0,2):
                new_vec_value=0
                for m in range(0,len(C[i])):
                    new_vec_value+=C[i][m][j]
                new_vec_value/=len(C[i])
                new_vec.append(new_vec_value)
            for pos in range(0,2):
                if new_vec[pos]!=avg_vec[i][pos]:   #更新均值向量
                    avg_vec[i]=new_vec
                    change=True

        if not change:  #收敛,退出循环
            break

    #画图
    plt.title('EXP5', fontsize=20)
    plt.xlabel('x', fontsize=10)
    plt.ylabel('y', fontsize=10)

    for i in range(0,k):
        X=[]
        Y=[]
        for j in range(0,len(C[i])):
            X.append(C[i][j][0])
            Y.append(C[i][j][1])
        if i==0:
            plt.plot(X, Y, 'o', c='blue', markersize=6)
        elif i==1:
            plt.plot(X, Y, 'o', c='red', markersize=6)
        else:
            plt.plot(X, Y, 'o', c='green', markersize=6)
    for i in range(0, k):   #画聚类中心点
        plt.plot([avg_vec[i][0]],[avg_vec[i][1]],'x',c='black',markersize=15)
    plt.show()

2、实验结果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值