在机器学习领域,半监督学习是一种利用少量标记数据和大量未标记数据进行模型训练的方法。本文将介绍如何使用标签传播模型对一个手写数字数据集进行分类。这个数据集包含1797个样本点,将使用全部的点进行训练,但只有30个点会被标记。通过这种方式,可以得到一个性能良好的分类模型,并且以混淆矩阵和一系列针对每个类别的指标来展示结果。最后,还会展示模型预测最不确定的前10个样本。
使用手写数字数据集,但只从中随机选取一部分样本。首先,导入必要的库,并加载数据集。然后,随机打乱样本的顺序,并从中选取340个样本,其中只有40个样本会有已知的标签。因此,需要存储另外300个样本的索引,这些样本的标签是不应该知道的。
import numpy as np
from sklearn import datasets
# 加载手写数字数据集
digits = datasets.load_digits()
# 设置随机数种子以确保结果可复现
rng = np.random.RandomState(2)
# 随机打乱样本顺序
indices = np.arange(len(digits.data))
rng.shuffle(indices)
# 选取340个样本,其中40个样本会有已知的标签
X = digits.data[indices[:340]]
y = digits.target[indices[:340]]
images = digits.images[indices[:340]]
n_total_samples = len(y)
n_labeled_points = 40
indices = np.arange(n_total_samples)
unlabeled_set = indices[n_labeled_points:]
接下来,将对数据进行进一步的打乱,以便在训练过程中使用。将已知标签的样本的标签复制到训练标签中,并将未知标签的样本的标签设置为-1。
# 复制标签到训练标签
y_train = np.copy(y)
y_train[unlabeled_set] = -1
现在,将使用标签传播模型来预测未知的标签。标签传播是一种基于图的半监督学习方法,它通过迭代传播已知标签的信息来预测未知标签。将使用sklearn库中的LabelSpreading类来实现这一过程。
from sklearn.metrics import classification_report
from sklearn.semi_supervised import LabelSpreading
# 初始化标签传播模型
lp_model = LabelSpreading(gamma=0.25, max_iter=20)
# 训练模型
lp_model.fit(X, y_train)
# 预测未知标签
predicted_labels = lp_model.transduction_[unlabeled_set]
true_labels = y[unlabeled_set]
# 打印模型信息
print("Label Spreading model: %d labeled & %d unlabeled points (%d total)" % (
n_labeled_points, n_total_samples - n_labeled_points, n_total_samples))
接下来,将打印分类报告,以展示模型在每个类别上的性能。分类报告包括精确度、召回率、F1分数和支持度等指标。
# 打印分类报告
print(classification_report(true_labels, predicted_labels))
混淆矩阵是一种用于评估分类模型性能的工具,它显示了模型预测的类别与真实类别之间的关系。将使用sklearn库中的ConfusionMatrixDisplay类来绘制混淆矩阵。
from sklearn.metrics import ConfusionMatrixDisplay
# 绘制混淆矩阵
ConfusionMatrixDisplay.from_predictions(true_labels, predicted_labels, labels=lp_model.classes_)
在模型预测中,有些样本的预测结果可能比其他样本更不确定。将计算每个样本的预测不确定性,并展示最不确定的前10个样本。
from scipy import stats
# 计算预测不确定性
pred_entropies = stats.distributions.entropy(lp_model.label_distributions_.T)
# 选择最不确定的10个样本
uncertainty_index = np.argsort(pred_entropies)[-10:]
# 绘制最不确定的预测
import matplotlib.pyplot as plt
f = plt.figure(figsize=(7, 5))
for index, image_index in enumerate(uncertainty_index):
image = images[image_index]
sub = f.add_subplot(2, 5, index + 1)
sub.imshow(image, cmap=plt.cm.gray_r)
plt.xticks([])
plt.yticks([])
sub.set_title("predict: %i\ntrue: %i" % (
lp_model.transduction_[image_index], y[image_index]))
f.suptitle("Learning with small amount of labeled data")
plt.show()
通过上述步骤,成功地使用标签传播模型对手写数字数据集进行了分类,并且展示了模型预测最不确定的前10个样本。这个例子展示了半监督学习在只有少量标记数据的情况下的强大能力。
以下是一些与本例相关的其他示例: