質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
scikit-learn

scikit-learnは、Pythonで使用できるオープンソースプロジェクトの機械学習用ライブラリです。多くの機械学習アルゴリズムが実装されていますが、どのアルゴリズムも同じような書き方で利用できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

1回答

2947閲覧

教師あり学習において、訓練データとテストデータに分割する際の層化サンプリングにの必要性

1mzmk

総合スコア42

scikit-learn

scikit-learnは、Pythonで使用できるオープンソースプロジェクトの機械学習用ライブラリです。多くの機械学習アルゴリズムが実装されていますが、どのアルゴリズムも同じような書き方で利用できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2020/04/14 21:32

教師あり学習において、訓練データとテストデータに分割する際の層化サンプリングにの必要性について質問させてください。

まず、あるデータセットに対して、X,yに格納した説明変数、目的変数があります。(yは0と1のどちらかの値をもつラベルです)

そのX,yを訓練データとテストデータに下記のコードにより分割しました。

Python

1X_train,X_test,y_train, y_test=train_test_split(X, y, stratify=y )

Python

1print(y_train.value_counts()) 2print(y_test.value_counts()) 3print(y.value_counts())

下記の結果は上記のコードの実行結果で、層化サンプリングによってyを訓練データとテストデータを分割したあとの0と1のデータの数です。

Python

1#訓練データ 20 265 31 181 4Name: Survived, dtype: int64 5#テストデータ 60 89 71 60 8Name: Survived, dtype: int64 9#元のデータセット 100 354 111 241

この結果から、層化サンプリングはあるデータセットに対して2種類の0と1を持つラベルデータをYに格納した場合、訓練データとテストデータに層化サンプリングを用いて分割する必要があるのは、データにどのような特徴がある場合でしょうか?

個人的には訓練データとテストデータそれぞれを0と1のデータを5:5に分割するべきではないかと考えてしまいます。

それでは、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

層化サンプリングを用いて分割する必要があるのは、データにどのような特徴がある場合でしょうか?

データセットのクラスごとのサンプル数が偏りがある場合に層化抽出法を使用します。(例: クラスAは800個、クラスBは200個)

そのような場合にランダムにサンプリングすると、あるクラスのサンプルが学習データまたはテストデータに偏るということが起こりえます。
例えば、学習データ、テストデータを8:2で分けたとき、クラスAだけ見ると、その比率が 9:1 とかになったりします。

クラスごとのサンプル数に偏りがない場合は、層化抽出しなくてもよいですが、したら逆にダメなケースというのはないので、クラス分割の場合は基本的に層化抽出ありでよいでしょう。

層化抽出する場合としない場合の検証コード

python

1import pandas as pd 2import numpy as np 3from sklearn.model_selection import train_test_split 4 5np.random.seed(0) 6 7# 2つのクラスのサンプル数に偏りがある場合 8y = np.random.choice([1, 2], 500, p=[0.2, 0.8]) 9 10# 層化抽出なし 11############################# 12train, test = train_test_split(y) # 75]25 の割合で分割 (デフォルト) 13print("層化抽出なし") 14df = pd.DataFrame({"y": pd.value_counts(y), "train": pd.value_counts(train), "test": pd.value_counts(test)}) 15print(df) 16 17df2 = df.div(pd.value_counts(y), axis=0) 18print(df2) 19 20# 層化抽出あり 21############################# 22train, test = train_test_split(y, stratify=y) # 75]25 の割合で分割 (デフォルト) 23print("層化抽出あり") 24 25df = pd.DataFrame({"y": pd.value_counts(y), "train": pd.value_counts(train), "test": pd.value_counts(test)}) 26print(df) 27 28df2 = df.div(pd.value_counts(y), axis=0) 29print(df2)
層化抽出なし y train test 2 401 307 94 1 99 68 31 y train test 2 1.0 0.765586 0.234414 ← ほぼ 75:25 の割合になってる 1 1.0 0.686869 0.313131 ← 75:25 の割合になってない 層化抽出あり y train test 2 401 301 100 1 99 74 25 y train test 2 1.0 0.750623 0.249377 ← ほぼ 75:25 の割合になってる 1 1.0 0.747475 0.252525 ← ほぼ 75:25 の割合になってる

不明点があれば追記しますので、コメントしてください

投稿2020/04/15 04:42

編集2020/04/15 04:45
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1mzmk

2020/04/15 06:38

ご回答いただきありがとうございます。 1つご質問させてください。 層化サンプリングについては理解することができたのですが、 ご回答いただいたクラスAは800個、クラスBは200個の例で データセットのサンプルをすべて使って学習、テストをしない場合は、訓練データをAから70,Bから70個使って学習させ、テストする際にはAから30,Bから30個使って検証を行う場合などはないのでしょうか?
tiitoi

2020/04/15 06:43 編集

もちろん、そうして各クラスのサンプル数を揃えてもいいのですが、機械学習の精度を上げるためにはデータの量が大事なので、持っているデータはできるだけ無駄にせずに学習及びテストに活用したいです。 そのため、少ないクラスのサンプル数に合わせて一部しか使わないということは、メリットがないので普通はやらないですね
tiitoi

2020/04/15 06:48

各クラスのサンプル数が同じぐらいのデータセットが手に入るのであれば、それが理想ですが、現実的には、クラスごとでサンプル数に偏りがある場合というのが多いです。
1mzmk

2020/04/15 07:13

再度、ご回答いただきありがとうございます。 最後に、ご回答頂いた内容を以下のように解釈しましたのでご確認いただいてもよろしいでしょうか? まず、大前提として、精度の良いモデルを組むためには多くのデータを使用する必要があり、 すべてのデータを使って学習及びテストを行うことが望ましく、その場合ですと基本的には層化サンプリングを用いないと片方のラベルを訓練データとしてもっと使った方がいいのではないかという問題、又、それと同時に片方のラベルをテストデータとして使った方がいいのではないかというような問題が起きてしまうので、訓練データとテストデータを同じ割合で用いるのが精度を最も上げるためには合理的であるという解釈でよろしいでしょうか? 長文になってしまいまいしたが、よろしくお願いします。
tiitoi

2020/04/15 07:35 編集

> まず、大前提として、精度の良いモデルを組むためには多くのデータを使用する必要があり、すべてのデータを使って学習及びテストを行うことが望ましく ここまではその通りです。できるだけ多くのデータを学習に使ったほうがよいです。 > 訓練データとテストデータを同じ割合で用いるのが精度を最も上げるためには合理的である 学習データとテストデータの割合を同じ (5:5) にすることに拘る必要はないです。普通は学習データを多くしたいので、例えば、学習データ75%、テストデータ25%ぐらいの割合で分割します。(学習データはできるだけ多くしたい、だけどテストデータを少なくしすぎると正しい精度評価ができないということで妥協した結果、だいたいこのぐらいの割合です) 層化抽出する理由は、各クラスのサンプル数に偏りがある場合、分割したときにクラスごとに学習データ、テストデータの割合が異なってしまうのを防ぐためです。 層化抽出しないと、例えば、8:2で分割したとしても、クラスAだけ見ると、6:4のように8:2と割合が異なってしまいます。
1mzmk

2020/04/15 07:41

ご回答頂きありがとうございます。 おかげさまで層化サンプリングを行う意味や必要性について理解することができました。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問