scikit-learn不原生支持主动学习,因其缺乏不确定性采样、查询策略和迭代标注循环;需借助modal等第三方库或手动组合模型与采样逻辑。

Scikit-learn 本身不提供主动学习(Active Learning)的原生实现,它只提供监督/半监督基础组件(如 SelfTrainingClassifier),但不支持不确定性采样、查询策略或迭代标注循环。想用 sklearn 做主动学习,必须搭配第三方库(如 modAL)或手动组合其模型与采样逻辑。
为什么不能直接用 train_test_split 或 fit 实现主动学习?
主动学习的核心是「模型驱动的样本选择」,而 train_test_split 是静态随机划分,fit 只负责训练——两者都不涉及「当前模型认为哪些未标注样本最难判别」这一关键步骤。常见错误包括:
- 把未标注数据全部喂给
predict_proba后直接挑最高置信度样本——这选的是最容易的,不是最有价值的 - 用
SelfTrainingClassifier但没设threshold或误设为 0.5——导致大量低置信伪标签污染训练集 - 在每次迭代中重复调用
train_test_split划分新训练集——破坏了主动学习的增量更新逻辑
用 modAL + sklearn 实现不确定性采样的最小可行路径
这是目前最轻量、兼容性最好、且不引入深度学习框架的方案。关键在于把 sklearn 模型包装进 ActiveLearner,并指定采样函数:
- 安装:
pip install modAL scikit-learn - 必须用
uncertainty_sampling(不是entropy_sampling,后者在modAL中已弃用) -
query_strategy参数必须是可调用对象,不能是字符串 - 初始训练集至少要有 2 个不同类别的样本,否则
RandomForestClassifier会报ValueError: Valid classes not found
示例片段(仅核心逻辑):
from modAL.models import ActiveLearner from modAL.uncertainty import uncertainty_sampling from sklearn.ensemble import RandomForestClassifier <p>learner = ActiveLearner( estimator=RandomForestClassifier(), query_strategy=uncertainty_sampling, X_training=X_initial, # shape (n_samples, n_features) y_training=y_initial # 1D array, at least 2 classes )</p><h1>主动查询 10 个新样本</h1><p>query_idx, query_instance = learner.query(X_pool) y_new = manual_labeling(query_instance) # 这步必须人工完成 learner.teach(X_pool[query_idx], y_new) </p>
SelfTrainingClassifier 能否替代主动学习?
不能,它是半监督的自训练(self-training),属于「自动打伪标签」范式,和主动学习目标相反:
-
SelfTrainingClassifier的threshold控制伪标签置信下限(默认 0.75),但它不主动筛选样本——而是对所有未标注样本预测,再过滤出高置信部分加入训练 - 它没有查询接口,无法控制「这次该问哪几个样本」,更无法对接人工标注流程
- 容易在类别不平衡时崩塌:多数类伪标签越积越多,少数类永远得不到标注机会
- 若硬要凑合用,必须配合
return_only_unlabeled=False和手动维护已标注索引,但已失去主动学习本质
真正做主动学习时,最易被忽略的不是代码怎么写,而是标注闭环的设计:你得有机制记录哪些样本已被查过、哪些正在排队、哪些被拒绝标注——这些状态管理不会出现在任何 sklearn 或 modAL 的 API 里,得自己用数组或数据库存。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











