私は非常に不均衡なバイナリラベル付きデータセットに取り組んでいます。この場合、真のラベルの数はデータセット全体の7%にすぎません。ただし、機能の組み合わせによっては、サブセット内の機能の数が平均よりも多くなる場合があります。
たとえば、単一の特徴(色)を持つ次のデータセットがあるとします。
180個の赤いサンプル— 0
20個の赤いサンプル— 1個
緑のサンプル300個— 0
緑のサンプル100個— 1
簡単な決定木を作ることができます:
(color)
red / \ green
P(1 | red) = 0.1 P(1 | green) = 0.25
データセット全体のP(1)= 0.2
このデータセットでXGBoostを実行すると、0.25以下の確率を予測できます。つまり、しきい値を0.5に決定した場合、
- 0-P <0.5
- 1-P> = 0.5
次に、常にゼロとしてラベル付けされたすべてのサンプルを取得します。私が問題を明確に説明したことを願っています。
ここで、初期データセットで次のプロットを取得しています(x軸のしきい値)。
しきい値= 0.1で最大のf1_scoreを持つ。今私は2つの質問があります:
- そのような構造のデータセットにf1_scoreを使用する必要がありますか?
- バイナリ分類にXGBoostを使用する場合、確率をラベルにマッピングするために0.5しきい値を使用することは常に合理的ですか?
更新。私はその話題が興味を引くと思います。以下は、XGBoostを使用して赤/緑の実験を再現するPythonコードです。それは実際に期待される確率を出力します:
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
import numpy as np
X0_0 = np.zeros(180) # red - 0
Y0_0 = np.zeros(180)
X0_1 = np.zeros(20) # red - 1
Y0_1 = np.ones(20)
X1_0 = np.ones(300) # green - 0
Y1_0 = np.zeros(300)
X1_1 = np.ones(100) # green - 1
Y1_1 = np.ones(100)
X = np.concatenate((X0_0, X0_1, X1_0, Y1_1))
Y = np.concatenate((Y0_0, Y0_1, Y1_0, Y1_1))
# reshaping into 2-dim array
X = X.reshape(-1, 1)
import xgboost as xgb
xgb_dmat = xgb.DMatrix(X_train, label=y_train)
param = {'max_depth': 1,
'eta': 0.01,
'objective': 'binary:logistic',
'eval_metric': 'error',
'nthread': 4}
model = xgb.train(param, xg_mat, 400)
X0_sample = np.array([[0]])
X1_sample = np.array([[1]])
print('P(1 | red), predicted: ' + str(model.predict(xgb.DMatrix(X0_sample))))
print('P(1 | green), predicted: ' + str(model.predict(xgb.DMatrix(X1_sample))))
出力:
P(1 | red), predicted: [ 0.1073855]
P(1 | green), predicted: [ 0.24398108]
xgboost
クラスの重みをサポートします。彼が最大化したい指標に満足していません。