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

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习之无监督学习-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()

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

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

通过聚类算法将红色样本点对应的类别标记为质心所对应的类别。

定义两个黑色的样本点进行预测,预测该样本点的分类情况 。

预测结果如下,一共0-5,共6类,两个样本点(0,0)和(10,7)分别属于第1类和第5类。

以上是关于机器学习之无监督学习-K均值聚类算法的主要内容,如果未能解决你的问题,请参考以下文章

机器学习之聚类

机器学习之聚类算法——K-Means算法

机器学习之K-Means聚类(python手写实现+使用Silhouette Coefficient来选取最优k值)

[机器学习][K-Means] 无监督学习之K均值聚类

机器学习之K-means算法

《机器学习实战》之K均值聚类--基于Python3