鸢尾花K-means聚类算法_python数据分析与机器学习


  1. 采用的算法。
    K-means即均值聚类,是一种容易上手的聚类机器学习算法。
  2. 鸢尾花概述
    鸢尾花(iris)是一种常见温带植物。鸢尾属(拉丁学名:Iris L.),单子叶植物纲,百合目,鸢尾科多年生草本植物,有块茎或匍匐状根茎;叶剑形,嵌叠状;花美丽,状花序或圆锥花序;花被花瓣状,有一长或短的管,外弯,花柱分枝扩大,花瓣状而有颜色,外展而覆盖着雄蕊;子房下位,胚珠多数,果为蒴果。本属模式种:德国鸢尾(Iris germanica L. )原产欧洲,中国各地常见栽培。鸢尾属约300种,分布于北温带,少数入药,鸢尾根茎为诱吐剂或缓下剂,具消炎作用。鸢尾花大而美丽,叶片青翠碧绿,观赏价值很高。很多种类供庭园观赏用,在园林中可用作布置花坛,栽植于水湿畦地、池边湖畔,或布置成鸢尾专类花园,亦可作切花及地被植物,是一种重要的庭园植物。

     

     

  3. 问题的转化:
    由于鸢尾种类庞杂,正确辨识鸢尾种类就具有重要的实践意义。而辨识过程往往是一种经验积累,无外乎对其外形进行观察和比较。因此,鸢尾花分类看似是一个实践问题,实际上可以转化为一个数据驱动的机器学习算法理论问题。
  4. 数据
    该数据集聚类时只输入前4个变量,聚类结果可以与物种(变量Species)进行比较,该变量包含了3个类别,分别为Setosa、Versicolour和Virginica,每类50个样本。
  5. 载入python库
    1 import pandas as pd 2 import numpy as np 3 from matplotlib import pyplot as plt 4 from matplotlib.colors import ListedColormap 5 from sklearn.datasets import load_iris, make_moons, make_circles, make_blobs 6 from sklearn.metrics import silhouette_score, homogeneity_completeness_v_measure 7 from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering

     

  6. sklearn.datasets的作用演示
    sklearn.datasets的函数make_moons()用于生成两个交织的半圆环(moons),
    make_circles()用于生成一个大圆环套小圆环(circles
    make_blobs()用于生成两团点(blobs)
    1 moons = make_moons(500, noise=0.05, random_state=0)
    2 circles = make_circles(500, noise=0.05, factor=0.5, random_state=1)
    3 blobs = make_blobs(500, centers=2, cluster_std = 0.1, center_box = (-1,1), random_state=8)
    4 synthetic_data = {"moons" : moons, "circles" : circles, "blobs" : blobs}

    运行代码后,利用matplotlib(from matplotlib import pyplot as plt)绘制图形

    1 plt.figure(figsize = (18,5))
    2 i = 0
    3 for name, (X, y) in synthetic_data.items():
    4     plt.subplot(131 + i)
    5     plt.scatter(X[:, 0], X[:, 1], c=y, cmap=ListedColormap(['#FF0000', '#0000FF']))
    6     plt.title(name)
    7     i += 1
    8 
    9 plt.show()

                       图1 交织的半圆                                     图2 同心圆                                     图3 两团数据点

  7. 聚类的目的,是把形如以上形状的数据点进行分类。
    聚类即clustering,将数据集中的样本划分为若干个子集,每个子集称为一个簇(cluster)。k均值算法需要指定簇的数量,可扩展性较强,能够适应大数据集。

  8. 解释K-means算法

    k均值算法将N个样本的数据集X划分为K个不相交的簇C,每个簇由簇内样本的均值μj作为代表,称为簇的中心。k均值算法最小化惯性即簇内平方和

     

    惯性能够衡量簇的内部是否紧密,然而也有一些缺点,之后章节会通过一些例子具体解读,包括:

    假定簇是凸的且各向同性的;
    并不是归一化的指标,即范围不是0到1之间,我们只知道该指标越小越好,0为最佳。
    k均值算法分为3个步骤:
    第1步,选择初始的簇中心,可以随机选择数据集中的样本;
    第2步,将每个样本分配到最近的簇中心所在的簇;
    第3步,计算新的簇中心。
    重复迭代第2和3步,直到簇中心在不同的迭代之间变化不大。

  9. 载入鸢尾花数据集
    sklearn.datasets自带鸢尾花数据集,可以用load_iris()载入
    iris数据集分为两部分,data部分为四个测量数据,target部分为分类数据用于训练模型参数
    1 iris = load_iris() ##读入数据集
    2 iris_X = iris.data  ##测量数据保存为自变量
    3 iris_y = iris.target ##target数据保存为因变量
  10. 构造K-means模型
    1 clf = KMeans(n_clusters=3,n_init=3,random_state=123)

    k-means聚类模型的属性参数:
    参数n_clusters:聚类得到簇的数量
    参数n_init:随机选择初始中心的组数,最终选择惯性最小的模型
    参数random_state:生成随机中心的点的数量
    代码中,指定簇的数量为3,初始中心的组数为3,生成随机中心点数量为123个,并训练

    1 clf.fit(iris_X)
    output:
    KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=3, n_jobs=None, precompute_distances='auto', random_state=123, tol=0.0001, verbose=0)


    cluster_centers_labels_inertia_得到簇的中心、每个样本的簇序号和惯性

    1 clf.cluster_centers_  ##簇的中心
    output:
    array([[5.006 , 3.428 , 1.462 , 0.246 ],
           [5.88360656, 2.74098361, 4.38852459, 1.43442623],
           [6.85384615, 3.07692308, 5.71538462, 2.05384615]])
    1 clf.labels_ ##每个样本的簇序号
    output:
    array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2,
           2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 1, 2, 2, 2, 2,
           2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 1])
    1 clf.inertia_ ##簇的惯性
    output:
    78.8556658259773

     

  11. 可视化前两个变量的聚类结果:花萼长度Sepal.Length,花萼宽度Sepal.Width

    1 plt.figure(figsize = (8,6))
    2 plt.scatter(iris_X[:, 0], iris_X[:, 1], c=clf.labels_, cmap=ListedColormap(['darkorange', 'c', 'darkblue']))
    3 plt.scatter(clf.cluster_centers_[:,0], clf.cluster_centers_[:,1], c=np.array([0,1,2]), 
    4             marker = 'x', s=300, cmap=ListedColormap(['darkorange', 'c', 'darkblue']))
    5 plt.show()

     

    可以看出,左上方的凸面分成了1个簇,右下方的凸面分成了2个簇。

    得到真实类别序号与簇的序号的交叉表。

    1 pd.crosstab(iris_y,clf.labels_)

     

     

    可以看出,类别序号0代表的setosa完全对应1个簇,而类别序号1代表的versicolor和类别序号2代表的virginica基本也分成了2个簇。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM