機械学習:訓練データとテストデータの分割方法

AIプログラミング
スポンサーリンク

今回は、機械学習プログラミングで用いられるデータの分割方法についてご紹介したいと思います。

この記事では、なぜデータ分割をする必要があるのかを説明した後、実際の分割方法としてscikit-learnが用意するtrain_test_split関数と、Chinerが用意するsplit_dataset_random関数についてご紹介したいと思います。

 

使い方だけ知りたい方は、3.と4.へ目次から移動してください!

 

1.データ分割をする理由

みなさん機械学習の問題に取り組むときは、訓練データとテストデータの2つに分けると思うのですが、なぜデータを分ける必要があるのか考えたことは一度はあると思います。

通常、機械学習はデータを入力し学習させて、訓練データだけを使って学習を行い、最適なパラメータを探索し更新していくのが、一般的な流れになると思います。

そしてその後、テストデータを使用して、訓練させたモデルを評価します。

 

では、なぜ訓練データとテストデータを分ける必要があるのでしょう。

 

理由は、汎化力を正しく評価するためです。機械学習のモデルを作るときに、そのモデルに求めることは汎化能力です。汎化能力とは、訓練データ以外に対して同じ性能を発揮できる能力を持つことです。

この汎化能力を獲得することが機械学習の最終的な目標です。

例えば、手書き文字の訓練データを全てモデルに学習させたとしましょう。

この学習モデルを使って、文字認識が非常に高い精度であったとしても成功とは言えません。理由は訓練データに含まれる「ある人の」クセ字や特徴だけを訓練しているのであって、このデータに特化したモデルができてしまっているからです。

そのため、ある特定のデータだけに過度に対応したモデルではなく、他のデータセットにも十分対応できるモデルを作成するために、訓練データとテストデータを分割させるのです。ちなみに、あるデータだけに過度に対応した状態の状態を過学習といいます。

 

では実際にデータ分割に挑戦していきましょう。

2.使用するデータの準備

今回使用するデータは、機械学習の入門で使用される、アヤメのデータセットを使用します。これはscikit-learnがあらかじめ用意したデータセットになります。

今回はデータに関する説明はしません。

詳細を知りたい方はこちらへ:kerasを使ってアヤメの分類

でもざっくり説明すると、

特徴データはがく片の長さ、がく片の幅、花びらの長さ、花びらの幅の4種類のデータが大量に格納されています。

ラベルデータは、ヒオウギアヤメ(setosa)・ブルーフラッグ(versicolor)     ・Virginicaの3種類のアヤメ品種データが格納されています。

 

3.【scikit-learn】train_test_split関数

引数:test_sizeを指定する方法

まずimport文で、train_test_split関数をインポートしましょう。

次に、train_test_split関数の使い方についてです。

Point:train _test_split関数の使い方

変数は、訓練データ(特徴・ラベル)とテストデータ(特徴・ラベル)の計4種類を指定します。

引数のtest_sizeを指定する場合は、テストデータを何割に分割したいかを0~1.0の間で指定します。

この時、訓練データは指定しなくてもOKです。自動的に分割されるので。

 

引数:train_sizeを指定する方法

今度は訓練データの分割割合を指定する場合です。これは、test_sizeの割合を決めたときと使い方は同じです。

 

Point: train _test_split関数の使い方

train_sizeは0~1.0の間で指定する。データ型はfloat型

評価データのサイズは指定しなくてもOKです。

 

引数:random_stateを指定する場合

ここでは、コードとその結果を記載します。

ランダムシードは、シード値によってランダム値が決められており、シード値を同じ数字にすると毎回同じ疑似乱数が生成されるものです。

つまり、ランダムで分割する際に、再度分割する時も同じ条件で分割してほしいときに使用します。もちろんシードを指定しないと、分割後の値がランダムになります。

 

コードを見てみると、

ランダムシードを1を指定した1回目の訓練データ・検証データの結果と、2回目の訓練データ・検証データの結果を比較してみてください。

同一の数字の並びになっているのがわかります。

このようにシードによって分割後の値が固定されるのです。

Point:random_stateの指定の仕方

 

引数:shuffleを指定する場合

引数にshuffleを指定する場合、datasetをシャッフルした上で分割されます。

Point:shuffleの指定の仕方

シャッフルの指定は、shuffle=Trueもしくはshuffle=FalseでON/OFFできます。

 

次にChainerに用意されているデータ分割方法について紹介します。

3.【Chainer】split_dataset_random関数

Chainerでのdatasetの作り方

Chainerではデータセットの作成に便利なクラスがあります。

それは、TupleDataset関数です。 ndarrayをデータセットとして同様に扱えるように、入力値とラベルデータをセットでデータを作成することができます。

datasets[0:10]の出力結果を見てみると、

array([特徴データ], ラベルデータ)

という特徴データとラベルデータがペアでアクセスできるようになっています。

Point:TupleDatasetの使い方

 

Chainerを使ったデータ分割方法

Chainerにはデータ分割に関する関数も用意されています。

sklearnでされている関数とは違い、datasetはTupleDatasetで特徴データとラベルデータを1つにまとめてあるので、

あとはそのデータをどの割合で分割するか決めるだけです。

Point:split_dataset_random関数の使い方

 

4.まとめ

最後にデータセットの分割方法は様々です。scikit-learnやChainerが用意する関数を使用しなくても分割することができます。

しかし、各関数を使用することでコードも少なくなりエラーも起こりにくくなる可能性があります。

積極的に使用してみるといいかもしれませんね。

コメント

  1. […] 機械学習:訓練データとテストデータの分割方法 […]

タイトルとURLをコピーしました