问题
聚类(clustering)是无监督学习中研究最多应用最广的分支,作为无监督学习,其训练数据集没有标记信息(因变量),将样本划分为若干不交子集,每个子集成为一个簇(cluster)。假设样本为
每个样品
是一个m维向量(m个特征)。
聚类算法将D划分为k个不交的簇
且它们的并是D,用λ_j∈{1,...,k}表示x_j的簇序号,即x_j∈C_λj,因此聚类结果可以用λ=(λ_1,...,λ_m)表示。
K-means算法通过最小化
来得到簇,其中||·||代表向量的二范数,上式表示样本点减去其从属的类均值的平方和。
算法
然而其最小化只能通过考察样本D的所有可能划分来实现,是一个NP难问题,因此其实际求解是通过如下贪心算法进行的:
即首先随机选取k个样品作为k个类的类均值,然后计算全部n个样品每一个和k个类均值的距离,将每个样品分入与之距离最近的类均值所在的类中,根据分类结果重新计算类均值,再将每个样品分入与之距离最近的类均值所在的类中,再重新计算类均值,如此反复直至类均值不再变化为止。
预测
聚类完成后得到了k个类均值
对新的x,将其分入距离x最近的类均值中。
Python实现
用sklearn库中的KMeans函数实现,输入数据X需要是2维ndarray(即矩阵)的形式,行代表样品,列代表特征。
from sklearn.cluster import KMeans
from sklearn import datasets
import numpy as np
# 鸢尾花数据集
X = datasets.load_iris()['data']
# 设置类别数量和随机数种子
kmeans = KMeans(n_clusters=3, random_state=1)
# 对数据聚类, X需要是二维numpy数组, 行代表样品, 列代表变量
kmeans.fit(X)
# 获取聚类标签(一维numpy数组形式, 代表每个样品所属类别)
labels = kmeans.labels_
# 获取聚类中心(二维numpy数组形式, 行代表类别中心)
cluster_centers = kmeans.cluster_centers_
# 预测类别(输入二维numpy数组, 行代表样品, 返回一维numpy数组, 表示每个样品对应类别)
kmeans.predict(Y)