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

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

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

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

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

13887閲覧

sckit-learnにおけるTypeError: Singleton array %r cannot be considered a valid collection.

shay

総合スコア13

scikit-learn

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

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2020/01/22 13:42

前提・実現したいこと

約5万個の30*300のデータに対し、sklearn.ensembleRandomForestClassfierを用いて二値分類の層化k分割交差検証を行いたい。

発生している問題・エラーメッセージ

最終的にTypeError: Singleton array %r cannot be considered a valid collection.というエラーが表示されます。このエラーが出なくなることが第一目標です。
以下エラー全文です(見やすさのため、1つのエラーを小分けにして表示しています)。

------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-762-10ee8ca88fe0> in <module> 3 from sklearn.model_selection import cross_val_score 4 rfc = RFC(verbose=True,n_jobs=-1,random_state=1) ----> 5 cvscore = cross_val_score(rfc, x, y, cv=StratifiedKFold)
~/.pyenv/versions/3.6.0/envs/mecab/lib/python3.6/site-packages/sklearn/model_selection/_validation.py in cross_val_score(estimator, X, y, groups, scoring, cv, n_jobs, verbose, fit_params, pre_dispatch, error_score) 388 fit_params=fit_params, 389 pre_dispatch=pre_dispatch, --> 390 error_score=error_score) 391 return cv_results['test_score'] 392
~/.pyenv/versions/3.6.0/envs/mecab/lib/python3.6/site-packages/sklearn/model_selection/_validation.py in cross_validate(estimator, X, y, groups, scoring, cv, n_jobs, verbose, fit_params, pre_dispatch, return_train_score, return_estimator, error_score) 234 return_times=True, return_estimator=return_estimator, 235 error_score=error_score) --> 236 for train, test in cv.split(X, y, groups)) 237 238 zipped_scores = list(zip(*scores))
~/.pyenv/versions/3.6.0/envs/mecab/lib/python3.6/site-packages/sklearn/model_selection/_split.py in split(self, X, y, groups) 728 to an integer. 729 """ --> 730 y = check_array(y, ensure_2d=False, dtype=None) 731 return super().split(X, y, groups) 732
~/.pyenv/versions/3.6.0/envs/mecab/lib/python3.6/site-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator) 579 580 if ensure_min_samples > 0: --> 581 n_samples = _num_samples(array) 582 if n_samples < ensure_min_samples: 583 raise ValueError("Found array with %d sample(s) (shape=%s) while a"
~/.pyenv/versions/3.6.0/envs/mecab/lib/python3.6/site-packages/sklearn/utils/validation.py in _num_samples(x) 150 if len(x.shape) == 0: 151 raise TypeError("Singleton array %r cannot be considered" --> 152 " a valid collection." % x) 153 # Check that shape is returning an integer or default to len 154 # Dask dataframes may not return numeric shape[0] value TypeError: Singleton array array(None, dtype=object) cannot be considered a valid collection.

上記のエラーから、cross_val_scoreの第二引数であるyの要素の中身に問題があると判断しました。
そこで中身がラベル(0,1)以外の要素を調べましたが、そのような要素は存在しませんでした。

該当のソースコード

Python

1from sklearn.ensemble import RandomForestClassifier as RFC 2from sklearn.model_selection import StratifiedKFold 3from sklearn.model_selection import cross_val_score 4rfc = RFC(verbose=True,n_jobs=-1,random_state=1) 5cvscore = cross_val_score(rfc, x, y, cv=StratifiedKFold)

x: 入力データ。x.shape=(48366, 30, 300)のndarray。
y: ラベルデータ。y.shape=(48366,)のndarray。
どちらもPandasDataFrameのカラムから生成したデータです。

xの作り方

Python

1# xの形を(48366,1) から (48366, 30, 300) に変える 2x = df.values[:,2:] 3xl = [x[i][0] for i in range(len(x))] 4x = np.array(xl)

yの作り方

Python

1from sklearn.preprocessing import LabelEncoder 2le = LabelEncoder() 3y = df.values[:,:1] 4y = le.fit_transform(y)

バージョン情報

Python==3.6.0
sckit-learn==0.22.1

どなたかご教授いただけたら幸いです。
「こうするのはどうだろう?」といった提案でも構いません。
よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

RandomForestClassifierfitの引数は、

Xarray-like or sparse matrix of shape (n_samples, n_features)

3.2.4.3.1. sklearn.ensemble.RandomForestClassifier — scikit-learn 0.22.1 documentation

と定められていて、(48366, 30, 300)の配列は渡すことが出来ません。

30, 300の部分が行列形式であることに特に本質的な意味がないのであれば、9000にflattenして動作させることは可能です。ただし、これだけ次元数が高いと通常はうまく動作しない、遅すぎて実用的ではないなどの問題があるので、先に特徴量選択を行うべきでしょう。

画像データであれば特徴量抽出などの前処理が必要ですが、そもそもランダムフォレストはそのようなデータに適していないので、画像処理に特化したモデルを用いたほうが良い結果が得られると思います。

投稿2020/01/23 14:08

hayataka2049

総合スコア30935

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

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

shay

2020/01/24 05:49

丁寧な説明ありがとうございます。 ドキュメントを参考にすることの大切さを改めて感じました。 詳細を省いていましたが、この(30, 300)は単語の300次元の分散表現が30個並んだもので、 これを二値分類しようとしています。 そのため行列形式であることには単語として捉えるという意味があるので、CNNやRNNのモデルで扱うことを検討しようと思います。 余談ですが、参考にしている論文(https://www.aclweb.org/anthology/D15-1284.pdf)にて、Word2Vecで文章の特徴量を作成しRandom Forestで分類を行っているというような記述があったため、同じことができないかなと考えたのですが、sklearnでの実装ではない可能性がありますね。 長くなりましたが、改めて迅速なご回答ありがとうございました!
hayataka2049

2020/01/24 06:22 編集

どんな実装にしろ30*300行列を単語30つを個別に捉えるように使うことはランダムフォレストでは難しいでしょう。 論文は読んでいませんが、word2vecだけでやるなら平均を取るとかする、もっと高度な解釈を行わないとできないようなタスクならシーケンスを扱えるモデル(RNN等)を使うのが常套手段です。その辺りを読み落としているのではないでしょうか。
shay

2020/02/04 02:31

私が読む限り、詳細な記述がなかったため、ベクトルの和だと受け取っていましたが、平均なども考えられますね。 この分野についての知識を集めながら、改めて読み直そうと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問