层次聚类算法 AGNES算法 BIRCH 算法 CURE算法 CHAMELEON算法

层级聚类算法分类

  • 自底向上的凝聚层次聚类:这种方法开始时将每个样本都视为一个单独的簇,然后不断合并最近的簇,直到满足某种停止条件(如簇的数量达到预设值、簇之间的距离超过某个阈值等)。常见的凝聚层次聚类算法有AGNES(AGglomerative NESting)算法等。
  • 自顶向下的分裂层次聚类:这种方法开始时将所有样本视为一个簇,然后不断分裂簇,直到满足某种停止条件(如簇的数量达到预设值、簇内部的紧密程度低于某个阈值等)。分裂层次聚类算法在实际应用中相对较少。

自底向上的凝聚层次聚类

  • 自底向上的凝聚层次聚类算法主要有以下几种:

AGNES(AGglomerative NESting)算法

  • AGNES是一种典型的自底向上的凝聚层次聚类算法。它开始时将每个样本都视为一个单独的簇,然后计算各簇之间的距离,并将最近的两个簇合并为一个新的簇。这个过程会不断迭代,直到满足某种停止条件(如簇的数量达到预设值、簇之间的距离超过某个阈值等)。AGNES算法的关键在于如何计算簇之间的距离,常见的距离度量方法包括最小距离、最大距离和平均距离等。
# 伪代码实现AGNES算法  
  
def agnes_clustering(data, max_clusters=None, distance_threshold=None):  
    # 初始化:每个数据点是一个簇  
    clusters = [{data_point} for data_point in data]  
      
    # 计算初始簇之间的距离矩阵  
    distance_matrix = compute_distance_matrix(clusters)  
      
    # 迭代直到满足停止条件  
    while True:  
        # 找出距离矩阵中的最小距离及其对应的簇对  
        min_dist, (cluster_i, cluster_j) = find_closest_clusters(distance_matrix)  
          
        # 如果达到最大簇数量或距离阈值,则停止迭代  
        if (max_clusters is not None and len(clusters) <= max_clusters) or min_dist >= distance_threshold:  
            break  
          
        # 合并簇  
        merged_cluster = cluster_i.union(cluster_j)  
          
        # 更新簇集合,移除被合并的簇,添加新簇  
        clusters.remove(cluster_i)  
        clusters.remove(cluster_j)  
        clusters.append(merged_cluster)  
          
        # 更新距离矩阵,计算新簇与其他簇之间的距离  
        distance_matrix = update_distance_matrix(clusters, distance_matrix, merged_cluster)  
      
    # 返回聚类结果  
    return clusters  
  
# 辅助函数:计算簇之间的距离矩阵  
def compute_distance_matrix(clusters):  
    # 实现计算簇间距离的逻辑,返回距离矩阵  
    pass  
  
# 辅助函数:找出距离最近的簇对  
def find_closest_clusters(distance_matrix):  
    # 实现找出最小距离及其对应的簇对的逻辑  
    pass  
  
# 辅助函数:更新距离矩阵,考虑新合并的簇  
def update_distance_matrix(clusters, old_distance_matrix, merged_cluster):  
    # 实现更新距离矩阵的逻辑,考虑新合并的簇  
    pass  
  
# 使用示例  
data = [...]  # 输入数据集  
clusters = agnes_clustering(data, max_clusters=5, distance_threshold=1.5)  
# clusters现在包含层次聚类的结果

BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)算法

  • 这是一种基于CF Tree(Clustering Feature Tree)的层次聚类算法。它通过使用CF Tree来存储和压缩数据,从而降低了内存消耗和计算复杂度。BIRCH算法能够处理大规模数据集,并且对于噪声和异常值具有一定的鲁棒性。
  • CF Tree(Clustering Feature Tree)是一种用于层次聚类的数据结构,特别适用于处理大规模数据集。它类似于平衡B+树,每个节点都由聚类特征(CF)组成。
  • CF Tree的每个节点包含三个聚类特征,它们构成一个三元组,用(N, LS, SS)来表示。其中,N表示该节点包含的样本数量,LS表示该节点包含的样本点的向量和,SS表示该节点包含的样本点各个特征的平方和。
  • 在CF Tree中,父节点的某个CF值等于其指向的所有子节点CF值的总和。CF Tree的构建过程是从空树开始,逐个读入样本并生成CF三元组,然后按照特定的规则将它们插入到树中。
class CFNode:  
    def __init__(self, threshold, entry_count):  
        self.threshold = threshold  # 阈值,用于决定是否分裂节点  
        self.entry_count = entry_count  # 当前节点包含的样本数量  
        self.LS = [0] * num_features  # 样本点向量和  
        self.SS = [0] * num_features  # 样本点各特征的平方和  
        self.children = []  # 子节点列表  
  
    def insert(self, sample):  
        # 插入一个样本到当前节点  
        for i in range(num_features):  
            self.LS[i] += sample[i]  
            self.SS[i] += sample[i] ** 2  
        self.entry_count += 1  
  
        # 如果超过阈值,则分裂节点  
        if self.entry_count > self.threshold:  
            self.split()  
  
    def split(self):  
        # 分裂节点  
        new_node = CFNode(self.threshold, 0)  
        for i in range(num_features):  
            # 将样本点向量和和平方和平均分配到两个子节点  
            new_node.LS[i] = self.LS[i] / 2  
            self.LS[i] -= new_node.LS[i]  
            new_node.SS[i] = self.SS[i] / 2  
            self.SS[i] -= new_node.SS[i]  
  
        self.entry_count = self.entry_count // 2  
        new_node.entry_count = self.entry_count  
  
        self.children.append(new_node)  
  
        # 递归地对子节点进行插入操作  
        for sample in self.samples:  
            new_node.insert(sample)  
  
    def merge(self, other_node):  
        # 合并两个节点  
        for i in range(num_features):  
            self.LS[i] += other_node.LS[i]  
            self.SS[i] += other_node.SS[i]  
        self.entry_count += other_node.entry_count  
  
        # 如果合并后超过阈值,则可能需要递归地合并子节点  
        if self.entry_count > self.threshold:  
            self.split()  
  
def birch_clustering(data, threshold):  
    # 初始化根节点  
    root = CFNode(threshold, 0)  
  
    # 遍历数据集,将样本插入到CF Tree中  
    for sample in data:  
        root.insert(sample)  
  
    # 执行聚类操作  
    clusters = []  
    for node in CFTree_traversal(root):  
        # 将节点转换为聚类  
        cluster = Cluster(node.LS, node.SS, node.entry_count)  
        clusters.append(cluster)  
  
    return clusters  
  
def CFTree_traversal(node):  
    # CF Tree的遍历函数  
    yield node  
    for child in node.children:  
        yield from CFTree_traversal(child)  
  
# 使用示例  
data = [...]  # 输入数据集  
threshold = ...  # 设置阈值  
clusters = birch_clustering(data, threshold)  
# clusters现在包含层次聚类的结果
  • CF Tree的主要优点是它能够有效地压缩数据并减少计算复杂度,从而在处理大规模数据集时提高聚类的效率。此外,由于它采用了树形结构,因此还具有天然的可扩展性和灵活性,可以方便地添加、删除或修改节点。这使得CF Tree成为一种非常适合于处理超大规模数据集的层次聚类算法。

CURE(Clustering Using Representatives)算法

CURE算法通过选择每个簇的代表点来进行聚类。它认为一个簇中的代表点应该能够反映该簇的整体形状和大小,而不仅仅是其中心或质心。因此,CURE算法在合并簇时,会考虑代表点之间的距离和数量,以得到更加合理的聚类结果。

import numpy as np  
  
class CURE:  
    def __init__(self, data, num_clusters, shrinkage_factor=0.5):  
        self.data = data                  # 输入数据集  
        self.num_clusters = num_clusters  # 期望的聚类数目  
        self.shrinkage_factor = shrinkage_factor  # 收缩因子,用于确定代表点的数量  
        self.representatives = []  # 代表点的集合  
        self.clusters = []  # 聚类结果的集合  
  
    def fit(self):  
        # 初始化:选择每个聚类的第一个代表点  
        self.representatives = self.data[:self.num_clusters]  
  
        # 迭代过程,直到代表点不再显著变化  
        while True:  
            # 计算每个点到最近代表点的距离  
            distances = self._calculate_distances(self.representatives)  
  
            # 更新代表点:选择每个聚类的中心点和最远的点作为新的代表点  
            new_representatives = []  
            for i in range(self.num_clusters):  
                # 找到第i个聚类的中心点  
                centroid = np.mean(self.data[distances[:, i] < np.inf], axis=0)  
  
                # 找到第i个聚类的最远点  
                farthest_point = self.data[np.argmax(distances[:, i])]  
  
                # 计算收缩后的点  
                shrunken_centroid = self._shrink(centroid, self.shrinkage_factor)  
  
                # 添加新的代表点到列表中  
                new_representatives.append(shrunken_centroid)  
                new_representatives.append(farthest_point)  
  
            # 检查代表点是否发生变化  
            if np.all(np.array(self.representatives) == np.array(new_representatives)):  
                break  
  
            self.representatives = new_representatives  
  
        # 使用最终的代表点生成聚类  
        self.clusters = self._form_clusters(self.representatives)  
  
    def _calculate_distances(self, representatives):  
        # 计算每个点到所有代表点的距离  
        distances = np.full((len(self.data), len(representatives)), np.inf)  
        for i, rep in enumerate(representatives):  
            distances[:, i] = np.linalg.norm(self.data - rep, axis=1)  
        return distances  
  
    def _shrink(self, point, factor):  
        # 根据收缩因子收缩点  
        return point * factor  
  
    def _form_clusters(self, representatives):  
        # 使用代表点形成聚类  
        clusters = []  
        for rep in representatives:  
            # 将每个点到最近代表点的距离小于无穷大的点分配到该聚类  
            cluster = self.data[np.min(np.linalg.norm(self.data - rep, axis=1), axis=1) < np.inf]  
            clusters.append(cluster)  
        return clusters  
  
# 使用示例  
data = np.random.rand(100, 2)  # 假设有100个二维数据点  
cure = CURE(data, num_clusters=5)  
cure.fit()  
  
# 输出聚类结果  
for i, cluster in enumerate(cure.clusters):  
    print(f"Cluster {i+1}: {cluster}")

CHAMELEON(Highly Adaptive MEthod for Learning Cluster Hierarchies from Data)算法

  • 这是一种基于动态模型的层次聚类算法。它通过使用一个动态模型来描述数据的分布和演化,从而能够发现不同尺度和密度的簇。CHAMELEON算法在处理复杂形状和密度的簇时表现出较好的性能。
import numpy as np  
from scipy.spatial.distance import pdist, squareform  
  
class CHAMELEON:  
    def __init__(self, data, k=5, m=2, t=2):  
        self.data = data  # 输入数据集  
        self.k = k  # k-最近邻参数  
        self.m = m  # 用于计算相似性的最小点数  
        self.t = t  # 阈值参数  
        self.graph = None  # 相似性图  
        self.clusters = []  # 聚类结果  
  
    def fit(self):  
        # 步骤1: 计算相似性图  
        self.graph = self._compute_similarity_graph(self.data)  
  
        # 步骤2: 初始化聚类  
        self.clusters = [self.data]  
  
        # 步骤3: 迭代聚类  
        while len(self.clusters) > 1:  
            new_clusters = []  
            for cluster in self.clusters:  
                # 步骤3.1: 计算子聚类  
                subclusters = self._compute_subclusters(cluster)  
                # 步骤3.2: 合并相似的子聚类  
                merged_clusters = self._merge_similar_clusters(subclusters)  
                new_clusters.extend(merged_clusters)  
            self.clusters = new_clusters  
  
    def _compute_similarity_graph(self, data):  
        # 计算数据点之间的距离  
        dist_matrix = squareform(pdist(data))  
        # 使用k-最近邻方法构建相似性图  
        graph = np.zeros((len(data), len(data)))  
        for i in range(len(data)):  
            for j in range(i+1, len(data)):  
                if dist_matrix[i, j] in np.sort(dist_matrix[i, :])[:self.k]:  
                    graph[i, j] = graph[j, i] = 1  
        return graph  
  
    def _compute_subclusters(self, cluster):  
        # 提取cluster中的数据点  
        data_points = cluster  
        # 计算点之间的相似性  
        similarity_matrix = np.dot(data_points, data_points.T)  
        # 初始化子聚类  
        subclusters = []  
        for i in range(len(data_points)):  
            subcluster = [data_points[i]]  
            for j in range(i+1, len(data_points)):  
                if similarity_matrix[i, j] > self.t:  
                    subcluster.append(data_points[j])  
            subclusters.append(subcluster)  
        return subclusters  
  
    def _merge_similar_clusters(self, subclusters):  
        # 合并相似的子聚类  
        merged_clusters = []  
        while subclusters:  
            clusters_to_merge = []  
            for sc in subclusters:  
                if not clusters_to_merge:  
                    clusters_to_merge.append(sc)  
                else:  
                    merged = False  
                    for c in clusters_to_merge:  
                        if self._is_similar(sc, c, self.m):  
                            merged = True  
                            break  
                    if not merged:  
                        clusters_to_merge.append(sc)  
            # 合并选中的子聚类  
            merged_cluster = np.vstack(clusters_to_merge)  
            merged_clusters.append(merged_cluster)  
            # 更新待合并的子聚类列表  
            subclusters = [sc for sc in subclusters if sc not in clusters_to_merge]  
        return merged_clusters  
  
    def _is_similar(self, cluster1, cluster2, m):  
        # 判断两个子聚类是否相似  
        # 这里使用简单的点集交集大小作为相似性的度量  
        intersection = len(set(cluster1).intersection(set(cluster2)))  
        return intersection >= min(len(cluster1), len(cluster2)) - m  
  
# 使用示例  
data = np.random.rand(100, 2)  # 假设有100个二维数据点  
chameleon = CHAMELEON(
  • 这些自底向上的凝聚层次聚类算法各有特点,适用于不同的数据集和聚类需求。在实际应用中,需要根据具体情况选择合适的算法,并进行参数调整和性能评估。

制作不易,感谢三连,谢谢啦

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AGNES(Agglomerative Nesting)层次聚类算法是一种自底向上的聚类算法。它首先将每个样本点看作是一个初始的独立聚类,然后通过计算样本点之间的距离(例如欧式距离)来合并距离最近的聚类,直到满足某个终止条件为止。 下面是一个用Python实现AGNES层次聚类算法的代码示例: ``` import numpy as np def compute_distance(point1, point2): # 计算两个样本点之间的欧式距离 return np.sqrt(np.sum((point1 - point2)**2)) def agnes(data): # 初始化每个样本点为一个聚类 clusters = [[point] for point in data] while len(clusters) > 1: # 计算每两个聚类之间的距离,并找到最小距离及对应的两个聚类索引 min_distance = float('inf') min_index = (0, 0) for i in range(len(clusters)): for j in range(i+1, len(clusters)): distance = compute_distance(clusters[i], clusters[j]) if distance < min_distance: min_distance = distance min_index = (i, j) # 合并最近的两个聚类 cluster1, cluster2 = clusters[min_index[0]], clusters[min_index[1]] merged_cluster = cluster1 + cluster2 clusters.remove(cluster1) clusters.remove(cluster2) clusters.append(merged_cluster) return clusters[0] # 测试代码 data = np.array([[1, 2], [3, 4], [5, 6]]) result = agnes(data) print(result) ``` 上述代码首先定义了计算两个样本点之间欧式距离的函数`compute_distance`。然后,`agnes`函数以传入的数据`data`初始化每个样本点为一个聚类。在循环中,它计算每两个聚类之间的距离,并找到最小距离及对应的两个聚类索引。然后,它合并最近的两个聚类,将合并后的聚类添加到聚类列表中,并移除原来的两个聚类。最后,返回合并后的聚类列表中的唯一聚类。 以上代码是一个简单的AGNES层次聚类算法的实现示例,可以根据实际需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值