元のページ

ステージ2-2: オープンテスト (estimator.fit + estimator.score + np.random.permutation, cross_validation) (情報工学実験 3 : データマイニング班)

目次
  1. 想定環境
    • OS: Mac OS X 10.8.5 (10.7.x以降であれば同じ方法で問題無いはず)
    • Python: 2.7.x
    • Mercurial: 2.2
    • Scikit-learn: 0.14.1 (sklearn.__version__)
    • matplotlib: 1.3.0 (matplotlib.__version__)
    • numpy: 1.9.0.dev (numpy.version)
    • scipy: 0.14.0.dev (scipy.version)
  2. iris データセットを素朴に2分割し、学習結果を採点してみる。
    from sklearn import datasets
    iris = datasets.load_iris()
    data = iris.data
    target = iris.target
    
    #学習用データ, 教師データを準備
    half = len(data)/2
    data_train = data[:half]
    target_train = target[:half]
    
    #テスト用データ, 教師データを準備
    data_test = data[half:]
    target_test = target[half:]
    
    #estimatorとしてSVMを用意
    from sklearn import svm
    clf = svm.SVC(gamma=0.001, C=100.)
    
    #学習用データで学習(fit)し、
    #テストデータで推測(predict)させた結果を検証
    clf.fit(data_train, target_train)
    clf.predict(data_test)
    target_test
    
    #テスト結果を採点
    score1 = clf.score(data_test, target_test)
    print score1
    
    #逆のパターン(学習用データとテスト用データを入れ替えて採点)
    clf.fit(data_test, target_test)
    score2 = clf.score(data_train, target_train)
    print score2
    
    #平均スコア
    totalscore = (score1 + score2) / 2.0
    print totalscore
    # 平均スコアは約32%程度のはず。
    

    (補足) irisデータセットは、サンプルが綺麗に並んでいる(最初の50件がクラス0、次の50件がクラス1、最後の50件がクラス2)。そのため、単純に前半後半で分割するやり方では「クラス0を50件+クラス1を25件で学習して、クラス1の25件+クラス2の25件を予測」するような形でしか学習することができない。言い換えると、学習時点ではクラス2の存在自体を教えない状況で学習していることと、クラス0については全くテストしていないため、適切な評価方法になっていない。








  3. iris データセットをシャッフルしてから2分割し、学習結果を採点してみる。
    from sklearn import datasets
    iris = datasets.load_iris()
    data = iris.data
    target = iris.target
    
    #学習用データ, 教師データを準備
    #乱数シード値は0に固定しておく
    import numpy as np
    np.random.seed(0)
    indices = np.random.permutation(len(data))
    half = len(data)/2
    data_train = data[indices[:half]]
    target_train = target[indices[:half]]
    
    #テスト用データ, 教師データを準備
    data_test = data[indices[half:]]
    target_test = target[indices[half:]]
    
    #estimatorとしてSVMを用意
    from sklearn import svm
    clf = svm.SVC(gamma=0.001, C=100.)
    
    #学習用データで学習(fit)し、
    #テストデータで採点。
    clf.fit(data_train, target_train)
    score1 = clf.score(data_test, target_test)
    print score1
    
    #逆のパターン(学習用データとテスト用データを入れ替えて採点)
    clf.fit(data_test, target_test)
    score2 = clf.score(data_train, target_train)
    print score2
    
    #平均スコア
    totalscore = (score1 + score2) / 2.0
    print totalscore
    







(自動) iris データセットをシャッフルしてからn分割し、学習結果を採点してみる (cross_validation.KFold + cross_validation.cross_val_score)

from sklearn import datasets
iris = datasets.load_iris()
data = iris.data
target = iris.target

from sklearn import svm
clf = svm.SVC(gamma=0.001, C=100.)

#交差検定での分割用インデックス(イテレータ)生成
# cross_validation.KFold(): n_folds=分割数
import numpy as np
np.random.seed(0)
from sklearn import cross_validation
kfold = cross_validation.KFold(n=len(data), n_folds=3, shuffle=True)
for train_idx, test_idx in kfold:
    print "train_idx: ", train_idx
    print "test_idx: ", test_idx

#交差検定
# cross_validation.creoss_val.score():
#     estimator, data, target, K-Foldsイテレータ, n_jobs
#     n_jobs=使用するCPU数。-1なら全CPU。
scores = cross_validation.cross_val_score(clf, data, target, cv=kfold, n_jobs=-1)
print "scores =", scores
print "max = %s, ave = %s, min = %s" % (scores.max(), scores.mean(), scores.min())




参考サイト一覧