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

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

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

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

Q&A

解決済

1回答

1698閲覧

特殊な配列をリストに変換することについて

bbettbn

総合スコア15

Python

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

0グッド

0クリップ

投稿2018/08/12 02:36

編集2018/08/13 13:35

scikit-learnのStratifiedKFoldでクロスバリデーションをしています。
通常配列をリストにするときにはtolist()を使うと思いますが、StratifiedKFoldを使って作った配列をリストにする際は、使えませんでした。
したいことは、この配列をリストにすることです。
以下のように読み込みますと、

from sklearn.cross_validation import StratifiedKFold train_indices, test_indices = StratifiedKFold(labels, n_folds=2, random_state=0)

このコードの出力は

(array([ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,…

のような配列となります。

それが、上記のコードを以下のように変えると、

from sklearn.cross_validation import StratifiedKFold train_indices, test_indices = list(StratifiedKFold(labels, n_folds=2, random_state=0))[0]
[ 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343

このようなリストになります。

どうして、list()[0]とすることで、リスト化できたのでしょうか?この[0]の意味がよく分かりません。

model_selection変更後は、このようになると思いました。しかし、split()の引数として、X,yの二つを指定するようになっていますが、私はlabels一つだけの中身をtrainとtestに分けたいと思っています。どうしたらいいでしょうか。出力はエラーです。

from sklearn.model_selection import StratifiedKFold stf = StratifiedKFold(n_splits=2, random_state=0) for train_indices, test_indices in stf.split(labels,labels): print(len(test_indices))

とすると、出力は

892 899

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

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

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

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

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

guest

回答1

0

ベストアンサー

そもそもそのコード自体間違っています。

StratifiedKFoldの返すイテレータは、

python

1[[訓練用インデックス1, テスト用インデックス1], 2 [訓練用インデックス2, テスト用インデックス2], 3 ... 4 ]

という構造ですね。

python

1train_indices, test_indices = StratifiedKFold(labels, n_folds=2, random_state=0)

という記述はシーケンスアンパックと言って、train_indicestest_indicesに外側のイテレータの要素を振っている訳です。

なので、

python

1train_indices = [訓練用インデックス1, テスト用インデックス1] 2test_indices = [訓練用インデックス2, テスト用インデックス2]

という状況になってしまうのでおかしいですね。n_folds=2なのでたまたま動いていますが、これを3とかにするといきなりエラーが出るはずです。また、n_folds=2でも期待通りの交差検証は行なえません。

それはともかくとして、[訓練用インデックス1, テスト用インデックス1]はリスト風に書きましたが、実際にはnumpy配列を要素に持つtupleとして返されます。listに変換しようとしても中身のtupleまでは変換されないので、そういう結果になる訳です。

python

1train_indices, test_indices = list(StratifiedKFold(labels, n_folds=2, random_state=0))[0]

だと、リストの0番目を取り出してそれに対してシーケンスアンパックなので、そもそも得られる結果が変わります。

python

1train_indices = 訓練用インデックス1 2test_indices = テスト用インデックス1

これもおかしな結果ですね。


StratifiedKFoldの使い方をもう一回よく調べ直してください。

また、sklearn.cross_validation.StratifiedKFoldはすでに非推奨になっているので、sklearn.model_selection.StratifiedKFoldの方を使ってください。この際はStratifiedKFoldのオブジェクトをイテレータとして使うのではなく、splitメソッドの返り値を利用する形になります。

投稿2018/08/12 03:29

hayataka2049

総合スコア30933

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

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

bbettbn

2018/08/13 01:17

申し訳ありません。返信が遅くなりました。 回答いただいたのに、気づきませんでした。 詳しく教えていただきましてありがとうございます。 ご指摘の通り、sklearn.model_selection.StratifiedKFoldを使ってやり直したいと思いましたが、うまくいきませんでした。 編集して、sklearn.model_selection.StratifiedKFold変更後も載せていますので、回答をよろしくお願いします。
hayataka2049

2018/08/13 03:30

Xも入れるという訳には行きませんか
bbettbn

2018/08/13 13:39

はい。今回はある参考書をもとに作っていて、その参考書では一つのlabelを二つに分割するという流れでした。 引数の(X,y)のどちらにも(labels,labels)として試した結果を再度修正して載せていますが、train_indicesを実行するだけで両方の値を取得してしまうようです。 実際に、自分でStratifiedKFoldを使うときには、sklearn.model_selection.のほうで使ってみようと思います。 ありがとうございました。またよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問