偏りのあるクラス分類時のclass_weight
解決したいこと
3クラス分類でクラス間の比が1:1:4のものをしています。LGBMClassifierやRandomForestなどにはclass_weightのハイパーパラメータがあり、今はこれを"balanced"に設定しています。
ここで他のハイパーパラメータをチューニングする時に(グリッドサーチやoptunaなど)そのままの不均衡データを使うかRandomUnderSamplerで同じ比に抽出したデータを使うかどちらが良いのでしょうか。最終的な予測では不均衡データを入れるので前者の方がいい気もしたり、学習時は後者の方が適切な気もしたりでわかりません。
またもしRandomUnderSamplerのデータを用いたほうがいい場合、チューニング時のclass_weightも"balanced"でいいのでしょうか?RandomUnderSamplerして不均衡データでないもので探索するので迷っています。
よろしくお願いします。
例)
Ruby on RailsでQiitaのようなWebアプリをつくっています。
記事を投稿する機能の実装中にエラーが発生しました。
解決方法を教えて下さい。
該当するソースコード
def run(trial):
import lightgbm as lgb
max_depth = trial.suggest_int('max_depth', 6, 10)
num_leaves = trial.suggest_int("num_leaves", 7, 70)
learning_rate = trial.suggest_float('learning_rate', 0.001,0.01)
min_child_samples = trial.suggest_int('min_child_samples', 10, 80)
subsample = trial.suggest_float('subsample', 0.01, 0.7)
colsample_bytree = trial.suggest_float('colsample_bytree', 0.1, 0.7)
reg_alpha = trial.suggest_float('reg_alpha', 0, 50)
reg_lambda = trial.suggest_float("reg_lambda", 0, 100)
lgb_clf = lgb.LGBMClassifier(random_state=1,
objective="multiclass",
num_class = 3,
n_estimators=650,
num_leaves=num_leaves,
max_depth=max_depth,
learning_rate=learning_rate,
min_child_samples=min_child_samples,
subsample=subsample,
colsample_bytree=colsample_bytree,
reg_alpha=reg_alpha,
reg_lambda=reg_lambda,
class_weight="balanced",
n_jobs=-1)
df_y = pd.Series(y)
def kfold_cks(x_data, y_data):
scores = []
# KFold クラス を 用い て クロス バリデーション の 分割 を 行う
kf = KFold(n_splits = 10, shuffle = True, random_state = 1)
for tr_idx, va_idx in kf.split(x_data):
tr_x, va_x = x_data.iloc[tr_idx], x_data.iloc[va_idx]
tr_y, va_y = y_data.iloc[tr_idx], y_data.iloc[va_idx]
# 学習 の 実行、 バリデーション データ の 予測 値 の 出力、 スコア の 計算 を 行う
lgb_clf.fit(tr_x, tr_y)
va_pred = lgb_clf.predict(va_x)
score = cohen_kappa_score(va_y, va_pred, weights='quadratic')
scores.append(score)
scores = np.array(scores)
mean_score = scores.mean()
return mean_score
mean_score = kfold_cks(pd.DataFrame(df_all), pd.Series(y))
return mean_score
lgb_study = optuna.create_study(direction="maximize")
lgb_study.optimize(run, n_trials=400)
lgb_trial = lgb_study.best_trial
print("accuracy:", lgb_trial.value)
print()
print("Best params:", lgb_trial.params)
0