
手里拿着一堆没有标签的数据基本是做数据相关项目最常见、也最容易被低估的处境。我最近连续做了几个跟无标签数据打交道的活儿有图像的、有文本的、也有纯数值特征的发现很多人一听“没标签”就判定没法训练模型或者二话不说把数据扔给标注外包预算和时间哗哗地烧掉。但实话说无标签数据恰恰是绝大多数业务场景里体量最大、最贴近真实分布的数据资产真正的问题不是它能不能用而是你会不会用。这篇是“无标签的数据指南”的第一篇先把整体思路和一套能直接照搬的操作流程讲清楚后面每一期再单独挑一个具体技术点展开。1. 无标签数据的价值在哪里三个我经手的真实场景每次跟人聊起“无标签数据”总有人觉得这是个伪需求——既然没标签那不如先去标注。但现实中标注的成本、周期、质量标准往往比想象中高得多而且有些数据本身就不存在“正确答案”。我把最近做过、也最有代表性的三个场景放在前面你对照一下手上的数据大概率能对上号。1.1 客户行为日志没有“是否购买”标签也要找规律之前有个项目业务方给了一批用户行为日志包括点击次数、浏览时长、访问路径、设备类型、首次访问来源数据量很大但唯一的遗憾是没有“这个用户最后有没有购买”的标签。销售团队希望的是“提前圈出高意向用户”而不是事后看成交记录。我们的做法很直白先对无标签数据做主成分降维把几百维的行为特征压到十几维再用聚类算法把用户分成几个群体然后结合少量人工抽检和业务规则给每个簇打上语义标签。最后看群体间的转化率差异发现有的簇转化率是平均值的3倍有的簇几乎全是羊毛党。整个过程没有用任何监督标签却能在业务上直接产出可用的圈人策略。这里有个关键认知无标签数据不代表没有信息。用户的聚集结构、行为模式、分布形态本身就是信息聚类和降维只是把这些隐信息显式化。1.2 工业质检只有良品样本怎么识别缺陷工业场景比互联网更极端。生产线上采集的图像绝大多数是良品缺陷样本极其稀少甚至很多缺陷类型在开始建模时根本没见过。我遇到的一条产线良品占比99.5%你没法用常规的有监督分类去训练一个“良品vs缺陷”的二分类器因为缺陷样本根本凑不够。这类问题的通用解法是把建模目标从“识别缺陷”换成“发现偏离”。具体做法是用自编码器或者预训练网络在大量无标签图像上提取特征然后建立正常样本的特征分布缺陷图像因为和良品分布差异大会在某个重建误差或距离指标上表现异常。说白了缺陷检测变成了“测一下你离正常有多远”。1.3 运维日志故障标记缺失靠模式突变做预警还有一个是运维日志场景。系统每天产生上亿条日志没有任何“这条日志对应故障”的标记工程师排查问题时全凭经验和搜索关键字。我们当时做的事情是先把日志模板化聚类把相似的原始日志归到同一模板然后对每个模板的出现频率做时间序列统计。发现一个很有意思的规律很多故障发生前某个日志模板的频率会出现明显的突增或突降这种模式在一两个小时内是看不见的一旦拉到以天为单位观察规律非常清楚。后来我们直接基于频率变化做预警不依赖任何标注纯无监督就把一批故障点位找出来了。2. 处理无标签数据的三条技术主线场景讲完之后该说方法论了。无标签数据的处理方式很多但万变不离其宗归纳下来就是三条主线自监督学习、半监督学习、伪标签。不同方法的适用条件、训练成本、风险差异非常大选错路线往往比不选还难受。2.1 自监督学习给数据“自己出题自己答”的机会自监督的核心思路是设计一个“预文本任务”让模型在无标签数据上自己构造监督信号并学习。比如经典的旋转预测把图像随机旋转角度让模型预测旋转了多少度再比如掩码重建把图像的一部分遮住让模型判断缺失区域是什么还有对比学习让模型学会“同一样本的两次增强在表征空间里拉近不同样本推远”。这些任务本身和下游业务目标无关但模型在完成这些任务的过程中会被迫学会数据的底层结构和语义信息。下游任务只需要很少的标注数据在一个预训练好的模型上做轻量微调效果经常会超过“直接从零开始在有标签数据上训练”。典型代表就是SimCLR、MoCo、MAE这些都是经过大规模无标签预训练验证过的。2.2 半监督学习让少量标签撬动海量无标签数据半监督学习解决的是“有一点标签但远远不够”的困境。核心思想是一致性正则对同一张无标签图像做两次不同的增强模型对两次结果的预测应该尽量一致。如果模型在弱增强版本上给出了高置信度预测那这个预测就可以看作对强增强版本的“软答案”。这类方法最著名的就是MixMatch和FixMatch。我实际测试过在有标签数据只有几百张、无标签数据几万张的图像场景下半监督方法可以把准确率从60%多直接拉到80%以上。少标签多无标签的组合里半监督学习的收益是最明显的而且它对现有训练流程的侵入很小基本就是在损失函数里多加一项。2.3 伪标签与聚类假设低成本高风险的捷径伪标签的思路更简单粗暴先用有标签数据训练一个模型然后对无标签数据做预测把置信度高的预测当作“伪标签”和真实标签混在一起继续训练。这样迭代几轮之后模型能利用的数据量大大增加。它的核心前提是聚类假设不同类别的数据在特征空间里分布在不同的簇上模型在低密度区域的决策边界是合理的。如果数据本身类间重叠严重或者模型初始能力太弱伪标签里的错误就会被当成真值学进去而且越滚越大。我的习惯是只有模型在验证集上的表现已经足够好且数据分布相对干净时才考虑用伪标签。便宜是便宜但风险要认。技术主线核心思想适用场景训练成本主要风险自监督学习预文本任务学表征无标签数据量大、语义丰富高需要大算力预文本任务和下游目标可能有差距半监督学习一致性正则少量标签大量无标签中等增强策略和数据分布敏感伪标签自训练迭代模型已有一定能力低错误累积噪声被放大3. 一套完整可复现的实操流程以图像分类为例理论讲完直接上一个可复现的实操流程。我以图像分类场景为例因为图像任务的数据增强、预训练、微调链路最成熟换成文本和数值特征的逻辑也是一样的只是增强方式和模型结构需要替换。3.1 第一步数据画像先搞清楚“无标签”不等于“杂乱”拿到无标签数据第一件事不是急着训练而是做数据画像。我会把下面这几个问题先查清楚数据总量多少格式是否统一有没有损坏文件图像分辨率分布是否需要统一缩放有没有大量近似重复样本感知哈希可以快速查重用聚类或者简单的嵌入看数据是否有多峰结构不同来源的数据是否混在一起时间跨度是否一致很多项目翻车就翻在这里。你以为的“无标签数据集”可能是不同渠道、不同分辨率、不同拍摄条件下的混合物。特别提醒一点近似重复样本在无标签数据集里占比经常高得吓人。我之前清理过一批图像数据去重之前是80万张去重之后只剩50万张性能不但没有下降反而提升了。重复样本会让模型看到过多次同样模式不利于泛化。3.2 第二步对比学习预训练的代码骨架自监督预训练的完整工程实现比较长我挑最核心的一段骨架出来。这里用的是对比学习思路参考SimCLR的结构用ResNet作为编码器后面接一个投影头import torch import torch.nn as nn import torch.nn.functional as F from torchvision import models, transforms class ProjectionHead(nn.Module): 把编码器输出的特征映射到对比损失空间 def __init__(self, in_dim2048, hidden_dim512, out_dim128): super().__init__() self.fc1 nn.Linear(in_dim, hidden_dim) self.fc2 nn.Linear(hidden_dim, out_dim) def forward(self, x): x F.relu(self.fc1(x)) return self.fc2(x) class ContrastiveModel(nn.Module): def __init__(self, base_encodermodels.resnet18, pretrainedFalse): super().__init__() self.encoder base_encoder(pretrainedpretrained) # 拿掉最后的全连接分类层只保留特征部分 self.encoder.fc nn.Identity() self.proj ProjectionHead(in_dim512) def forward(self, x): feat self.encoder(x) return self.proj(feat) def contrastive_loss(z1, z2, temperature0.1): InfoNCE损失正样本对拉近负样本对推远 batch_size z1.size(0) z torch.cat([z1, z2], dim0) # 2N x d z F.normalize(z, dim1) similarity torch.mm(z, z.t()) # 2N x 2N mask torch.eye(2 * batch_size, dtypetorch.bool, devicez.device) similarity similarity[~mask].view(2 * batch_size, -1) positives torch.cat([similarity[batch_size:2*batch_size, :batch_size].diag(), similarity[:batch_size, batch_size:2*batch_size].diag()]) logits similarity / temperature labels torch.zeros(2 * batch_size, dtypetorch.long, devicez.device) # 正样本排在每行前N个位置里具体位置是行号偏移后的对应项 loss F.cross_entropy(logits, labels) return loss这段代码里的InfoNCE损失是自监督训练的核心。实际操作时要注意的点很多对比学习对batch size极其敏感太小的batch比如32会让负样本数量不足表征质量明显下降温度系数temperature也不是越大越好0.1附近通常比较稳。预训练阶段不要急着用太强的数据增强先跑通流程再逐步加Cutout、随机灰度化这些强增强。3.3 第三步下游微调和伪标签迭代预训练完成后把投影头扔掉只保留编码器在有标签的小数据集上做微调。微调完成后对无标签数据做预测然后按置信度阈值挑选高置信度的样本把它们当作伪标签加入训练集再来一轮。这个过程一般迭代三轮左右在有标签数据上微调得到初始模型对无标签数据预测保留置信度超过0.9的样本混合真实标签和伪标签重新训练重复上述过程但伪标签置信度阈值可以逐步降低到0.8这里有个容易踩的坑伪标签的类别分布往往不均匀模型对多数类预测置信度偏高导致伪标签加剧类别不平衡。我通常会在伪标签筛选时做一次类别数量约束每个类别最多保留不超过真实标签数量5倍的伪标签。这个技巧不复杂但对最终效果的影响非常显著。所有迭代结束后我会预留一份从未参与训练的真实标签数据来评估模型否则你很难判断伪标签迭代到底是在变好还是在把错误固化。3.4 效果评估怎么做才靠谱无标签数据项目的评估比有监督项目麻烦很多因为“没有标签”天然意味着没有标准答案。但项目要交付、要让业务方认可必须拿出数字说话。我的经验是三层次评估第一层如果手头有一小份哪怕只有几百条真实标注数据就把它当作测试集在这个测试集上报告准确率、召回率、F1。这部分能够反映模型真实泛化表现。第二层没有标注数据或标注极少时至少要让人工对模型的高置信度预测做抽检看预测是否符合业务常识。第三层把模型预测结果放到业务侧做小范围验证比如通过A/B测试观察实际业务指标的变化。特别提醒别用自监督训练中的loss或者重建误差当作模型好的证据。有个项目当时用自编码器做异常检测模型把图像还原得特别漂亮loss很低结果检测出来的异常全是错位模糊的坏图。后来才发现问题在于我们手里的数据大部分本来就是清晰良品重建loss低只能说明模型记住了良品模式并不能直接等价为异常检测的准确率。这种指标上的自欺欺人会让你在错误方向上花掉大量时间。4. 避坑清单无标签数据项目里我踩过的四类坑这一部分是我最想写的。很多坑不是从论文里看来的是加班到凌晨才试出来的。用无标签数据做项目技术和业务问题交织在一起一个不留神就能坑掉整个项目周期。4.1 坑一无标签数据的分布偏移比你想的严重无标签数据往往是从多个渠道捞回来的不同渠道的采集条件、时间跨度、人群构成可能完全不同。我遇到过一个案例训练用的无标签图像大部分是白天拍摄但实际部署时夜间图像比例明显增加结果整个模型的表现雪崩式下降。解决办法是在数据画像阶段就把来源渠道、采集时间等信息记下来然后分别统计各个子集的特征分布比如亮度直方图、颜色分布、图像清晰度等发现明显偏移的子集要么单独建模要么在训练时有意识地按比例混合。4.2 坑二伪标签噪声会“滚雪球”伪标签最大的隐患是早期的错误预测被模型当作正确标签学进去然后在后续迭代里被继续放大。置信度阈值不是调得越高越安全有些错误预测的置信度本身就很高尤其是模型已经对某些模式形成了错误偏好的时候。我现在的习惯是每个迭代轮次后随机抽200个伪标签样本给人看哪怕只是扫一眼。这个习惯救过我很多次有次模型把有瑕疵的样本预测成了完美样本置信度高达0.95人一眼就能看出问题但模型根本不care。4.3 坑三对比学习对超参极其敏感不是跑起来就行对比学习不是“把代码跑通就完事”的东西。batch size太小负样本不够表征空间会被局部结构主导学习率调度不合适模型可能一直在震荡投影头输出的维度也会影响表征的判别力。我用的是线性评估协议来检验预训练质量——把预训练好的编码器冻结只训练一个线性分类层如果在保留的真实标签测试集上线性评估准确率能打到70%以上说明预训练表征质量是过关的。如果线性评估只有50%不要急着微调回去调预训练参数。超参常见取值范围我的经验值说明batch size256 ~ 4096512至少256太小时负样本不足temperature0.05 ~ 0.50.1过低训练不稳定过高语义区分变弱投影头维度64 ~ 512128维度太大会引入噪声4.4 坑四用错了评估指标项目白做一半如果你负责的项目最终是以“指标达标”作为交付标准那评估指标的选择必须在项目开始前就和业务方对齐不能等做完了再解释。无标签数据项目的指标很容易出现“看起来合理但实际没用”的情况。比如用户分群项目之前用的指标是簇内距离业务方看不懂也不关心他们只看“圈出来的人转化率有没有提升”。后来我们把指标换成“圈人规模”和“对比大盘的转化率提升”一次就通过了。记住指标不是给自己看的是给业务做决策用的。5. 团队协作与项目汇报中容易被忽略的细节写到这里技术内容已经差不多了。最后这部分聊点软性的但往往是项目能不能落地、能不能拿到资源的关键。5.1 用业务语言解释“无标签数据的价值”你拿着对比学习、InfoNCE损失、伪标签迭代去跟业务方讲大概率聊不到五分钟就被打断。同样一件事换一种说法效果完全不一样。不要说“我们用了无标签数据做自监督预训练”要说“我们没有购买标签但用行为轨迹把用户分成五类人工抽检后发现其中一类用户的行为模式像高意向人群可以优先跟进”。业务方在乎的是数据利用率、人效提升、成本下降不是你的技术架构。5.2 数据版本管理与分布监控无标签数据项目有个特点随着时间推移新数据会不断进来。如果不做版本管理你会发现实验复现不了团队协作来回扯皮。具体操作上我每个实验都会记录数据快照的哈希值、预处理参数、伪标签筛选阈值、随机种子保证任何一次实验结果都可以被完整复现。数据分布监控方面可以基于预训练模型的特征中心点定期做漂移检测一旦发现特征分布偏离基线超过阈值就触发重新训练或者报警。5.3 关于“无标签数据”的立项建议如果你发现团队里没人提“无标签数据利用”这件事那说明大家都默认了“没标签就没办法”。实际情况是很多业务本身积累了海量数据但标注比例可能连1%都不到。与其上来就申请大笔标注预算不如先把手上的无标签数据用起来。你可以把“无标签数据利用率”作为一项可量化指标哪怕先从一个小的业务场景跑通也比空洞的技术讨论有说服力得多。这一篇先把无标签数据的整体框架讲完了从场景价值、技术选型、实操流程到避坑经验都有涉及。下一期我准备专门写伪标签筛选阈值怎么调顺便把我在文本数据上用无标签方法做的几个实际项目拿出来拆一下。如果你有特别想看的方向也可以留言我会优先安排。