共计 10500 个字符,预计需要花费 27 分钟才能阅读完成。
无监督聚类办法的评估指标必须依赖于数据和聚类后果的外在属性,例如聚类的紧凑性和分离性,与内部常识的一致性,以及同一算法不同运行后果的稳定性。
本文将全面概述 Scikit-Learn 库中用于的聚类技术以及各种评估办法。
本文将分为 2 个局部,1、常见算法比拟 2、聚类技术的各种评估办法
本文作为第一局部将介绍和比拟各种聚类算法:
- K-Means
- Affinity Propagation
- Agglomerative Clustering
- Mean Shift Clustering
- Bisecting K-Means
- DBSCAN
- OPTICS
- BIRCH
首先咱们生成一些数据,前面将应用这些数据作为聚类技术的输出。
importpandasaspd
importnumpyasnp
importseabornassns
importmatplotlib.pyplotasplt
#Set the number of samples and features
n_samples=1000
n_features=4
#Create an empty array to store the data
data=np.empty((n_samples, n_features))
#Generate random data for each feature
foriinrange(n_features):
data[:, i] =np.random.normal(size=n_samples)
#Create 5 clusters with different densities and centroids
cluster1=data[:200, :] +np.random.normal(size=(200, n_features), scale=0.5)
cluster2=data[200:400, :] +np.random.normal(size=(200, n_features), scale=1) +np.array([5,5,5,5])
cluster3=data[400:600, :] +np.random.normal(size=(200, n_features), scale=1.5) +np.array([-5,-5,-5,-5])
cluster4=data[600:800, :] +np.random.normal(size=(200, n_features), scale=2) +np.array([5,-5,5,-5])
cluster5=data[800:, :] +np.random.normal(size=(200, n_features), scale=2.5) +np.array([-5,5,-5,5])
#Combine the clusters into one dataset
X=np.concatenate((cluster1, cluster2, cluster3, cluster4, cluster5))
# Plot the data
plt.scatter(X[:, 0], X[:, 1])
plt.show()
后果如下:
咱们将用特征值和簇 ID 创立一个 DF。稍后在模型性能时将应用这些数据。
df=pd.DataFrame(X, columns=["feature_1", "feature_2", "feature_3", "feature_4"])
cluster_id=np.concatenate((np.zeros(200), np.ones(200), np.full(200, 2), np.full(200, 3), np.full(200, 4)))
df["cluster_id"] =cluster_id
df
当初咱们将构建和可视化 8 个不同的聚类模型:
1、K-Means
K-Means 聚类算法是一种罕用的聚类算法,它将数据点分为 K 个簇,每个簇的中心点是其所有成员的平均值。K-Means 算法的外围是迭代寻找最优的簇心地位,直到达到收敛状态。
K-Means 算法的长处是简略易懂,计算速度较快,实用于大规模数据集。然而它也存在一些毛病,例如对于非球形簇的解决能力较差,容易受到初始簇心的抉择影响,须要预先指定簇的数量 K 等。此外,当数据点之间存在噪声或者离群点时,K-Means 算法可能会将它们调配到谬误的簇中。
#K-Means
fromsklearn.clusterimportKMeans
#Define function:
kmeans=KMeans(n_clusters=5)
#Fit the model:
km=kmeans.fit(X)
km_labels=km.labels_
#Print results:
#print(kmeans.labels_)
#Visualise results:
plt.scatter(X[:, 0], X[:, 1],
c=kmeans.labels_,
s=70, cmap='Paired')
plt.scatter(kmeans.cluster_centers_[:, 0],
kmeans.cluster_centers_[:, 1],
marker='^', s=100, linewidth=2,
c=[0, 1, 2, 3, 4])
2、Affinity Propagation
Affinity Propagation 是一种基于图论的聚类算法,旨在辨认数据中的 ”exemplars”(代表点) 和 ”clusters”(簇)。与 K -Means 等传统聚类算法不同,Affinity Propagation 不须要当时指定聚类数目,也不须要随机初始化簇心,而是通过计算数据点之间的相似性得出最终的聚类后果。
Affinity Propagation 算法的长处是不须要预先指定聚类数目,且可能解决非凸形态的簇。然而该算法的计算复杂度较高,须要大量的存储空间和计算资源,并且对于噪声点和离群点的解决能力较弱。
fromsklearn.clusterimportAffinityPropagation
#Fit the model:
af=AffinityPropagation(preference=-563, random_state=0).fit(X)
cluster_centers_indices=af.cluster_centers_indices_
af_labels=af.labels_
n_clusters_=len(cluster_centers_indices)
#Print number of clusters:
print(n_clusters_)
importmatplotlib.pyplotasplt
fromitertoolsimportcycle
plt.close("all")
plt.figure(1)
plt.clf()
colors=cycle("bgrcmykbgrcmykbgrcmykbgrcmyk")
fork, colinzip(range(n_clusters_), colors):
class_members=af_labels==k
cluster_center=X[cluster_centers_indices[k]]
plt.plot(X[class_members, 0], X[class_members, 1], col+".")
plt.plot(cluster_center[0],
cluster_center[1],
"o",
markerfacecolor=col,
markeredgecolor="k",
markersize=14,
)
forxinX[class_members]:
plt.plot([cluster_center[0], x[0]], [cluster_center[1], x[1]], col)
plt.title("Estimated number of clusters: %d"%n_clusters_)
plt.show()
3、Agglomerative Clustering
凝聚档次聚类(Agglomerative Clustering)是一种自底向上的聚类算法,它将每个数据点视为一个初始簇,并将它们逐渐合并成更大的簇,直到达到进行条件为止。在该算法中,每个数据点最后被视为一个独自的簇,而后逐渐合并簇,直到所有数据点被合并为一个大簇。
Agglomerative Clustering 算法的长处是实用于不同形态和大小的簇,且不须要当时指定聚类数目。此外,该算法也能够输入聚类层次结构,便于剖析和可视化。毛病是计算复杂度较高,尤其是在解决大规模数据集时,须要耗费大量的计算资源和存储空间。此外,该算法对初始簇的抉择也比拟敏感,可能会导致不同的聚类后果。
fromsklearn.clusterimportAgglomerativeClustering
#Fit the model:
clustering=AgglomerativeClustering(n_clusters=5).fit(X)
AC_labels=clustering.labels_
n_clusters=clustering.n_clusters_
print("number of estimated clusters : %d"%clustering.n_clusters_)
# Plot clustering results
colors= ['purple', 'orange', 'green', 'blue', 'red']
forindex, metricinenumerate([#"cosine",
"euclidean",
#"cityblock"
]):
model=AgglomerativeClustering(n_clusters=5, linkage="ward", affinity=metric)
model.fit(X)
plt.figure()
plt.axes([0, 0, 1, 1])
forl, cinzip(np.arange(model.n_clusters), colors):
plt.plot(X[model.labels_==l].T, c=c, alpha=0.5)
plt.axis("tight")
plt.axis("off")
plt.suptitle("AgglomerativeClustering(affinity=%s)"%metric, size=20)
plt.show()
4、Mean Shift Clustering
Mean Shift Clustering 是一种基于密度的非参数聚类算法,其根本思维是通过寻找数据点密度最大的地位(称为 ” 部分最大值 ” 或 ” 顶峰 ”),来辨认数据中的簇。算法的外围是通过对每个数据点进行部分密度估计,并将密度估计的后果用于计算数据点挪动的方向和间隔。算法的外围是通过对每个数据点进行部分密度估计,并将密度估计的后果用于计算数据点挪动的方向和间隔。
Mean Shift Clustering 算法的长处是不须要指定簇的数目,且对于形态简单的簇也有很好的成果。算法还可能无效地解决噪声数据。他的毛病也是计算复杂度较高,尤其是在解决大规模数据集时,须要耗费大量的计算资源和存储空间,该算法还对初始参数的抉择比拟敏感,须要进行参数调整和优化。
fromsklearn.clusterimportMeanShift, estimate_bandwidth
# The following bandwidth can be automatically detected using
bandwidth=estimate_bandwidth(X, quantile=0.2, n_samples=100)
#Fit the model:
ms=MeanShift(bandwidth=bandwidth)
ms.fit(X)
MS_labels=ms.labels_
cluster_centers=ms.cluster_centers_
labels_unique=np.unique(labels)
n_clusters_=len(labels_unique)
print("number of estimated clusters : %d"%n_clusters_)
fromitertoolsimportcycle
plt.figure(1)
plt.clf()
colors=cycle("bgrcmykbgrcmykbgrcmykbgrcmyk")
fork, colinzip(range(n_clusters_), colors):
my_members=labels==k
cluster_center=cluster_centers[k]
plt.plot(X[my_members, 0], X[my_members, 1], col+".")
plt.plot(cluster_center[0],
cluster_center[1],
"o",
markerfacecolor=col,
markeredgecolor="k",
markersize=14,
)
plt.title("Estimated number of clusters: %d"%n_clusters_)
plt.show()
5、Bisecting K-Means
Bisecting K-Means 是一种基于 K -Means 算法的档次聚类算法,其根本思维是将所有数据点划分为一个簇,而后将该簇分成两个子簇,并对每个子簇别离利用 K -Means 算法,反复执行这个过程,直到达到预约的聚类数目为止。
算法首先将所有数据点视为一个初始簇,而后对该簇利用 K -Means 算法,将该簇分成两个子簇,并计算每个子簇的误差平方和(SSE)。而后,抉择误差平方和最大的子簇,并将其再次分成两个子簇,反复执行这个过程,直到达到预约的聚类数目为止。
Bisecting K-Means 算法的长处是具备较高的准确性和稳定性,可能无效地解决大规模数据集,并且不须要指定初始聚类数目。该算法还可能输入聚类层次结构,便于剖析和可视化。毛病是计算复杂度较高,尤其是在解决大规模数据集时,须要耗费大量的计算资源和存储空间。此外该算法对初始簇的抉择也比拟敏感,可能会导致不同的聚类后果。
fromsklearn.clusterimportBisectingKMeans
#Build and fit model:
bisect_means=BisectingKMeans(n_clusters=5).fit(X)
BKM_labels=bisect_means.labels_
#Print model attributes:
#print('Labels:', bisect_means.labels_)
print('Number of clusters:', bisect_means.n_clusters)
#Define varaibles to be included in scatterdot:
y=bisect_means.labels_
#print(y)
centers=bisect_means.cluster_centers_
# Visualize the results using a scatter plot
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.scatter(centers[:, 0], centers[:, 1], c='r', s=100)
plt.show()
6、DBSCAN
DBSCAN (Density-Based Spatial Clustering of Applications with Noise) 是一种基于密度的聚类算法,其能够无效地发现任意形态的簇,并可能解决噪声数据。DBSCAN 算法的核心思想是:对于一个给定的数据点,如果它的密度达到肯定的阈值,则它属于一个簇中;否则,它被视为噪声点。
DBSCAN 算法的长处是可能自动识别簇的数目,并且对于任意形态的簇都有较好的成果。并且还可能无效地解决噪声数据,不须要预先指定簇的数目。毛病是对于密度差别较大的数据集,可能会导致聚类成果不佳,须要进行参数调整和优化。另外该算法对于高维数据集的成果也不如其余算法
fromsklearn.clusterimportDBSCAN
db=DBSCAN(eps=3, min_samples=10).fit(X)
DBSCAN_labels=db.labels_
# Number of clusters in labels, ignoring noise if present.
n_clusters_=len(set(labels)) - (1if-1inlabelselse0)
n_noise_=list(labels).count(-1)
print("Estimated number of clusters: %d"%n_clusters_)
print("Estimated number of noise points: %d"%n_noise_)
unique_labels=set(labels)
core_samples_mask=np.zeros_like(labels, dtype=bool)
core_samples_mask[db.core_sample_indices_] =True
colors= [plt.cm.Spectral(each) foreachinnp.linspace(0, 1, len(unique_labels))]
fork, colinzip(unique_labels, colors):
ifk==-1:
# Black used for noise.
col= [0, 0, 0, 1]
class_member_mask=labels==k
xy=X[class_member_mask&core_samples_mask]
plt.plot(xy[:, 0],
xy[:, 1],
"o",
markerfacecolor=tuple(col),
markeredgecolor="k",
markersize=14,
)
xy=X[class_member_mask&~core_samples_mask]
plt.plot(xy[:, -1],
xy[:, 1],
"o",
markerfacecolor=tuple(col),
markeredgecolor="k",
markersize=6,
)
plt.title(f"Estimated number of clusters: {n_clusters_}")
plt.show()
7、OPTICS
OPTICS(Ordering Points To Identify the Clustering Structure)是一种基于密度的聚类算法,其可能主动确定簇的数量,同时也能够发现任意形态的簇,并可能解决噪声数据。OPTICS 算法的核心思想是:对于一个给定的数据点,通过计算它到其它点的间隔,确定其在密度上的可达性,从而构建一个基于密度的间隔图。而后,通过扫描该间隔图,主动确定簇的数量,并对每个簇进行划分。
OPTICS 算法的长处是可能主动确定簇的数量,并可能解决任意形态的簇,并可能无效地解决噪声数据。该算法还可能输入聚类层次结构,便于剖析和可视化。毛病是计算复杂度较高,尤其是在解决大规模数据集时,须要耗费大量的计算资源和存储空间。另外就是该算法对于密度差别较大的数据集,可能会导致聚类成果不佳。
fromsklearn.clusterimportOPTICS
importmatplotlib.gridspecasgridspec
#Build OPTICS model:
clust=OPTICS(min_samples=3, min_cluster_size=100, metric='euclidean')
# Run the fit
clust.fit(X)
space=np.arange(len(X))
reachability=clust.reachability_[clust.ordering_]
OPTICS_labels=clust.labels_[clust.ordering_]
labels=clust.labels_[clust.ordering_]
plt.figure(figsize=(10, 7))
G=gridspec.GridSpec(2, 3)
ax1=plt.subplot(G[0, 0])
ax2=plt.subplot(G[1, 0])
# Reachability plot
colors= ["g.", "r.", "b.", "y.", "c."]
forklass, colorinzip(range(0, 5), colors):
Xk=space[labels==klass]
Rk=reachability[labels==klass]
ax1.plot(Xk, Rk, color, alpha=0.3)
ax1.plot(space[labels==-1], reachability[labels==-1], "k.", alpha=0.3)
ax1.set_ylabel("Reachability (epsilon distance)")
ax1.set_title("Reachability Plot")
# OPTICS
colors= ["g.", "r.", "b.", "y.", "c."]
forklass, colorinzip(range(0, 5), colors):
Xk=X[clust.labels_==klass]
ax2.plot(Xk[:, 0], Xk[:, 1], color, alpha=0.3)
ax2.plot(X[clust.labels_==-1, 0], X[clust.labels_==-1, 1], "k+", alpha=0.1)
ax2.set_title("Automatic Clustering\nOPTICS")
plt.tight_layout()
plt.show()
8、BIRCH
BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)是一种基于档次聚类的聚类算法,其能够疾速地解决大规模数据集,并且对于任意形态的簇都有较好的成果。BIRCH 算法的核心思想是:通过对数据集进行分级聚类,逐渐减小数据规模,最终失去簇构造。BIRCH 算法采纳一种相似于 B 树的构造,称为 CF 树,它能够疾速地插入和删除子簇,并且能够主动均衡,从而确保簇的品质和效率。
BIRCH 算法的长处是可能疾速解决大规模数据集,并且对于任意形态的簇都有较好的成果。该算法对于噪声数据和离群点也有较好的容错性。毛病是对于密度差别较大的数据集,可能会导致聚类成果不佳,对于高维数据集的成果也不如其余算法。
importmatplotlib.colorsascolors
fromsklearn.clusterimportBirch, MiniBatchKMeans
fromtimeimporttime
fromitertoolsimportcycle
# Use all colors that matplotlib provides by default.
colors_=cycle(colors.cnames.keys())
fig=plt.figure(figsize=(12, 4))
fig.subplots_adjust(left=0.04, right=0.98, bottom=0.1, top=0.9)
# Compute clustering with BIRCH with and without the final clustering step
# and plot.
birch_models= [Birch(threshold=1.7, n_clusters=None),
Birch(threshold=1.7, n_clusters=5),
]
final_step= ["without global clustering", "with global clustering"]
forind, (birch_model, info) inenumerate(zip(birch_models, final_step)):
t=time()
birch_model.fit(X)
print("BIRCH %s as the final step took %0.2f seconds"% (info, (time() -t)))
# Plot result
labels=birch_model.labels_
centroids=birch_model.subcluster_centers_
n_clusters=np.unique(labels).size
print("n_clusters : %d"%n_clusters)
ax=fig.add_subplot(1, 3, ind+1)
forthis_centroid, k, colinzip(centroids, range(n_clusters), colors_):
mask=labels==k
ax.scatter(X[mask, 0], X[mask, 1], c="w", edgecolor=col, marker=".", alpha=0.5)
ifbirch_model.n_clustersisNone:
ax.scatter(this_centroid[0], this_centroid[1], marker="+", c="k", s=25)
ax.set_ylim([-12, 12])
ax.set_xlim([-12, 12])
ax.set_autoscaley_on(False)
ax.set_title("BIRCH %s"%info)
plt.show()
总结
下面就是咱们常见的 8 个聚类算法,咱们对他们进行了简略的阐明和比拟,并且用 sklearn 演示了如何应用,在下一篇文章中咱们将介绍聚类模型评估办法。
https://avoid.overfit.cn/edit?postslug=e8ecff6dce514fbbbad9c6d6b882fe4e