在机器学习领域,决策边界是分类模型区分不同类别的分界线。本文将探讨在Iris数据集上,使用半监督学习算法Label Spreading和Self-training与支持向量机(SVM)算法比较其决策边界。Iris数据集是一个经典的多类分类问题,包含了150个样本,每个样本有4个特征,分别属于3个不同的类别。
半监督学习是一种机器学习范式,其中模型使用大量未标记数据和少量标记数据进行训练。在本文中,将使用Label Spreading和Self-training两种半监督学习算法,并与SVM算法进行比较。Label Spreading算法通过迭代过程将标签信息从标记样本传播到未标记样本,而Self-training算法则利用一个基础分类器对未标记样本进行预测,并将预测为确定性较高的样本加入训练集。
为了公平比较,将在不同比例的标记数据上训练这些模型。首先,将30%的数据标记,然后是50%,最后使用全部100%的数据。对于Self-training算法,当使用100%的数据时,其表现与直接使用SVM训练无异,因此省略了这部分的比较。
在实验中,首先导入了必要的库,包括matplotlib用于绘图,numpy用于数值计算,以及scikit-learn中的datasets、semi_supervised和svm模块。加载了Iris数据集,并选取了前两个特征用于简化问题。接着,创建了网格点用于绘制决策边界,并随机选择了一部分样本作为未标记数据。
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
from sklearn.semi_supervised import LabelSpreading, SelfTrainingClassifier
from sklearn.svm import SVC
iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target
# 网格点步长
h = 0.02
rng = np.random.RandomState(0)
y_rand = rng.rand(y.shape[0])
y_30 = np.copy(y)
y_30[y_rand < 0.3] = -1 # 设置随机样本为未标记
y_50 = np.copy(y)
y_50[y_rand < 0.5] = -1 # 设置随机样本为未标记
接下来,创建了SVM、Label Spreading和Self-training分类器的实例,并在不同比例的标记数据上进行训练。没有对数据进行缩放,因为希望在图中展示支持向量。
# 创建SVM、Label Spreading和Self-training分类器实例
ls30 = (LabelSpreading().fit(X, y_30), y_30, "Label Spreading 30% 数据")
ls50 = (LabelSpreading().fit(X, y_50), y_50, "Label Spreading 50% 数据")
ls100 = (LabelSpreading().fit(X, y), y, "Label Spreading 100% 数据")
base_classifier = SVC(kernel="rbf", gamma=0.5, probability=True)
st30 = (SelfTrainingClassifier(base_classifier).fit(X, y_30), y_30, "Self-training 30% 数据")
st50 = (SelfTrainingClassifier(base_classifier).fit(X, y_50), y_50, "Self-training 50% 数据")
rbf_svc = (SVC(kernel="rbf", gamma=0.5).fit(X, y), y, "使用rbf核的SVC")
为了绘制决策边界,创建了一个网格,并使用分类器对网格点进行预测。然后,将预测结果映射到颜色图上,并绘制了训练点。未标记的点被涂成白色。
# 创建网格以绘制
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
color_map = {-1: (1, 1, 1), 0: (0, 0, 0.9), 1: (1, 0, 0), 2: (0.8, 0.6, 0)}
classifiers = (ls30, st30, ls50, st50, ls100, rbf_svc)
for i, (clf, y_train, title) in enumerate(classifiers):
plt.subplot(3, 2, i + 1)
Z = clf[0].predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.axis("off")
colors = [color_map[y] for y in y_train]
plt.scatter(X[:, 0], X[:, 1], c=colors, edgecolors="black")
plt.title(title)
plt.suptitle("未标记点涂成白色", y=0.1)
plt.show()
实验结果显示,即使在标记数据量较少的情况下,Label Spreading和Self-training算法也能学习到良好的决策边界。这表明半监督学习算法在处理标记数据不足的问题上具有潜力。