栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python手撸机器学习系列(七):聚类(Kmeans)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python手撸机器学习系列(七):聚类(Kmeans)

聚类

聚类算法,一般情况下将给定的数据集划分为若干个不相交的子集,每个子集称为一个簇,即将数据集划分为几类。在这种情况下,可能会对一些潜在的概念进行划分,用周志华《机器学习》中的话来讲,聚类算法可能会将原本的西瓜数据集潜在地划分为浅色瓜、深色瓜、有籽瓜、无籽瓜等,虽然你原本将其分为好瓜和坏瓜。值得注意的是,这些概念对于聚类算法而言是事先未知的,即聚类算法会自动地把数据集划分为簇结构,每个簇的名称和含义需要使用者来命名和把握。

一、Kmeans聚类 1.1 原理

属于原型聚类的一种,较为简单给。定样本集 D = { x 1 , x 2 , . . . , x m } D={x_1,x_2,...,x_m} D={x1​,x2​,...,xm​},对于聚类,可以划分为簇 C = { C 1 , C 2 , . . , C k } C = {C_1,C_2,..,C_k} C={C1​,C2​,..,Ck​},即将原数据划分为 k k k类,然后最小化平方误差:
E = ∑ i = 1 k ∑ x ∈ C i ∣ ∣ x − μ i ∣ ∣ 2 2 large E =displaystylesum_{i=1}^kdisplaystylesum_{xin C_i}||x-mu_i||^2_2 E=i=1∑k​x∈Ci​∑​∣∣x−μi​∣∣22​
其中 μ i = 1 ∣ C i ∣ ∑ x ∈ C i x large mu_i=frac{1}{|C_i|}sum_{xin C_i}x μi​=∣Ci​∣1​∑x∈Ci​​x是簇 C i C_i Ci​的均值向量

上述公式不好求解,一般我们通过迭代的方式近视化求解,大致过程如下:

  1. 从数据集 D D D中随机选取 k k k个样本作为 k k k个簇的初始均值(簇中心)
  2. 计算每个样本跟每个簇均值的距离,将样本放入距离最近的簇中
  3. 根据每个簇中的样本,重新计算每个簇的均值
  4. 判断,如果新的均值等于之前的均值,则停止迭代,否者以新均值继续循环2-3
  5. 查看最后结果绘图

即根据每个簇的均值不断构建新的簇来迭代,直到每个簇的均值不变为止。

1.2 代码实现

使用了周志华《机器学习》p202表9.1西瓜数据集4.0,已经处理成CSV格式,请自取:

https://pan.baidu.com/s/1ecLAbe_ZP75u1h7Ig9KVRw
提取码:c2sh

数据集预览(共计30条,此处略去):

代码实现:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = pd.read_csv('xigua3.0.csv')
feature = ['密度','含糖率']
data = data[feature]

K = 3
#随机选取簇初始化
C_list = data.sample(K).values
data = data.values
while True:
    cur_cluster = [[] for _ in range(K)] #用于存储每个簇的元素
    for i in range(len(data)):
        choose = {} #字典形式存放每个元素对于每个簇的距离,以此来判断该放入哪个簇
        for j in range(K):
            diff = np.mean((data[i]-C_list[j])**2)
            choose[j] = diff
        choose = sorted(choose.items(),key=lambda kv:(kv[1],kv[0]))
        cur_cluster[choose[0][0]].append(data[i]) #将元素放入对应簇
    flag = True#用于判断是否结束循环

    #计算每个簇的均值并置为新的中心点,若均值与之前相等则结束循环
    for i in range(K):
        c = np.mean(cur_cluster[i],axis=0)
        for j in range(c.shape[0]):
            if c[j] != C_list[i][j]:
                flag = False
                C_list[i] = c
                break
    if flag:
        break

color = np.random.random((3,K)) #随机颜色

#得到最终的分类结果并绘图
for i in range(K):
    C = cur_cluster[i] #每一簇的元素
    x = [i[1] for i in C]
    y = [i[0] for i in C]
    plt.scatter(x,y,c = color[i],label = 'C'+str(i)) #随机颜色
plt.legend()
plt.xlabel('midu')
plt.ylabel('hantang')
plt.show()

最终结果:
注意,由于每次抽取的初始样本不同,所以每次运行的结果也不相同

注意,由于每次抽取的初始样本不同,所以每次运行的结果也不相同

如果有兴趣,可以自行存储每一个迭代过程的聚类情况绘图,这里不再赘述

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/656534.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号