当前位置:   article > 正文

机器学习之无监督学习-K均值聚类算法_从各子图可以看出,经过多次求均值更新质心,多次把点分配到距离最近的质

从各子图可以看出,经过多次求均值更新质心,多次把点分配到距离最近的质

机器学习之无监督学习-K均值聚类算法

对于无监督学习,有两类重要的应用,一个是聚类,一个是降维。我们今天主要学习聚类中的K均值聚类。

我们先看看下图,图a为原始的数据点,我们想要对图a的数据点进行分类,在图b中我们先随机的指定两个质心点(×)作为初始点。如图c所示,距离红色点(×)近的我们分到红色类中,距离蓝色点(×)近的我们分类到蓝色类中。接下来我们更新质心点,如图d所示,根据已有红色的点,求均值,得到它们中间的质心点,更新为当前红色质心点,根据已有蓝色的点,求均值,得到它们中间的质心点,更新为当前蓝色的质心点。接下来如图e所示,再进行红色和蓝色数据点的划分,如图f所示,如此不停的迭代。
在这里插入图片描述
K均值聚类是聚类算法中最简单,最高效的,属于无监督学习方法,核心思想是:用户初始指定K个质心,以作为聚类的类别,重复迭代直至算法收敛。

基本算法流程如下:
1-选取K个初始的质心,作为初始的类别
2-对于每个样本点,计算得到距离其最近的质心,将该样本点对应的类别标记为质心所对应的类别
3-根据当前划分的类别情况,计算并更新K个类别对应的质心
4-直到质心不再发生变化或者达到迭代上限

下面我们具体实现K均值聚类算法,代码如下:

#K均值聚类算法实现
import numpy as np
import matplotlib.pyplot as plt

#从sklearn中直接生成聚类数据
from sklearn.datasets._samples_generator import make_blobs

#数据加载和处理,100个样本点,x为100行的,2列的矩阵
x, y = make_blobs(n_samples=100, centers=6, random_state=1234, cluster_std=0.6)
#画出散点图
#plt.figure(figsize=(6,6))
plt.scatter(x[:,0],x[:,1],c=y)
plt.show()

#算法实现
#引入scipy的距离函数,默认为欧式距离
from scipy.spatial.distance import cdist

class K_means(object):
    #初始化n_clusters,就是我们认为的K,迭代上限max_iter,初始质心centroids
    def __init__(self, n_clusters=6, max_iter=300, centroids=[]):
        self.n_clusters = n_clusters
        self.max_iter = max_iter
        self.centroids = np.array(centroids, np.float64) #数组转矩阵

    #训练模型的方法,K均值聚类过程,传入原始数据
    def fit(self, data):
        #假如没有指定初始质心,就随机选取data中的点作为初始质心
        if(self.centroids.shape == (0,)):
            #从data中随机生成0到data行数的6个整数,作为索引值
            self.centroids = data[np.random.randint(0, data.shape[0], self.n_clusters), :]

        #开始迭代
        for i in range(self.max_iter):
            #1.计算距离矩阵,得到是一个100*6的矩阵
            distance = cdist(data, self.centroids)
            #2.对距离按由近到远排序,选取距离质心点最近的类别,作为当点的分类
            c_ind = np.argmin(distance, axis=1)
            #3.对每一类进行均值计算,更新质心点坐标
            for i in range(self.n_clusters):
                #排除掉没有出现c_ind里面的类别
                if i in c_ind:
                    #选出所有类别为i的点,取data里面坐标的均值,更新第i个质心
                    self.centroids[i] = np.mean(data[c_ind==i], axis=0)
    #实现预测方法
    def predict(self, samples):
        #先计算距离矩阵,选取距离最近的质心类别
        distance = cdist(samples, self.centroids)
        c_ind = np.argmin(distance, axis=1)
        return c_ind

#测试
#定义一个绘制子图的函数
def plotKMeans(x, y, centroids, subplot, title):
    #分配子图,121表示第一行二列的子图的第一个
    plt.subplot(subplot)
    plt.scatter(x[:,0], x[:,1], c='r')
    #画出质心点
    plt.scatter(centroids[:,0], centroids[:,1], c=np.array(range(6)), s=100)
    plt.title(title)

kmeans = K_means(max_iter=300, centroids=np.array([[2,1],[2,2],[2,3],[2,4],[2,5],[2,6]]))
plt.figure(figsize=(16, 6))
plotKMeans(x, y, kmeans.centroids, 121, 'Initial State ')

#开始聚类
kmeans.fit(x)
plotKMeans(x, y,kmeans.centroids, 122, 'Final State')

#预测新数据点的类别
x_new = np.array([[0,0], [10,7]])
y_pred = kmeans.predict(x_new)
print(kmeans.centroids)
print(y_pred)

plt.scatter(x_new[:,0],x_new[:,1], s=100, c='black')
plt.show()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

这幅图是调用原始数据集画出的6个聚类的散点图。当然这个不用管,主要看下面几幅图。
在这里插入图片描述

这个是利用原始数据集生成的100个红色样本点和随机生成的6个初始质心点。对于每个样本点,计算得到距离其最近的质心,将该样本点对应的类别标记为质心所对应的类别
在这里插入图片描述

通过聚类算法将红色样本点对应的类别标记为质心所对应的类别。
在这里插入图片描述

定义两个黑色的样本点进行预测,预测该样本点的分类情况 。
在这里插入图片描述

预测结果如下,一共0-5,共6类,两个样本点(0,0)和(10,7)分别属于第1类和第5类。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/320855
推荐阅读
相关标签
  

闽ICP备14008679号