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

自定义仿lazypredict的K折验证模型对比类,重复运行时数据框追加行问题

问题分析与解决方案

问题现象

实现了支持K折交叉验证的Compare_Models类,可返回模型平均评分的DataFrame,但重复运行时,新的模型评分会追加到原有DataFrame中,无法生成全新的结果。

问题根源

代码中f1_list、name_list等存储评分的列表是类属性,所有Compare_Models的实例会共享这些列表。每次创建实例时,不会清空旧数据,而是继续追加新的模型评分,导致重复运行时结果累加。

修复方案

将这些共享的类属性改为实例属性,在__init__方法中初始化空列表,确保每个实例拥有独立的数据存储,每次创建新实例时都会从头开始收集数据。

修改后的完整代码

import time
from typing import List

import numpy as np
import pandas as pd

pd.set_option("display.precision", 4)

from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_validate

from sklearn.metrics import classification_report
from sklearn.metrics import ConfusionMatrixDisplay

from tqdm.notebook import tqdm


class Compare_Models:

    scoring = [
        "accuracy",
        "balanced_accuracy",
        "roc_auc",
        "precision_weighted",
        "recall_weighted",
        "f1_weighted",
    ]

    def __init__(
        self,
        X: pd.DataFrame,
        y: pd.DataFrame,
        models: List,
        should_print_report: bool = False,
    ) -> None:

        self.X = X
        self.y = y
        # 初始化实例专属的空列表,替代原类属性
        self.f1_list = []
        self.name_list = []
        self.recall_list = []
        self.roc_auc_list = []
        self.accuracy_list = []
        self.fit_time_list = []
        self.precision_list = []
        self.score_time_list = []
        self.balanced_accuracy_list = []

        self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(
            X, y, random_state=0
        )

        for model in tqdm(models):
            name = model.__class__.__name__
            if should_print_report:
                self.__single_run(name, model)
            self.__cv_run(name, model)

    def __single_run(self, name, model):
        start = time.time()
        clf = model.fit(self.X_train, self.y_train)
        fit_time = time.time() - start

        start = time.time()
        y_pred = clf.predict(self.X_test)
        predict_time = time.time() - start

        report = classification_report(self.y_test, y_pred)
        print(name)
        print("Fit Time:", fit_time)
        print("Predict Time:", predict_time)
        print(report)
        ConfusionMatrixDisplay.from_predictions(
            self.y_test,
            y_pred,
            normalize="pred",
        )

    def __cv_run(self, name, model):
        cv_results = cross_validate(model, self.X, self.y, scoring=self.scoring)

        fit_time = np.mean(cv_results["fit_time"])
        f1 = np.mean(cv_results["test_f1_weighted"])
        roc_auc = np.mean(cv_results["test_roc_auc"])
        score_time = np.mean(cv_results["score_time"])
        accuracy = np.mean(cv_results["test_accuracy"])
        recall = np.mean(cv_results["test_recall_weighted"])
        precision = np.mean(cv_results["test_precision_weighted"])
        balanced_accuracy = np.mean(cv_results["test_balanced_accuracy"])

        self.f1_list.append(f1)
        self.name_list.append(name)
        self.recall_list.append(recall)
        self.roc_auc_list.append(roc_auc)
        self.accuracy_list.append(accuracy)
        self.fit_time_list.append(fit_time)
        self.precision_list.append(precision)
        self.score_time_list.append(score_time)
        self.balanced_accuracy_list.append(balanced_accuracy)

    def get_scores(self):
        scores = pd.DataFrame(
            {
                "Model": self.name_list,
                "Accuracy": self.accuracy_list,
                "Balanced Accuracy": self.balanced_accuracy_list,
                "ROC AUC": self.roc_auc_list,
                "Precision Weighted": self.precision_list,
                "Recall Weighted": self.recall_list,
                "F1 Weighted": self.f1_list,
                "Fit Time": self.fit_time_list,
                "Score Time": self.score_time_list,
            }
        )
        scores = scores.sort_values(["Fit Time", "Balanced Accuracy"])
        return scores

修改说明

  1. 移除了类定义中的f1_list、name_list等类属性
  2. 在__init__方法中添加这些列表的实例化代码,每个实例都会创建独立的空列表
  3. 其余逻辑保持不变,确保每次创建Compare_Models实例时,都会从头开始收集模型评分,不会与之前的实例共享数据

内容的提问来源于stack exchange,提问作者Burhan Khanzada

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:54:58