加深对非监督学习的理解和认识。
掌握基于距离的和基于密度的动态聚类算法的设计方法。
本次实验采用两种均值聚类算法实现聚类
随机的从样本中选择 K 个点作为初始质心。
计算每个样本到各个质心的距离,将样本划分到距离最近的质心所对应的簇中。
样本之间的距离选用欧式距离: d i j = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 d_{ij} = \sqrt{{(x_1-x_2)}^2+{(y_1-y_2)}^2} dij=(x1−x2)2+(y1−y2)2
计算每个簇内所有样本的均值,并根据计算出的均值对质心进行更新
重复步骤 2 与 3 ,直到满足下列模型中的一个
其主要工作原理是从某个核心点出发向外扩张,从而得到一个包含核心点和边界点的最大化区域。具体实现步骤如下:
选择聚类算法对鸢尾花做聚类;
读入要分类的数据;
设置初始聚类中心;
根据不同的聚类算法实现聚类。
按照同样步骤实现所学过的聚类算法。
取 y 轴为SSE,x 轴为 k ,可以绘制出随着x的增加,SSE降低的图像。当下降幅度明显趋向于缓慢的时候,取该值为K的值。
SSE(误差平方和)的计算公式: S S E = ∑ i = 1 m w i ( y i − y i ^ ) 2 SSE = \sum\limits^m_{i = 1}w_i{(y_i-\hat{y_i})}^2 SSE=i=1∑mwi(yi−yi^)2
eps 过大,类别数可能会减少, 本来不应该是一类的样本也会被划为一类。eps 过小,类别数可能会增大,本来是一类的样本却被划分开。
min_samples 过大,核心对象会过少,此时簇内部分本来是一类的样本可能会被标为噪音点,类别数也会变多。min_samples 过小的话,将产生大量的核心对象,可能会导致类别数过少。
metric:最近邻距离度量参数。可以使用的距离度量较多,一般来说DBSCAN使用默认的欧式距离。
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.cluster import DBSCAN
from sklearn.datasets import load_iris
iris = load_iris()
X_0 = iris.data[:] # 表示我们只取特征空间中的后两个维度
X_1 = iris.data[:, :2]
dbscan = DBSCAN(eps=0.3, min_samples=10) # r, number of pointer
dbscan.fit(X_1)
label_pred = dbscan.labels_
print(label_pred)
X10 = X_0[dbscan.labels_ == 0]
X11 = X_0[dbscan.labels_ == 1]
X12 = X_0[dbscan.labels_ == 2]
plt.scatter(X10[:, 0], X10[:, 1], c="darkorange", marker='o', label='label0')
plt.scatter(X11[:, 0], X11[:, 1], c="grey", marker='*', label='label1')
plt.scatter(X12[:, 0], X12[:, 1], c="blue", marker='+', label='label2')
plt.xlabel('petal length')
plt.ylabel('petal width')
plt.legend(loc=2)
plt.show()
estimator_1 = KMeans(n_clusters=3) # 构造聚类器:K-means
estimator_1.fit(X_0)
label_pred_1 = estimator_1.labels_ # 获取聚类标签
# 绘制k-means结果
x00 = X_0[label_pred_1 == 0]
x01 = X_0[label_pred_1 == 1]
x02 = X_0[label_pred_1 == 2]
plt.scatter(x00[:, 0], x00[:, 1], c="red", marker='o', label='label0')
plt.scatter(x01[:, 0], x01[:, 1], c="green", marker='*', label='label1')
plt.scatter(x02[:, 0], x02[:, 1], c="blue", marker='+', label='label2')
plt.xlabel('petal length')
plt.ylabel('petal width')
plt.legend(loc=2)
plt.show()