admin管理员组

文章数量:1660205

🎩 欢迎来到技术探索的奇幻世界👨‍💻

📜 个人主页:@一伦明悦-CSDN博客

✍🏻 作者简介: C++软件开发、Python机器学习爱好者

🗣️ 互动与支持:💬评论      👍🏻点赞      📂收藏     👀关注+

如果文章有所帮助,欢迎留下您宝贵的评论,点赞加收藏支持我,点击关注,一起进步!


目录

前言       

正文  

01-聚类分析简介   

02-绘制基于层次聚类的树状图   

03-基于特征集聚方法合并相似特征   

04-均值移位聚类算法实例分析   

05-k-均值聚类算法假设的证明   

总结       

参考文献


前言       

        机器学习中的聚类分析是一种无监督学习方法,旨在将数据点划分为相似的组或簇,使得同一组内的数据点彼此相似,而不同组之间的数据点则相对较不相似。聚类分析可以帮助我们理解数据的内在结构,发现数据中隐藏的模式,并将数据进行自然的分组,从而为进一步分析或决策提供基础。

正文  

01-聚类分析简介   

        在机器学习中,常见的聚类算法包括:

        K-Means 聚类:将数据点分成预先指定的 k 个簇,每个簇具有最小化簇内平方误差的中心点。K-Means 是一种迭代算法,通过不断更新簇中心点来优化聚类结果。

        层次聚类:逐步将数据点合并到不断增长的聚类中,形成层次结构。层次聚类可分为凝聚式和分裂式两种方法,分别是自底向上和自顶向下的聚类过程。

        谱聚类:基于图论中的谱分析方法,通过构建数据的相似度矩阵,并对其进行特征分解来进行聚类。谱聚类通常适用于数据集中存在非凸形状的聚类结构或者复杂的聚类结构。

        均值移位聚类:基于核密度估计的非参数聚类方法,通过寻找数据空间中密度最大化的区域来发现聚类中心。

        DBSCAN:基于密度的聚类算法,将高密度区域视为聚类,并通过将低密度区域视为噪声点来实现聚类。

        亲密传播聚类:基于图论的聚类方法,通过在数据点之间传播消息来发现聚类中心,并将数据点分配到这些中心。

        这些算法各有特点,适用于不同类型的数据和聚类问题。在选择聚类算法时,需要考虑数据的特征、聚类结构的性质以及算法的计算复杂度等因素。下面从一些实例中分析应用过程:

02-绘制基于层次聚类的树状图   

        层次聚类(Hierarchical Clustering):它是一种基于树形结构的聚类方法,它通过逐步将数据点合并到不断增长的聚类中来构建聚类层次结构。这种方法在不需要预先指定聚类数量的情况下能够发现数据的自然分组,并且提供了直观的可视化方式来展示数据点之间的相似性。

        层次聚类通常分为两种类型:凝聚式(自底向上)和分裂式(自顶向下)。

        凝聚式层次聚类

        凝聚式层次聚类从每个数据点作为一个单独的聚类开始,然后逐步将最相似的聚类合并,直到所有数据点都被合并到一个大的聚类中,形成完整的聚类层次结构。

        合并的相似性通常通过某种距离或相似度度量来确定,常见的度量包括欧氏距离、曼哈顿距离、相关系数等。

        该过程可以用树状图(树状图或树状图)来表示,树的节点表示聚类,树的叶子节点表示单个数据点,树的分支表示聚类的合并过程。

        分裂式层次聚类

        分裂式层次聚类从一个包含所有数据点的大型聚类开始,然后逐步将其分割成更小的子聚类,直到每个子聚类只包含一个数据点为止。

        分割的过程通常通过将大聚类中的数据点分割成两个或多个子聚类来完成,这种分割是基于某种判据,例如距离的增长或者类内方差的减小。

        层次聚类的优点包括:

        a、不需要预先指定聚类数量,能够自动发现数据的聚类结构。

        b、提供了直观的聚类层次结构,便于对数据的分组和理解。

        c、可以通过树状图来可视化聚类结果,直观地展示数据点之间的相似性和层次关系。

        然而,层次聚类的缺点也是显而易见的:

        a、在处理大型数据集时,计算复杂度较高,尤其是凝聚式层次聚类需要计算所有数据点之间的距离或相似度。

        b、聚类结果可能受到初始化的影响,不同的初始化可能导致不同的聚类结果。

        c、对于非凸形状的聚类结构,层次聚类可能会产生不理想的结果。

        综上所述,层次聚类是一种强大而灵活的聚类方法,适用于多种类型的数据和聚类问题。通过了解其原理和特点,可以更好地应用和理解这一方法。

        下面给出具体代码分析应用过程,这段代码是用于绘制层次聚类的树状图,展示数据点之间的聚类关系和层次结构。解释如下:

        导入必要的库:首先,代码导入了必要的库,包括NumPy用于数值计算,Matplotlib用于绘图,SciPy中的层次聚类模块和Scikit-Learn中的数据集和聚类算法。

        定义绘制树状图的函数 plot_dendrogram:这个函数的作用是根据层次聚类模型的结果绘制树状图。函数首先计算每个节点下的样本数量,然后创建链接矩阵,最后绘制树状图。

        加载数据集:代码加载了鸢尾花(iris)数据集,这是一个经典的机器学习数据集,包含了三种不同种类的鸢尾花的花萼和花瓣的长度和宽度。

        初始化层次聚类模型 AgglomerativeClustering:这里使用了Scikit-Learn中的AgglomerativeClustering类来进行层次聚类。distance_threshold=0表示不设置距离阈值,n_clusters=None表示不指定聚类数量,而是通过完整的树状图展示聚类结构。

        拟合模型并绘制树状图:代码对模型进行拟合,并调用plot_dendrogram函数绘制树状图。truncate_mode='level', p=3指定了截断模式为按层级截断,只显示树的前三个层级。这有助于避免树状图过于复杂而难以解读。

import numpy as np

from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram
from sklearn.datasets import load_iris
from sklearn.cluster import AgglomerativeClustering
plt.rcParams['font.sans-serif'] = ['SimHei']  #解决中文显示乱码问题
plt.rcParams['axes.unicode_minus'] = False 

def plot_dendrogram(model, **kwargs):
    # Create linkage matrix and then plot the dendrogram

    # create the counts of samples under each node
    counts = np.zeros(model.children_.shape[0])
    n_samples = len(model.labels_)
    for i, merge in enumerate(model.children_):
        current_count = 0
        for child_idx in merge:
            if child_idx < n_samples:
                current_count += 1  # leaf node
            else:
                current_count += counts[child_idx - n_samples]
        counts[i] = current_count

    linkage_matrix = np.column_stack([model.children_, model.distances_,
                                      counts]).astype(float)

    # Plot the corresponding dendrogram
    dendrogram(linkage_matrix, **kwargs)


iris = load_iris()
X = iris.data

# setting distance_threshold=0 ensures we compute the full tree.
model = AgglomerativeClustering(distance_threshold=0, n_clusters=None)

model = model.fit(X)
plt.title('分层聚类树状图')
# plot the top three levels of the dendrogram
plot_dendrogram(model, truncate_mode='level', p=3)
plt.xlabel("节点中的点数(如果没有括号,则为点的索引).")
plt.savefig("../4.png", dpi=500)
plt.show()

        实例运行结果如下图所示:图像展示了鸢尾花数据集的层次聚类结果。在树状图中,横轴表示样本点的索引或样本点所在的聚类,纵轴表示聚类过程中的距离或合并程度。通过观察树状图,可以发现不同样本点之间的聚类关系和层次结构,以及聚类过程中的合并情况。

03-基于特征集聚方法合并相似特征   

        特征集聚(Affinity Propagation):它是一种基于消息传递的聚类算法,旨在通过网络中的消息传递来识别数据中的样本点作为聚类中心的候选项,并将其它样本点分配给这些中心。这种方法与传统的聚类算法不同,它不需要事先指定聚类的数量,而是自动地找出数据中的潜在聚类中心。

        以下是特征集聚算法的主要步骤:

        相似度矩阵计算:首先,根据数据集中样本点之间的相似度,构建一个相似度矩阵。相似度通常可以使用欧氏距离、余弦相似度等度量来计算。

        消息传递:算法通过在样本点之间交换两种类型的消息来进行迭代。一种是"责任"(responsibility)消息,表示样本点 𝑖i 希望样本点 𝑗j 作为其聚类中心的程度;另一种是"可用性"(availability)消息,表示样本点 𝑗j 作为聚类中心的适合程度。通过更新这两种消息,算法逐步收敛到合适的聚类结果。

        聚类中心选择:在每次迭代中,算法根据当前的责任和可用性消息,选择作为聚类中心的样本点。这些样本点通常具有较高的可用性和责任值,被视为潜在的聚类中心。

        样本点分配:根据聚类中心的选择,算法将其它样本点分配给这些中心。分配的依据是每个样本点与各个聚类中心之间的相似度以及其它样本点对当前样本点的影响程度。

        收敛判据:算法通过设置收敛条件(例如消息变化小于某个阈值或达到最大迭代次数)来确定是否达到了最终的聚类结果。

        特征集聚的优点包括:

        a、不需要预先指定聚类数量,能够自动发现数据的聚类结构。

        b、能够处理非凸形状的聚类结构,并且对噪声数据相对鲁棒。

        然而,特征集聚也有一些缺点:

        a、算法的时间复杂度较高,尤其是在处理大型数据集时。

        b、对于某些数据集,算法可能收敛到局部最优解而非全局最优解。

        c、算法的性能高度依赖于相似度矩阵的构建,不同的相似度度量和参数选择可能导致不同的聚类结果。

        综上所述,特征集聚是一种灵活且有效的聚类算法,尤其适用于不确定聚类数量的情况下。通过消息传递和迭代优化,它能够发现数据中的潜在聚类结构,并在一定程度上克服了传统聚类算法的一些限制。

        下面给出具体应用实例分析应用过程:这段代码展示了使用特征集聚类(Feature Agglomeration)对手写数字图像进行降维和重建的过程,并展示了原始图像、聚合后的图像以及聚类标签的可视化结果。解释如下:

        导入必要的库:代码导入了NumPy用于数值计算,Matplotlib用于绘图,以及Scikit-Learn中的数据集和聚类模块。

        加载手写数字数据集:代码加载了Scikit-Learn中的手写数字数据集(digits),该数据集包含了一系列手写数字图像。

        准备数据:通过对图像进行reshape操作,将二维图像数据转换为一维向量。同时,使用grid_to_graph函数构建了图像的连通性,用于特征集聚类。

        特征集聚类:使用cluster.FeatureAgglomeration类进行特征集聚类,其中connectivity参数指定了图像的连通性,n_clusters参数指定了聚类的数量。

        降维和重建:通过fittransform方法对数据进行降维,然后使用inverse_transform方法将降维后的数据重建到原始维度。

import numpy as np
import matplotlib.pyplot as plt

from sklearn import datasets, cluster
from sklearn.feature_extraction.image import grid_to_graph

digits = datasets.load_digits()
images = digits.images
X = np.reshape(images, (len(images), -1))
connectivity = grid_to_graph(*images[0].shape)

agglo = cluster.FeatureAgglomeration(connectivity=connectivity,
                                     n_clusters=32)

agglo.fit(X)
X_reduced = agglo.transform(X)

X_restored = agglo.inverse_transform(X_reduced)
images_restored = np.reshape(X_restored, images.shape)
plt.figure(1, figsize=(4, 3.5))
plt.clf()
plt.subplots_adjust(left=.01, right=.99, bottom=.01, top=.91)
for i in range(4):
    plt.subplot(3, 4, i + 1)
    plt.imshow(images[i], cmap=plt.cm.gray, vmax=16, interpolation='nearest')
    plt.xticks(())
    plt.yticks(())
    if i == 1:
        plt.title('原始数据')
    plt.subplot(3, 4, 4 + i + 1)
    plt.imshow(images_restored[i], cmap=plt.cm.gray, vmax=16,
               interpolation='nearest')
    if i == 1:
        plt.title('聚合数据')
    plt.xticks(())
    plt.yticks(())

plt.subplot(3, 4, 10)
plt.imshow(np.reshape(agglo.labels_, images[0].shape),
           interpolation='nearest', cmap=plt.cm.nipy_spectral)
plt.xticks(())
plt.yticks(())
plt.title('标签')
plt.savefig("../4.png", dpi=500)
plt.show()

         实例运行结果如下图所示:图像解释:

        a、左侧列显示了原始的手写数字图像。

        b、右侧列显示了经过特征集聚类降维和重建后的图像。

        c、底部显示了聚类标签的可视化结果,将聚类标签映射为颜色。

        这样的可视化结果有助于理解特征集聚类对数据的降维效果,并且可以直观地观察到降维后的图像重建质量以及聚类标签的分布情况。

04-均值移位聚类算法实例分析   

        均值移位聚类算法(Mean Shift Clustering):它是一种基于密度估计的非参数聚类算法,它能够自动地发现数据中的聚类中心,并将样本点归属到这些中心。与K均值等聚类算法不同,均值移位算法不需要预先指定聚类数量,因此适用于各种类型的数据,尤其适用于具有复杂形状和尺寸不均匀的聚类结构。

        以下是均值移位聚类算法的主要步骤:

        核密度估计:首先,算法通过对数据进行核密度估计来寻找潜在的聚类中心。核密度估计是一种估计数据点周围密度的方法,通常使用高斯核函数进行计算。

        均值漂移:在核密度估计的基础上,算法通过迭代地移动每个样本点,使其向局部密度最大的方向移动。这个移动的过程是通过计算每个样本点周围数据点的密度加权平均来实现的,因此被称为“均值漂移”。

        聚类中心确定:在均值漂移过程中,样本点会向局部密度最大的区域移动,最终会收敛到密度较高的区域,这些区域即为聚类中心。

        样本点归属:根据最终确定的聚类中心,将每个样本点分配给距离其最近的聚类中心,确定每个样本点的聚类归属。

        收敛判据:算法通常通过设置收敛条件(例如,迭代次数或移动距离小于某个阈值)来确定是否达到了最终的聚类结果。

        均值移位聚类算法的优点包括:

        a、不需要预先指定聚类数量,能够自动发现数据的聚类结构。

        b、能够处理非凸形状和尺寸不均匀的聚类结构。

        c、不需要假设数据的分布类型,适用于各种类型的数据。

        然而,均值移位聚类算法也有一些缺点:

        a、算法的时间复杂度较高,特别是在处理大型数据集时。

        b、对初始聚类中心的选择和带宽参数的设定较为敏感,可能影响聚类结果的质量。

        c、在处理高维数据时,需要特别注意带宽参数的选择,以避免过度平滑或过度集中的问题。

        综上所述,均值移位聚类算法是一种灵活且有效的聚类方法,尤其适用于不确定聚类数量和具有复杂结构的数据。通过核密度估计和均值漂移过程,它能够自动地找出数据中的聚类中心,并将样本点归属到这些中心,从而实现聚类分析。

        下面给出具体应用实例分析应用过程:这段代码演示了如何使用均值移位聚类算法对生成的样本数据进行聚类,并可视化聚类结果。解释如下:

        生成样本数据:首先使用make_blobs函数生成了一个具有三个中心的随机样本数据集。这个数据集包含了10000个样本,每个中心点周围的标准差为0.6。

        计算带宽:使用estimate_bandwidth函数估计了均值移位算法中的带宽参数。这个参数用于控制聚类的宽度,影响着聚类中心的数量和形状。

        应用均值移位聚类:使用MeanShift类构建了均值移位聚类器,并将估计的带宽参数传入。在这个例子中,还设置了bin_seeding=True,表示使用数据的离散化来初始化聚类中心。

        获取聚类结果:通过调用fit方法拟合模型,并获取聚类的标签和聚类中心。

        可视化聚类结果:使用Matplotlib绘制了聚类结果的散点图。每个聚类用不同的颜色表示,聚类中心用大圆圈标出。

import numpy as np
from sklearn.cluster import MeanShift, estimate_bandwidth
from sklearn.datasets import make_blobs

# #############################################################################
# Generate sample data
centers = [[1, 1], [-1, -1], [1, -1]]
X, _ = make_blobs(n_samples=10000, centers=centers, cluster_std=0.6)

# #############################################################################
# Compute clustering with MeanShift

# The following bandwidth can be automatically detected using
bandwidth = estimate_bandwidth(X, quantile=0.2, n_samples=500)

ms = MeanShift(bandwidth=bandwidth, bin_seeding=True)
ms.fit(X)
labels = ms.labels_
cluster_centers = ms.cluster_centers_

labels_unique = np.unique(labels)
n_clusters_ = len(labels_unique)

print("估计的集群数 : %d" % n_clusters_)

# #############################################################################
# Plot result
import matplotlib.pyplot as plt
from itertools import cycle

plt.figure(1)
plt.clf()

colors = cycle('bgrcmykbgrcmykbgrcmykbgrcmyk')
for k, col in zip(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('估计的集群数: %d' % n_clusters_)
plt.savefig("../4.png", dpi=500)
plt.show()

        实例运行结果如下图所示:

        在生成的图像中,你可以看到不同颜色的点代表了不同的聚类,而大圆圈则表示了每个聚类的中心。这些聚类中心是根据数据的密度分布自动确定的,而不需要预先指定聚类的数量。这正是均值移位聚类算法的一个优势所在。

        通过观察图像,你可以看到数据点被聚类成了三个主要的簇,对应着我们在生成样本数据时设定的三个中心。这说明均值移位算法成功地识别出了数据中的聚类结构,并将数据点分配到了相应的簇中。

05-k-均值聚类算法假设的证明   

        k-均值聚类算法(K-means Clustering):它是一种常用的基于距离的聚类算法,它将数据点分为预先指定数量的簇,以使簇内的数据点尽可能接近簇内的中心点(质心),并且尽可能远离其他簇的中心点。下面是k-均值聚类算法的主要步骤:

        初始化:首先,随机选择k个数据点作为初始簇中心(质心)。

        分配样本:将每个数据点分配给距离其最近的簇中心,形成k个簇。

        更新簇中心:对每个簇,计算该簇所有数据点的均值,将该均值作为新的簇中心。

        重复步骤2和步骤3,直到簇中心不再发生变化或者达到预定的迭代次数。

        收敛判据:通常使用簇中心的变化量或者迭代次数来确定算法是否收敛。

        k-均值聚类算法的优点包括:

        a、简单、直观,易于理解和实现。

        b、对处理大型数据集具有较高的效率。

        c、在处理凸形状簇时表现良好。

        然而,k-均值聚类算法也有一些缺点:

        a、需要预先指定簇的数量k,对结果产生影响。

        b、对初始簇中心的选择敏感,可能导致陷入局部最优解。

        c、对非凸形状的簇效果较差。

        总的来说,k-均值聚类算法是一种常用且有效的聚类方法,特别适用于处理大型数据集和凸形状簇。然而,在处理非凸形状簇或者不确定簇数量的情况下,可能需要考虑其他聚类算法。

        下面给出具体应用实例分析应用过程:这段代码演示了使用K均值聚类算法在不同情况下对数据进行聚类,并可视化了聚类结果。解释如下:

        生成样本数据:使用make_blobs函数生成了四组不同特征的随机样本数据集,其中包括了不同形状、大小和方差的斑点。

        聚类并可视化:对于每组样本数据,使用K均值聚类算法进行聚类,并将聚类结果可视化在一个大图中的不同子图中。

                第一个子图:展示了一个blob数据集,但指定的聚类数量不正确(n_clusters=2),导致部分数据点被错误地分配到了同一个簇中。

                第二个子图:展示了一个具有各向异性分布的blob数据集,由于数据点的分布形状不规则,K均值聚类可能无法很好地捕捉到簇的形状。

                第三个子图:展示了一个具有不同方差的blob数据集,这种情况下,K均值聚类可能会受到不同方差的影响,导致聚类结果不理想。

                第四个子图:展示了一个大小不均匀的blob数据集,其中一些簇比其他簇更大,这种情况下,K均值聚类可能会对较大的簇进行过度拟合,而忽略掉较小的簇。

        通过观察这些子图,可以更好地理解K均值聚类算法在不同数据情况下的表现,以及它对于数据分布形状、方差和大小的敏感程度。

import numpy as np
import matplotlib.pyplot as plt

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

plt.figure(figsize=(12, 12))

n_samples = 1500
random_state = 170
X, y = make_blobs(n_samples=n_samples, random_state=random_state)

# Incorrect number of clusters
y_pred = KMeans(n_clusters=2, random_state=random_state).fit_predict(X)

plt.subplot(221)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.title("Blob 数不正确")

# Anisotropicly distributed data
transformation = [[0.60834549, -0.63667341], [-0.40887718, 0.85253229]]
X_aniso = np.dot(X, transformation)
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_aniso)

plt.subplot(222)
plt.scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)
plt.title("各向异性分布的 Blob")

# Different variance
X_varied, y_varied = make_blobs(n_samples=n_samples,
                                cluster_std=[1.0, 2.5, 0.5],
                                random_state=random_state)
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_varied)

plt.subplot(223)
plt.scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)
plt.title("不等方差")

# Unevenly sized blobs
X_filtered = np.vstack((X[y == 0][:500], X[y == 1][:100], X[y == 2][:10]))
y_pred = KMeans(n_clusters=3,
                random_state=random_state).fit_predict(X_filtered)

plt.subplot(224)
plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)
plt.title("大小不均匀的斑点")
plt.savefig("../4.png", dpi=500)
plt.show()

        实例运行结果如下图所示:

总结       

        综上所述,以下是对层次聚类、特征集聚、均值移位聚类和k-均值聚类四种聚类算法的简要总结:

        层次聚类原理:层次聚类是一种自底向上或自顶向下的聚类方法,通过将数据点逐步合并或分割成不同的簇来构建聚类层次结构。优点:不需要预先指定聚类数量;可以形成聚类的层次结构,提供更丰富的信息。缺点:计算复杂度较高;对于大型数据集可能不太适用。

        特征集聚原理:特征集聚是一种基于特征选择的聚类方法,它将数据点聚类时不仅考虑数据本身的相似性,还考虑到特征之间的相似性。优点:能够处理高维数据;可以发现特征之间的关联性。缺点:对特征之间的相似性定义较为复杂;计算量可能较大。

        均值移位聚类原理:均值移位聚类是一种基于密度估计的非参数聚类方法,通过迭代地调整数据点的位置来找到局部最优的聚类中心。优点:不需要预先指定聚类数量;对于不规则形状的簇具有较好的适应性。缺点:计算复杂度较高;可能收敛速度较慢。

        k-均值聚类原理:k-均值聚类是一种基于距离的聚类方法,将数据点分配到预先指定数量的簇中,使得簇内数据点尽可能接近簇中心。优点:简单、直观;对于大型数据集具有较高的效率。缺点:需要预先指定簇的数量;对初始簇中心敏感;对非凸形状的簇效果较差。

        总的来说,选择合适的聚类算法取决于数据的特点、聚类的目的以及算法的计算效率要求。在实际应用中,常常需要根据具体情况选择合适的算法并进行参数调优。

参考文献

[1] Dorin Comaniciu and Peter Meer, “Mean Shift: A robust approach toward feature space analysis”. IEEE Transactions on Pattern Analysis and Machine Intelligence. 2002. pp. 603-619.

本文标签: 算法实战进阶均值机器