商業銀行はクレジット カードの申し込みを 大量 に受け取ります。その多くは、ローン残高が多い、収入レベルが低い、個人の信用報告書の照会が多すぎるなど、さまざまな理由で拒否されます。これらのアプリケーションを手動で分析するのは日常的で、エラーが発生しやすく、時間がかかります (時は金なりです!)。幸いなことに、このタスクは機械学習の力で自動化することができ、現在ではほぼすべての商業銀行が自動化しています。
実際の銀行が行うのと同じように、機械学習技術を使用して自動クレジット カード承認予測ツールを構築します。

カリフォルニア大学アーバイン校 Machine Learning リポジトリの クレジット カード承認データセット を使用します。
ウェブサイトからデータセットをロードして表示します。
zipファイルであるため、必要なライブラリをインポートして、データを取得します。
from zipfile import ZipFile
from io import BytesIO
import pandas as pd
import requests
url = "https://archive.ics.uci.edu/static/public/27/credit+approval.zip"
buf = BytesIO(requests.get(url).content)
with ZipFile(buf, "r") as f:
for name in f.namelist():
print('File name : ',name)
if name.endswith('.data'):
with f.open(name) as zd:
cc_apps = pd.read_csv(zd, encoding='utf-8', sep=',', header=None)
print(cc_apps.head())
break
else: print('Not found data')
File name : Index File name : credit.lisp File name : credit.names File name : crx.data 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 b 30.83 0.000 u g w v 1.25 t t 1 f g 00202 0 + 1 a 58.67 4.460 u g q h 3.04 t t 6 f g 00043 560 + 2 a 24.50 0.500 u g q h 1.50 t f 0 f g 00280 824 + 3 b 27.83 1.540 u g w v 3.75 t t 5 t g 00100 3 + 4 b 20.17 5.625 u g w v 1.71 t f 0 f s 00120 0 +
このデータは機密であるため、データセットの提供者が特徴名(カラム名)を匿名化していることがわかりましたのでリセットして取得し直します。
出力は一見すると少し混乱しているように見えますが、クレジット カード アプリケーションの最も重要な機能を理解してみましょう。
このデータセットの特徴はプライバシーを保護するために匿名化されていますが、このブログ では、考えられる特徴のかなり良い概要が得られます。
典型的なクレジット カード アプリケーションで考えられる特徴は、Gender, Age, Debt, Married, BankCustomer, EducationLevel, Ethnicity, YearsEmployed, PriorDefault, Employed, CreditScore, DriversLicense, Citizen, ZipCode, Income、そして最後に ApprovalStatus です。
これは非常に良い出発点となり、出力の列に関してこれらの特徴をマッピングできます。
データを一目見てわかるように、データセットには数値的特徴と非数値的特徴が混在しています。これは前処理を行うことで修正できますが、その前に、データセットについてもう少し詳しく学び、修正する必要のあるデータセットの問題が他にあるかどうかを確認してみます。
print(cc_apps.describe())
print("\n")
print(cc_apps.info())
print("\n")
print(cc_apps.tail(17))
2 7 10 14
count 690.000000 690.000000 690.00000 690.000000
mean 4.758725 2.223406 2.40000 1017.385507
std 4.978163 3.346513 4.86294 5210.102598
min 0.000000 0.000000 0.00000 0.000000
25% 1.000000 0.165000 0.00000 0.000000
50% 2.750000 1.000000 0.00000 5.000000
75% 7.207500 2.625000 3.00000 395.500000
max 28.000000 28.500000 67.00000 100000.000000
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 690 entries, 0 to 689
Data columns (total 16 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 0 690 non-null object
1 1 690 non-null object
2 2 690 non-null float64
3 3 690 non-null object
4 4 690 non-null object
5 5 690 non-null object
6 6 690 non-null object
7 7 690 non-null float64
8 8 690 non-null object
9 9 690 non-null object
10 10 690 non-null int64
11 11 690 non-null object
12 12 690 non-null object
13 13 690 non-null object
14 14 690 non-null int64
15 15 690 non-null object
dtypes: float64(2), int64(2), object(12)
memory usage: 86.4+ KB
None
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
673 ? 29.50 2.000 y p e h 2.000 f f 0 f g 00256 17 -
674 a 37.33 2.500 u g i h 0.210 f f 0 f g 00260 246 -
675 a 41.58 1.040 u g aa v 0.665 f f 0 f g 00240 237 -
676 a 30.58 10.665 u g q h 0.085 f t 12 t g 00129 3 -
677 b 19.42 7.250 u g m v 0.040 f t 1 f g 00100 1 -
678 a 17.92 10.210 u g ff ff 0.000 f f 0 f g 00000 50 -
679 a 20.08 1.250 u g c v 0.000 f f 0 f g 00000 0 -
680 b 19.50 0.290 u g k v 0.290 f f 0 f g 00280 364 -
681 b 27.83 1.000 y p d h 3.000 f f 0 f g 00176 537 -
682 b 17.08 3.290 u g i v 0.335 f f 0 t g 00140 2 -
683 b 36.42 0.750 y p d v 0.585 f f 0 f g 00240 3 -
684 b 40.58 3.290 u g m v 3.500 f f 0 t s 00400 0 -
685 b 21.08 10.085 y p e h 1.250 f f 0 f g 00260 0 -
686 a 22.67 0.750 u g c v 2.000 f t 2 t g 00200 394 -
687 a 25.25 13.500 y p ff ff 2.000 f t 1 t g 00200 1 -
688 b 17.92 0.205 u g aa v 0.040 f f 0 f g 00280 750 -
689 b 35.00 3.375 u g c h 8.290 f f 0 t g 00000 0 -
機械学習モデルを変更しないとパフォーマンスに影響を及ぼす可能性があるいくつかの問題が判明しました。
float64、int64、および object 型のデータ)。具体的には、機能 2、7、10、および 14 には数値(float64、 int64) が含まれており、他のすべての機能には数値以外の値が含まれています。平均、最大、最小など) を取得できます。数値を持つ特徴。? を含むデータの存在を視覚化すると、(黒い部分に)多数含まれていることがわかります。
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 6))
sns.heatmap(cc_apps.applymap(lambda x: x == '?'), cmap="YlGnBu", cbar_kws={'label': 'include `?` mark'})
plt.show()
question_mark_counts = cc_apps.applymap(lambda x: isinstance(x, str) and '?' in x).sum()
pd.DataFrame({'Number_of_question_mark': question_mark_counts}).T
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Number_of_question_mark | 12 | 12 | 0 | 6 | 6 | 9 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 13 | 0 | 0 |
具体的には各カラムに上記の数の ? が含まれていることがわかりました。
これらの欠損値である ? を一時的に NaN に置き換えます。
import numpy as np
cc_apps = cc_apps.replace('?', np.NaN)
print(cc_apps.tail(17))
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 673 NaN 29.50 2.000 y p e h 2.000 f f 0 f g 00256 17 - 674 a 37.33 2.500 u g i h 0.210 f f 0 f g 00260 246 - 675 a 41.58 1.040 u g aa v 0.665 f f 0 f g 00240 237 - 676 a 30.58 10.665 u g q h 0.085 f t 12 t g 00129 3 - 677 b 19.42 7.250 u g m v 0.040 f t 1 f g 00100 1 - 678 a 17.92 10.210 u g ff ff 0.000 f f 0 f g 00000 50 - 679 a 20.08 1.250 u g c v 0.000 f f 0 f g 00000 0 - 680 b 19.50 0.290 u g k v 0.290 f f 0 f g 00280 364 - 681 b 27.83 1.000 y p d h 3.000 f f 0 f g 00176 537 - 682 b 17.08 3.290 u g i v 0.335 f f 0 t g 00140 2 - 683 b 36.42 0.750 y p d v 0.585 f f 0 f g 00240 3 - 684 b 40.58 3.290 u g m v 3.500 f f 0 t s 00400 0 - 685 b 21.08 10.085 y p e h 1.250 f f 0 f g 00260 0 - 686 a 22.67 0.750 u g c v 2.000 f t 2 t g 00200 394 - 687 a 25.25 13.500 y p ff ff 2.000 f t 1 t g 00200 1 - 688 b 17.92 0.205 u g aa v 0.040 f f 0 f g 00280 750 - 689 b 35.00 3.375 u g c h 8.290 f f 0 t g 00000 0 -
すべての疑問符を NaN に置き換えました。これは、次に実行する欠損値の処理に役立ちます。
ここで生じる重要な疑問は、なぜ欠損値をそれほど重要視するのか ということです。
無視できない理由として:
したがって、この問題を回避するために、平均代入と呼ばれる戦略を使用して欠損値を代入します。
import warnings
warnings.filterwarnings("ignore", category=FutureWarning)
cc_apps.fillna(np.NaN, inplace=True)
np.mean(cc_apps, axis=0)
cc_apps.tail(17)
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 673 | NaN | 29.50 | 2.000 | y | p | e | h | 2.000 | f | f | 0 | f | g | 00256 | 17 | - |
| 674 | a | 37.33 | 2.500 | u | g | i | h | 0.210 | f | f | 0 | f | g | 00260 | 246 | - |
| 675 | a | 41.58 | 1.040 | u | g | aa | v | 0.665 | f | f | 0 | f | g | 00240 | 237 | - |
| 676 | a | 30.58 | 10.665 | u | g | q | h | 0.085 | f | t | 12 | t | g | 00129 | 3 | - |
| 677 | b | 19.42 | 7.250 | u | g | m | v | 0.040 | f | t | 1 | f | g | 00100 | 1 | - |
| 678 | a | 17.92 | 10.210 | u | g | ff | ff | 0.000 | f | f | 0 | f | g | 00000 | 50 | - |
| 679 | a | 20.08 | 1.250 | u | g | c | v | 0.000 | f | f | 0 | f | g | 00000 | 0 | - |
| 680 | b | 19.50 | 0.290 | u | g | k | v | 0.290 | f | f | 0 | f | g | 00280 | 364 | - |
| 681 | b | 27.83 | 1.000 | y | p | d | h | 3.000 | f | f | 0 | f | g | 00176 | 537 | - |
| 682 | b | 17.08 | 3.290 | u | g | i | v | 0.335 | f | f | 0 | t | g | 00140 | 2 | - |
| 683 | b | 36.42 | 0.750 | y | p | d | v | 0.585 | f | f | 0 | f | g | 00240 | 3 | - |
| 684 | b | 40.58 | 3.290 | u | g | m | v | 3.500 | f | f | 0 | t | s | 00400 | 0 | - |
| 685 | b | 21.08 | 10.085 | y | p | e | h | 1.250 | f | f | 0 | f | g | 00260 | 0 | - |
| 686 | a | 22.67 | 0.750 | u | g | c | v | 2.000 | f | t | 2 | t | g | 00200 | 394 | - |
| 687 | a | 25.25 | 13.500 | y | p | ff | ff | 2.000 | f | t | 1 | t | g | 00200 | 1 | - |
| 688 | b | 17.92 | 0.205 | u | g | aa | v | 0.040 | f | f | 0 | f | g | 00280 | 750 | - |
| 689 | b | 35.00 | 3.375 | u | g | c | h | 8.290 | f | f | 0 | t | g | 00000 | 0 | - |
数値列に存在する欠損値を正常に処理しました。列 0、1、3、4、5、6、および 13 には、代入される欠損値がまだいくつかあります。
これらの列にはすべて非数値データが含まれているため、ここでは平均代入戦略が機能しません。これには別の方法が必要です。
これらの欠損値を、それぞれの列に存在する最も頻度の高い値で代入します。
for col in cc_apps:
if cc_apps[col].dtypes == 'object':
cc_apps = cc_apps.fillna(cc_apps[col].value_counts().index[0])
cc_apps[col].isnull().sum()
0
Nan値が0になったことが確認できました。
欠損値が正常に処理されるようになりました。
機械学習モデルの構築の前に、小規模ではあるが重要なデータの前処理がまだ必要です。これらの残りの前処理ステップを 3 つの主要なタスクに分割します。
まず、すべての非数値を数値に変換します。これを行うのは、計算が高速化されるだけでなく、多くの機械学習モデル (XGBoost など) (特に scikit-learn を使用して開発されたモデル) ではデータが厳密な数値形式である必要があるためです。これを行うには、ラベル エンコーディング と呼ばれる手法を使用します。
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
for col in cc_apps.columns.to_numpy():
if cc_apps[col].dtypes == 'object':
cc_apps[col] = le.fit_transform(cc_apps[col])
cc_apps.head()
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 156 | 0.000 | 2 | 1 | 13 | 8 | 1.25 | 1 | 1 | 1 | 0 | 0 | 68 | 0 | 0 |
| 1 | 0 | 328 | 4.460 | 2 | 1 | 11 | 4 | 3.04 | 1 | 1 | 6 | 0 | 0 | 11 | 560 | 0 |
| 2 | 0 | 89 | 0.500 | 2 | 1 | 11 | 4 | 1.50 | 1 | 0 | 0 | 0 | 0 | 96 | 824 | 0 |
| 3 | 1 | 125 | 1.540 | 2 | 1 | 13 | 8 | 3.75 | 1 | 1 | 5 | 1 | 0 | 31 | 3 | 0 |
| 4 | 1 | 43 | 5.625 | 2 | 1 | 13 | 8 | 1.71 | 1 | 0 | 0 | 0 | 2 | 37 | 0 | 0 |
全てが数値に変化されたことがわかります。
データセットをトレーニング セットとテスト セットに分割する
次に、データをトレーニング セットとテスト セットに分割して、機械学習モデリングの 2 つの異なるフェーズ (トレーニングとテスト) に向けてデータを準備します。
理想的には、テスト データからの情報をトレーニング データのスケーリングに使用したり、機械学習モデルのトレーニング プロセスを指示するために使用したりすべきではありません。したがって、最初にデータを分割し、次にスケーリングを適用します。
また、DriversLicense や ZipCode などの特徴は、クレジット カードの承認を予測するデータセット内の他の特徴ほど重要ではありません。
最適な機能セットを備えた機械学習モデルを設計するには、それらを削除する必要があります。
データ サイエンスの文献では、これは 特徴選択 と呼ばれます。
train_test_split をインポートするfrom sklearn.model_selection import train_test_split
cc_apps_drop = cc_apps.drop([11, 13], axis=1)
cc_apps_drop.columns = range(cc_apps_drop.shape[1])
X = cc_apps_drop.drop([13] , axis=1)
y = cc_apps_drop[13]
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 0.3,
random_state = 42
)
データは現在、トレーニング セットとテスト セットの 2 つの別々のセットに分割されています。
機械学習モデルをデータに適合させる前に、スケーリングという最後の前処理ステップが 1 つだけ残っています。
ここで、これらのスケール値が現実の世界で何を意味するのかを理解してみましょう。例として CreditScore を使用してみましょう。
個人の信用スコアは、信用履歴に基づいた信用度です。この数値が高いほど、その人は経済的に信頼できると考えられます。
したがって、すべての値を 0 ~ 1 の範囲に再スケーリングしているため、CreditScore 1 が最高になります。
scaler としてインスタンス化from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range = (0, 1))
rescaledX_train = scaler.fit_transform(X_train)
rescaledX_test = scaler.transform(X_test)
基本的に、クレジット カードの申請が承認されるかどうかを予測することは、分類 タスクです。
UCI によると、データセットには、「承認」ステータスに対応するインスタンスよりも「拒否」ステータスに対応するインスタンスの方が多く含まれています。
具体的には、690 件の申請のうち、383 件 (55.5%) の申請が拒否され、307 件 (44.5%) の申請が承認されました。
これによりベンチマークが得られます。優れた機械学習モデルは、これらの統計に関してアプリケーションのステータスを正確に予測できる必要があります。
どのモデルを選択すればよいでしょうか?
尋ねるべき質問は次のとおりです: クレジット カードの承認決定プロセスに影響を与える機能は相互に相関しているか?
相関関係を測定することはできますが、次の直観に頼ることになります。
今のところ、それらは確かに相関しています。この相関関係により、このような場合には一般化線形モデルが適切に機能するという事実を利用します。
ロジスティック回帰モデル (一般化線形モデル) を使用して機械学習モデリングを開始しまします。
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(rescaledX_train, y_train)
LogisticRegression()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
LogisticRegression()
from sklearn.metrics import confusion_matrix
y_pred = logreg.predict(rescaledX_test)
print("ロジスティック回帰の精度 test: ", logreg.score(rescaledX_test, y_test))
print("ロジスティック回帰の精度 train: ", logreg.score(rescaledX_train, y_train))
print(confusion_matrix(y_test, y_pred))
ロジスティック回帰の精度 test: 0.8405797101449275 ロジスティック回帰の精度 train: 0.8716356107660456 [[87 10] [23 87]]
ロジスティック回帰モデルは84%、サポートベクターマシンは85% の精度スコアを得ることができました。
混乱マトリックスの場合、最初の行の最初の要素は真の陰性を示し、モデルによって正しく予測された否定的なインスタンス (拒否されたアプリケーション) の数を意味します。
また、2 行目の最後の要素は、モデルによって正しく予測された陽性インスタンス (承認されたアプリケーション) の数を意味する真陽性を示します。
もっと改善できるかどうか見てみましょう。
モデル パラメーターの グリッド検索 を実行して、クレジット カードの承認を予測するモデルの能力を向上させることができます。
scikit-learn のロジスティック回帰の実装 はさまざまなハイパーパラメータで構成されていますが次の 2 つについてグリッド検索を行います。
from sklearn.model_selection import GridSearchCV
C = [0.1, 1, 10]
tol = [0.01, 0.001, 0.0001]
max_iter = [100, 150, 200, 300, 400]
param_grid = dict(C = C, tol=tol, max_iter=max_iter)
ハイパーパラメータ値のグリッドを定義し、それらを GridSearchCV() がパラメータの 1 つとして期待する単一の辞書形式に変換しました。
次に、グリッド検索を開始して、どの値が最もパフォーマンスが高いかを確認します。
持っているすべてのデータを使用して、以前の logreg モデルを使用して GridSearchCV() をインスタンス化します。
トレーニング セットとテスト セットを別々に渡す代わりに、X (スケーリングされたバージョン) と y を提供します。
また、GridSearchCV() に 5 つの分割の 相互検証 を実行するように指示します。
rescaledX = scaler.fit_transform(X_train)
grid_model = GridSearchCV(estimator=logreg, param_grid=param_grid, cv=5)
grid_model_result = grid_model.fit(rescaledX, y_train)
print("最高値: %f 使用パラメータ %s" % (grid_model_result.best_score_, grid_model_result.best_params_))
最高値: 0.867397 使用パラメータ {'C': 0.1, 'max_iter': 100, 'tol': 0.01}
ロジスティック回帰では86.7%がベストスコアとそれぞれのパラメーターとなります。
from sklearn.svm import SVC
svc = SVC()
svc.fit(rescaledX_train, y_train)
y_pred_svc = svc.predict(rescaledX_test)
print("サポートベクターマシンの精度 test: ", svc.score(rescaledX_test, y_test))
print("サポートベクターマシンの精度 train: ", svc.score(rescaledX_train, y_train))
print(confusion_matrix(y_test, y_pred_svc))
サポートベクターマシンの精度 test: 0.8502415458937198 サポートベクターマシンの精度 train: 0.8861283643892339 [[85 12] [19 91]]
svc_params = {
'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf', 'poly'],
'gamma': ['scale', 'auto', 0.1, 1, 10],
'coef0': [0.0, 0.1, 0.5],
'degree': [2, 3, 4]
}
svc_grid_model = GridSearchCV(estimator=svc, param_grid=svc_params, cv=5)
svc_grid_model_result = svc_grid_model.fit(rescaledX, y_train)
print("最高値: %f 使用パラメータ %s" % (svc_grid_model_result.best_score_, svc_grid_model_result.best_params_))
最高値: 0.871521 使用パラメータ {'C': 0.1, 'coef0': 0.0, 'degree': 2, 'gamma': 1, 'kernel': 'rbf'}
from sklearn.ensemble import RandomForestClassifier
rf_model = RandomForestClassifier()
rf_model.fit(rescaledX_train, y_train)
y_pred_rf = rf_model.predict(rescaledX_test)
print("ランダムフォレストの精度 test: ", rf_model.score(rescaledX_test, y_test))
print("ランダムフォレストの精度 train: ", rf_model.score(rescaledX_train, y_train))
print(confusion_matrix(y_test, y_pred_svc))
ランダムフォレストの精度 test: 0.8695652173913043 ランダムフォレストの精度 train: 1.0 [[85 12] [19 91]]
rf_params = {
'n_estimators': [10, 50, 100],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10]
}
rf_grid_model = GridSearchCV(estimator=rf_model, param_grid=rf_params, cv=5)
rf_grid_model_result = rf_grid_model.fit(rescaledX, y_train)
print("最高値: %f 使用パラメータ %s" % (rf_grid_model_result.best_score_, rf_grid_model_result.best_params_))
最高値: 0.873647 使用パラメータ {'max_depth': 20, 'min_samples_split': 5, 'n_estimators': 10}
4種類のスケーリングを検証し、更にロジスティック回帰と一緒にランダムフォレスト、リッジ回帰、ラッソ回帰、勾配ブースティング、サポートベクターマシンをれぞれの最適パラーメータで最適なものを探します。
from sklearn.preprocessing import StandardScaler, MinMaxScaler, Normalizer, RobustScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import Ridge, Lasso
from sklearn.ensemble import GradientBoostingRegressor
スケーラー、モデル、パラメータを定義
scalers = [
('StandardScaler', StandardScaler()),
('MinMaxScaler', MinMaxScaler()),
('RobustScaler', RobustScaler()),
('Normalizer', Normalizer())
]
models_and_params = [
{'model': LogisticRegression(),
'params': {
'C': [0.1, 1, 10],
'tol': [0.01, 0.001, 0.0001],
'max_iter': [100, 150, 200, 300]},
},
{'model': RandomForestClassifier(),
'params': {
'n_estimators': [10, 50, 100],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10]},
},
{'model': Ridge(),
'params': {'alpha': [0.01, 0.1, 1, 10]},
},
{'model': Lasso(),
'params': {'alpha': [0.01, 0.1, 1, 10]},
},
{'model': GradientBoostingRegressor(),
'params': {
'n_estimators': [50, 100, 200],
'learning_rate': [0.01, 0.1, 1.0],
'max_depth': [3, 4, 5]},
},
{'model': SVC(),
'params': {
'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf', 'poly'],
'gamma': ['scale', 0.1, 1],
'degree': [2, 3, 4]}
},
]
関数を定義
from concurrent.futures import ThreadPoolExecutor
def process_model_scales(scaler_name, scaler, model_info):
model_name = model_info['model'].__class__.__name__
param_grid = model_info['params']
X_train_scaled = scaler.fit_transform(X_train)
grid_search = GridSearchCV(estimator=model_info['model'], param_grid=param_grid, cv=5)
result_grid_search = grid_search.fit(X_train_scaled, y_train)
best_params = result_grid_search.best_params_
best_score = result_grid_search.best_score_
return {
'Model': model_name,
'Scaler': scaler_name,
'Best Parameters': best_params,
'Best Score': best_score
}
model_scaler_combinations = []
with ThreadPoolExecutor() as executor:
for scaler_name, scaler in scalers:
for item in models_and_params:
future = executor.submit(process_model_scales, scaler_name, scaler, item)
model_scaler_combinations.append(future.result())
df_model_info = pd.DataFrame(model_scaler_combinations)
best_scalers = df_model_info.groupby('Model')['Best Score'].idxmax()
df_best_scalers = df_model_info.loc[best_scalers]
df_best_scalers.set_index('Model')
df_best_scalers.sort_values('Best Score', ascending= False)
| Model | Scaler | Best Parameters | Best Score | |
|---|---|---|---|---|
| 19 | RandomForestClassifier | Normalizer | {'max_depth': 10, 'min_samples_split': 10, 'n_... | 0.882002 |
| 11 | SVC | MinMaxScaler | {'C': 0.1, 'degree': 2, 'gamma': 1, 'kernel': ... | 0.871521 |
| 6 | LogisticRegression | MinMaxScaler | {'C': 0.1, 'max_iter': 100, 'tol': 0.01} | 0.867397 |
| 22 | GradientBoostingRegressor | Normalizer | {'learning_rate': 0.01, 'max_depth': 3, 'n_est... | 0.609969 |
| 8 | Ridge | MinMaxScaler | {'alpha': 0.1} | 0.573402 |
| 3 | Lasso | StandardScaler | {'alpha': 0.01} | 0.569103 |
for i in df_best_scalers.loc[19,:]:print(i)
RandomForestClassifier
Normalizer
{'max_depth': 10, 'min_samples_split': 10, 'n_estimators': 50}
0.8820017182130584
上データから
にすると88.2%の精度になることがわかりました。
このクレジット カード予測機能を構築する際、スケーリング、ラベル エンコーディング、欠損値の代入など、最も広く知られている前処理ステップのいくつかに取り組みました。
ある人のクレジット カードの申請が承認されるか、その人に関する情報が与えられないかを予測するための機械学習を完了しました。