PyCaret 3.4.0和 scikit-learn得到的结果不一致

人工智能 2026-07-09

我目前在使用PyCaret 3.4.0,因为4.0缺少一些对我情况有用的配置参数。
我尝试用scikit-learn来复现PyCaret的结果。

这是我的脚本,在运行PyCaret的 setup并获得转换后的数据后:

compare_models(include=['rf'],cross_validation=True)

scoring=['accuracy','precision','recall','f1','f1_macro','f1_weighted','f1_micro', 'roc_auc']
rfc = RandomForestClassifier(random_state=42, n_jobs=-1)
scores = cross_validate(rfc, xtrain_trans, ytrain_trans, scoring=scoring, cv=cv)

compare_models 返回这些结果:

    Model   Accuracy    AUC Recall  Prec.   F1  Kappa   MCC TT (Sec)
rf  Random Forest Classifier    0.7164  0.7617  0.7164  0.7254  0.7137  0.4329  0.4416  0.25

但我从sklearn得到的结果如下:

  • 准确率=0.6948717948717947
  • AUC=0.7411665257819103
  • 召回率=0.6908791208791208
  • 精确率=0.7005056185644422
  • F1=0.6867142420587947
  • F1宏平均=0.6910345427878428
  • F1加权平均=0.6911863570749788
  • F1微平均=0.6948717948717947

为澄清一下,我在PyCaret和 sklearn上使用的交叉验证划分器完全相同。

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=10, random_state=42)

所使用的setup是:

setup(xtrain, 
            target = 'Group',
            session_id=42,
            test_data=xtest, #None default
            imputation_type=None, 
            remove_multicollinearity=True,
            multicollinearity_threshold=0.70,
            remove_outliers=True,
            transformation=True,
            transformation_method='quantile',
            normalize=True,
            feature_selection=False,
            fold_strategy=cv,
            use_gpu=True)

我知道差异很小—but我想使用RFECV来减少特征数量。问题在于如果我执行RFECV,必须使用sklearn来完成,因为PyCaret中未实现RFECV,结果就不可比。在执行RFECV之后,我得到的最佳平均分(F1=0.70,特征数减少)低于PyCaret的平均分(F1=0.7137,全部特征),但高于sklearn的平均分(F1=0.6867)。所以现在我不确定该如何继续,是否应该使用降维后的集合。

可复现实例:

from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier

cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=10, random_state=42)

from sklearn.datasets import make_classification
X, y = make_classification(n_samples=100, n_features=5, n_informative=2, n_classes=2, flip_y=0.2, random_state=42)
dataset = pd.DataFrame(X)
dataset.columns = ['X1', 'X2', 'X3', 'X4', 'X5']
dataset['y'] = y
setup0 = setup(dataset,target = 'y',session_id=42,train_size=0.7,imputation_type=None,remove_multicollinearity=True,multicollinearity_threshold=0.70,remove_outliers=True,transformation=True,transformation_method='quantile',normalize=True,feature_selection=False,fold_strategy=cv,use_gpu=True)

# CV average results from PyCaret
compare_models(include=['rf'],sort='F1',errors='raise',cross_validation=True)

xtrain_trans = setup0.get_config('X_train_transformed')
ytrain_trans = setup0.get_config('y_train_transformed')
scoring=['accuracy', 'roc_auc', 'recall', 'precision', 'f1','f1_macro','f1_weighted','f1_micro']
rfc = RandomForestClassifier(random_state=42, n_jobs=-1)
scores = cross_validate(rfc, xtrain_trans, ytrain_trans, scoring=scoring, cv=cv)
scores=pd.DataFrame(scores)
scores=scores.mean().round(4)

# CV average results from sklearn
pd.DataFrame(scores).transpose()

解决方案

好吧,我觉得我找到了答案,但也并非百分之百确定。

我认为 PyCaret会在CV阶段的每个分割上运行一个管道。 在每个分割上,训练集会经过归一化和变换的预处理,然后测试集也会被转换。之后,模型会拟合,并使用经过转换的测试集进行预测。

如果我在PyCaet的设置中关闭所有预处理选项,那么来自 compare_models 和sklearn的平均CV结果将完全相同。

我在PyCaret的指南中找不到任何确认,而且由于4.0更新,GitHub最近也有变化,现在再研究这些脚本也不太容易。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章