1.1 聚类
聚类就是按照某个特定标准(如距离准则)把一个数据集分割成不同的类或簇,
使得同一个簇内的数据对象的相似性尽可能大同时不在同一个簇中的数据对象的差
异性也尽可能地大。即聚类后同一类的数据尽可能聚集到一起,不同数据尽量分离
。聚类算法属于无监督学习,即事先不会给出标记信息,通过对无标记样本的学习
来解释数据的内在性质及规律,为进一步的数据分析提供基础。
下面介绍的kmeans算法就是聚类算法的一种。
1.2 Kmeans算法
什么是kmeans算法?
举个社会现象:在混社会时,小弟会归顺结识的“大哥”,进而形成了一个个不同小团体,而不同的团体会有不一样的大哥,当大哥不行时,小弟会依傍这个团体新的“老大”。
而Kmeans算法就相当于不同团体找老大的过程。
1.2.1K-means(即K-均值)
定义:对于给定的样本的样本集,按照样本之间的距离大小将样本划分为K个簇,使得簇内的点之间的距离尽量小一些,簇间的距离尽量大一些。
1.2.2 K-means 步骤:
1.从已知样本中随机选择K个中心点,代表K个类别;
2.计算N个样本点和K个中心点的欧氏距离;
3.迭代1——将每一个样本划分到最近的(即欧式距离最小的)中心点类别中;
4.迭代2——计算每个类别中样本点的均值,进而得到K个均值(即K个新的中心点);
5.重复步骤2,3,4;
6.当满足迭代前后中心点的位置不再改变时,迭代停止,K-means算法结束。
1.2.3距离公式——欧式算法
K-Means 聚类可以用欧式距离,欧式距离很简单,二维平面就是两个点的距离公式,在多维空间里,假设两个样本为a(x1,x2,x3,x4…xn),b(y1,y2,y3,y4…yn),那么他们之间的欧式距离的计算公式是:
可以用下面的图很好地说明:
有 ABCDE 5个样本,一开始选定右边的 2 个初始中心点,K=2,大家颜色都不一样,谁都不服谁;
有 ABCDE 5个样本,一开始选定右边的 2 个初始中心点,K=2,大家颜色都不一样,小弟们除了老大以外谁都不服;
然后开始换老大啦,2 个初始中心点消失,重新在 2 个类分别中心的位置出现 2 个新的中心点,这 2 个新的中心点离类别里样本的距离之和必须是最小的;
新的老大出现,类别的划分也不一样啦,C 开始叛变,傍依了新老大,因为他离新老大更近一点;
新的老大消失,新新老大出现,发现划分的类别没有变化,帮派稳定,于是收敛,K-means算法结束。
用代码简单实现一下:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
X, y_true = make_blobs(n_samples=300, centers=4,
cluster_std=0.60, random_state=0)
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.show()
生成一些随机点。
然后使用 K-Means 进行聚类。
from sklearn.cluster import KMeans
"""
KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300,
tol=0.0001, precompute_distances='auto', verbose=0,
random_state=None, copy_x=True, n_jobs=1, algorithm='auto')
Parameters:
n_clusters: 聚类个数
max_iter: 最大迭代数
n_init: 用不同的质心初始化值运行算法的次数
init: 初始化质心的方法
precompute_distances:预计算距离
tol: 关于收敛的参数
n_jobs: 计算的进程数
random_state: 随机种子
copy_x:是否修改原始数据
algorithm:“auto”, “full” or “elkan”
”full”就是我们传统的K-Means算法,
“elkan”elkan K-Means算法。默认的
”auto”则会根据数据值是否是稀疏的,来决定如何选择”full”和“elkan”,稠密的选 “elkan”,否则就是”full”
Attributes:
cluster_centers_:质心坐标
Labels_: 每个点的分类
inertia_:每个点到其簇的质心的距离之和。
"""
m_kmeans = KMeans(n_clusters=4)
from sklearn import metrics
def draw(m_kmeans,X,y_pred,n_clusters):
centers = m_kmeans.cluster_centers_
print(centers)
plt.scatter(X[:, 0], X[:, 1], c=y_pred, s=50, cmap='viridis')
#中心点(质心)用红色标出
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5)
print("Calinski-Harabasz score:%lf"%metrics.calinski_harabasz_score(X, y_pred) )
plt.title("K-Means (clusters = %d)"%n_clusters,fontsize=20)
plt.show()
m_kmeans.fit(X)
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
n_clusters=4, n_init=10, n_jobs=None, precompute_distances='auto',
random_state=None, tol=0.0001, verbose=0)
y_pred = m_kmeans.predict(X)
draw(m_kmeans,X,y_pred,4)
聚类运行结果:
1.2.4 总结
优点:
1.K-Means 聚类是最简单、经典的聚类算法;
2.当处理大数据时,该算法可保持可伸缩性和高效性;
3.当簇近似为高斯分布时,它的效果较好;
缺点:
1.因为聚类中心个数,即 K 是需要提前设置好的超参数,所以能使用的场景也比较局限;(超参数:当参数随机变化时,该参数分布中的参数就是超参数;简单地说就是参数中的参数)
2.不适合非凸形状的簇或者大小差别很大的簇;
3.对噪声和孤立点敏感;