聚类分析是什么
相对于分类,聚类是一种不清楚类别的种类,或类别不清楚的情况下,通过计算数据之间的相似度(其中用得最多的是距离)来进行小组划分的一种数据挖掘方法。其特点是组中数据的相似度很高,而不同组别之间的相似度却很低。
聚类分析有哪些
根据不同的划分方式,聚类可分为K-Means聚类、K-中心点聚类、系统聚类等。其中最常用以及应用范围最广的是K-Means聚类,下面着重介绍K-Means聚类。
K-Means聚类
K-Means聚类是很典型的基于距离的聚类算法,以组内元素的均值作为每个组的中心,采用距离作为相似性的指标,即认为两个对象距离近,则相似,否则,不相似。该算法认为组内元素是由距离相近的元素组成的,因此,组间元素的距离相近,不同组的距离则较远。
算法步骤:
- 随机选取K个对象作为聚类中心
- while 聚类中心发生变化
- 计算数据集中各个对象到K个聚类中心的距离,并将距离相近的对象归为同一个聚类
- 重新计算聚类中心(即重新计算组内均值)
算法实践:
我们以常用的分类数据集Iris作为我们的原始数据
iris = datasets.load_iris()
x,y = iris.data,iris.target
data = x[:, [1, 3]] #只取两个维度便于可视化
f = plt.scatter(data[:, 0], data[:, 1])
欧几里得距离:
我们采用欧几里得距离来计算点与点之间的距离
def distance(p1, p2):
"""
返回两个点之间的欧几里得距离
"""
tmp = np.sum((p1-p2)**2)
return np.sqrt(tmp)
聚类中心的初始化:
def _rand_center(data, k):
"""
随机挑选K个初始点
"""
n = data.shape[1] #数据集包含的特征数
centroids = np.zeros((k, n)) #初始化一个K行n列的0矩阵
for i in range(n):
dmin, dmax = np.min(data[:, i]), np.max(data[:, i])
centroids[:, i] = dmin + (dmax - dmin) * np.random.rand(k)
# 这里产生的是介于极小值和极大值之间的数,产生的数有可能不是数据集的数据
return centroids
K均值聚类:
该算法中,当聚类中心不再改变的时候,迭代停止,返回聚类中心,各点归属于哪一聚类和他们之间距离的和。
注意到K-Means有可能陷于局部最小值,我们采用多次计算取最小值来解决此问题,当然也可以用二分K均值来解决此问题。
n = data.shape[0] #数据集的行数
centroids = _rand_center(data, k)
label = np.zeros(n, dtype=np.int) #用于标记最近的聚类中心
assessment = np.zeros(n) #用于对模型的评估
converged = False
while not converged:
old_centroids = np.copy(centroids)
for i in range(n): #决定最相近的聚类中心并记录在label中
min_dist, min_index = np.inf, -1
for j in range(k):
dist = distance(data[i], centroids[j])
if dist < min_dist:
min_dist, min_index = dist, j
label[i] = j
assessment[i] = distance(data[i], centroids[j])
for m in range(k): #更新聚类中心
centroids[m] = np.mean(data[label == m], axis=0)
converged = _converged(old_centroids, centroids)
return centroids, label, np.sum(assessment)
最后经过多次计算之后显示的结果如下图:
从图可以看出,聚类的效果还不错。