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

基于K折交叉验证计算Accuracy、Precision等指标的代码正确性疑问

K折交叉验证中指标计算的准确性验证与代码优化

你的代码存在的两个核心问题

  1. 拆分方式错误:用train_test_split循环拆分数据不是标准K折交叉验证——每次拆分都是随机从全量数据中抽取测试集,会导致不同折的测试集甚至训练集重叠,不符合K折“数据互不重叠、全覆盖”的要求,得到的指标平均值没有统计意义。
  2. 指标函数参数顺序错误:sklearn的指标函数(如accuracy_score)要求第一个参数是真实标签,第二个是预测标签,你写的accuracy_score(x_test_prediction, y_test)把顺序搞反了,会导致计算结果完全错误。

关于“求和除以折数”的合理性

如果是正确的K折拆分(将数据分成K个互不重叠的子集,每折用其中一个做测试集,其余做训练集),对每折的Accuracy、Precision等指标取平均是K折交叉验证中常用且合理的指标汇总方式。但前提是拆分和指标计算的逻辑都正确。

正确的代码实现

分类任务优先使用StratifiedKFold,它能保证每折的类别分布与原数据一致,避免因拆分导致的类别失衡。以下是修正后的代码:

from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

# 初始化分层K折,shuffle=True打乱数据,random_state保证结果可复现
skf = StratifiedKFold(n_splits=n_folds, shuffle=True, random_state=42)

total_acc = 0
total_prec = 0
total_recall = 0
total_f1 = 0

# 标准K折拆分:每折测试集互不重叠,全覆盖
for train_idx, test_idx in skf.split(X, y):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]
    
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    
    # 修正参数顺序:真实标签在前,预测标签在后
    total_acc += accuracy_score(y_test, y_pred)
    total_prec += precision_score(y_test, y_pred)
    total_recall += recall_score(y_test, y_pred)
    total_f1 += f1_score(y_test, y_pred)

# 计算平均指标
avg_acc = total_acc / n_folds
avg_prec = total_prec / n_folds
avg_recall = total_recall / n_folds
avg_f1 = total_f1 / n_folds

print(f"accuracy score : {avg_acc:.4f}")
print(f"precision score : {avg_prec:.4f}")
print(f"recall score : {avg_recall:.4f}")
print(f"f1 score : {avg_f1:.4f}")

如何验证计算的准确性

你可以通过以下三种方式验证结果的正确性:

  1. 与sklearn内置工具对比:用cross_validate直接计算指标,对比手动计算的平均值是否一致:

    from sklearn.model_selection import cross_validate
    
    # 根据任务选择合适的评分指标,二分类用'precision',多分类用'precision_macro'
    scoring = ['accuracy', 'precision', 'recall', 'f1']
    results = cross_validate(clf, X, y, cv=skf, scoring=scoring)
    
    print("cross_validate 平均准确率:", results['test_accuracy'].mean())
    print("cross_validate 平均精确率:", results['test_precision'].mean())
    

    两者结果应基本一致(误差来自浮点数精度)。

  2. 两种指标汇总方式对比:除了平均每折指标,还可以收集所有折的真实标签和预测标签,整体计算指标,对比两种方式的差异:

    all_y_true = []
    all_y_pred = []
    
    for train_idx, test_idx in skf.split(X, y):
        X_train, X_test = X[train_idx], X[test_idx]
        y_train, y_test = y[train_idx], y[test_idx]
        
        clf.fit(X_train, y_train)
        y_pred = clf.predict(X_test)
        
        all_y_true.extend(y_test)
        all_y_pred.extend(y_pred)
    
    print("整体计算准确率:", accuracy_score(all_y_true, all_y_pred))
    print("整体计算精确率:", precision_score(all_y_true, all_y_pred))
    

    两种方式结果可能略有差异:“平均折指标”是先每折计算再平均,“整体计算”是合并所有结果后计算,两种都是合理的,按需选择即可。

  3. 小数据集手动验证:用一个极小的已知标签数据集(比如10个样本,5正5负),手动拆分K折(如K=2),手动计算每折指标再平均,和代码运行结果对比,看是否完全一致。

内容的提问来源于stack exchange,提问作者AL MAHMUD SIAM

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:32:25