경고, 저는이 절차의 전문가가 아닙니다. 좋은 결과를 얻지 못했다고해서 기술이 제대로 작동하지 않는다는 증거는 아닙니다. 또한 이미지에는 다양한 기술을 갖춘 넓은 영역 인 "반감 독식"학습에 대한 일반적인 설명이 있습니다.
나는 당신의 직감에 동의합니다. 나는 이와 같은 기술이 어떻게 작동하는지 볼 수 없습니다. 즉, 특정 응용 프로그램에서 제대로 작동하려면 많은 노력이 필요하다고 생각하며 다른 응용 프로그램에서는 이러한 노력이 도움이 될 필요는 없습니다.
예제 이미지의 것과 같은 바나나 모양의 데이터 세트와 두 개의 간단한 정규 분산 클러스터를 사용하여 더 쉬운 데이터 세트를 가진 두 가지 인스턴스를 시도했습니다. 두 경우 모두 초기 분류기를 개선 할 수 없었습니다.
사물을 장려하기위한 작은 시도로서, 나는 이것이 더 나은 결과를 초래할 것이라는 희망으로 모든 예상 확률에 소음을 추가했습니다.
첫 번째 예는 위의 이미지를 최대한 충실하게 재현 한 것입니다. psuedo-labeling이 여기에서 전혀 도움이 될 것이라고 생각하지 않습니다.
두 번째 예는 훨씬 쉽지만 여기서도 초기 분류기에서 개선되지 않습니다. 나는 특별히 왼쪽 계급의 중심에서 하나의 레이블이 붙은 점을 선택했고, 오른쪽 계급의 오른쪽은 올바른 방향으로 움직이기를 바랐습니다.
예 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()