元のページ

ステージ2-5: 半教師あり学習の練習 (label_propagation.LabelSpreading) (情報工学実験 3 : データマイニング班)

目次

想定環境

データセットの用意

import numpy as np
from sklearn.datasets import make_circles
n_samples = 200
data, target0 = make_circles(n_samples=n_samples, shuffle=False)

# make_circles() がどういうデータを生成したのかを確認してみる。
#  dataは2次元特徴ベクトル: 
#  targetは教師データ: 前半=0, 後半=1
import pylab as pl
pl.figure()
X = data[:,0]
Y = data[:,1]
labels = target0
pl.title("make_circles")
pl.scatter(X, Y, c=labels)
#pl.show()
pl.savefig("fig0_make_circles.svg")




# 半教師あり学習用にラベルを設定し直す。
#  教師データ2種:
#   内側と外側の円上で最短距離にあるサンプル2点のみに教師信号を与える。
#    外側の円(outer): label=0
#    内側の円(inner): label=1
#  それ以外のデータは未知ラベルとして-1を設定
target1 = - np.ones(n_samples)
unlabeled = -1
outer = 1
inner = 2
target1[0] = outer
target1[-1] = inner

pl.figure(1)
pl.title("before learning (law data)")
pl.scatter(X[:,target1==outer], Y[:,target1==outer], c='b', label='outer')
pl.scatter(X[:,target1==inner], Y[:,target1==inner], c='r', label='inner')
pl.scatter(X[:,target1==unlabeled], Y[:,target1==unlabeled], c='g', label='unlabeled')
pl.legend()
#pl.show()
pl.savefig("fig1_lawdata.svg")






2点にのみ教師データを用意し、残りを「ラベルが無いデータ」として半教師あり学習を適用してみる

# 半教師あり学習(label_propagetion.LabelSpreading)を実行。
#  unlabeled がどうなったかを確認。
from sklearn.semi_supervised import label_propagation
label_spread = label_propagation.LabelSpreading(kernel='knn', alpha=1.0)
label_spread.fit(data, target1)
output_labels = label_spread.transduction_

pl.figure(2)
pl.title("LabelSpreading")
pl.scatter(X[:,output_labels==outer], Y[:,output_labels==outer], c='b', label='outer')
pl.scatter(X[:,output_labels==inner], Y[:,output_labels==inner], c='r', label='inner')
pl.scatter(X[:,output_labels==unlabeled], Y[:,output_labels==unlabeled], c='g', label='unlabeled')
pl.legend()
#pl.show()
pl.savefig("fig2_LabelSpreading.svg")





(平等な条件ではないが)教師あり学習(svm.SVC)でも試してみる

# 類似条件(2点のみ教師データあり)で教師あり学習(svm.SVC)を試してみる。
#  教師あり学習の場合には「教師データが無いデータ」は学習時に提示できない。
#  その状況で学習したモデルを使って、unlabeled がどうなるかを確認。

def filter(data, target, label):
    u'''labelで指定されたtarget値を持つdataのみを抽出。
    ここでは教師データを付与したtarget[0], target[-1]に該当するdata[0], data[1]
    のみを切り出せば十分なので手動でやっても良いが、汎用性のある関数として記述した例。
    '''
    filtered_list = []
    samples = data[target==label].tolist()
    for sample in samples:
        filtered_list.append(sample)
    return filtered_list

# 教師データを付与した2点のみで学習用データセット(data2, target2)を構築。
# 残りの未ラベルデータでテスト用データセット(data2_test)を構築。
data2 = filter(data, target1, inner) + filter(data, target1, outer)
target2 = filter(target1, target1, inner) + filter(target1, target1, outer)
data2_test = filter(data, target1, unlabeled)

from sklearn import svm
clf = svm.SVC(gamma=0.001, C=100.)
clf.fit(data2, target2)
output_labels2 = clf.predict(data2_test)

pl.figure(3)
pl.title("svm.SVC")
pl.scatter(X[:,output_labels2==outer], Y[:,output_labels2==outer], c='b', label='outer')
pl.scatter(X[:,output_labels2==inner], Y[:,output_labels2==inner], c='r', label='inner')
pl.scatter(X[:,output_labels2==unlabeled], Y[:,output_labels2==unlabeled], c='g', label='unlabeled')
pl.legend()
#pl.show()
pl.savefig("fig3_SVC.svg")






(平等な条件ではないが)教師無し学習(cluster.KMeans)でも試してみる

# 教師なし学習(cluster.KMeans)を試してみる。 from sklearn import cluster k_means = cluster.KMeans(n_clusters=2) k_means.fit(data) output_labels3 = k_means.labels_ pl.figure(4) pl.title("cluster.KMeans") pl.scatter(X[:,output_labels3==0], Y[:,output_labels3==0], c='b', label='label = 0') pl.scatter(X[:,output_labels3==1], Y[:,output_labels3==1], c='r', label='label = 1') pl.scatter(X[:,output_labels3==unlabeled], Y[:,output_labels3==unlabeled], c='g', label='unlabeled') pl.legend() #pl.show() pl.savefig("fig4_KMeans.svg")




参考サイト一覧