lightgbmでGridSearchCVを使用したときにエラーが発生します。
同じコードで3クラス分類(0,1,2の3値)を実行するとエラーは発生しません。
しかし元データを**2値(0,1)**に変更して2クラス分類で実行すると何故かエラーが発生します。
アドバイス頂戴できれば幸いです。
#グリッドサーチ import lightgbm as lgb from sklearn.model_selection import GridSearchCV # LGB用のデータセットを登録 #lgb_train = lgb.Dataset(x_train_std, y_train) #lgb_test = lgb.Dataset(x_test_std, y_test, reference=lgb_train) lightgbm = lgb.LGBMClassifier(objective='binary', random_state=0) params = {'task':[ 'train'], # タスクを訓練に設定 'boosting_type': ['gbdt'], # GBDTを指定 'objective': ['multiclass'], # 多クラス分類を指定 'metric': ['multi_logloss'], # 多クラス分類の損失(誤差) 'num_class': [2], # クラスの数 'learning_rate': [0.2,0.4], # 学習率 'max_dapth': [1,5], # 木の深さ 'num_leaves': [5,10], # ノードの数 'min_data_in_leaf': [15,20], # 決定木ノードの最小データ数 'num_iteration': [100]# 予測器(決定木)の数:インタレーション(反復数)(デフォルトは100) } gbm = GridSearchCV(estimator=lightgbm, param_grid=params, scoring='accuracy', cv=2, n_jobs=-1, verbose=0, ) gbm.fit(x_train_std, y_train) # 最も良いパラメータとスコア print(gbm.best_params_) print(gbm.best_score_)
以下、エラー
--------------------------------------------------------------------------- _RemoteTraceback Traceback (most recent call last) _RemoteTraceback: """ Traceback (most recent call last): File "C:\python\anaconda\pgm\lib\site-packages\joblib\externals\loky\process_executor.py", line 418, in _process_worker r = call_item() File "C:\python\anaconda\pgm\lib\site-packages\joblib\externals\loky\process_executor.py", line 272, in __call__ return self.fn(*self.args, **self.kwargs) File "C:\python\anaconda\pgm\lib\site-packages\joblib\_parallel_backends.py", line 567, in __call__ return self.func(*args, **kwargs) File "C:\python\anaconda\pgm\lib\site-packages\joblib\parallel.py", line 225, in __call__ for func, args, kwargs in self.items] File "C:\python\anaconda\pgm\lib\site-packages\joblib\parallel.py", line 225, in <listcomp> for func, args, kwargs in self.items] File "C:\python\anaconda\pgm\lib\site-packages\sklearn\model_selection\_validation.py", line 560, in _fit_and_score test_scores = _score(estimator, X_test, y_test, scorer) File "C:\python\anaconda\pgm\lib\site-packages\sklearn\model_selection\_validation.py", line 607, in _score scores = scorer(estimator, X_test, y_test) File "C:\python\anaconda\pgm\lib\site-packages\sklearn\metrics\_scorer.py", line 88, in __call__ *args, **kwargs) File "C:\python\anaconda\pgm\lib\site-packages\sklearn\metrics\_scorer.py", line 206, in _score y_pred = method_caller(estimator, "predict", X) File "C:\python\anaconda\pgm\lib\site-packages\sklearn\metrics\_scorer.py", line 53, in _cached_call return getattr(estimator, method)(*args, **kwargs) File "C:\python\anaconda\pgm\lib\site-packages\lightgbm\sklearn.py", line 819, in predict return self._le.inverse_transform(class_index) File "C:\python\anaconda\pgm\lib\site-packages\sklearn\preprocessing\_label.py", line 301, in inverse_transform "y contains previously unseen labels: %s" % str(diff)) ValueError: y contains previously unseen labels: [ 94 291] """ The above exception was the direct cause of the following exception: ValueError Traceback (most recent call last) <ipython-input-132-e861004b35ec> in <module> 29 ) 30 ---> 31 gbm.fit(x_train_std, y_train) 32 33 # 最も良いパラメータとスコア C:\python\anaconda\pgm\lib\site-packages\sklearn\utils\validation.py in inner_f(*args, **kwargs) 70 FutureWarning) 71 kwargs.update({k: arg for k, arg in zip(sig.parameters, args)}) ---> 72 return f(**kwargs) 73 return inner_f 74 C:\python\anaconda\pgm\lib\site-packages\sklearn\model_selection\_search.py in fit(self, X, y, groups, **fit_params) 734 return results 735 --> 736 self._run_search(evaluate_candidates) 737 738 # For multi-metric evaluation, store the best_index_, best_params_ and C:\python\anaconda\pgm\lib\site-packages\sklearn\model_selection\_search.py in _run_search(self, evaluate_candidates) 1186 def _run_search(self, evaluate_candidates): 1187 """Search all candidates in param_grid""" -> 1188 evaluate_candidates(ParameterGrid(self.param_grid)) 1189 1190 C:\python\anaconda\pgm\lib\site-packages\sklearn\model_selection\_search.py in evaluate_candidates(candidate_params) 713 for parameters, (train, test) 714 in product(candidate_params, --> 715 cv.split(X, y, groups))) 716 717 if len(out) < 1: C:\python\anaconda\pgm\lib\site-packages\joblib\parallel.py in __call__(self, iterable) 932 933 with self._backend.retrieval_context(): --> 934 self.retrieve() 935 # Make sure that we get a last message telling us we are done 936 elapsed_time = time.time() - self._start_time C:\python\anaconda\pgm\lib\site-packages\joblib\parallel.py in retrieve(self) 831 try: 832 if getattr(self._backend, 'supports_timeout', False): --> 833 self._output.extend(job.get(timeout=self.timeout)) 834 else: 835 self._output.extend(job.get()) C:\python\anaconda\pgm\lib\site-packages\joblib\_parallel_backends.py in wrap_future_result(future, timeout) 519 AsyncResults.get from multiprocessing.""" 520 try: --> 521 return future.result(timeout=timeout) 522 except LokyTimeoutError: 523 raise TimeoutError() C:\python\anaconda\pgm\lib\concurrent\futures\_base.py in result(self, timeout) 430 raise CancelledError() 431 elif self._state == FINISHED: --> 432 return self.__get_result() 433 else: 434 raise TimeoutError() C:\python\anaconda\pgm\lib\concurrent\futures\_base.py in __get_result(self) 382 def __get_result(self): 383 if self._exception: --> 384 raise self._exception 385 else: 386 return self._result ValueError: y contains previously unseen labels: [ 94 291]
>>元データを2値(0,1)に変更して
とは具体的にどのように変更したのですか? もう一度y_trainがきちんと0,1になっているか、.value_counts()等を行って確認してみては? 変換に失敗してNullになっているデータがある等が原因かも知れません。
ご連絡ありがとうございます。
.value_counts()を実行した結果、
1 340
0 152
と出力されました。
元データは2値(0,1)となっているようです。
その他、原因がありますでしょうか?
よろしくお願いいたします。
'objective': ['multiclass'], は'objective': ['binary'], に直すべきかと思います。
あとy_testが2値(0,1)になっているかも、確認して下さい。
またLabelEncoderを使う際、trainとtestのカテゴリ値の種類が一致していない場合も、同様のエラーが出るようです。
https://teratail.com/questions/277153
ご連絡ありがとうございます。
'objective': ['multiclass'], を'objective': ['binary'], に変更しましたら、以下のエラーが出ました。
「LightGBMError: Number of classes must be 1 for non-multiclass training」
y_testが2値(0,1)になっていることを確認いたしました。
また、trainとtestのカテゴリ値の種類も一致しておりました。
以下にも同様の質問をさせて頂いておりますが、グリッドサーチをしない場合は、ハイパーパラメータが同じであっても、何故かエラーにはなりません。
(同じデータセット(2値)を使用しているのにも関わらずです)
https://teratail.com/questions/373572
グリッドサーチの場合はハイパーパラメータ使用の制約などがあるのでしょうか?
あるいは、まだどこかコード自体に誤りがあるのでしょうか?
ご指導頂ければありがたいです。
よろしくお願いいたします。
'num_class': [2],のままだと、そのエラーになりそうです。'num_class': [1],に直してみて下さい
ありがとうございます。
'num_class': [1],にするとエラーが無くなりました。
【疑問点】
今回、2値(0,1)なので、'num_class': [2]と思っていたのですが、それは誤りなのでしょうか?
'num_class': [1]だと1値? それとも別の意味があるのでしょうか?
'num_class': [3]ですと3値(0,1,2)、'num_class': [10]ですと10値(0,1,・・9)で正しいのでしょうか?
エラーが無くなりました。←これはこの質問の解決と とらえていいですか?
これは私見ですが、num_classはクラスの数というより「クラスをワンホットエンコーディングした時に、必要となるコラム数(列数)」的な感じなのかも知れません。
2値(0,1)なら一列で表せますが、3値(0,1,2)なら(0,1)で表現する場合、3列使います(2列でも表わせないことはありませんが、普通3列だと思います)。
別の言い方をすれば、2値分類は「クラスAに属するか、属さないか で分類するもの」。3値分類は「クラスA、クラスB、クラスCの3つに分類するもの」と考えるのかも知れません。
問題、解決いたしました。
どうもありがとうございました。