接上一篇:
#### DBSCAN
from sklearn.cluster import DBSCAN
X, y = make_blobs(random_state=0, n_samples=12)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X)
print("Cluster memberships:\n{}".format(clusters))
# 所有数据点都被分配了标签-1,这代表噪声。这是eps和min_samples默认参数设置的结果,对于小型的玩具数据集并没有调节这些参数
Cluster memberships:
[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
mglearn.plots.plot_dbscan()
# min_samples和eps取不同值时的簇分类如下所示
# 在这张图中,属于簇的点是实心的,而噪声点则显示为空心的。核心样本显示为较大的标记,
# 而边界点则显示为较小的标记。增大eps(在图中从左到右),更多的点会被包含在一个簇中。
# 这让簇变大,但可能也会导致多个簇合并成一个。
# 增大min_samples(在图中从上到下),核心点会变得更少,更多的点被标记为噪声。
# 参数eps在某种程度上更加重要,因为它决定了点与点之间“接近”的含义。
# 将eps设置得非常小,意味着没有点是核心样本,可能会导致所有点都被标记为噪声。
# 将eps设置得非常大,可能会导致所有点形成单个簇。
# 设置min_samples主要是为了判断稀疏区域内的点被标记为异常值还是形成自己的簇。
# 如果增大min_samples,任何一个包含少于min_samples个样本的簇现在将被标记为噪声。
# 因此,min_samples决定簇的最小尺寸。在图3-37中eps=1.5时,从min_samples=3到min_samples=5,
# 你可以清楚地看到这一点。min_samples=3时有三个簇:一个包含4个点,一个包含5个点,一个包含3个点。min_samples=5时,
# 两个较小的簇(分别包含3个点和4 个点)现在被标记为噪声,只保留包含5个样本的簇。
# 虽然DBSCAN不需要显式地设置簇的个数,但设置eps可以隐式地控制找到的簇的个数。
# 使用StandardScaler或MinMaxScaler对数据进行缩放之后,
# 有时会更容易找到eps的较好取值,因为使用这些缩放技术将确保所有特征具有相似的范围
min_samples: 2 eps: 1.000000 cluster: [-1 0 0 -1 0 -1 1 1 0 1 -1 -1]
min_samples: 2 eps: 1.500000 cluster: [0 1 1 1 1 0 2 2 1 2 2 0]
min_samples: 2 eps: 2.000000 cluster: [0 1 1 1 1 0 0 0 1 0 0 0]
min_samples: 2 eps: 3.000000 cluster: [0 0 0 0 0 0 0 0 0 0 0 0]
min_samples: 3 eps: 1.000000 cluster: [-1 0 0 -1 0 -1 1 1 0 1 -1 -1]
min_samples: 3 eps: 1.500000 cluster: [0 1 1 1 1 0 2 2 1 2 2 0]
min_samples: 3 eps: 2.000000 cluster: [0 1 1 1 1 0 0 0 1 0 0 0]
min_samples: 3 eps: 3.000000 cluster: [0 0 0 0 0 0 0 0 0 0 0 0]
min_samples: 5 eps: 1.000000 cluster: [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
min_samples: 5 eps: 1.500000 cluster: [-1 0 0 0 0 -1 -1 -1 0 -1 -1 -1]
min_samples: 5 eps: 2.000000 cluster: [-1 0 0 0 0 -1 -1 -1 0 -1 -1 -1]
min_samples: 5 eps: 3.000000 cluster: [0 0 0 0 0 0 0 0 0 0 0 0]
下图展示了在two_moons数据集上运行DBSCAN的结果。利用默认设置,算法找到了两个半圆形并将其分开
# 图3-38展示了在two_moons数据集上运行DBSCAN的结果。利用默认设置,算法找到了两个半圆形并将其分开
X, y = make_moons(n_samples=200, noise=0.05, random_state=0)
# Rescale the data to zero mean and unit variance
# 将数据缩放成平均值为0、方差为1
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X_scaled)
# plot the cluster assignments
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=clusters, cmap=mglearn.cm2, s=60)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
由于算法找到了我们想要的簇的个数(2个),因此参数设置的效果似乎很好。如果将eps 减小到0.2(默认值为0.5),我们将会得到8个簇,这显然太多了。将eps增大到0.7则会导致只有一个簇。