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

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

ただいまの
回答率

90.33%

  • Python

    9237questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    7424questions

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

  • 機械学習

    769questions

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

python scikit-learn 交差検証について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 722

---stax---

score 73

表題の件で質問させてください

現在こちらの書籍を読みながら機械学習の勉強を進めています
Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎

その中で交差検証について学習しているのですが分からない箇所があります
データセットの分割は訓練セット、検証セット、テストセットに分けて、
モデルのチューニングには検証セットを使い、テストセットはモデルの最終評価にのみ使うという記述があり、こちらは理解出来ました

以下訓練セット、検証セット、テストセットに分けてのモデル作成

from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedKFold #層化k分割交差検証
from sklearn.model_selection import KFold #k分割交差検証
from sklearn.svm import SVC
import numpy as np

## データを(訓練セット+検証セット)とテストセットに分割する
X_trainval, X_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0)
print(X_trainval.shape)
print(X_test.shape)
print(y_trainval.shape)
print(y_test.shape)

print('-------------------')
## (訓練セット+検証セット)とを分割する訓練セットと検証セットに分割する
X_train, X_valid, y_train, y_valid = train_test_split(X_trainval, y_trainval, random_state=1)
print(X_train.shape)
print(X_valid.shape)
print(y_train.shape)
print(y_valid.shape)

print('-------------------')

print("Size of training set: {}   size of validation set: {}   size of test set:"
      " {}\n".format(X_train.shape[0], X_valid.shape[0], X_test.shape[0]))


best_score = 0

for gamma in [0.001, 0.01, 0.1, 1, 10, 100]:
    for C in [0.001, 0.01, 0.1, 1, 10, 100]:
        ## それぞれの組み合わせに対してSVCを訓練する
        svm = SVC(gamma=gamma, C=C)
        svm.fit(X_train, y_train)
        ## SVCを”検証セット”で評価する
        score = svm.score(X_valid, y_valid)
        ## いいスコアだったらスコアとパラメータを保存
        if score > best_score:
            best_score = score
            best_parameters = {'C':C, 'gamma':gamma}

## 訓練セットと検証セットを用いて改めてモデル作成
svm = SVC(**best_parameters)
svm.fit(X_trainval, y_trainval)
## テストセットを使って評価
test_score = svm.score(X_test, y_test)

print('Best score on validation set : {:.2f}'.format(best_score))
print('Best parameters: ', best_parameters)
print('Test set score with Best parameters:{:.2f}'.format(test_score))

ただ、その次にscikit-learnのGridSearchCVを利用する方法が喜寿されていたのですが、そのコードには交差検証はされているのですが訓練セットを検証セットに分ける方法は記述されておらず、「訓練セットと検証セットを分割する代わりに交差検証を行う」とありました
個人的には「訓練セットと検証セットを分割する代わりに交差検証を行う」という部分が、データを分割することと交差検証は別の話じゃないのかなと引っかかっています

GridSearchCVは自動的に訓練セットと検証セットを分けたうえでモデルを作成しているのでしょうか?
またデータセットを分割する方法は訓練セットとテストセットに分けるだけなのか、検証セットも作ってモデルを作るのはどちらで行うべきなのでしょうか?
的外れな質問かもしれませんがアドバイス宜しくお願い致します

以下、scikit-learnのGridSearchCVを利用する方法

X_trainval, X_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0)

X_train, X_valid, y_train, y_valid = train_test_split(X_trainval, y_trainval, random_state=1)


param_grid = {'C':[0.001, 0.01, 0.1, 1, 10, 100],
             'gamma':[0.001, 0.01, 0.1, 1, 10, 100]}
print('Parameter grid:\n{}'.format(param_grid))

grid_search = GridSearchCV(SVC(), param_grid, cv=5)

X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0)

grid_search.fit(X_train, y_train)

print('Test set score : {:.2f}'.format(grid_search.score(X_test, y_test)))
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

結論から言うと、パラメタチューニングを訓練データセットの交差検証で行うなら、検証セットは不要です。

  • 何のためにテスト用データセットを作るのか
  • 何のために検証用データセットを作るのか
  • 交差検証の仕組みと利点

このあたりの理解があやふやで、納得できていないのでは?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/23 14:29

    分かったつもりになっている部分があるかもしれません
    自分の現状の理解をまとめてみました

    何のためにテスト用データセットを作るのか
    →作成したモデルの性能を評価するために未知のデータとしてモデルに渡すために必要だと考えます

    何のために検証用データセットを作るのか
    →テストセットをつかってモデルを評価し、その結果によってモデルをチューニングしてしまうとテストセットに合わせたモデルとなってしまうので性能が出ているか判断しにくいため、訓練セットを(訓練セット:検証セット)のように分割し検証セットを用いてチューニングを行うために必要だと考えます

    交差検証の仕組みと利点
    →データセットをtrain_test_split()で分割するとデータはシャッフルされていますがもし[0,0,1,1,0,1,2][3,3,4]のように分割されてしまう可能性があるのでデータセットを3分割したとして、1をテストデータ、2,3を訓練データとして使用、次に2をテストデータ、1.3を訓練データのようにすることでデータセットの中身が漏れなく訓練にもテストにも使われることが利点だと理解しています

    誤っていたらすいません・・・

    キャンセル

  • 2018/07/23 17:38 編集

    交差検証に関して、
    >[0,0,1,1,0,1,2][3,3,4]のように分割されてしまう可能性があるので
    というのは本質的な問題ではありません。ラベルの比率を見て分割する方法はありますから。実際、sklearnのtrain_test_split()の実装にはstratifyというオプションがあって、ラベル(基本的には第二引数yと同じもの)を渡すことで適当に比率を揃えて分割してくれます。

    仕組みの理解は良さそうです。利点は全データを使うので、それなりに結果が妥当なことですね(極論するとleave-one-outが究極の交差検証で「1つ取り出しただけ=ほぼ訓練データそのもの」で学習させた場合で評価できる。実際はそこまでやらなくてもそこそこの結果になる)。検証用データセットを作ると、それに合わせたモデルになっちゃう恐れがなくもない訳ですが、それに対する利点があります。

    キャンセル

  • 2018/07/23 17:40

    それで、けっきょくのところは汎化性能見れれば良いんだから、「パラメタチューニングを訓練データセットの交差検証で行うなら、検証セットは不要」という結論になります。

    キャンセル

  • 2018/07/23 23:27

    回答ありがとうございます
    >検証用データセットを作ると、それに合わせたモデルになっちゃう恐れがなくもない訳ですが
    確かにこれも結局は検証セットに合わせこんでいるということにもなりますね・・・
    そう聞くとモデルはどうやってもデータセットに合わせこんでチューニングしていくしかないように感じるのですが、あくまでモデルは汎化性能を求めているのであってテストデータに対して良いスコアが出せていればデータセットにある程度依存するのは仕方ない、ということなのでしょうか
    かなり的外れな質問ですいません
    資料には訓練セットと検証セットに分けましょう、という記述があって、GridSearchCVを使う部分ではそのやり方をしていなくて、結局この訓練セット、検証セット、テストセットに分ける考え方はどこで使うのだろうと感じます
    あくまで資料がそういう書き方をしているだけで本質的な問題ではないかもしれませんがそこが不思議です

    キャンセル

  • 2018/07/24 08:12

    考え方の上では、交差検証の内部で分けているとみなすこともまあできます。
    交差検証をやりたくなくて、上に書いたような問題が起きないだろうとそれなりの確信を持って言えるようなときは、訓練データのホールドアウト法(訓練セットと検証セットに分割)で評価するのも一つの手です。
    計算コストが大きくて、データがたくさんあるときとか。深層学習なんかそんな雰囲気です。

    キャンセル

  • 2018/07/24 11:18

    回答ありがとうございます
    データセットのサイズなどで使い分ける必要があるということですね
    そこの見極めは難しそうです

    本来の質問と大きくそれてしまうのですが、現在現場の不良予知や要因分析などが行えるようになりたいと思い機械学習の勉強を始めました。
    プログラミングの経験も浅く、機械学習の知識自体全然ないので参考書や、courseraで講義を聞いて基礎的な知識をまず理解しようと思い勉強を進めています。
    周りに聞ける環境が無く独学なので勉強自体の進め方がこれで良いのかと自分自身定まっていないのですが、実際活用出来るレベルになる為にはどのように学習をするべきでしょうか?
    知識とともに経験も非常に大切な部分ですし、人によってさまざまなので一概には言えないと思うのですが参考に聞かせて頂けたら幸いです。
    本来の質問とそれているのでご面倒でしたらスルーでも大丈夫です

    キャンセル

  • 2018/07/24 17:42

    私も勉強中の身なので、実務的なアドバイスはできません。
    参考書やネットで情報が得られるので、技術的な面では独学できると思います。
    あと、データサイエンスや機械学習といっても広い分野ですし、基礎知識から応用までの振れ幅も大きいので、どの辺りをターゲットにしていくのかを明確にする必要があるのかな、と(単に分析するだけなら、統計の基礎と既存のツールの使い方がわかればいい、とか)。

    キャンセル

  • 2018/07/29 23:15

    回答ありがとうございます。
    返答遅くなり申し訳ありません。
    答えにくい問題で申し訳ありません。
    何が必要な知識でどこにフォーカスするべきかすら分からない段階なのでまずは概要だけでも抑えて何のために使うのかイメージを持てるようにまずは頑張ります。

    キャンセル

同じタグがついた質問を見る

  • Python

    9237questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    7424questions

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

  • 機械学習

    769questions

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