Python: scikit-learnでK-fold cross validation
Scikit-learn
http://scikit-learn.org/stable/
はクロスバリデーションまでできてしまいます。
というか、グリッドサーチとかも。
使ってみたので、コード例を貼っておきます。
ポイントとして、単なるKFoldをそのまま使うと
順番にサンプルを分割して行くので、
事前にデータのサンプルの順番を入れ替えるひと手間を入れます。
こうすると、期待通りのn-fold cross validationになるって寸法です。
Shuffle&Splitをしてもいいのですが、これだと一部のサンプルが複数回テストされる事態になりそうなので使用は回避しています。実際の挙動はわかりませんが。
>>> import numpy as np
>>> from sklearn.cross_validation import KFold
>>> X = np.array( [[0.,0.], [1., 1.], [2.,2.], [3.,3.], [4.,4.], [5., 5.], [6., 6.]] )
>>> Y = np.array( [0, 1, 0, 1, 0, 1, 0] )
>>> print X
[[ 0. 0.]
[ 1. 1.]
[ 2. 2.]
[ 3. 3.]
[ 4. 4.]
[ 5. 5.]
[ 6. 6.]]
>>> print Y
[0 1 0 1 0 1 0]
# ここでひと手間いれる
>>> permute_idx = np.random.permutation(len(Y))
>>> print permute_idx
[1 3 4 5 0 2 6]
>>> Xp = X[permute_idx]
>>> Yp = Y[permute_idx]
>>> print Xp
[[ 1. 1.]
[ 3. 3.]
[ 4. 4.]
[ 5. 5.]
[ 0. 0.]
[ 2. 2.]
[ 6. 6.]]
>>> print Yp
[1 1 0 1 0 0 0]>>> kf = KFold(len(Yp), n_folds=3)
>>> for train, test in kf:
... Xtrain= Xp[train]
... Xtest = Xp[test]
... Ytrain = Yp[train]
... Ytest = Yp[test]
# do some machine-learning by "fit" and "predict"
... print "\n"
... print Xtrain
... print Xtest
... print Ytrain
... print Ytest
...
# ちゃんとデータが分割されてる# fold 1
[[ 4. 4.]
[ 5. 5.]
[ 0. 0.]
[ 2. 2.]
[ 6. 6.]] # Xtrain
[[ 1. 1.]
[ 3. 3.]] # Xtest
[0 1 0 0 0] # Ytrain
[1 1] # Ytest
# fold 2
[[ 1. 1.]
[ 3. 3.]
[ 0. 0.]
[ 2. 2.]
[ 6. 6.]] # Xtrain
[[ 4. 4.]
[ 5. 5.]] # Xtest
[1 1 0 0 0] # Ytrain
[0 1] # Ytest# fold 3
# fold数とデータ数が割り切れなくても適当に分けてくれている
[[ 1. 1.]
[ 3. 3.]
[ 4. 4.]
[ 5. 5.]] # Xtrain ちょっと少ない
[[ 0. 0.]
[ 2. 2.]
[ 6. 6.]] # Xtest ちょっと多い
[1 1 0 1] # Ytrain ちょっと多い
[0 0 0] # Ytest ちょっと多い