PyCaret中compare_models()在setup()后自动完成预处理并训练15个模型,返回最优模型;需指定target和session_id保证可复现,结果指标来自5折交叉验证,预测须用predict_model()而非直接调用model.predict()。

PyCaret中用setup()初始化数据后直接调用compare_models()
只要数据已加载为pandas.DataFrame,且目标列明确,PyCaret就能自动完成缺失值处理、编码、标准化等预处理——不需要手动调用fit()或train_test_split。compare_models()默认训练并交叉验证15个常见模型(如lr、rf、xgboost),返回性能最优的那个模型对象。
常见错误是跳过setup()直接比较:会报ValueError: setup() must be called before compare_models();另一个坑是目标列类型为object但实际是分类任务,导致PyCaret误判为回归——此时需显式传session_id固定随机性,或用fix_imbalance=True应对类别不均衡。
-
setup(data, target='label', session_id=42):必须指定target,session_id保证结果可复现 -
compare_models(sort='f1', n_select=3):按f1排序选前3个模型,返回list而非单个模型 - 若想跳过某些模型(比如不用
svm),加参数exclude=['svm']
如何让compare_models()输出更稳定、可复现
默认情况下,compare_models()每次运行结果可能不同,因为底层使用了未设种子的交叉验证和部分模型自身的随机性(如rf的特征抽样)。这不是bug,而是设计使然——但基线对比阶段需要确定性。
关键不是只设session_id,还要注意:PyCaret 3.x 默认启用fold_strategy='stratifiedkfold'(分类)或kfold(回归),而stratifiedkfold本身依赖random_state,这个状态由session_id统一控制。但像catboost这类模型内部还有独立随机种子,需额外传kwargs覆盖:
立即学习“Python免费学习笔记(深入)”;
-
compare_models(session_id=42)→ 控制交叉验证和多数模型种子 -
compare_models(kwargs={'random_state': 42})→ 针对支持random_state的模型补一层 - 若仍波动,检查是否启用了
use_gpu=True:某些GPU加速路径存在非确定性行为,建议基线阶段关掉
对比结果里F1、AUC、R2这些指标怎么来的
PyCaret不直接暴露CV fold的原始预测,但所有指标都来自5折分层交叉验证(分类)或普通5折CV(回归)的平均值+标准差,计算逻辑和sklearn.metrics一致。例如F1是macro-F1,AUC是ovo(one-vs-one)多分类AUC(二分类则为标准AUC)。
容易被忽略的是:这些分数是「验证集上」的,不是训练集拟合度;而且PyCaret默认对每个模型做完整CV,不缓存中间结果——所以反复调用compare_models()会重复计算,很慢。如果只想看分数不保留模型,加cross_validation=False可跳过CV(仅用单次train/val划分),但这时指标不可靠,仅作粗略参考。
- 查看某模型详细CV报告:
pull()在compare_models()之后立即调用,返回pandas.DataFrame - 想换评估指标?
sort参数支持任意sklearn.metrics函数名字符串,如'precision_weighted' -
fold=3可减少CV耗时,但3折稳定性较差,慎用于小数据集
为什么compare_models()返回的模型不能直接predict()
它返回的是已训练好的模型对象,但PyCaret封装了一层——你不能像原生sklearn那样直接调用model.predict(X),会报AttributeError: 'Pipeline' object has no attribute 'predict'(因为返回的是带预处理器的Pipeline)。正确做法是用PyCaret提供的predict_model()函数。
典型错误是把新数据丢进模型对象本身,而不是走PyCaret流程。另外,predict_model()要求输入DataFrame结构与setup()时一致(列名、类型、缺失值处理方式),否则可能报ValueError: Input contains NaN,哪怕你肉眼看不到NaN——因为setup()可能把空字符串转成了np.nan。
- 正确预测:
model = compare_models(); predictions = predict_model(model, data=new_df) - 如果只想拿模型本身给其他系统用,用
finalize_model(model)解包出原始sklearn对象(但丢失预处理逻辑) - 部署前务必用
save_model(model, 'best_model')保存整个pipeline,别只存joblib.dump(model)
get_config('prep_pipe')或get_logs()确认每一步到底做了什么。


















