ステージ2-2: オープンテスト (estimator.fit + estimator.score + np.random.permutation, cross_validation) (情報工学実験 3 : データマイニング班)
目次- 想定環境
- (手動1) iris データセットを素朴に2分割し、学習結果を採点してみる (estimator.fit + estimator.score)
- (手動2) iris データセットをシャッフルしてから2分割し、学習結果を採点してみる (np.random.permutation + estimator.fit + estimator.score)
- (自動) iris データセットをシャッフルしてからn分割し、学習結果を採点してみる (cross_validation.KFold + cross_validation.cross_val_score)
- 参考サイト一覧
- 想定環境
- 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)
- 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については全くテストしていないため、適切な評価方法になっていない。
- 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)
- 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())