赞
踩
对于无监督学习,有两类重要的应用,一个是聚类,一个是降维。我们今天主要学习聚类中的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类。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。