7.0.k-means聚类以及图像压缩(颜色压缩)

1)题目:

在本练习中,您将使用k-means聚类算法并且将其应用于压缩图像。在第二部分中你将使用主成分分析来找到脸部图像的一个低维表示。
第一部分为k-means聚类,你首先从一个2维的样本集开始,他可以帮助你对k-means算法有一个直观的感受。然后你将使用k-means算法对图像进行压缩,通过减少颜色数量,直到只出现在该图像中最常见的那些颜色。
数据集链接: https://pan.baidu.com/s/1cEgQIvehUcLxZ0WVhxcPuQ 提取码: xejn

2)知识点概括:

  • 无监督学习的数据是不带标签的

  • k-means算法:
    原理
    1、随机初始化生成k个点,即聚类中心(cluster centroids)
    2、重复迭代进行簇分配(cluster assignment)和移动聚类中心(move centroid),直到聚类中心不再改变

  • 输入:k和不带标签的数据集

    其中
    c(i)c^{(i)}c(i)表示当前样本x(i)x^{(i)}x(i)所属的那个簇的索引号或者序号
    μk\mu_kμk​表示第k个聚类中心的位置
    μc(i)\mu_{c^{(i)}}μc(i)​表示x(i)x^{(i)}x(i)所属簇的聚类中心

  • 代价函数(优化目标)为J(c(1),⋯ ,c(m),μ1,⋯ ,μK)=1m∑i=1m∥x(i)−μc(i)∥2J(c^{(1)},\cdots,c^{(m)},\mu_1,\cdots,\mu_K)={1\over m}\sum_{i=1}^m\|x^{(i)}-\mu_{c^{(i)}}\|^2J(c(1),⋯,c(m),μ1​,⋯,μK​)=m1​∑i=1m​∥x(i)−μc(i)​∥2
    有时也称这个代价函数为失真代价函数(distortion cost function)

  • 随机初始化
    随机挑选k个样本作为初始的聚类中心

  • 防止陷入局部最优解的方法:尝试多次(这里举100次迭代)初始化k-means算法并实现,然后选择代价函数最小的那个作为最优解。这个方法一般对于聚类中心在10个以下比较有效。

  • 关于选择聚类的数量
    1、肘部法则(Elbow method)画出代价函数随聚类数量变化的曲线,选择肘部点对应的聚类数量即为较好的(不常用,效果不是很好)
    2、看哪个聚类数量能更好的应用于后续目的(downstream purpose)

3)大致步骤:

  • 簇分配,寻找最近的聚类中心。历遍所有数据,返回一个取值为1到K的索引向量。用初始化的聚类中心[3, 3], [6, 2], [8, 5]测试下,应该得到x的前三个数据分别归属第1 3 2个聚类中心。
  • 计算聚类中心。
  • 运行k-means,设置一个布尔值,若为真则画出每次迭代的图像,以及最后的聚类结果和聚类中心移动的路径;若为假则只输出聚类中心和样本索引向量。
  • 随机初始化聚类中心。尝试以上步骤观察图像。
  • 图像压缩。原图像存储在一个三维数组(height,width,RGB)中,以0~255的整数表示红/绿/蓝的强度,这种编码通常被称为RGB编码。这里只需要把颜色的数量减少到16种颜色,即设置初始聚类数量为16,把原始图片的每个像素看作一个数据样本,然后利用k-means算法去找分组最好的16种颜色。这里需要把像素数据先展开成一个三列的矩阵,然后每行相当于一个数据样本,对这个样本进行k-means聚类,最后得到一个16个的聚类中心,然后每个数据用它的索引来得到距离最近的聚类中心的RGB编码,重组成之前shape的一个矩阵,即可得到压缩后的图像。

4)关于Python:

  • np.argmin函数返回最小值的索引。
  • plt.plot(mu[:, 4], mu[:, 5], ‘kx–’, markersize=8)中kx—可以直接规定连线的颜色,标记点形状和连线形状等。
  • matplotlib.image程序包中mpimg.imread函数可以用于读取图片,imsave函数用来保存图片。
  • .reshape(-1, 3)表示行数由Numpy自动计算,3列。
  • .set_title可以给子图加标题。
  • 用sklearn中的MiniBatchKMeans可以直接进行k-means回归,Mini Batch KMeans算法是一种能尽量保持聚类准确性下但能大幅度降低计算时间的聚类模型,采用小批量的数据子集减少计算时间,同时仍试图优化目标函数,这里所谓的Mini Batch是指每次训练算法时随机抽取的数据子集,采用这些随机选取的数据进行训练,大大的减少了计算的时间,减少的KMeans算法的收敛时间,但要比标准算法略差一点,建议当样本量大于一万做聚类时,就需要考虑选用Mini Batch KMeans算法。

5)代码与结果:


import numpy as np
import matplotlib.pyplot as plt
import scipy.io as scio
import matplotlib.image as mpimg #用于读取、保存图片
from sklearn.cluster import MiniBatchKMeans #Mini Batch K-Means聚类data = scio.loadmat('ex7data2.mat')
x = data['X']'''============================part1 簇分配========================='''
'''可视化数据集'''
plt.scatter(x[:,0], x[:,1], marker='o', c='w', edgecolors='k')'''初始化'''
K = 3 #设置聚类数量
initial_centroids = np.array([[3, 3], [6, 2], [8, 5]]) #初始聚类中心'''簇分配函数,找出距离最近的那个聚类中心'''
def findClosestCentroids(x, centroids):idx = np.zeros(len(x))for i in range(len(x)):c = np.sqrt(np.sum(np.square((x[i,:]-centroids)), axis=1)) #行求和idx[i] = np.argmin(c)+1return idxidx = findClosestCentroids(x, initial_centroids) #前三个的索引为[1 3 2]'''============================part2 计算聚类中心========================='''def computeCentroids(x, idx, K):mu = np.zeros((K, x.shape[1]))for i in range(1, K+1):mu[i-1] = x[idx==i].mean(axis=0) #列求均值return mucomputeCentroids(x, idx, K)    #array([[2.42830111, 3.15792418],#       [5.81350331, 2.63365645],#       [7.11938687, 3.6166844 ]])'''============================part3 k-means聚类========================='''
max_iters = 10 #设置迭代次数#画出每次迭代的结果
def plot_process(x, mu, idx):color = ['r', 'g', 'b'] #颜色序列for i in range(1,len(mu)+1):plt.scatter(x[idx==i][:,0], x[idx==i][:,1], marker='o', c='w', edgecolors=color[i-1])plt.plot(mu[:,0], mu[:,1], 'kx', markersize=8)#运行k-means
def runKmeans(x, centroids, max_iters, true):if true == True:mu = np.reshape(centroids, (1, centroids.size))for i in range(max_iters):idx = findClosestCentroids(x, centroids) #簇分配if true == True:plt.figure(i)plot_process(x, centroids, idx) #画图plt.title(i+1)centroids = computeCentroids(x, idx, len(centroids)) #移动聚类中心if true == True:mu = np.r_[mu, np.reshape(centroids, (1, centroids.size))] #用来储存聚类中心的移动坐标if true == True:plt.figure(max_iters)plot_process(x, centroids, idx)j = 0while j < centroids.size:plt.plot(mu[:, j], mu[:, j+1], 'kx--', markersize=8)j = j+2plt.title('Moving path')return centroids, idxrunKmeans(x, initial_centroids, max_iters, True)'''============================part4 随机初始化聚类中心========================='''
def kMeansInitCentroids(x, K):randidx = np.random.permutation(x) #随机排列centroids = randidx[:K, :] #选前K个return centroidscentroids = kMeansInitCentroids(x, K)
runKmeans(x, centroids, 5, True)'''============================part5 图像压缩========================='''
'''图像读入'''
A = mpimg.imread('bird_small.png') #读取图片
A.shape #(128, 128, 3)plt.imshow(img) # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()'''图像数据'''
img = scio.loadmat('bird_small.mat')['A']
img.shape #(128, 128, 3)
img = img/255.0 #使得像素数据为0-1之间#这里随便用A还是用img,都一样的'''k-means聚类'''
#数据重构
X = A.reshape(-1, 3) #(16384, 3)
K = 16
max_iters = 10
initial_centroids = kMeansInitCentroids(X, K) #随机初始化聚类中心
#聚类
centroids, idx = runKmeans(X, initial_centroids, max_iters, False)'''还原压缩后的图像'''
X_recovered = np.zeros(X.shape)
for i in range(len(centroids)):X_recovered[idx==i] = centroids[i]
#重构
X_recovered = X_recovered.reshape(A.shape)
#画图对比
fig, axes = plt.subplots(1, 2, figsize=(14,6))
plt.title('Original')
axes[0].set_title('Original')
axes[0].imshow(A)
axes[1].set_title('Compressed, with %d colors'%K)
axes[1].imshow(X_recovered)'''============================part6 sklearn========================='''
#picture = A #优化上面的图片
picture = mpimg.imread('IMG_4994.jpeg') #读取图片
picture #查看下是不是0-1之间
data = picture/255 #如果是0-255的话需要除以255,如果已经是0-1就不需要
data = data.reshape(data.shape[0]*data.shape[1],3) '''用sklearn中的MiniBatchKMeans'''
#MiniBatchKMeans聚类
kmeans = MiniBatchKMeans(K)
kmeans.fit(data) #先fit
picture_recolored = kmeans.cluster_centers_[kmeans.predict(data)] #再predict,然后再分配标记的聚类中心的RGB编码
picture_recolored = picture_recolored.reshape(picture.shape)#画图
fig, axes = plt.subplots(1, 2, figsize=(14,6))
axes[0].imshow(picture)
axes[0].set_title('Original')
axes[1].imshow(picture_recolored)
axes[1].set_title('Compressed, with %d colors'%K)#保存,观察文件大小是否变化
mpimg.imsave('IMG_4994_recoverd.jpeg', picture_recolored)

样本集可视化结果

每次迭代的图像(1-10)


最后的聚类结果和聚类中心移动的路径

原始图像和压缩后的图像对比

我认为这里聚类效果不好可能是和随机初始化聚类中心有关,陷入了局部最优解,其实这里应该尝试下多次迭代初始化k-means算法并实现,然后选择代价函数最小的那个作为最优解。但考虑到sklearn中有现成的可以调用,就没再继续优化了。

下面是采用mini Batch K-Means算法压缩后的图像

然后用自己的图片试了下,效果也还不错,在保持了较多信息下压缩了图片,文件大小也变小了

吴恩达|机器学习作业7.0.k-means聚类相关推荐

  1. 吴恩达|机器学习作业6.0支持向量机(SVM)

    6.0.支持向量机 1)题目: 在本练习中,您将使用支持向量机来建立一个垃圾邮件分类器. 在本练习的前半部分,您将使用支持向量机(SVM)处理各种两维的样本数据集.使用这些数据集进行实验将帮助您直观地 ...

  2. 吴恩达|机器学习作业4.0神经网络反向传播(BP算法)

    4.0.神经网络学习 1)题目: 在本练习中,您将实现神经网络的反向传播算法,并将其应用于手写数字识别任务.在之前的练习中,已经实现了神经网络的前馈传播,并使用Andrew Ng他们提供的权值来预测手 ...

  3. 吴恩达|机器学习作业5.0.偏差与方差

    5.0.偏差与方差 1)题目: 在本练习中,您将实现正则化线性回归,并使用它来研究具有不同偏差-方差属性的模型.在练习的前半部分,您将使用水库水位的变化实现正则化线性回归来预测大坝的出水量.在下半部分 ...

  4. 吴恩达|机器学习作业8.0.异常检测

    8.0.异常检测 1)题目: 在本练习中,您将实现异常检测算法,并将其应用于检测网络中的故障服务器.在第二部分中,您将使用协同过滤来构建电影推荐系统. 在本练习中,您将实现一个异常检测算法来检测服务器 ...

  5. k均值算法python实现(吴恩达机器学习作业)

    k均值算法python实现(吴恩达机器学习作业) 题目要求 数据集 读取mat文件 K-means 实现 结果 问题 题目要求 采用K均值算法对样本进行聚类. 编写K均值算法源代码,对ex7data2 ...

  6. 吴恩达机器学习作业7 - K-means和PCA主成分分析(Python实现)

    吴恩达机器学习作业7 - K-means和PCA主成分分析(Python实现) Introduction 在本实验中,将实现K-means聚类算法,并将其应用于图像压缩.在第二部分实验中,将使用主成分 ...

  7. 吴恩达机器学习作业ex2-python实现

    系列文章目录 吴恩达机器学习作业ex1-python实现 吴恩达机器学习作业ex2-python实现 吴恩达机器学习作业ex3-python实现 作业说明及数据集 链接:https://pan.bai ...

  8. 第一章-机器学习简介 深度之眼_吴恩达机器学习作业训练营

    目录 专栏简介: 一,机器学习简介 1.1 机器学习定义 1.1 机器学习的重要性 1.2 应用领域 二.监督学习 三.无监督学习 四.总结 专栏简介: 本栏主要内容为吴恩达机器学习公开课的学习笔记, ...

  9. 吴恩达机器学习作业Python实现(七):K-means和PCA主成分分析

    吴恩达机器学习系列作业目录 1 K-means Clustering 在这个练习中,您将实现K-means算法并将其用于图像压缩.通过减少图像中出现的颜色的数量,只剩下那些在图像中最常见的颜色. 1. ...

最新文章

  1. James 3.0 邮箱配置
  2. 南核目录2020pdf_北核+南核|《消费经济》2020年重点选题
  3. 0308互联网新闻 | 网易云音乐App上线小程序入口;谷歌为机器学习框架TensorFlow发新模块...
  4. java从键盘上录入学生人数和每个学生的姓名以及分数,按照分数降序输出,学生名次、学生姓名、学生分数
  5. 哈哈~我这个月工资涨了1万5!
  6. 开通qq邮箱的smtp服务的流程详情
  7. 卓越领导者的智慧(精华版)
  8. Android系统Audio框架介绍(一)
  9. 待续--著名软件公司笔试算法题:122345排列组合
  10. ISSCC 2017论文导读 Session 14 Deep Learning Processors,DNPU: An 8.1TOPS/W Reconfigurable CNN-RNN
  11. Vlan的access、trunk以及hybird接口配置实验
  12. sata AHCI驱动下载(AMD Intel Nvidia)
  13. Hibernate ORM - 一对多双向关联关系(我是韦小宝)
  14. Android实现网络视频播放
  15. uniapp获取手机状态栏和头部导航栏高度(可用于制作头部自定义导航栏)
  16. 运行最新创建的镜像:
  17. php ajax 考试倒计时,ajax实现在线考试倒计时
  18. C语言射击类打飞机小游戏
  19. Foxmail 去掉签名横线 Foxmail 去掉签名默认横线
  20. 星起航跨境—亚马逊发展现状及未来趋势分析

热门文章

  1. gevent的同步与异步
  2. 安装好grunt,cmd 提示grunt不是内部或外部命令 怎么办?
  3. Ubantu下安装adobe flash player插件
  4. 痛苦如此持久,像蜗牛充满耐心地移动;快乐如此短暂,像兔子的尾巴掠过秋天的草原...
  5. 进程间通信 - 整理
  6. HNOI2019 退役记
  7. 翻译:TRUNCATE TABLE(已提交到MariaDB官方手册)
  8. 22-1图的遍历的源代码
  9. rsync+sersync多线程实时同步
  10. hdu 3549 最大流(EK实现)