:tropical_drink: ์‹œ์ž‘ํ•˜๋ฉฐ: ํ˜„์‹ค์ ์ธ ๋ชจ๋ธ๋ง์— ๋„์ „ํ•˜๋‹ค

์ด๋ฒˆ์—๋Š” ์€ํ–‰ ๋งˆ์ผ€ํŒ… ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ๊ณ ๊ฐ์ด ์ •๊ธฐ ์˜ˆ๊ธˆ์— ๊ฐ€์ž…ํ• ์ง€ ์˜ˆ์ธกํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ๋ถ€ํ„ฐ ์—ฌ๋Ÿฌ ๋ชจ๋ธ์„ ๋น„๊ตํ•˜๊ณ , ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํŠœ๋‹, ๊ทธ๋ฆฌ๊ณ  AutoML ๋„๊ตฌ์ธ PyCaret๊นŒ์ง€ ์‚ฌ์šฉํ•ด๋ณธ, ๊ทธ์•ผ๋ง๋กœ ๋จธ์‹ ๋Ÿฌ๋‹ ๋ถ„๋ฅ˜์˜ ์ข…ํ•ฉ์„ ๋ฌผ์„ธํŠธ ๊ฐ™์€ ๊ฒฝํ—˜์ด์—ˆ๋‹ค.

๐Ÿ’ก โ€œ์ง„์งœ ์ค‘์š”ํ•œ ๊ฑด, ์‹ค์ œ ์˜ˆ๊ธˆ ๊ณ ๊ฐ์„ ๋†“์น˜์ง€ ์•Š๋Š” ๊ฒƒ!โ€

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ํ•ต์‹ฌ ๋ชฉํ‘œ๋Š” ๋ฐ”๋กœ ์žฌํ˜„์œจ(Recall) ์„ ๋†’์ด๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ๋ชจ๋ธ์˜ ์ •ํ™•๋„๋งŒ ๋†’์ด๋Š” ๊ฑด ์˜๋ฏธ๊ฐ€ ์—†์—ˆ๋‹ค. ์ง„์งœ ๊ณ ๊ฐ์„ ํ•˜๋‚˜๋ผ๋„ ๋” ์ฐพ์•„๋‚ด๋Š” ๋ชจ๋ธ์„ ๋งŒ๋“œ๋Š” ์—ฌ์ •, ์ง€๊ธˆ ์‹œ์ž‘ํ•œ๋‹ค.


๐Ÿ“ฅ 1๋‹จ๊ณ„: ๋ฐ์ดํ„ฐ์™€์˜ ์ฒซ ๋งŒ๋‚จ

UCI ์ €์žฅ์†Œ์˜ ์€ํ–‰ ๋งˆ์ผ€ํŒ… ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. ๊ณ ๊ฐ์˜ ๋‚˜์ด, ์ง์—…, ๋Œ€์ถœ ์—ฌ๋ถ€ ๊ฐ™์€ ์ •๋ณด๋กœ ์˜ˆ๊ธˆ ๊ฐ€์ž… ์—ฌ๋ถ€(y)๋ฅผ ์˜ˆ์ธกํ•˜๋Š” ๋ฌธ์ œ์˜€๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์‚ดํŽด๋ณด๋‹ˆ no์™€ yes ๋น„์œจ์ด ์•ฝ 8:1๋กœ, ๋ฐ์ดํ„ฐ ๋ถˆ๊ท ํ˜•์ด ์‹ฌ๊ฐํ–ˆ๋‹ค. ์ด๊ฑด ์ •ํ™•๋„๋งŒ ๋ฏฟ๊ณ  ๊ฐ€๋‹ค๊ฐ„ ํฐ์ผ๋‚œ๋‹ค๋Š” ์‹ ํ˜ธ์˜€๋‹ค. ๐Ÿšจ

๊ทธ๋ฆฌ๊ณ  ์ค‘์š”ํ•œ ๋ฐœ๊ฒฌ! duration(ํ†ตํ™” ์‹œ๊ฐ„)์ด๋ผ๋Š” ํ”ผ์ฒ˜๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ, ์ด๊ฑด ์˜ˆ์ธก ์‹œ์ ์—์„œ๋Š” ์•Œ ์ˆ˜ ์—†๋Š”, ๊ฒฐ๊ณผ์— ๊ฐ€๊นŒ์šด ์ •๋ณด์˜€๋‹ค. ์ด๋Ÿฐ ์‚ฌํ›„ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋ธ์ด ๊ณผ๋Œ€์ ํ•ฉ๋˜๊ธฐ ์‰ฌ์›Œ์„œ ๊ณผ๊ฐํžˆ ์ œ์™ธํ–ˆ๋‹ค. ํ˜„์‹ค์ ์ธ ๋ชจ๋ธ๋ง์˜ ์ฒซ๊ฑธ์Œ์ด์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

โœจ 2๋‹จ๊ณ„: ๋ฐ์ดํ„ฐ ์„ฑํ˜•์ˆ˜์ˆ  (์ „์ฒ˜๋ฆฌ)

๋ชจ๋ธ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ž˜ ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊น”๋”ํ•˜๊ฒŒ ๋‹ค๋“ฌ์–ด์ฃผ๋Š” ๊ณผ์ •์ด ํ•„์ˆ˜์˜€๋‹ค.

  • ์ˆ˜์น˜ํ˜• ๋ฐ์ดํ„ฐ: ํ”ผ์ฒ˜๋งˆ๋‹ค ๊ฐ’์˜ ๋ฒ”์œ„๊ฐ€ ์ œ๊ฐ๊ฐ์ด๋ผ StandardScaler๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ‰๊ท  0, ๋ถ„์‚ฐ 1๋กœ ๋งž์ถฐ์คฌ๋‹ค. ์ด์ƒ์น˜์— ๋œ ๋ฏผ๊ฐํ•ด์„œ ๊ฐ€์žฅ ๋ฌด๋‚œํ•˜๊ณ  ์•ˆ์ •์ ์ธ ์„ ํƒ์ด์—ˆ๋‹ค.
  • ๋ฒ”์ฃผํ˜• ๋ฐ์ดํ„ฐ: ๋ฌธ์ž์—ด์€ ๋ชจ๋ธ์ด ์ดํ•ด ๋ชป ํ•˜๋‹ˆ๊นŒ ์ˆซ์ž๋กœ ๋ฐ”๊ฟ”์•ผ ํ–ˆ๋‹ค. ๊ฐ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ƒˆ๋กœ์šด ํ”ผ์ฒ˜๋กœ ๋งŒ๋“œ๋Š” OneHotEncoder๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. drop='first' ์˜ต์…˜์œผ๋กœ ๋‹ค์ค‘๊ณต์„ ์„ฑ ๋ฌธ์ œ๋„ ํ”ผํ•˜๊ณ  ํ”ผ์ฒ˜ ์ˆ˜๋„ ์ค„์ด๋Š” ๊ฟ€ํŒ๋„ ์žŠ์ง€ ์•Š์•˜๋‹ค.
# ์ˆ˜์น˜ํ˜• ๋ฐ์ดํ„ฐ ์Šค์ผ€์ผ๋ง
scaler = StandardScaler()
X_train[num_cols] = scaler.fit_transform(X_train[num_cols])
X_test[num_cols] = scaler.transform(X_test[num_cols])

# ๋ฒ”์ฃผํ˜• ๋ฐ์ดํ„ฐ ์ธ์ฝ”๋”ฉ
encoder = OneHotEncoder(drop='first')
# ... ์ธ์ฝ”๋”ฉ ๊ณผ์ • ์ƒ๋žต ...

โš™๏ธ 3๋‹จ๊ณ„: ๋ชจ๋ธ ์‡ผํ•‘! ์ตœ๊ณ ์˜ ๋ถ„๋ฅ˜๊ธฐ๋Š”?

์˜์‚ฌ๊ฒฐ์ • ๋‚˜๋ฌด, ๋žœ๋ค ํฌ๋ ˆ์ŠคํŠธ, KNN, ๋กœ์ง€์Šคํ‹ฑ ํšŒ๊ท€, ์ด๋ ‡๊ฒŒ 4๊ฐ€์ง€ ๊ธฐ๋ณธ ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด์„œ ์„ฑ๋Šฅ์„ ๋น„๊ตํ•ด๋ดค๋‹ค. ์ด๋ฒˆ ๋ฌธ์ œ์—์„œ๋Š” ์žฌํ˜„์œจ(Recall) ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ง€ํ‘œ์˜€๊ธฐ ๋•Œ๋ฌธ์—, ์ด ์ ์ˆ˜๋ฅผ ์ค‘์ ์ ์œผ๋กœ ๋ดค๋‹ค.

๊ฒฐ๊ณผ๋Š”? ์ „๋ฐ˜์ ์ธ ์„ฑ๋Šฅ(์ •ํ™•๋„, AUC)์€ ๋žœ๋ค ํฌ๋ ˆ์ŠคํŠธ๊ฐ€ ๊ฐ€์žฅ ์ข‹์•˜์ง€๋งŒ, ์ •์ž‘ ์ค‘์š”ํ•œ ์žฌํ˜„์œจ์€ ๋‹ค๋ฅธ ๋ชจ๋ธ๊ณผ ๋น„์Šทํ•˜๊ฑฐ๋‚˜ ์˜คํžˆ๋ ค ๋‚ฎ๊ธฐ๋„ ํ–ˆ๋‹ค. ๋ชจ๋ธ๋งˆ๋‹ค ์žฅ๋‹จ์ ์ด ์žˆ๋‹ค๋Š” ๊ฑธ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋А๊ผˆ๋‹ค.

๐Ÿ› ๏ธ 4๋‹จ๊ณ„: ๋ชจ๋ธ ์„ฑ๋Šฅ ์ฅ์–ด์งœ๊ธฐ (ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํŠœ๋‹)

๊ฐ€์žฅ ์œ ๋ ฅํ–ˆ๋˜ ๋žœ๋ค ํฌ๋ ˆ์ŠคํŠธ๋ฅผ RandomizedSearchCV๋กœ ์ตœ์ ํ™”ํ•ด๋ดค๋‹ค. ๋ชจ๋“  ์กฐํ•ฉ์„ ๋‹ค ํ•ด๋ณด๋Š” GridSearchCV๋ณด๋‹ค ํ›จ์”ฌ ํšจ์œจ์ ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

# RandomizedSearchCV๋กœ ์ตœ์  ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰
param_grid = {'n_estimators': [100, 300, 500], 'max_depth': [50, 80, 100], ...}
rfc = RandomForestClassifier(random_state=42)
rm_model = RandomizedSearchCV(rfc, param_distributions=param_grid, cv=5, scoring='recall', n_iter=5)
rm_model.fit(X_train, y_train)

๊ทธ๋Ÿฐ๋ฐโ€ฆ ํŠœ๋‹ ํ›„ ์žฌํ˜„์œจ์ด ์˜คํžˆ๋ ค ๋–จ์–ด์กŒ๋‹ค. ๐Ÿ˜ญ ๋ฌด์กฐ๊ฑด ํŠœ๋‹์ด ๋Šฅ์‚ฌ๋Š” ์•„๋‹ˆ๋ผ๋Š” ๋ผˆ์•„ํ”ˆ ๊ตํ›ˆ์„ ์–ป์—ˆ๋‹ค. ๊ธฐ๋ณธ ๋ชจ๋ธ์ด ์ด๋ฏธ ๊ดœ์ฐฎ์•˜๊ฑฐ๋‚˜, ๋‚ด๊ฐ€ ์„ค์ •ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฒ”์œ„๊ฐ€ ์ตœ์ ์ด ์•„๋‹ˆ์—ˆ์„ ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.


๐Ÿค– 5๋‹จ๊ณ„: AutoML ์น˜ํŠธํ‚ค, PyCaret ๋ง›๋ณด๊ธฐ

๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋กœ ์ด ๋ชจ๋“  ๊ณผ์ •์„ ์ž๋™ํ™”ํ•˜๋Š” PyCaret์„ ์จ๋ดค๋Š”๋ฐ, ์ด๊ฑด ์ •๋ง ์‹ ์„ธ๊ณ„์˜€๋‹ค!

from pycaret.classification import *

s = setup(df_bank_ready2, target = 'y', session_id = 123)
best = compare_models()
tuned_best_model = tune_model(best)

๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ๋ถ€ํ„ฐ ๋ชจ๋ธ ๋น„๊ต, ํŠœ๋‹๊นŒ์ง€ ์•Œ์•„์„œ ๋‹ค ํ•ด์ฃผ๋‹ˆ ์ƒ์‚ฐ์„ฑ์ด ํญ๋ฐœํ–ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐ์— ๋น ๋ฅด๊ฒŒ ๋ฒ ์ด์Šค๋ผ์ธ ๋ชจ๋ธ์„ ๋งŒ๋“ค ๋•Œ ์•ž์œผ๋กœ ๋ฌด์กฐ๊ฑด ์‚ฌ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค.


โœจ ์˜ค๋Š˜์˜ ํšŒ๊ณ 

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ๋จธ์‹ ๋Ÿฌ๋‹ ๋ถ„๋ฅ˜ ๋ฌธ์ œ์˜ A to Z๋ฅผ ๊ฒฝํ—˜ํ•ด๋ณธ ์†Œ์ค‘ํ•œ ์‹œ๊ฐ„์ด์—ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๋ถˆ๊ท ํ˜•์˜ ์ค‘์š”์„ฑ์„ ๋ชธ์œผ๋กœ ๋А๊ผˆ๊ณ , ์ƒํ™ฉ์— ๋งž๋Š” ์ „์ฒ˜๋ฆฌ์™€ ํ‰๊ฐ€ ์ง€ํ‘œ(ํŠนํžˆ ์žฌํ˜„์œจ!) ์„ ํƒ์ด ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ๊นจ๋‹ฌ์•˜๋‹ค.

์—ฌ๋Ÿฌ ๋ชจ๋ธ์„ ์ง์ ‘ ๋งŒ๋“ค๊ณ  ๋น„๊ตํ•˜๋ฉฐ ๊ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์žฅ๋‹จ์ ์„ ํŒŒ์•…ํ–ˆ๊ณ , ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํŠœ๋‹์ด ํ•ญ์ƒ ์ •๋‹ต์€ ์•„๋‹ˆ๋ผ๋Š” ํ˜„์‹ค์ ์ธ ๊ตํ›ˆ๋„ ์–ป์—ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ PyCaret ๊ฐ™์€ AutoML ๋„๊ตฌ์˜ ๊ฐ•๋ ฅํ•จ์„ ๋ง›๋ณด๋ฉด์„œ, ์•ž์œผ๋กœ๋Š” ๋” ๋น ๋ฅด๊ณ  ํšจ์œจ์ ์œผ๋กœ ๋ชจ๋ธ๋ง์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค๋Š” ์ž์‹ ๊ฐ์ด ์ƒ๊ฒผ๋‹ค.