如何在Sklearn中高效计算矩阵X各列与y的Matthews相关系数
批量计算特征与目标变量的Matthews相关系数(MCC)
你的循环方法在特征数量较大时效率低下,核心原因是每次调用matthews_corrcoef都会产生函数调用开销,且无法利用numpy的向量化计算优势。我们可以直接基于MCC的数学公式,用numpy实现全量向量化计算,完全避免循环。
MCC的数学公式
对于二元分类的特征和目标变量,MCC的计算公式为:
MCC = (TP*TN - FP*FN) / sqrt( (TP+FP)(TP+FN)(TN+FP)(TN+FN) )
其中:
- TP:特征为1且目标y为1的样本数
- TN:特征为0且目标y为0的样本数
- FP:特征为1且目标y为0的样本数
- FN:特征为0且目标y为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]]) y = np.array([1, 0, 1, 0, 1, 0, 1, 0, 1, 0]) # 将y转为列向量,方便广播运算 y_col = y.reshape(-1, 1) # 向量化计算四个混淆矩阵统计量 TP = (X & y_col).sum(axis=0) TN = ((1 - X) & (1 - y_col)).sum(axis=0) FP = (X & (1 - y_col)).sum(axis=0) FN = ((1 - X) & y_col).sum(axis=0) # 计算分子和分母 numerator = TP * TN - FP * FN denominator = np.sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN)) # 处理分母为0的情况(避免除以0),此时MCC为0 mcc = np.where(denominator == 0, 0, numerator / denominator) # 取绝对值并计算均值 rcf_all = np.abs(mcc) rcf = np.mean(rcf_all) print(rcf_all) print(rcf)
效率说明
这种方法直接利用numpy的广播和矩阵运算,所有计算都在底层C实现的向量操作中完成,比Python循环快几个数量级,尤其当特征数达到数千甚至上万时,优势会非常明显。
内容的提问来源于stack exchange,提问作者Erwin
相关产品推荐
相关产品推荐

