本文内容

  • 测试sklearn中以下聚类算法在digits手写数字数据集上的聚类效果。

  • 使用不同的评估方法对实验结果进行评估。

准备

- [ ] sklearn库

自2007年发布以来,scikit-learn已经成为Python重要的机器学习库了,scikit-learn简称sklearn,支持包括分类,回归,降维和聚类四大机器学习算法。还包括了特征提取,数据处理和模型评估者三大模块。

sklearn是Scipy的扩展,建立在Numpy和matplolib库的基础上。利用这几大模块的优势,可以大大的提高机器学习的效率。

sklearn拥有着完善的文档,上手容易,具有着丰富的API,在学术界颇受欢迎。sklearn已经封装了大量的机器学习算法,包括LIBSVM和LIBINEAR。同时sklearn内置了大量数据集,节省了获取和整理数据集的时间。

库的算法主要有四类:分类,回归,聚类,降维。其中:

常用的回归:线性、决策树、SVM、KNN ;集成回归:随机森林、Adaboost、GradientBoosting、Bagging、ExtraTrees

常用的分类:线性、决策树、SVM、KNN,朴素贝叶斯;集成分类:随机森林、Adaboost、GradientBoosting、Bagging、ExtraTrees

常用聚类:k均值(K-means)、层次聚类(Hierarchical clustering)、DBSCAN

常用降维:LinearDiscriminantAnalysis、PCA

它具有以下特点

  • 简单高效的数据挖掘和数据分析工具
  • 每个人都可以访问,并且可以在各种情况下重用
  • 基于NumPy,SciPy和matplotlib构建
  • 开源,可商业使用-BSD许可证

  • sklearn datasets

sklearn中包含了大量的优质的数据集,在我们学习机器学习的过程中,我们可以使用这些数据集实现出不同的模型。

首先,要使用sklearn中的数据集,必须导入datasets模块。

from sklearn import datasets

  • digits手写数字数据集
    实验要求采用digits数据集,我们先对这个数据集进行一个初步的了解:
    手写数字数据集包含1797个0-9的手写数字数据,每个数据由8 * 8 大小的矩阵构成,矩阵中值的范围是0-16,代表颜色的深度。
    我们先加载一下数据,了解一下数据的维度,并以图像的形式展示一些第一个数据:
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
digits = load_digits()
print(digits.data.shape)
print(digits.target.shape)
print(digits.images.shape)
plt.matshow(digits.images[0])
plt.show()

可以看到数据维度和第一张手写数字
(1797, 64)
(1797,)
(1797, 8, 8)

实验过程

  • K-means聚类digits数据集
    在sklearn官网中提供的K-means对digits的聚类的demo代码中运行出来的结果如下:(链接:https://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_digits.html#sphx-glr-auto-examples-cluster-plot-kmeans-digits-py)

整个可视化的生成很漂亮,细细研究下整个实现过程来发现官方给出的示例也很棒,下面对代码进行分析并进行改动,给出我们通常意义上的直接的聚类效果:

从库sklearn.datasets中加载digits数据集,数据集的介绍见上面。数据集是分好label的,存在digits.target中,同时我们可以提取出数据集的样本数,每个样本的维度,分别存在n_samples n_features中,输出这三个变量,可以得到:
n_digits: 10
n_samples 1797
n_features 64

下面是一段核心评估代码,使用不同的评分方法来计算score表示聚类后类别的准确性,下面再分别用三种k-means聚类的方式来调用这段评分代码,得到不同的score,这也是输出文字的全部内容(ps:这段代码写的真的很漂亮)

def bench_k_means(estimator, name, data):t0 = time()estimator.fit(data)print('%-9s\t%.2fs\t%i\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f\t%.3f'% (name, (time() - t0), estimator.inertia_,metrics.homogeneity_score(labels, estimator.labels_),metrics.completeness_score(labels, estimator.labels_),metrics.v_measure_score(labels, estimator.labels_),metrics.adjusted_rand_score(labels, estimator.labels_),metrics.adjusted_mutual_info_score(labels,  estimator.labels_,average_method='arithmetic'),metrics.silhouette_score(data, estimator.labels_, metric='euclidean',sample_size=sample_size)))
bench_k_means(KMeans(init='k-means++', n_clusters=n_digits, n_init=10),name="k-means++", data=data)
bench_k_means(KMeans(init='random', n_clusters=n_digits, n_init=10),name="random", data=data)
# in this case the seeding of the centers is deterministic, hence we run the
# kmeans algorithm only once with n_init=1
pca = PCA(n_components=n_digits).fit(data)
bench_k_means(KMeans(init=pca.components_, n_clusters=n_digits, n_init=1),name="PCA-based",data=data)

由此得到init=random,k-means++,pca下各个方式的score
init time inertia homo compl v-meas ARI AMI silhouette
k-means++ 0.42s 69432 0.602 0.650 0.625 0.465 0.621 0.146

random 0.22s 69694 0.669 0.710 0.689 0.553 0.686 0.147

PCA-based 0.04s 70804 0.671 0.698 0.684 0.561 0.681 0.118

补充:KMeans函数主要参数:
(这里只列出一部分,详见https://blog.csdn.net/weixin_44707922/article/details/91954734)


  • 可视化聚类

其实上面的代码k-means聚类和评估已经全部完成了,但是为了更好可视化输出,我们可以进行如下操作:
pca降维至两维,再次进行聚类,这是因为
1.散点图中的数据点就是两位的
2.在2维的基础上再次k-means聚类是因为已经聚类高维数据映射到二维空间的prelabel可能分散不过集中,影响可视化效果。

reduced_data = PCA(n_components=2).fit_transform(data)
kmeans = KMeans(init='k-means++', n_clusters=n_digits, n_init=10)
kmeans.fit(reduced_data)  # 对降维后的数据进行kmeans
result = kmeans.labels_

得到各个类的中心点:

centroids = kmeans.cluster_centers_

最后这一部分就是定义输出的变化范围和输出的效果了

#窗口
plt.imshow(Z, interpolation='nearest',extent=(xx.min(), xx.max(), yy.min(), yy.max()),cmap=plt.cm.Paired,aspect='auto', origin='lower')
#降维后的数据点
plt.plot(reduced_data[:, 0], reduced_data[:, 1], 'k.', markersize=2)
#聚类中心
plt.scatter(centroids[:, 0], centroids[:, 1],marker='x', s=169, linewidths=3,color='w', zorder=10)
  • 对demo可视化效果的修改/另一种形式展示

在通俗的理解中,聚类后的结果应该是不同类以不同的颜色来表明,所以在修改的时候我用不同颜色来表示不同的聚类点,最后再加上聚类中心,会有更加直观的结果:

plt.scatter(reduced_data[:, 0], reduced_data[:, 1],c=kmeans.labels_)

  • 使用不同的方法对digits数据集聚类
    有了前一部分的探索,使用其他的聚类方法处理起来就会相对轻松,下面我们分别来看这几种方法的聚类和评估结果:

  • AffinityPropagation

使用AffinityPropagation的核心算法如下所示:

af = AffinityPropagation().fit(reduced_data)
result = af.labels_

按照demo模型形式,绘制出来的效果如下:

(是不是很丑,分了90余类),按照我修改后的方式,效果稍微好点(只是相对好点):

  • MeanShift
bandwidth = estimate_bandwidth(reduced_data, quantile=0.1)#经过测试,在quantile=0.1的情况下得到的结果是最好的
bench_k_means(MeanShift(bandwidth=bandwidth, bin_seeding=True),name="MeanShift",data=data)
meanshift = MeanShift(bandwidth=bandwidth, bin_seeding=True).fit(reduced_data)

init time nmi homo comp labelnum

MeanShift 2.72s 0.554 1.000 0.307 10

使用demo的效果本身就很好,如下:

  • SpectralClustering
pca = PCA(n_components=n_digits).fit_transform(data)#要使用数据降维是因为高维情况在建图过程存在数据缺失bench_k_means(SpectralClustering(n_clusters=10),name="spectralcluster",data=pca)

init time nmi homo comp labelnum

spectralcluster 5.15s 0.598 0.449 0.796 10

这个聚类是没有聚类中心的。

  • ward hierarchical clustering
ward = AgglomerativeClustering(n_clusters=10, linkage='ward')
ward.fit(data)

init time nmi homo comp

ward hierarchical clustering 0.36s 0.797 0.758 0.836

其他的聚类情况可视化效果都类似,这里不再一一可视化。只给出评估指标:

  • AgglomerativeClustering
clustering = AgglomerativeClustering().fit(data)
  • DBSCN
db = DBSCAN().fit(data)
result = db.labels_

init time nmi homo comp

DBSCAN 0.53s 0.375 0.000 1.000

  • 对比

以下是上面各种方法的指标对比:

init time nmi homo comp

k-means++ 0.28s 0.626 0.602 0.650

random 0.22s 0.689 0.669 0.710

PCA-based 0.03s 0.681 0.667 0.695

AP 6.71s 0.655 0.932 0.460

MeanShift 2.72s 0.554 1.000 0.307

spectralcluster 5.15s 0.598 0.449 0.796

whc 0.36s 0.797 0.758 0.836

AC 0.21s 0.466 0.239 0.908

DBSCAN 0.53s 0.375 0.000 1.000

  • 小结

各种方法看下来,还是感觉k-means算法是最经典的算法,尽管在种子选点的方式上存在随机性,但这个算法的逻辑和原理,对聚类的测定和迭代方法是它成为最经典,也是首选的聚类方法,在各个评价指标上都有一个相对较好的结果。其他方法各有优劣,如AP和sc的时间复杂性较高,也有些准确度上有较大的偏差,无法求得聚类中心等,但感谢各方的优秀工程师提供的这些聚类算法为我们提供了多种数据的聚类方式,成为sklearn的重要部分之一;
太多了,再往下写我hold不住了,就先到这里,其他的聚类等待看下一篇吧!

import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle
from time import time
from sklearn import metrics
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.metrics import normalized_mutual_info_score
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import scale
from sklearn.cluster import KMeans, AffinityPropagation, estimate_bandwidth, MeanShift, SpectralClustering, \AgglomerativeClustering, DBSCAN#Loading  digits  data
np.random.seed(42)
digits = load_digits()
data = scale(digits.data)
n_samples, n_features = data.shape
n_digits = len(np.unique(digits.target))
labels = digits.target
sample_size = 300
print("n_digits: %d, \t n_samples %d, \t n_features %d"% (n_digits, n_samples, n_features))
print(82 * '_')
print('init\t\ttime\tnmi\thomo\tcompl')#Evaluation
def bench_k_means(estimator, name, data):t0 = time()estimator.fit(data)print('%-9s\t%.2fs\t%.3f\t%.3f\t%.3f'% (name, (time() - t0),#metrics.normalized_mutual_info_score(labels, estimator.labels_),metrics.v_measure_score(labels, estimator.labels_),metrics.homogeneity_score(labels, estimator.labels_),metrics.completeness_score(labels, estimator.labels_)))#kmeans
bench_k_means(KMeans(init='k-means++', n_clusters=n_digits, n_init=10),name="k-means++", data=data)
bench_k_means(KMeans(init='random', n_clusters=n_digits, n_init=10),name="random", data=data)
pca = PCA(n_components=n_digits).fit(data)
bench_k_means(KMeans(init=pca.components_, n_clusters=n_digits, n_init=1),name="PCA-based",data=data)#AffinityPropagation
bench_k_means(AffinityPropagation(),name="AffinityPropagation", data=data)# MeanShift
bandwidth = estimate_bandwidth(data, quantile=0.1)
bench_k_means(MeanShift(bandwidth=bandwidth, bin_seeding=True),name="MeanShift",data=data)# ward hierarchical clustering
bench_k_means(AgglomerativeClustering(n_clusters=10, linkage='ward'),name="ward hierarchical clustering",data=data)# AgglomerativeClustering
bench_k_means(AgglomerativeClustering(),name="AgglomerativeClustering",data=data)# DBSCN
bench_k_means(DBSCAN(),name="DBSCAN()",data=data)print(82 * '_')
reduced_data = PCA(n_components=2).fit_transform(data)# Visualize the results on PCA-reduced data  way1
# example:meanshiftbandwidth = estimate_bandwidth(reduced_data, quantile=0.07)
meanshift = MeanShift(bandwidth=bandwidth, bin_seeding=True).fit(reduced_data)
result = meanshift.labels_
centroids = meanshift.cluster_centers_
labels_unique = np.unique(result)
n_clusters_ = len(labels_unique)
plt.figure(1)
plt.clf()
colors = cycle('bgrcmybgrcmybgrcmybgrcmy')
for k, col in zip(range(n_clusters_), colors):my_members = result == kcluster_center = centroids[k]plt.plot(reduced_data[my_members, 0], reduced_data[my_members, 1], col + '.')plt.plot(cluster_center[0], cluster_center[1], 'o', markerfacecolor=col,markeredgecolor='k', markersize=5)
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()# Visualize the results on PCA-reduced data  way2
# example:kmeans
kmeans = KMeans(init='k-means++', n_clusters=n_digits, n_init=10)
kmeans.fit(reduced_data)  # 对降维后的数据进行kmeans
result = kmeans.labels_
plt.figure(2)
plt.clf()
plt.scatter(reduced_data[:, 0], reduced_data[:, 1],c=result)
centroids = kmeans.cluster_centers_
plt.scatter(centroids[:, 0], centroids[:, 1],marker='x', s=169, linewidths=3,color='w', zorder=10)
plt.show()

使用sklearn不同方法在digits手写数字数据集上聚类并用matplotlib呈现相关推荐

  1. python sklearn.datasets.fetch_mldata MNIST手写数字数据集无法获取, 报错 Function fetch_mldata is deprecated 的解决办法

    解决方法: 直接从GitHub下载MNIST数据集 参考文章: scikit-learn使用fetch_mldata无法下载MNIST数据集问题解决方法 https://blog.csdn.net/c ...

  2. 基于支持向量机的Digits手写数字识别

    基于支持向量机的Digits手写数字识别 描述 支持向量机(Support Vector Machine,简称SVM)模型既可以用于分类也可以用于回归.手写数字识别是一个多分类问题(判断一张手写数字图 ...

  3. sklearn识别单张自定义手写数字图片

    sklearn内置了手写数字的数据集digits.此数据集的官方介绍在这里.摘录如下: Each datapoint is a 8x8 image of a digit. Classes 10 Sam ...

  4. svm对未知数据的分类_SVM对sklearn自带手写数字数据集进行分类

    sklearn自带一些数据集,其中手写数字数据集可通过load_digits加载,我找到load_digits里头是这样 def load_linnerud(): """ ...

  5. Dataset之Handwritten Digits:Handwritten Digits(手写数字图片识别)数据集简介、安装、使用方法之详细攻略

    Dataset之Handwritten Digits:Handwritten Digits(手写数字图片识别)数据集简介.安装.使用方法之详细攻略 目录 Handwritten Digits数据集的简 ...

  6. 将MNIST手写数字数据集导入NumPy数组(《深度学习入门:基于Python的理论与实现》实践笔记)

    将MNIST手写数字数据集导入NumPy数组(<深度学习入门:基于Python的理论与实现>实践笔记) 一.下载MNIST数据集(使用urllib.request.urlretrieve( ...

  7. BP算法实现--minst手写数字数据集识别

    实验步骤 初始化网络架构 网络层数,每层神经元数,连接神经元的突触权重,每个神经元的偏置 构造bp算法函数 对于一个输入数据,前向计算每层的输出值,保存未激活的输出和激活过的输出值,这里用的激活函数是 ...

  8. [TensorFlow深度学习入门]实战九·用CNN做科赛网TibetanMNIST藏文手写数字数据集准确率98%+

    [TensorFlow深度学习入门]实战九·用CNN做科赛网TibetanMNIST藏文手写数字数据集准确率98.8%+ 我们在博文,使用CNN做Kaggle比赛手写数字识别准确率99%+,在此基础之 ...

  9. [PyTorch] 基于Python和PyTorch的MNIST的手写数字数据集的分类

    文章目录 讲解 MNIST的介绍 须导入的函数库 检查 pytorch 的版本 定义超参数 下载 MNIST的数据集 定义网络 网络实例化 定义训练函数 定义测试函数 主函数 全部源代码 2020.0 ...

  10. 如何教计算机认识手写数字(上)

    本图文介绍了一种简单的教会计算机识别手写数字的方法.

最新文章

  1. centos 7 卸载 mariadb 的正确命令
  2. react中context到底是如何传递的-源码分析
  3. python np fft_Python的武器库05:numpy模块(下)
  4. MySQL中表连接方式
  5. 报告PPT(123页):Python编程基础精要
  6. 模板题——数位DP、状态压缩、记忆化搜索
  7. 推荐七个逆天神器APP,让你分分秒秒变优秀
  8. 高德地图通过经纬度获取位置信息
  9. 基于单片机的语音小车设计
  10. Linux 查看日志文件命令(整合)
  11. 1299: Problem 1
  12. 微型计算机的地址加法器,地址加法器
  13. 小程序软件有必要申请软件著作权登记么?
  14. 苹果云服务器满,苹果云备份满了怎么清理
  15. 360扫描出来html木马,你的电脑真的做好防护了吗?使用360安全卫士木马查杀一键扫描就知道...
  16. 马尔可夫链的常返态和非常返态-零常返态
  17. 加解密后字节数组和(16进制)字符串的相互转换问题
  18. [javascript] 实现展开全文和收起全文效果
  19. 读取excel文件并使用matplotlib绘图(含柱状图、柱状图加数值的显示和直方图)
  20. PHP单例模式与常驻内存

热门文章

  1. uniapp使用colorUI 组件
  2. VMware Workstation PRO15  下 Win7镜像中LoadRunner安装
  3. 网络:简述传统CPE向VCPE的演进
  4. winxp netbeui install
  5. 2017 idea 代码字体加粗
  6. 深度学习(1): 深度学习简介
  7. VBA函数:int()函数
  8. 遥感影像预处理流程及基本概念介绍(辐射校正、辐射定标、大气校正、正射校正等)
  9. nekohtml 用法
  10. 电梯新时达系统服务器密码,国内主要电梯主板密码及变频器密码