本文目录导读:

我来介绍用Scikit-learn做半监督学习的几种方法,主要使用LabelPropagation和LabelSpreading两种算法。
基础示例:LabelPropagation
import numpy as np
import matplotlib.pyplot as plt
from sklearn.semi_supervised import LabelPropagation, LabelSpreading
from sklearn.datasets import make_moons
from sklearn.metrics import accuracy_score
# 生成数据
X, y = make_moons(n_samples=200, noise=0.15, random_state=42)
# 创建半监督学习场景:只标记部分数据
rng = np.random.RandomState(42)
random_unlabeled_points = rng.rand(len(y)) < 0.7 # 70%的数据无标签
y_mixed = y.copy()
y_mixed[random_unlabeled_points] = -1 # -1表示无标签
# 训练LabelPropagation模型
lp_model = LabelPropagation(kernel='knn', n_neighbors=7, max_iter=100)
lp_model.fit(X, y_mixed)
# 预测
y_pred = lp_model.predict(X)
# 评估(只对原始有标签的数据)
labeled_indices = ~random_unlabeled_points
accuracy = accuracy_score(y[labeled_indices], y_pred[labeled_indices])
print(f"LabelPropagation准确率: {accuracy:.3f}")
LabelSpreading算法
# 使用LabelSpreading算法
ls_model = LabelSpreading(kernel='rbf', gamma=20, alpha=0.8)
ls_model.fit(X, y_mixed)
y_pred_ls = ls_model.predict(X)
accuracy_ls = accuracy_score(y[labeled_indices], y_pred_ls[labeled_indices])
print(f"LabelSpreading准确率: {accuracy_ls:.3f}")
# 查看传播后的标签概率
probabilities = ls_model.predict_proba(X)
print(f"传播概率维度: {probabilities.shape}")
完整的示例:对比不同方法
import numpy as np
from sklearn.semi_supervised import LabelPropagation, LabelSpreading
from sklearn.semi_supervised import SelfTrainingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 1. 加载数据集
digits = load_digits()
X, y = digits.data, digits.target
# 2. 分割数据集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 3. 创建半监督场景:只保留少量标签
n_labeled = 50 # 只有50个有标签的样本
rng = np.random.RandomState(42)
indices = rng.permutation(len(X_train))
# 创建混合标签:大多数设为-1(无标签)
y_train_mixed = y_train.copy()
y_train_mixed[indices[n_labeled:]] = -1
print(f"训练集大小: {len(X_train)}")
print(f"有标签样本数: {n_labeled}")
print(f"无标签样本数: {len(X_train) - n_labeled}")
# 4. 训练各个模型
models = {
'LabelPropagation': LabelPropagation(kernel='rbf', gamma=20),
'LabelSpreading': LabelSpreading(kernel='rbf', gamma=20),
'SelfTraining': SelfTrainingClassifier(
LogisticRegression(max_iter=1000, random_state=42)
)
}
# 5. 训练和评估
for name, model in models.items():
model.fit(X_train, y_train_mixed)
y_pred = model.predict(X_test)
accuracy = np.mean(y_pred == y_test)
print(f"\n{name} 准确率: {accuracy:.3f}")
可视化传播过程
import numpy as np
import matplotlib.pyplot as plt
from sklearn.semi_supervised import LabelSpreading
from sklearn.datasets import make_swiss_roll
from mpl_toolkits.mplot3d import Axes3D
# 生成Swiss Roll数据集
n_samples = 500
X, color = make_swiss_roll(n_samples=n_samples, noise=0.1, random_state=42)
# 随机选择标签点
np.random.seed(42)
n_labeled = 20
random_states = np.random.randint(0, n_samples, n_labeled)
y_labels = np.full(n_samples, -1)
y_labels[random_states] = color[random_states].astype(int) % 3 # 3个类别
# 训练LabelSpreading
model = LabelSpreading(kernel='rbf', gamma=20, alpha=0.8)
model.fit(X, y_labels)
# 获取传播后的标签
y_propagated = model.predict(X)
# 可视化
fig = plt.figure(figsize=(12, 5))
# 原始标签
ax1 = fig.add_subplot(121, projection='3d')
scatter = ax1.scatter(X[:, 0], X[:, 1], X[:, 2],
c=y_labels, cmap='viridis', s=50)
ax1.set_title('原始标签(蓝色=无标签)')
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_zlabel('Z')
# 传播后的标签
ax2 = fig.add_subplot(122, projection='3d')
scatter = ax2.scatter(X[:, 0], X[:, 1], X[:, 2],
c=y_propagated, cmap='viridis', s=50)
ax2.set_title('传播后的标签')
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_zlabel('Z')
plt.tight_layout()
plt.show()
超参数调优示例
from sklearn.model_selection import GridSearchCV
from sklearn.semi_supervised import LabelSpreading
from sklearn.metrics import make_scorer, f1_score
import numpy as np
# 创建数据集
np.random.seed(42)
X = np.random.randn(200, 10)
y = (X[:, 0] + X[:, 1] > 0).astype(int)
# 创建半监督场景
y_mixed = y.copy()
mask = np.random.random(len(y)) > 0.1 # 90%无标签
y_mixed[mask] = -1
# 定义参数网格
param_grid = {
'kernel': ['knn', 'rbf'],
'gamma': [10, 20, 30, 40],
'n_neighbors': [3, 5, 7, 9],
'alpha': [0.5, 0.7, 0.9]
}
# 创建模型
ls = LabelSpreading(max_iter=100)
# 网格搜索
grid_search = GridSearchCV(
ls, param_grid, cv=3,
scoring=make_scorer(f1_score, average='weighted'),
n_jobs=-1
)
# 使用有标签的数据进行验证
labeled_mask = y_mixed != -1
grid_search.fit(X[labeled_mask], y[labeled_mask])
print(f"最佳参数: {grid_search.best_params_}")
print(f"最佳分数: {grid_search.best_score_:.3f}")
实战:图像分类示例
from sklearn.semi_supervised import LabelPropagation
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# 加载手写数字数据集
digits = load_digits()
X, y = digits.data, digits.target
# 降维可视化
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
# 创建半监督场景
n_labeled = 30
rng = np.random.RandomState(42)
labeled_idx = rng.choice(len(y), n_labeled, replace=False)
y_mixed = -np.ones_like(y)
y_mixed[labeled_idx] = y[labeled_idx]
# 训练
model = LabelPropagation(kernel='rbf', gamma=10)
model.fit(X, y_mixed)
# 可视化结果
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 真实标签
scatter1 = ax1.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='tab10', alpha=0.6)
ax1.set_title('真实标签')
plt.colorbar(scatter1, ax=ax1)
# 预测标签
y_pred = model.transduction_
scatter2 = ax2.scatter(X_pca[:, 0], X_pca[:, 1], c=y_pred, cmap='tab10', alpha=0.6)
ax2.set_title('传播后标签')
plt.colorbar(scatter2, ax=ax2)
plt.tight_layout()
plt.show()
# 评估
accuracy = np.mean(y_pred == y)
print(f"整体准确率: {accuracy:.3f}")
关键要点
-
数据准备:无标签样本用 -1 标记
-
算法选择:
LabelPropagation:基于图传播LabelSpreading:改进版,更稳定SelfTrainingClassifier:可以结合任何分类器
-
适用场景:
- 标注数据稀缺
- 数据量大但标注成本高
- 需要利用无标签数据提升性能
-
注意事项:
- 选择合适的核函数(knn 或 rbf)
- 调整传播参数(gamma, alpha 等)
- 监控传播效果的稳定性
这些示例展示了 Scikit-learn 中半监督学习的基本用法,适合处理标签数据稀缺的实际问题。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播