scikit-learn でトレーニングデータとテストデータを作成する

Last update: 2017-10-08

本ページでは、Python の機械学習ライブラリの scikit-learn を用いてトレーニングデータとテストデータを作成するために、サンプリングを行なう手順を紹介します。

トレーニングデータ・テストデータとは

教師あり機械学習(回帰分析、決定木分析、ランダムフォレスト法、ナイーブベイズ法、ニューラルネットワークなど)によるモデルを作成するには、準備したデータセットをトレーニングデータ(訓練用データ、学習用データとも呼ばれます)とテストデータ(検証用データ、評価用データ、検証用データとも呼ばれます)の 2 つに分割して予測モデルの作成、評価を行なうことが一般的です。このように一定の割合でトレーニングデータとテストデータに分割することをホールドアウト (hold-out) と呼びます。

以下は、クレジットカードの解約予測の分析テーマを例に挙げて、そのイメージを説明します。

トレーニングデータとテストデータの分割

データセット全体 (20 レコード) を本例では、80 : 20 の割合でトレーニングデータ (16 件) とテストデータ (4件) に分割します。

sampling01

トレーニングデータとテストデータはどのような割合 (何対何) で分割すべきといった決まりはありませんが、トレーニングデータ : テストデータを 80 % : 20 % や、75 % : 25 % 、70 % : 30 % の比率で分割することが一般的です。

トレーニングデータを用いた機械学習モデルの作成

分割したデータのうち、トレーニングデータのみを用いて、説明変数 (x) と目的変数 (y) の関係性を学習し、説明変数 (x) が与えられたときに、目的変数 (y) を返す機械学習モデルを作成します。

sampling02

テストデータを用いた予測の実行

続いて、作成した機械学習モデルとテストデータの説明変数 (x) のみを用いて、予測結果を算出します。

sampling03

テストデータを用いた評価

前段で求めた予測結果と、実際の解約有無を比較することで、どれだけ正確に予測できるかを確認することで、機械学習モデルの予測性能を測ります。

sampling04

サンプリングを行なうときに注意すべきこと

データセット全体からレーニングデータとテストデータを分割する際に、データの特性に偏りのあるトレーニングデータやテストデータを使って機械学習モデルを作成すると、精度の悪いモデルができてしまいます。それを防ぐために、ランダムに並び替えたデータからデータセットを抽出します。そのような作業をサンプリング、特に、ランダムに抽出することをランダムサンプリングと呼びます。

train_test_split: トレーニングデータとテストデータを分割

scikit-learn には、トレーニングデータとテストデータの分割を行なうメソッドとしてsklearn.model_selection.train_test_split が用意されています。このメソッドは、与えられたデータフレームから、指定された条件に基づいてトレーニングデータとテストデータを分割します。

train_test_split の使い方

train_test_split の引数

arrays 分割対象の同じ長さを持った複数のリスト、Numpy の array, matrix, Pandasのデータフレームを指定。
test_size 小数もしくは整数を指定。小数で指定した場合、テストデータの割合を 0.0 〜 1.0 の間で指定します。整数を指定した場合は、テストデータに必ず含めるレコード件数を整数で指定します。指定しなかった場合や None を設定した場合は、train_size のサイズを補うように設定します。train_size を設定していない場合、デフォルト値として 0.25 を用います。
train_size 小数もしくは整数を指定。小数で指定した場合、トレーニングデータの割合を 0.0 〜 1.0 の間で指定します。整数を指定した場合は、トレーニングデータに必ず含めるレコード件数を整数で指定します。指定しなかった場合や None を設定した場合は、データセット全体から test_size を引いた分のサイズとします。
random_state 乱数生成のシードとなる整数または、RandomState インスタンスを設定します。指定しなかった場合は、Numpy のnp.random を用いて乱数をセットします。
shuffle データを分割する前にランダムに並び替えを行なうかどうか。True または False で指定します。False に設定した場合、stratify を None に設定しなければいけません。(デフォルト値: True)
stratify Stratified Sampling (層化サンプリング) を行なう場合に、クラスを示す行列を設定します。 (デフォルト値: None)

train_test_split の使用例

今回使用するデータフレーム (4 カラム、12 レコード) を作成します


テストデータを 30% (test_size=0.3) としてトレーニングデータ、テストデータに分割します。


テストデータを具体的な数値で、5 件 (test_size=5) としてトレーニングデータ、テストデータに分割します。


トレーニングデータを 50% (training_size=0.5) としてトレーニングデータ、テストデータに分割します。


データの並び替え(シャッフル)を行わないで、分割のみを実施します。


乱数のシードを 42 に固定します。1 回目と 2 回目で全く同じサンプリングがなされていることが見て取れます。


“department” のクラスによる層化サンプリングを行います。

層化サンプリングとは、サンプリングしたデータが偏らないよう、指定した変数の出現頻度が一定になるように調整した上で、サンプリングを行なうものです。以下の例では、”department” (=部門) を stratify=namelist['department'] として指定しているので、テストデータには、各部門 (IT (情報システム), HR (人事), Legal (法務)) が、全体の分布と同じになるよう、各 1 件ずつ抽出されています。


上記で説明した層化サンプリングを “attendance” (総会への出席状況) の列に基づいて実施した例は以下になります。テストデータには、1 が 2 件、0 が 1 件と、全体の分布とほぼ同じように抽出されていることがわかります。


例えば、説明変数 x (attendance 以外) と 目的変数 y (attendance) を分割し、train_test_split に 2 つ以上の引数を与えることもできます。以下の例では、データフレームとarray を渡し、データフレーム、array を 2 つずつ返します。

サンプリングを実施し、トレーニングデータ、テストデータに分割します。

参考:
sklearn.model_selection.train_test_split — scikit-learn 0.19.0 documentation

See also