
第十二章 半监督学习
✅ 核心价值:大幅降低标注成本! 例如:标注1万条文本需10万元,但用100条+9900条无标签,效果接近全标注。
算法有效的前提:数据必须满足以下至少一种结构特性。
同类样本倾向于聚集在一起

图:红蓝点自然成簇,即使只有两个标签,也能推断整簇类别
✅ 应用:K-Means、Label Propagation 都依赖此假设
高维数据实际分布在低维“弯曲曲面”(流形)上,相近点应有相同标签

图:瑞士卷数据,欧氏距离远的两点在流形上其实很近
✅ 应用:Label Spreading、图神经网络(GNN)利用此结构
💡 通俗理解: 就像地球表面是2D流形,虽然北京和纽约在3D空间很远,但在地表路径上可连通。
✅ 优点:实现简单,兼容任何分类器(如SVM、神经网络) ❌ 缺点:若初始模型差,会传播错误标签(“垃圾进,垃圾出”)
✅ 优点:天然利用聚类假设,无需训练模型 ❌ 缺点:计算复杂度高($O(n^3)$),不适合大数据
场景 | 指标 | 说明 |
|---|---|---|
有测试集标签 | 准确率、F1、AUC | 标准监督指标,衡量预测能力 |
无测试标签 | 轮廓系数、CH指数 | 衡量预测结果是否符合数据聚类结构 |
综合评估 | 准确率 + 轮廓系数 | 既要看预测对不对,也要看是否尊重数据分布 |
💡 最佳实践: 在验证集上同时监控两个指标,避免模型“过拟合标签但违背数据结构”。
⚠️ 重要提醒: 不要盲目使用半监督!先验证:无标签数据是否与标签数据同分布? 数据是否呈现明显聚类结构?
import numpy as np
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.semi_supervised import LabelPropagation, LabelSpreading
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
# 加载新闻数据
categories = ['alt.atheism', 'soc.religion.christian', 'comp.graphics', 'sci.med']
news = fetch_20newsgroups(subset='all', categories=categories, remove=('headers', 'footers'))
X_text = news.data
y_true = news.target
# 向量化
vectorizer = TfidfVectorizer(max_features=5000, stop_words='english')
X = vectorizer.fit_transform(X_text)
# 模拟:仅用1%数据有标签
np.random.seed(42)
n_total = len(y_true)
n_labeled = int(0.01 * n_total) # 1%有标签
# 随机选择有标签样本
labeled_indices = np.random.choice(n_total, size=n_labeled, replace=False)
y_semi = np.full(n_total, -1) # -1 表示无标签
y_semi[labeled_indices] = y_true[labeled_indices]
# 方法1:伪标签法(用逻辑回归)
lr = LogisticRegression(max_iter=1000)
lr.fit(X[labeled_indices], y_true[labeled_indices])
# 预测无标签数据,取高置信度(>0.95)
proba = lr.predict_proba(X)
pseudo_labels = lr.predict(X)
high_conf = np.max(proba, axis=1) > 0.95
# 构建新训练集
X_train_pseudo = X[np.concatenate([labeled_indices, np.where(high_conf)[0]])]
y_train_pseudo = np.concatenate([y_true[labeled_indices], pseudo_labels[high_conf]])
# 重新训练
lr_pseudo = LogisticRegression(max_iter=1000)
lr_pseudo.fit(X_train_pseudo, y_train_pseudo)
# 方法2:Label Spreading
ls = LabelSpreading(kernel='knn', n_neighbors=10, max_iter=100)
ls.fit(X, y_semi)
# 评估(用完整测试集)
test_indices = np.setdiff1d(np.arange(n_total), labeled_indices)
y_test = y_true[test_indices]
print("=== 伪标签法 ===")
print(classification_report(y_test, lr_pseudo.predict(X[test_indices])))
print("\n=== Label Spreading ===")
print(classification_report(y_test, ls.predict(X[test_indices])))📊 典型结果(1%标签):纯监督(仅1%):准确率 ~60% 伪标签法:~75% Label Spreading:~78%
from sklearn.datasets import make_classification
from sklearn.semi_supervised import LabelSpreading
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score as ARI
# 模拟客户数据(收入、消费、活跃度)
X, y_true = make_classification(n_samples=1000, n_features=3, n_redundant=0,
n_clusters_per_class=1, n_classes=3, random_state=42)
# 仅10个客户有标签(业务专家标注)
labeled_idx = np.random.choice(1000, size=10, replace=False)
y_semi = np.full(1000, -1)
y_semi[labeled_idx] = y_true[labeled_idx]
# 1. 纯无监督:K-Means
kmeans = KMeans(n_clusters=3, random_state=42)
y_km = kmeans.fit_predict(X)
# 2. 半监督:Label Spreading
ls = LabelSpreading(kernel='rbf', gamma=10)
ls.fit(X, y_semi)
y_ls = ls.predict(X)
# 评估(假设我们知道真实标签)
print("K-Means ARI:", ARI(y_true, y_km))
print("Label Spreading ARI:", ARI(y_true, y_ls))
# 可视化(前两维)
plt.figure(figsize=(12, 4))
plt.subplot(131)
plt.scatter(X[:, 0], X[:, 1], c=y_true, cmap='tab10')
plt.title("真实标签")
plt.subplot(132)
plt.scatter(X[:, 0], X[:, 1], c=y_km, cmap='tab10')
plt.title("K-Means (无监督)")
plt.subplot(133)
plt.scatter(X[:, 0], X[:, 1], c=y_ls, cmap='tab10')
plt.title("Label Spreading (半监督)")
plt.show()💡 业务价值: 即使只有10个专家标注,半监督结果显著优于纯聚类,且能对齐业务定义的类别!
方法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
伪标签法 | 高置信预测作标签 | 简单、通用 | 错误传播 | 文本、图像分类 |
Label Propagation | 图上标签扩散 | 利用局部结构 | 计算慢 | 小规模结构化数据 |
Label Spreading | 正则化标签扩散 | 更鲁棒 | 同上 | 同上,推荐优先用 |
📘 延伸方向:
公众号:咚咚王
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。