【機械学習アルゴリズム/フレームワーク/Kaggle】ローン承認の予測においてLightGBM(フレームワーク)とOptuna(ハイパーパラメータ)

## はじめに
　金融業界では、ローン承認の予測は重要なタスクです。ローン申請が承認されるかどうかを正確に予測するモデルの開発は、金融機関がリスクを最小限に抑え、意思決定を迅速化し、公正な審査を行うための助けとなります。本ブログでは、LightGBMという勾配ブースティングフレームワークと、Optunaというハイパーパラメータ最適化ツールを用いたローン承認予測モデルの構築方法について説明します。このプロジェクトはKaggleのPlayground Seriesコンペティションの一環であり、実際のデータを活用した機械学習アルゴリズムの実装例となります。

LightGBMは、勾配ブースティングにおけるフレームワークになります。参考までに下記をご参照ください。

https://qiita.com/Life-tech/items/6aa31c5910c0755a9b09



　本記事では、プロジェクトの全体像に加え、逆敵対検証（Adversarial Validation）やデータの探索的分析（EDA）、特徴量エンジニアリング、そしてモデルのチューニング方法について詳しく解説します。また、ハイパーパラメータの最適化がどのようにモデルのパフォーマンスを向上させるか、特にデータ分布が異なる場合にどのような効果があるかについても考察します。

## データの概要
このプロジェクトでは、3つのデータセットを使用します。2つのデータセット（トレーニングデータとテストデータ）はKaggleから提供されており、これらは元のローン承認予測データセットを基にディープラーニングモデルで生成された合成データです。Kaggleはこれらの合成データセットの特徴量分布が「元データに非常に近いが、完全に同じではない」と明言しています。このため、データの分布の違いを明らかにするために逆敵対検証を実施します。

ターゲット変数および特徴量について、以下のように分類されます。

ターゲット変数:
loan_status：ローン承認のステータスを表し、バイナリ（0または1）の形式で表現されます。
0 = ローンが承認されていない
1 = ローンが承認されている
カテゴリカル特徴量:
person_home_ownership：申請者の住宅所有状況。例：賃貸、自宅所有、住宅ローンなど。
loan_intent：ローンの目的。例：教育、リフォーム、医療費など。
loan_grade：ローンの信用グレード。通常はAからFなどのランク付けが行われます。
cb_person_default_on_file：申請者の信用履歴に過去のデフォルト記録があるかどうか。
数値特徴量:
person_age：申請者の年齢。
person_income：申請者の年間収入。
person_emp_length：申請者の雇用期間（年単位）。
loan_amnt：申請されたローンの金額。
loan_int_rate：ローンの利率。
loan_percent_income：ローン金額が収入に占める割合。
cb_person_cred_hist_length：申請者の信用履歴の長さ。

本記事では、KaggleのPlayground Seriesコンペティションに取り組む中で、LightGBMとOptunaを使ったローン承認予測モデルの構築手法について解説します。具体的には、以下のステップに従ってモデルを開発していきます。

1. 必要なライブラリのインポート
1. データの読み込みと基本的な確認
1. 逆敵対検証 (Adversarial Validation)
1. データの前処理と特徴量エンジニアリング
1. LightGBMモデルの構築とOptunaを用いたハイパーパラメータの最適化
1. モデルの評価と予測
1. 提出データの作成

### 必要なライブラリのインポート
必要な機械学習のライブラリなどをインポートします。

### データの読み込みと確認
トレーニングデータとテストデータを読み込みます。元々のデータセットも読み込みます。
また、それぞれのデータセットの最初の5行を表示し、データの構造を確認します。
```
# データの読み込み
df_train = pd.read_csv('/kaggle/input/playground-series-s4e10/train.csv', index_col='id')
df_test = pd.read_csv('/kaggle/input/playground-series-s4e10/test.csv', index_col='id')
df_original = pd.read_csv('/kaggle/input/ps4e9-original-data-loan-approval-prediction/credit_risk_dataset.csv')

# トレーニングデータの確認
df_train.head()
```


### 逆敵対検証 (Adversarial Validation)
ここで、元データとトレーニングデータが同じ分布に従っているかどうかを確認する為に、Catboostモデルを使って逆敵対検証を実施しています。元データとトレーニングデータを結合し、Catboost分類器でこれらを区別できるかどうかを確認します。

```python.py
# カテゴリカル特徴量と数値特徴量を宣言
cat_cols = ['person_home_ownership', 'loan_intent', 'loan_grade', 'cb_person_default_on_file']
num_cols = ['person_age', 'person_income', 'person_emp_length', 'loan_amnt', 'loan_int_rate', 
            'loan_percent_income', 'cb_person_cred_hist_length']

# 特徴量とラベルを作成
df_train['label'] = 0
df_original['label'] = 1
all_cols = cat_cols + num_cols + ['label']

# データセットを結合し、Catboostモデルで学習
train_data = Pool(data=df_train[cat_cols + num_cols], label=df_train['label'], cat_features=cat_cols)
model = CatBoostClassifier(iterations=100, eval_metric='AUC', od_type='Iter', random_seed=42, verbose=0)
model.fit(train_data)

# ROC曲線をプロット
def plot_roc(y_true, y_pred):
    fpr, tpr, _ = roc_curve(y_true, y_pred)
    auc = roc_auc_score(y_true, y_pred)
    plt.plot(fpr, tpr, label=f'AUC = {auc:.3f}')
    plt.plot([0, 1], [0, 1], linestyle='--')
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('ROC Curve')
    plt.legend()
    plt.show()

plot_roc(df_train['label'], model.predict_proba(df_train[cat_cols + num_cols])[:, 1])

```


### データ前処理と特徴量エンジニアリング
カテゴリカルデータのエンコードや新しい特徴量の作成を行います。

### モデルの構築とハイパーパラメータの最適化
Optunaを使用して、LightGBMモデルのハイパーパラメータを最適化します。100回のトライアルを行い、AUCスコアを最大化するパラメータを探します。
```python.py
# Optunaによるハイパーパラメータ最適化
def objective(trial):
    params = {
        'objective': 'binary',
        'boosting_type': 'gbdt',
        'num_leaves': trial.suggest_int('num_leaves', 100, 500),
        'learning_rate': trial.suggest_float('learning_rate', 0.01, 1.0, log=True),
        'n_estimators': trial.suggest_int('n_estimators', 300, 1000),
        'max_depth': trial.suggest_int('max_depth', 1, 15),
    }
    model = LGBMClassifier(**params)
    cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
    scores = []
    for train_idx, val_idx in cv.split(X_train, y_train):
        model.fit(X_train.iloc[train_idx], y_train.iloc[train_idx])
        y_pred = model.predict_proba(X_train.iloc[val_idx])[:, 1]
        scores.append(roc_auc_score(y_train.iloc[val_idx], y_pred))
    return np.mean(scores)

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)

```

### モデル評価と予測
最適化されたモデルを用いてテストデータの予測を行います。また、特徴量の重要度をプロットします。

### 提出

### 最後に
今回のプロジェクトでは、LightGBMとOptunaを使ってローン承認予測モデルを構築しました。最適化されたモデルは高いAUCスコアを達成し、Kaggleコンペティションでの提出データを作成しました。この手法は、金融データの予測に限らず、さまざまな分類タスクに応用可能です。