马尔可夫聚类算法

马尔可夫聚类算法(Markov Clustering Algorithm,MCL)是一种用于图聚类的算法,广泛应用于生物信息学、社交网络分析、推荐系统等领域。

其核心思想是模拟随机游走过程,通过迭代地扩散和收缩图上的概率分布来识别图中的自然聚类或社区结构。

马尔可夫聚类算法的核心步骤

  1. 构建转移矩阵

    1. 对于给定的图,生成转移矩阵(Markov Matrix),其中每个元素表示从一个节点转移到另一个节点的概率。

    2. 设图的邻接矩阵为 A,转移矩阵 M 的元素定义为

      M_{ij} = \frac{A_{ij}}{\sum_k A_{ik}}

      ,即从节点 i 转移到节点 j 的概率是节点 i 的所有边的权重的归一化值。

  2. 扩散(扩展)操作:

    • 对转移矩阵进行幂运算 Mr,通常 r=2。这相当于模拟多步随机游走,使得概率分布扩散开来。

    • 扩展步骤是为了使节点间的相似性得以传播,能捕捉到较长路径上的信息。

  3. 收缩(膨胀)操作

    • 对转移矩阵的每个元素进行逐项幂操作

      M_{ij} = M_{ij}^\alpha

      ,然后重新归一化。通常,膨胀因子 α 取值大于1。

    • 膨胀步骤是为了增强高概率路径,同时抑制低概率路径,这样能把概率集中在更紧密相关的节点上,从而分离出聚类。

  4. 归一化

    • 收缩操作后需要重新归一化矩阵,使得每行的概率和为1,以确保结果仍然是一个有效的转移矩阵。

  5. 迭代

    • 不断重复扩散和收缩操作,直到矩阵收敛,得到稳定的概率分布。收敛时,转移矩阵的列通常会收敛到一些特定的块结构,这些块对应图中的不同聚类。

  6. 解码聚类

    • 通过观察收敛后的矩阵,确定聚类。一般来说,转移矩阵的每一列的高值(接近1)集中在特定的行上,这些行就代表了同一个聚类。

算法优点

  • 自适应性:不需要预先指定聚类的数量。

  • 适应性强:可以很好地处理带有噪声的网络。

  • 捕捉复杂结构:能有效捕捉到网络中的复杂拓扑结构。

算法缺点

  • 参数选择:膨胀因子和扩展次数的选择对结果有较大影响。

  • 计算复杂度:对于大规模图,计算量较大,需要有效的矩阵运算方法。

算法实现

import numpy as np

def add_self_loops(matrix):
    """在对角线上添加自环(self-loops)"""
    np.fill_diagonal(matrix, 1)
    return matrix
def normalize(matrix):
    """归一化矩阵使其行和为1"""
    return matrix / np.sum(matrix, axis=1, keepdims=True)

def expand(matrix, power):
    """对矩阵进行幂次乘法"""
    return np.linalg.matrix_power(matrix, power)
def inflate(matrix, power):
    """对矩阵元素逐元素幂乘"""
    return normalize(np.power(matrix, power))

def converged(matrix1, matrix2, tol=1e-5):
    """检查矩阵是否收敛"""
    return np.all(np.abs(matrix1 - matrix2) < tol)

def mcl(graph, expand_factor=2, inflate_factor=2, max_iterations=100, tol=1e-5):
    """执行马尔可夫聚类算法"""
    # 创建初始转移矩阵
    matrix = add_self_loops(graph)
    matrix = normalize(matrix)

    for i in range(max_iterations):
        print(f"Iteration {i+1}")
        previous_matrix = matrix.copy()
        # 扩展
        matrix = expand(matrix, expand_factor)
        # 收缩(膨胀)
        matrix = inflate(matrix, inflate_factor)
        # 检查收敛
        if converged(previous_matrix, matrix, tol):
            break

    return matrix

def extract_clusters(result_matrix):
    """
    从 result_matrix 中提取聚类。
    :param result_matrix: 马尔可夫聚类算法得到的稳定转移矩阵
    :return: 每个节点的聚类标签
    """
    # 获取每一行的最大值索引,这些索引代表聚类标签
    cluster_assignments = np.argmax(result_matrix, axis=1)
    return cluster_assignments

def group_nodes_by_cluster(cluster_assignments):
    """
    将节点按聚类分组。
    :param cluster_assignments: 每个节点的聚类标签
    :return: 每个聚类包含的节点列表
    """
    clusters = defaultdict(list)
    for node, cluster in enumerate(cluster_assignments):
        clusters[cluster].append(node)
    return clusters
# 示例图(邻接矩阵)
graph = np.array([
    [0, 1, 1, 0, 0, 0],
    [1, 0, 1, 1, 0, 0],
    [1, 1, 0, 0, 0, 0],
    [0, 1, 0, 0, 1, 1],
    [0, 0, 0, 1, 0, 1],
    [0, 0, 0, 1, 1, 0]
])

# 执行MCL
result_matrix = mcl(graph)

# 提取聚类信息
cluster_assignments = extract_clusters(result_matrix)
clusters_grouped = group_nodes_by_cluster(cluster_assignments)

print("Cluster Assignments:", cluster_assignments)
print("Grouped Clusters:", clusters_grouped)

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惊雲浅谈天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值