🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Kaggle

Kaggleは、機械学習モデルを構築するコンペティションのプラットフォームおよびその運営企業を指します。企業や政府といった組織とデータサイエンティスト・機械学習エンジニアを繋げるプラットフォームであり、単純なマッチングではなくコンペティションが特徴です。

パラメータ

関数やプログラム実行時に与える設定値をパラメータと呼びます。

機械学習

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

Python

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

Q&A

解決済

1回答

8675閲覧

lgbmの二値分類の結果について

fu_3823

総合スコア81

Kaggle

Kaggleは、機械学習モデルを構築するコンペティションのプラットフォームおよびその運営企業を指します。企業や政府といった組織とデータサイエンティスト・機械学習エンジニアを繋げるプラットフォームであり、単純なマッチングではなくコンペティションが特徴です。

パラメータ

関数やプログラム実行時に与える設定値をパラメータと呼びます。

機械学習

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

Python

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

0グッド

0クリップ

投稿2021/03/12 22:34

編集2021/03/13 05:43

Pyhton APIのlgbmで、単純な二値分類をしています。
二値分類の場合、例えば、目的変数が0と1の分類ならば、各説明変数のデータセットに対して、0,1に対してそれぞれの確率を出すかと思います。そして、最終的に、閾値を決めたり活性化関数を使ったりして0,1に変換するのが一般的なやり方と考えており、そうしていました。
ただ、lgbmでモデルを作る際、lgbm内での評価関数による評価は、0,1ではなく、変換前の連続値で行われているように思います。これは手法として正しいのでしょうか。というのも、モデル生成のする際に、パラメータとして"objective":"binary"はあっりますが、閾値を決めたりするような過程がなく、以下のコードのoofに格納した値も確率になっているためです。

抜き出したものですが、以下がモデル生成と予測のコードです。
ごく一般的なものと思います。

Python

1folds = 20 2kf = KFold(n_splits=folds, random_state=0, shuffle=True) 3 4lgbm_params = { 5 "objective":"binary", 6 "metric": 'auc', 7 "random_seed":0, 8 "learning_rate":0.05, 9 "n_estimators":1000, 10 'num_leaves': 12, 11 'max_bin': 179, 12 'bagging_fraction': 0.7918221226509443, 13 'bagging_freq': 4, 14 'feature_fraction': 0.7107392007498818, 15 'min_data_in_leaf': 10, 16 'min_sum_hessian_in_leaf': 5 17} 18 19models =[] 20roc_auc_scores = [] 21oof = np.zeros(len(train_X)) 22 23for train_index, val_index in kf.split(train_X): 24 X_train = train_X.iloc[train_index] 25 X_valid = train_X.iloc[val_index] 26 y_train = train_y.iloc[train_index] 27 y_valid = train_y.iloc[val_index] 28 29 lgb_train = lgb.Dataset(X_train, y_train) 30 lgb_eval = lgb.Dataset(X_valid, y_valid, reference=lgb_train) 31 32 model_lgb = lgb.train(lgbm_params, 33 lgb_train, 34 valid_sets=lgb_eval, 35 num_boost_round=5000, 36 early_stopping_rounds=200, 37 verbose_eval=10, 38 ) 39 40 y_pred = model_lgb.predict(X_valid, num_iteration=model_lgb.best_iteration) 41 tmp_score = roc_auc_score(y_valid, y_pred) 42 print(tmp_score) 43 44 models.append(model_lgb) 45 roc_auc_scores.append(tmp_score) 46 oof[val_index] = y_pred 47

PYthon

1oof 2# array([0.12186042, 0.23685486, 0.04406063, ..., 0.96849681, 0.1656876, 0.04805159])

python

1pred_prob = model_lgb.predict(test_df.drop(['id', 'target'], axis=1), num_iteration=model_lgb.best_iteration) 2pred= np.where(pred_prob < 0.5, 0, 1) 3pred_df = pd.DataFrame(pred)

Python

1pred_df 2 3# id target 4# 0 5 0 5# 1 6 0 6# 2 8 1 7# . . . 8# . . . 9

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

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

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

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

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

toast-uz

2021/03/13 00:47 編集

質問がよくわかりません。モデルは「連続値(0〜1)」(→(A)とします) を出力して、その結果に閾値を当てはめて「0,1の2値」(→(B)とします) にしていることはご理解されていますよね。すなわち、モデル自身は(B)は持っていないことになります。であるのに、モデルが自身の評価(B)でなはく(A)を使っていることが不思議なので教えて下さい、という質問になっています。むしろ逆で、モデル自身が持っていない(B)を使っていたら不思議であると思います。 なお、(A)を確率として解釈するのは間違いですので、ご注意ください。「確率」などという意味は持たない、単なる数値です。
fu_3823

2021/03/13 06:11

コメントありがとうございます。 モデルが(A)しか持たないのはわかります。疑問に思ったのは次の点です。 モデルの精度は、(A)の連続値を0,1の二値へ変換する閾値によって変わります。そのため、lgbmでもパラメータで閾値を設定し、連続値ではなく最終的に0,1の二値(B)で評価できるようにする必要があるのではないか。 ということです。 ですので、lgbmで二値分類をしたつもりでいるが、結果として連続値しか出力できていない。これは手法として誤ったことをしているのではないかということをお聞きしたかったのです。 二値分類のコードを書いたのに、lgbmの結果が二値ではなく(A)であるのは私の間違いではないか、と思っています。
guest

回答1

0

ベストアンサー

LightGBMが二値分類で0〜1の連続値を出力するのは自然なことです。深層学習のライブラリ(TensorFlow、PyTorch)も二値分類および多値分類では、同様に1次元または多次元の0〜1の連続値を出力し、ライブラリ外での後処理をPythonコードで書くことで0,1の2値や、多値に変換します。

機械学習ライブラリによってはsklearnのように、class分類を直接出力できるものもあります。実はLightGBMには、sklearn APIも存在します(LGBMClassifier)。それを使うと、class分類を直接出力できます。ただし、内部的には連続値で処理をされており、その連続値を出力することもできます。

これらは何か本質的な違いがあるのではなく、単純に、後処理を普通にPythonで書けば十分と考えているか、後処理用のメソッドまで親切に用意しているかの、ライブラリの思想の違いでしかありません。両方とも内部的には連続値で処理がされています。

参考: LightGBMの基本的な使い方(2値分類編)

投稿2021/03/13 07:05

toast-uz

総合スコア3266

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

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

fu_3823

2021/03/14 14:36

参考になりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問