scikit-learn LabelSpreading 怎样标记未标注样本
来源:17golang原创
时间:2026-10-31 08:59:54 283浏览 收藏
scikit-learn LabelSpreading 怎样标记未标注样本
LabelSpreading 在传给 fit 的 y 中使用整数 -1表示未标注样本。已标注和未标注样本的特征都放进 X,y 与 X 按行对应;训练后,从 transduction_ 读取这批样本的推断标签。不要把未知标签填成0,因为0可以是正常类别,会被当作已有标注参与建模。
官方地址:https://scikit-learn.org/。下面依据官方稳定版接口说明,重点讨论数值类别的输入契约。我的取舍是保留原始标签和未标注掩码,把模型结果另存;这是一种接口设计建议,文中小例子未执行,不代表某个实际项目的测试结论。
我会先把未标注与类别零分开
当一份数据表同时存在“类别0”和“尚未确认”时,我会先把两者分开,再选择模型参数。否则,即使程序能顺利运行,也已经改变了监督信号:模型看到的是大量类别0,而不是等待推断的样本。
| 值或状态 | 在本例中的含义 | 处理方式 |
|---|---|---|
| 整数0、1 | 真实类别编码 | 保留为已知标签 |
| 整数-1 | LabelSpreading未标注标记 | 特征仍参与fit,标签等待推断 |
| 空字符串、None、NaN | 上游缺失表示 | 导入时明确转换,不作为本例占位 |
| 字符串“-1” | 文本值 | 不能当成整数-1的同义写法 |
如果业务原本把-1当作真实类别,我会先建立其他整数编码,并保留映射表。这个保留标记不能同时承担真实类别与未知状态两种职责。
让特征、标签和来源掩码一一对应
接口最重要的约定是 X 的第 i 行与 y 的第 i 项代表同一个样本。筛选、排序或拼接后都要维持对应关系。未标注样本只是在 y 中未知,不意味着它的特征行可以删掉,更不意味着它可以缺少必要特征。
我会额外保存 was_unlabeled = y_input == -1。训练完成后,单看预测出来的0或1无法分辨它是原始人工标注还是模型补全;掩码为后续回看、抽样和结果展示保留这个区别。

一个保留原标签的完整例子
import numpy as np
from sklearn.semi_supervised import LabelSpreading
# 原创二维小样本,仅演示输入输出契约,不代表业务准确率。
X = np.array([
[0.0, 0.0], [0.2, 0.1], [0.1, 0.3],
[2.8, 3.0], [3.0, 2.9], [3.1, 3.2],
], dtype=float)
# -1表示未标注,0与1是已有真实类别,使用有符号整数。
y_input = np.array([0, -1, -1, 1, -1, -1], dtype=np.int64)
was_unlabeled = y_input == -1
if X.shape[0] != y_input.shape[0]:
raise ValueError("特征行数必须与标签数量一致")
if not np.any(~was_unlabeled):
raise ValueError("至少需要已有标注")
if not np.isfinite(X).all():
raise ValueError("示例要求所有特征为有限数值")
# 参数用于这个小示例,不是通用最优配置。
model = LabelSpreading(kernel="rbf", gamma=1.0,
alpha=0.2, max_iter=100)
model.fit(X, y_input.copy())
# 单独保存推断结果,不覆盖输入标签或人工来源标记。
inferred = model.transduction_.copy()
y_completed = y_input.copy()
y_completed[was_unlabeled] = inferred[was_unlabeled]
print("原始标签:", y_input)
print("未标注位置:", np.flatnonzero(was_unlabeled))
print("这些位置的推断:", inferred[was_unlabeled])
print("保留人工标签的合并视图:", y_completed)
print("分布列对应类别:", model.classes_)
本例中索引1、2、4、5是未标注位置,这是由输入数组直接确定的。它们最终被分到什么类别,要由模型拟合结果决定;本文不预填预测输出。执行示例的读者应关注输入是否保留、输出长度是否与样本一致,以及取出的推断是否对应原来的未知位置。
代码把 y_input 保留下来,y_completed 只覆盖原先未知的位置。这是展示层的合并规则,不是对模型内部行为的描述。LabelSpreading 采用软约束,不能假设 transduction_ 中已标注位置永远与输入完全相同。
输出接口应保留哪些区别
我倾向于把三种数据分开命名:原始标注 y_input、模型对训练样本的赋类 transduction_、保留原标注的应用合并视图 y_completed。这样调用方不会把“模型给出的类”误当成“已经人工确认的标签”。

label_distributions_ 的每一列对应 classes_ 中的类别,而不是必然对应“列号就是业务类别号”。如果之后展示各类分布,应把这两个属性一起解释。分布最大值也不能未经评估就命名为业务正确率或人工可信度。
对这次参与 fit 的样本读取 transduction_;对新增特征调用 predict。两种用途在接口中应分开表达,不要为了处理已有训练样本而把新增样本预测的语义混进来。
哪些输入问题需要提前处理
第一类问题是数据类型。数值类别需要能表达-1的有符号类型;无符号数组不适合直接容纳这个标记。另一类问题是种子标注:如果全部样本都未知,就没有本例所依赖的已有类别信息,不能期待模型凭空给出业务类别定义。
示例的检查也不等于完整生产输入规范。实际服务还应定义类别编码、特征维度、规模限制和返回错误方式。不同特征的量纲会影响相似关系,是否缩放、采用何种核及参数,应由具体数据任务决定;不要因为这个小例子能演示接口就认为参数通用。
未标注样本是不是测试集?不应直接等同。它的特征已参与fit,如果用隐藏真值评价,应明确这是对同一批样本的传导式评估;要评价新样本泛化,另设对应的数据划分和评估方式。
填完标签就能直接替代人工数据吗?推断结果应带模型版本和来源,是否采纳由应用规则决定。保留原始标签能避免把推断伪装成事实,也方便重新建模。
可以把缺失特征也填成-1吗?y中的-1是标签标记,不是X中缺失特征的通用处理规则。两个问题应分别定义。
对于少量已有标注、其余样本等待补全的数值分类任务,这个接口约定很简洁。我会先把未知标记、样本对应关系与输出来源固定下来,再讨论模型质量;这几个字段的职责清楚,调用方才更容易正确使用结果。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习