You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在sklearn中高效计算二维布尔数组所有特征列间的Matthews相关系数

如何在sklearn中高效计算二维布尔数组所有特征列间的Matthews相关系数

嗨,我完全理解你的困扰——当特征维度很高时,用双重循环逐对调用matthews_corrcoef确实会慢到难以接受,毕竟每一次函数调用都有额外开销,而且Python的循环本身就不适合处理这种大规模的成对计算场景。

其实我们可以直接基于Matthews相关系数(MCC)的数学公式,通过向量化运算一次性计算所有特征对的MCC值,彻底摆脱循环的低效问题。

先回顾MCC的核心公式

对于两个布尔特征列(0/1取值),MCC的计算公式是:

MCC = (TP*TN - FP*FN) / sqrt( (TP+FP)*(TP+FN)*(TN+FP)*(TN+FN) )

其中:

  • TP:两个特征都为1的样本数
  • TN:两个特征都为0的样本数
  • FP:第一个特征为1、第二个为0的样本数
  • FN:第一个特征为0、第二个为1的样本数

向量化实现步骤

我们可以利用矩阵运算直接批量计算所有特征对的这些统计量:

  1. 先计算每个特征的1值总数,以及总样本数:
import numpy as np

X = np.array([[1, 0, 0, 0, 0],
              [1, 0, 0, 1, 0],
              [1, 0, 0, 0, 1],
              [1, 1, 0, 0, 0],
              [1, 1, 0, 1, 0],
              [1, 1, 0, 0, 1],
              [1, 0, 1, 0, 0],
              [1, 0, 1, 1, 0],
              [1, 0, 1, 0, 1],
              [1, 0, 0, 0, 0]])

n_samples = X.shape[0]
# 每个特征的1值数量
s = X.sum(axis=0)
  1. 批量计算所有特征对的TP值(两个特征都为1的样本数,等价于X的矩阵乘法):
# X是0/1矩阵,X @ X.T的(i,j)位置就是第i列和第j列的点积,即TP数量
TP = X @ X.T
  1. 基于TP推导其他统计量:
FP = s[None, :] - TP  # 第i列1、第j列0的数量
FN = s[:, None] - TP  # 第i列0、第j列1的数量
TN = n_samples - s[None, :] - s[:, None] + TP  # 都为0的数量
  1. 计算MCC矩阵,同时处理分母为0的情况(避免除以0错误):
# 计算分子
numerator = TP * TN - FP * FN
# 计算分母
denominator = np.sqrt( (TP + FP) * (TP + FN) * (TN + FP) * (TN + FN) )
# 处理分母为0的情况,直接设为极小值(此时MCC无意义,通常取0)
denominator[denominator == 0] = 1e-10
# 计算MCC矩阵,取绝对值
mcc_matrix = np.abs(numerator / denominator)
  1. 提取上三角区域的非对角线元素(避免重复计算,对应你原来循环里的i<j的情况),然后计算平均值:
# 生成上三角掩码,排除对角线
upper_tri_mask = np.triu(np.ones_like(mcc_matrix), k=1)
# 提取所有符合条件的MCC值
rff_all = mcc_matrix[upper_tri_mask == 1]
# 计算平均值
rff = np.mean(rff_all)

为什么这个方法更快?

整个过程都是基于numpy的向量化运算,numpy的底层是C实现的,比Python的循环快几个数量级,尤其是当特征数量很大时(比如几百上千个特征),性能提升会非常明显。你可以对比一下原来的循环方法和这个向量化方法的运行时间,对于大规模数据集,差异会非常显著。

备注:内容来源于stack exchange,提问作者Erwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 10:49:28