sklearn 星号导入为什么会报 HalvingGridSearchCV experimental
scikit-learn 1.8.0 和 1.9.1 的星号导入可能读取未启用的实验搜索类。只导入所需稳定接口,确需 Halving 搜索再明确启用实验模块。
代码只有 from sklearn.model_selection import *,没有用过 HalvingGridSearchCV,升级后却被实验功能的 ImportError 拦住。scikit-learn 1.8.0 和已核对的 1.9.1 中,这与模块的导出名单有关:星号导入会读取其中的实验类名,触发正常的实验 API 保护。
报错包含:
ImportError: HalvingGridSearchCV is experimental and the API might change without any deprecation cycle.
这并不说明训练数据有问题,也不要求所有项目都启用实验搜索。
只导入实际使用的接口
如果只需要划分数据、普通网格搜索或交叉验证,把星号改成明确的公开名称:
from sklearn.model_selection import (
GridSearchCV,
cross_val_score,
train_test_split,
)
名单按当前文件真正使用的对象调整。大型 Notebook 原先可能靠星号引入了其他名称,应重新执行依赖这些名称的单元格,避免只是把导入异常换成后面的 NameError。
原因在 __all__ 与 __getattr__ 的组合。受影响版本将 HalvingGridSearchCV、HalvingRandomSearchCV 列入公开导出名单,但这两个属性在没有启用实验模块时会抛 ImportError。星号导入按名单逐一读取,即使后面不用这些类,也会经过它们。普通的 import sklearn.model_selection 与明确导入稳定接口,不会因为同一名单就自动读取所有实验类。
因此,不建议删除 site-packages 中的保护代码或手工修改 __all__。那会制造与锁文件不一致的安装,下一次重建环境又恢复原状。
确实需要 Halving 搜索时再启用
如果业务本来就使用 successive halving,按实验接口的要求先执行启用导入,再导入具体类:
from sklearn.experimental import enable_halving_search_cv # noqa: F401
from sklearn.model_selection import HalvingGridSearchCV
第一行具有启用效果,看起来未使用也不能被自动清理掉。需要随机搜索版本时,再明确导入 HalvingRandomSearchCV。启用后这些对象仍属于实验 API,接口和结果可能在没有通常弃用周期的情况下变化;它不是让普通 GridSearchCV 能运行的必要步骤。
已经合并的修正与正式发行版要分开看。已核对的 1.9.1 仍有这组导出名单,不能仅因后续修复讨论结束,就承诺升级某个未核实的版本会恢复星号导入。显式导入也让依赖更清楚,通常无需等待这个入口修复。
检查时应启动干净解释器或重新启动 Notebook 内核。先前某个单元格启用过实验模块,可能让同一条星号导入暂时成功,掩盖其他机器从头运行时的失败。验收至少覆盖“未启用实验模块时导入所需稳定接口”和项目真正使用的训练、验证入口;若使用实验类,再单独检查启用顺序及原有搜索参数。
如果明确导入 train_test_split 本身也失败,或者错误来自 NumPy、SciPy 的二进制加载,就不满足这条导出名单路径。应保留新的完整异常,继续核对依赖安装,不能继续增加实验功能导入来掩盖其他错误。


