对于有监督学习,我们知道其训练数据形式为\(T=\left \{ (x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),\cdots ,(x^{(n)},y^{(n)})\right \}\),其中,\(x\)表示样本实例,\(y\)表示样本所属类别。而对于无监督学习,训练数据不提供对应的类别,训练数据形式为\(T=\left \{ (x^{(1)}),(x^{(2)}),\cdots ,(x^{(n)})\right \}\)。这里,对无监督的聚类算法K-Means进行总结。

1 K-Means原理

K-Means作为聚类算法是如何完成聚类的呢?正如其算法名称,\(K\)表示簇的个数,Means表示均值。(注: 在聚类中,把数据所在的集合称为簇)。K-Means算法的基本思想是将训练数据集按照各个样本到聚类中心的距离分配到距离较近的\(K\)个簇中,然后计算每个簇中样本的平均位置,将聚类中心移动到该位置。

根据上面K-Means算法的基本思想,K-Means算法可以总结成两步:
- 簇分配:样本分配到距离较近的簇
- 移动聚类中心:将聚类中心移动到簇中样本平均值的位置

假设有\(K\)个簇\((C_{1},C_{2},\cdots ,C_{k})\),样本距离簇类中心的距离的表达式为:
\[\sum_{i=1}^{k}\sum_{x\epsilon C_{i}}\left \| x-\mu _{i} \right \|^{2}\]
其中\(C_{i}\)是第1到\(K\)个最接近样本\(x\)的聚类中心,\(\mu _{i}\)是该簇\(C_{i}\)中所有样本点的均值组成的向量。\(\mu _{i}\)的表达式为:
\[\mu _{i}=\frac{1}{|C_{i}|}\sum_{x\epsilon C_{i}}x\]
举例,如何计算\(\mu _{2}\)的聚类中心?假设被分配到了聚类中心2的4个样本有:\(x^{(1)}\),\(x^{(5)}\),\(x^{(6)}\),\(x^{(10)}\),也就是\(C_{(1)}=2\),\(C_{(5)}=2\),\(C_{(6)}=2\),\(C_{(10)}=2\)
\[\mu _{2}=\frac{1}{4}\left [ x^{(1)}+x^{(5)}+x^{(6)}+x^{(10)} \right ]\epsilon \mathbb{R}^{n}\] \(n\)表示样本的特征个数。

2 K-Means算法

K-Means算法: 簇分配和移动聚类中心

输入: \(T=\left \{ x^{(1)},x^{(2)},\cdots ,x^{(m)} \right \}\),\(K\)

step1 随机初始化\(K\)个聚类中心\(\mu _{1},\mu _{2},\cdots ,\mu _{k}\epsilon \mathbb{R}^{n}\)

step2 计算各个样本点到聚类中心的距离,如果样本距离第\(i\)个聚类中心更近,将其分配到第\(i\)簇

step3 计算每个簇中所有样本点的平均位置,将聚类中心移动到该位置

step4 重复2-3直至各个聚类中心的位置不再发生变化

3 K-Means代码实现

簇分配+移动聚类中心


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat#簇分配 将每一个训练样本分配给最接近的簇中心
def findClosestCentroids(X, centroids):"""output a one-dimensional array idx that holds theindex of the closest centroid to every training example."""idx = []max_dist = 1000000  # 限制一下最大距离for i in range(len(X)):minus = X[i] - centroids  # here use numpy's broadcastingdist = minus[:,0]**2 + minus[:,1]**2if dist.min() < max_dist:ci = np.argmin(dist)idx.append(ci)return np.array(idx)mat = loadmat('D:/Python/Andrew-NG-Meachine-Learning/machine-learning-ex7/ex7/ex7data2.mat')
X = mat['X']
#print(X.shape)  #(300, 2)
init_centroids = np.array([[3, 3], [6, 2], [8, 5]]) #自定义一个centroids,[3, 3], [6, 2], [8, 5]
idx = findClosestCentroids(X, init_centroids)
#print(idx) #[0 2 1 ..., 1 1 0]
#print(idx.shape) #(300,)
print(idx[0:3])   #[0 2 1]  计算idx[0:3] 也就是前三个样本所属簇的索引或者序号#移动聚类中心 重新计算每个簇中心—这个簇中所有点位置的平均值  def computeCentroids(X, idx):centroids = []for i in range(len(np.unique(idx))):  # np.unique() means Ku_k = X[idx==i].mean(axis=0)  # 求每列的平均值centroids.append(u_k)return np.array(centroids)print(computeCentroids(X, idx))#输出[[ 2.42830111  3.15792418]
[ 5.81350331  2.63365645]
[ 7.11938687  3.6166844 ]]#kmeans on an example dataset
def plotData(X, centroids, idx=None):"""可视化数据,并自动分开着色。idx: 最后一次迭代生成的idx向量,存储每个样本分配的簇中心点的值centroids: 包含每次中心点历史记录"""colors = ['b','g','gold','darkorange','salmon','olivedrab','maroon', 'navy', 'sienna', 'tomato', 'lightgray', 'gainsboro''coral', 'aliceblue', 'dimgray', 'mintcream', 'mintcream']assert len(centroids[0]) <= len(colors), 'colors not enough 'subX = []  # 分号类的样本点if idx is not None:for i in range(centroids[0].shape[0]):x_i = X[idx == i]subX.append(x_i)else:subX = [X]  # 将X转化为一个元素的列表,每个元素为每个簇的样本集,方便下方绘图# 分别画出每个簇的点,并着不同的颜色plt.figure(figsize=(8,5))    for i in range(len(subX)):xx = subX[i]plt.scatter(xx[:,0], xx[:,1], c=colors[i], label='Cluster %d'%i)plt.legend()plt.grid(True)plt.xlabel('x1',fontsize=14)plt.ylabel('x2',fontsize=14)plt.title('Plot of X Points',fontsize=16)# 画出簇中心点的移动轨迹xx, yy = [], []for centroid in centroids:xx.append(centroid[:,0])yy.append(centroid[:,1])plt.plot(xx, yy, 'rx--', markersize=8)plotData(X, [init_centroids])

运行效果:

查看聚类中心移动效果


def runKmeans(X, centroids, max_iters):K = len(centroids)centroids_all = []centroids_all.append(centroids)centroid_i = centroidsfor i in range(max_iters):idx = findClosestCentroids(X, centroid_i)centroid_i = computeCentroids(X, idx)centroids_all.append(centroid_i)return idx, centroids_allidx, centroids_all = runKmeans(X, init_centroids, 20)
plotData(X, centroids_all, idx)

对簇中心点进行初始化的一个好的策略就是从训练集中选择随机的例子。

随机初始化簇中心


def initCentroids(X, K):
"""随机初始化"""
m, n = X.shape
idx = np.random.choice(m, K)
centroids = X[idx]
return centroids

进行三次随机初始化,看下各自的效果。会发现第三次的效果并不理想,这是正常的,落入了局部最优

for i in range(3):
centroids = initCentroids(X, 3)
idx, centroids_all = runKmeans(X, centroids, 10)
plotData(X, centroids_all, idx)

进行三次随机初始化,看下各自的效果。看到第三次的效果并不理想,都落入了局部最优。

用K-Means进行图像压缩, 通过减少图像中出现的颜色的数量 ,只剩下那些在图像中最常见的颜色。

K-Means图像压缩


from skimage import io
import matplotlib.pyplot as plt

A = io.imread('D:/Python/Andrew-NG-Meachine-Learning/machine-learning-ex7/ex7/bird_small.png')
print(A.shape) #(128, 128, 3)
plt.imshow(A)
A = A/255 #Divide by 255 so that all values are in the range 0-1

X = A.reshape(-1, 3)
K = 16
centroids = initCentroids(X, K)
idx, centroids_all = runKmeans(X, centroids, 10)

img = np.zeros(X.shape)
centroids = centroids_all[-1]
for i in range(len(centroids)):
img[idx == i] = centroids[i]

img = img.reshape(128, 128, 3)
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(A)
axes[1].imshow(img)

参考:吴恩达机器学习 吴恩达机器学习作业Python实现

转载于:https://www.cnblogs.com/eugene0/p/11461496.html

K-Means原理及代码实现相关推荐

  1. K均值(K-means)聚类算法原理与代码详解

    0. 算法原理: 上述过程简单描述: a: 初始数据 b: 选择质点 c: 根据质点划分 d: 求均值,更新质心点 e: 划分 f: 更新质心点 1. 代码实现: # K means 教程# 0. 引 ...

  2. K-Means(K均值聚类)原理及代码实现

    机器学习 没有免费午餐定理和三大机器学习任务 如何对模型进行评估 K-Means(K均值聚类)原理及代码实现 KNN(K最近邻算法)原理及代码实现 KMeans和KNN的联合演习 文章目录 机器学习 ...

  3. 为了联盟还是为了部落 | K means

    1. 问题 人类有个很有趣的现象,一群人在一起,过一段时间就会自发的形成一个个的小团体.好像我们很擅长寻找和自己气质接近的同类.其实不只是人类,数据也有类似情况,这就是聚类(Clustering)的意 ...

  4. k均值聚类算法(K Means)及其实战案例

    算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑.其中K表示要聚类的数量,就是说样本要被划分成几个类别.而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本 ...

  5. 视觉SLAM开源算法ORB-SLAM3 原理与代码解析

    来源:深蓝学院,文稿整理者:何常鑫,审核&修改:刘国庆 本文总结于上交感知与导航研究所科研助理--刘国庆关于[视觉SLAM开源算法ORB-SLAM3 原理与代码解析]的公开课. ORB-SLA ...

  6. 统计学习方法|K近邻原理剖析及实现

    欢迎直接到我的博客查看最近文章:www.pkudodo.com.更新会比较快,评论回复我也能比较快看见,排版也会更好一点. 原始blog链接: http://www.pkudodo.com/2018/ ...

  7. DeepLearning tutorial(1)Softmax回归原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43157801 DeepLearning tutorial(1)Softmax回归原理简介 ...

  8. OpenCV的k - means聚类 -对图片进行颜色量化

    OpenCV的k - means聚类 目标 学习使用cv2.kmeans()数据聚类函数OpenCV 理解参数 输入参数 样品:它应该的np.float32数据类型,每个特性应该被放在一个单独的列. ...

  9. 【深度学习】搞懂 Vision Transformer 原理和代码,看这篇技术综述就够了

    作者丨科技猛兽 编辑丨极市平台 导读 本文对Vision Transformer的原理和代码进行了非常全面详细的解读,一切从Self-attention开始.Transformer的实现和代码以及Tr ...

  10. SAGAN原理及代码(B站详解,很值得一看)

    代码地址:https://github.com/heykeetae/Self-Attention-GAN 视频讲解:SAGAN原理及代码_哔哩哔哩_bilibili 目录 1.背景+整体介绍 2.算法 ...

最新文章

  1. JavaScript创建元素的三种方法特点及对元素的操作
  2. BZOJ[1713][Usaco2007 China]The Bovine Accordion and Banjo Orchestra 音乐会 二维斜率优化
  3. 机房收费--操作员注册
  4. 计算机d盘给c盘,win10 c盘与d盘都是主分区如何将d盘空间分给c盘
  5. 高清摄像头MIPI接口与ARM连接【转】
  6. 阿里云移动端播放器高级功能---截图和音频波形 1
  7. Win7怎么设置文件共享 Win7共享设置方法
  8. nginx 504 Gateway Time-out 解决办法
  9. java后台生成动态二维码
  10. css音乐播放器插件,jQuery MPlayer音乐播放器插件
  11. 英特尔核显驱动hd630_技术力井喷!深度解析英特尔11代酷睿处理器
  12. PostgreSQL Array 数组类型与 FreeSql 打出一套【组合拳】
  13. 软件测试的发展前景怎么样 做软件测试有前途吗
  14. 【AI视野·今日NLP 自然语言处理论文速览 第十七期】Thu, 1 Jul 2021
  15. 第一阶段冲刺 博客评价
  16. CDH 6系列(CDH 6.0.0、CHD 6.1.0等)安装和使用
  17. 内嵌汇编(ARM64)
  18. BZOJ3713: [PA2014]Iloczyn
  19. Rockchip开发系列 - 3.2.引脚配置默认上拉下拉
  20. Android自定义控件之RecyclerView打造万能ViewPager TabLayout(仿今日头条Tab滑动、Tab多布局、indicator蠕动、自定义indicator、文字颜色渐变)

热门文章

  1. python缩进的描述_Python编程思想(2):Python主要特性、命名规则与代码缩进
  2. 7.2 重入锁(ReentrantLock)
  3. [渝粤教育] 中央财经大学 金融学 参考 资料
  4. Computing Platform------系统平台及其系列
  5. CRF++ Source code reading experience
  6. MySQL游标循环取出空值的BUG
  7. 2013年第四届蓝桥杯C/C++B组省赛题目解析
  8. 【bzoj1194】 HNOI2006—潘多拉的盒子
  9. [转]网上整理 Web JS 通用
  10. ng-show和ng-if的区别和使用场景