警告,我不是此过程的专家。我未能产生良好的结果并不能证明该技术无法奏效。此外,您的图像具有“半监督”学习的一般描述,这是使用各种技术的广泛领域。
我同意您的直觉,但我看不出这种技术如何可以立即使用。换句话说,我认为您需要付出很多努力才能使其在特定应用程序中正常运行,而这种努力不一定会对其他应用程序有所帮助。
我尝试了两个不同的实例,一个实例具有香蕉形数据集(如示例图像中的一个),另一个实例具有两个简单的正态分布群集的简单数据集。在这两种情况下,我都无法改善初始分类器。
为了鼓励事物,我尝试将噪声添加到所有预测的概率中,希望这会带来更好的结果。
第一个示例我尽可能地忠实地重新创建了上面的图像。我认为伪标签不会在这里提供任何帮助。
第二个示例要容易得多,但是即使在这里,它也无法在初始分类器上进行改进。我专门从左类的中心选择了一个标记点,而右类的右侧则希望它可以沿正确的方向移动,而没有这样的运气。
示例1的代码(示例2足够相似,在此不再赘述):
import numpy as np
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
import seaborn
np.random.seed(2018-10-1)
N = 1000
_x = np.linspace(0, np.pi, num=N)
x0 = np.array([_x, np.sin(_x)]).T
x1 = -1 * x0 + [np.pi / 2, 0]
scale = 0.15
x0 += np.random.normal(scale=scale, size=(N, 2))
x1 += np.random.normal(scale=scale, size=(N, 2))
X = np.vstack([x0, x1])
proto_0 = np.array([[0], [0]]).T # the single "labeled" 0
proto_1 = np.array([[np.pi / 2], [0]]).T # the single "labeled" 1
model = RandomForestClassifier()
model.fit(np.vstack([proto_0, proto_1]), np.array([0, 1]))
for itercount in range(100):
labels = model.predict_proba(X)[:, 0]
labels += (np.random.random(labels.size) - 0.5) / 10 # add some noise
labels = labels > 0.5
model = RandomForestClassifier()
model.fit(X, labels)
f, axs = plt.subplots(1, 2, squeeze=True, figsize=(10, 5))
axs[0].plot(x0[:, 0], x0[:, 1], '.', alpha=0.25, label='unlabeled x0')
axs[0].plot(proto_0[:, 0], proto_0[:, 1], 'o', color='royalblue', markersize=10, label='labeled x0')
axs[0].plot(x1[:, 0], x1[:, 1], '.', alpha=0.25, label='unlabeled x1')
axs[0].plot(proto_1[:, 0], proto_1[:, 1], 'o', color='coral', markersize=10, label='labeled x1')
axs[0].legend()
axs[1].plot(X[~labels, 0], X[~labels, 1], '.', alpha=0.25, label='predicted class 0')
axs[1].plot(X[labels, 0], X[labels, 1], '.', alpha=0.25, label='predicted class 1')
axs[1].plot([np.pi / 4] * 2, [-1.5, 1.5], 'k--', label='halfway between labeled data')
axs[1].legend()
plt.show()