はじめに
Pythonでロジスティック回帰①に続けて、ロジスティック回帰の精度向上を試みる。
ロジスティック回帰の偏回帰係数
データに標準化処理を行った場合、学習した後に得られる偏回帰係数の絶対値の大きさがその変数の影響度の大きさといえる。そこで前回の学習時の偏回帰係数の絶対値が大きい順にソートしてみる。
sortCo.py
l = []
for i, c in enumerate(lr.coef_[0]):
l.append([i, X.columns[i], c])
li = pd.DataFrame(sorted(l, reverse=True, key=lambda x: abs(x[2]))) # 係数の絶対値に注目してソート
li.columns = ["index", "colnames", "coefficients"]
print(li)
# index colnames coefficients
# 0 23 PAY_0_2 2.170240
# 1 24 PAY_0_3 2.052640
# 2 25 PAY_0_4 1.744103
# 3 26 PAY_0_5 1.237172
# 4 28 PAY_0_7 1.088260
# .. ... ... ...
# 71 43 PAY_3_4 0.009774
# 72 12 PAY_AMT5 -0.003782
# 73 38 PAY_2_8 0.000000
# 74 58 PAY_5_1 0.000000
# 75 67 PAY_6_1 0.000000
上記結果より、重要度が高そうな PAY_0, EDUCATION, PAY_2, MARRIAGE, PAY_3 に関連する変数のみを残して再度学習してみる。
retrain.py
X = df_quality_dummies[['EDUCATION_1', 'EDUCATION_2', 'EDUCATION_3', 'EDUCATION_4',
'MARRIAGE_1', 'MARRIAGE_2', 'MARRIAGE_3',
'PAY_0_1', 'PAY_0_2', 'PAY_0_3', 'PAY_0_4', 'PAY_0_5', 'PAY_0_6', 'PAY_0_7', 'PAY_0_8', 'PAY_0_-1',
'PAY_2_1', 'PAY_2_2', 'PAY_2_3', 'PAY_2_4', 'PAY_2_5', 'PAY_2_6', 'PAY_2_7', 'PAY_2_8', 'PAY_2_-1',
'PAY_3_1', 'PAY_3_2', 'PAY_3_3', 'PAY_3_4', 'PAY_3_5', 'PAY_3_6', 'PAY_3_7', 'PAY_3_8', 'PAY_3_-1']]
Y = df["default payment next month"]
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)
lr_co = LogisticRegression(max_iter=2000)
lr_co.fit(X_train, Y_train)
THRESHOLD = 0.30
Y_pred = np.where(lr_co.predict_proba(X_test)[:,1] > THRESHOLD, 1, 0)
print("Prediction:", np.count_nonzero(Y_pred==1))
print(" Test:", np.count_nonzero(np.array(Y_test)==1))
print("AUC Score:", roc_auc_score(Y_test, Y_pred))
# Prediction: 1120
# Test: 1297
# AUC Score: 0.6883146488133773
前回はTHRESHOLD=0.30の際のAUCスコアが約0.696であったため、変数を削減したもののスコアの向上は見られなかった。scikit-learnのLogisticRegressionでは、デフォルトでL2正則化を用いるので(わずかな特徴量しか扱わないよう制限をかける)L1正則化も試してはみたが、ほとんど変化はみられなかった。
l1.py
lr_l1 = LogisticRegression(penalty="l1", solver="liblinear", max_iter=2000)
lr_l1.fit(X_train, Y_train)
別の精度改善方法を検討しつつ、ロジスティック回帰以外の他モデルでも分類を試してみようと思う。