加载已保存PyCaret模型调用tune_model触发ValueError报错求助
问题原因
你通过save_model保存的是包含预处理流程的完整Pipeline对象,而非PyCaret内置的模型实例。当用load_model加载后,tune_model无法从这个Pipeline中识别出对应的内置模型ID(比如xgboost),因此将其判定为自定义模型,触发必须提供custom_grid的报错。
解决方法
方法一:保存模型名称而非完整模型(推荐)
不需要保存整个模型文件,直接记录compare_models返回的模型对应的名称,后续调参时直接使用模型名称调用tune_model,PyCaret会自动识别内置模型并使用默认参数网格:
# 对比模型时同时记录模型名称 models = exp.compare_models(include=models_to_ignore, n_select=4) # 获取模型名称列表(比如['xgboost', 'lightgbm', ...]) model_names = [exp.models_dict[model.__class__.__name__]['name'] for model in models] # 后续调参直接循环模型名称 for model_name in model_names: print(f'Started tuning {model_name} model') tuned_model = tune_model( model_name, n_iter=20, optimize='RMSLE', search_library="tune-sklearn", search_algorithm="optuna", early_stopping='asha', return_tuner=True, return_train_score=True ) save_model(tuned_model, os.path.join(model_dir, f'tuned_{model_name}'))
方法二:从加载的Pipeline中提取模型并指定默认参数网格
如果必须加载保存的Pipeline,可以从中提取底层模型,然后获取PyCaret内置的参数网格传给tune_model:
from pycaret.regression import get_config model_dir = Path('../models') for model_path in glob(os.path.join(model_dir, '*.pkl')): tuned_model_file = os.path.splitext(os.path.basename(model_path))[0] print(f'Started tuning {tuned_model_file} model') # 加载Pipeline loaded_pipeline = load_model(os.path.splitext(model_path)[0]) # 提取底层模型(Pipeline的最后一步是模型) model = loaded_pipeline.steps[-1][1] # 获取对应模型的默认参数网格 model_id = [k for k, v in exp.models_dict.items() if v['class'] == model.__class__][0] custom_grid = get_config(f'{model_id}_grid') # 调参时传入custom_grid tuned_model = tune_model( model, n_iter=20, optimize='RMSLE', search_library="tune-sklearn", search_algorithm="optuna", early_stopping='asha', return_tuner=True, return_train_score=True, custom_grid=custom_grid ) save_model(tuned_model, os.path.join(model_dir, f'tuned_{tuned_model_file}'))
方法三:复用实验上下文并直接使用模型标识符
确保调参时的实验上下文和之前compare_models的实验一致,直接使用模型名称而非加载的Pipeline:
# 确保当前实验是之前的exp exp = get_current_experiment() model_dir = Path('../models') # 假设保存的模型文件名就是模型名称(比如xgboost.pkl) for model_path in glob(os.path.join(model_dir, '*.pkl')): model_name = os.path.splitext(os.path.basename(model_path))[0] print(f'Started tuning {model_name} model') tuned_model = tune_model( model_name, n_iter=20, optimize='RMSLE', search_library="tune-sklearn", search_algorithm="optuna", early_stopping='asha', return_tuner=True, return_train_score=True ) save_model(tuned_model, os.path.join(model_dir, f'tuned_{model_name}'))
内容的提问来源于stack exchange,提问作者Bappa
相关产品推荐
相关产品推荐

