- 采用的算法。
K-means即均值聚类,是一种容易上手的聚类机器学习算法。 - 鸢尾花概述
鸢尾花(iris)是一种常见温带植物。鸢尾属(拉丁学名:Iris L.),单子叶植物纲,百合目,鸢尾科多年生草本植物,有块茎或匍匐状根茎;叶剑形,嵌叠状;花美丽,状花序或圆锥花序;花被花瓣状,有一长或短的管,外弯,花柱分枝扩大,花瓣状而有颜色,外展而覆盖着雄蕊;子房下位,胚珠多数,果为蒴果。本属模式种:德国鸢尾(Iris germanica L. )原产欧洲,中国各地常见栽培。鸢尾属约300种,分布于北温带,少数入药,鸢尾根茎为诱吐剂或缓下剂,具消炎作用。鸢尾花大而美丽,叶片青翠碧绿,观赏价值很高。很多种类供庭园观赏用,在园林中可用作布置花坛,栽植于水湿畦地、池边湖畔,或布置成鸢尾专类花园,亦可作切花及地被植物,是一种重要的庭园植物。 - 问题的转化:
由于鸢尾种类庞杂,正确辨识鸢尾种类就具有重要的实践意义。而辨识过程往往是一种经验积累,无外乎对其外形进行观察和比较。因此,鸢尾花分类看似是一个实践问题,实际上可以转化为一个数据驱动的机器学习算法理论问题。 - 数据
该数据集聚类时只输入前4个变量,聚类结果可以与物种(变量Species
)进行比较,该变量包含了3个类别,分别为Setosa、Versicolour和Virginica,每类50个样本。 - 载入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
- 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 两团数据点
- 聚类的目的,是把形如以上形状的数据点进行分类。
聚类即clustering,将数据集中的样本划分为若干个子集,每个子集称为一个簇(cluster)。k均值算法需要指定簇的数量,可扩展性较强,能够适应大数据集。 - 解释K-means算法
k均值算法将N个样本的数据集X划分为K个不相交的簇C,每个簇由簇内样本的均值μj作为代表,称为簇的中心。k均值算法最小化惯性即簇内平方和
惯性能够衡量簇的内部是否紧密,然而也有一些缺点,之后章节会通过一些例子具体解读,包括:
假定簇是凸的且各向同性的;
并不是归一化的指标,即范围不是0到1之间,我们只知道该指标越小越好,0为最佳。
k均值算法分为3个步骤:
第1步,选择初始的簇中心,可以随机选择数据集中的样本;
第2步,将每个样本分配到最近的簇中心所在的簇;
第3步,计算新的簇中心。
重复迭代第2和3步,直到簇中心在不同的迭代之间变化不大。 - 载入鸢尾花数据集
sklearn.datasets自带鸢尾花数据集,可以用load_iris()载入
iris数据集分为两部分,data部分为四个测量数据,target部分为分类数据用于训练模型参数
1 iris = load_iris() ##读入数据集 2 iris_X = iris.data ##测量数据保存为自变量 3 iris_y = iris.target ##target数据保存为因变量
- 构造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
- 可视化前两个变量的聚类结果:花萼长度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个簇。