adjusted_rand_score函数出现longlong_scalars溢出及负结果异常求助
解决adjusted_rand_score计算时的longlong溢出问题
问题原因
你的样本总量接近8万,scikit-learn旧版本的adjusted_rand_score在计算交叉项乘积时,数值会超出64位整数的范围,导致溢出并返回错误的负数结果。另一台电脑运行正常,大概率是因为其scikit-learn版本更高,已经修复了该溢出问题。
解决方法
1. 升级scikit-learn到最新稳定版
0.24版本之前的adjusted_rand_score未针对大样本做溢出处理,升级到0.24+后,函数会自动采用更高精度的计算逻辑避免溢出。执行以下命令升级:
pip install --upgrade scikit-learn
2. 手动实现高精度ARI计算
如果暂时无法升级依赖,可基于Python任意精度整数或浮点型手动实现ARI计算,彻底规避溢出风险:
import numpy as np from scipy.special import comb def adjusted_rand_score_high_precision(labels_true, labels_pred): # 自动转换字符串标签为数值型 if isinstance(labels_true[0], str): labels_true, _ = np.unique(labels_true, return_inverse=True) if isinstance(labels_pred[0], str): labels_pred, _ = np.unique(labels_pred, return_inverse=True) # 构建混淆矩阵 contingency = np.histogram2d(labels_true, labels_pred, bins=(len(np.unique(labels_true)), len(np.unique(labels_pred))))[0] # 用精确整数计算组合数,避免溢出 sum_comb_c = sum(comb(int(n_c), 2, exact=True) for n_c in np.sum(contingency, axis=1)) sum_comb_k = sum(comb(int(n_k), 2, exact=True) for n_k in np.sum(contingency, axis=0)) sum_comb = sum(comb(int(n_ij), 2, exact=True) for n_ij in contingency.flatten()) total = comb(len(labels_true), 2, exact=True) if total == 0: return 1.0 # 浮点型计算避免整数除法偏差 expected_index = (sum_comb_c * sum_comb_k) / total max_index = (sum_comb_c + sum_comb_k) / 2.0 ari = (sum_comb - expected_index) / (max_index - expected_index) return ari
3. 预处理字符串标签
你的基线标签是字符串类型,需先转换为数值型再进行计算:
import pandas as pd # 读取并转换基线标签 gt = pd.read_csv('nano_gt.csv', header=0, index_col=0) gt_labels, _ = pd.factorize(gt['merge_cell_type']) # 读取聚类结果 data_raw = pd.read_csv('recon.csv', header=0, index_col=0) data_test = data_raw.to_numpy()[:,1:982] cluster, label = kmeans(data_test, k=7) # 计算ARI(二选一) # 自定义函数 ari_score = adjusted_rand_score_high_precision(gt_labels, label) # 升级sklearn后用官方函数 # from sklearn.metrics import adjusted_rand_score # ari_score = adjusted_rand_score(gt_labels, label) print(ari_score)
内容的提问来源于stack exchange,提问作者FATEXIII
相关产品推荐
相关产品推荐

