bong9513 commited on
Commit
f49ae2e
ยท
verified ยท
1 Parent(s): aad08b4

Delete Analysis_code/5.optima

Browse files
This view is limited to 50 files because it contains too many changes. ย  See raw diff
Files changed (50) hide show
  1. Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_busan.py +0 -98
  2. Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_daegu.py +0 -97
  3. Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_daejeon.py +0 -97
  4. Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_gwangju.py +0 -97
  5. Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_incheon.py +0 -97
  6. Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_seoul.py +0 -97
  7. Analysis_code/5.optima/deepgbm_ctgan10000/utils.py +0 -721
  8. Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_busan.py +0 -98
  9. Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_daegu.py +0 -99
  10. Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_daejeon.py +0 -99
  11. Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_gwangju.py +0 -99
  12. Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_incheon.py +0 -99
  13. Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_seoul.py +0 -99
  14. Analysis_code/5.optima/deepgbm_pure/utils.py +0 -720
  15. Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_busan.py +0 -97
  16. Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_daegu.py +0 -97
  17. Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_daejeon.py +0 -97
  18. Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_gwangju.py +0 -97
  19. Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_incheon.py +0 -97
  20. Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_seoul.py +0 -97
  21. Analysis_code/5.optima/deepgbm_smote/utils.py +0 -720
  22. Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_busan.py +0 -97
  23. Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_daegu.py +0 -97
  24. Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_daejeon.py +0 -97
  25. Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_gwangju.py +0 -97
  26. Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_incheon.py +0 -97
  27. Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_seoul.py +0 -97
  28. Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/utils.py +0 -720
  29. Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_busan.py +0 -96
  30. Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_daegu.py +0 -96
  31. Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_daejeon.py +0 -96
  32. Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_gwangju.py +0 -96
  33. Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_incheon.py +0 -96
  34. Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_seoul.py +0 -96
  35. Analysis_code/5.optima/ft_transformer_ctgan10000/utils.py +0 -720
  36. Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_busan.py +0 -97
  37. Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_daegu.py +0 -99
  38. Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_daejeon.py +0 -99
  39. Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_gwangju.py +0 -99
  40. Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_incheon.py +0 -99
  41. Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_seoul.py +0 -98
  42. Analysis_code/5.optima/ft_transformer_pure/utils.py +0 -720
  43. Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_busan.py +0 -97
  44. Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_daegu.py +0 -97
  45. Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_daejeon.py +0 -97
  46. Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_gwangju.py +0 -97
  47. Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_incheon.py +0 -97
  48. Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_seoul.py +0 -97
  49. Analysis_code/5.optima/ft_transformer_smote/utils.py +0 -719
  50. Analysis_code/5.optima/ft_transformer_smotenc_ctgan20000/ft_transformer_smotenc_ctgan20000_busan.py +0 -97
Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_busan.py DELETED
@@ -1,98 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="busan", data_sample='ctgan10000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_ctgan10000_busan_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="busan",
80
- data_sample='ctgan10000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
98
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_daegu.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daegu", data_sample='ctgan10000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_ctgan10000_daegu_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daegu",
80
- data_sample='ctgan10000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_daejeon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daejeon", data_sample='ctgan10000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_ctgan10000_daejeon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daejeon",
80
- data_sample='ctgan10000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_gwangju.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="gwangju", data_sample='ctgan10000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_ctgan10000_gwangju_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="gwangju",
80
- data_sample='ctgan10000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_incheon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="incheon", data_sample='ctgan10000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_ctgan10000_incheon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="incheon",
80
- data_sample='ctgan10000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_ctgan10000/deepgbm_ctgan10000_seoul.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="seoul", data_sample='ctgan10000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_ctgan10000_seoul_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="seoul",
80
- data_sample='ctgan10000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_ctgan10000/utils.py DELETED
@@ -1,721 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.optim as optim
4
- import numpy as np
5
- import random
6
- import os
7
- import copy
8
- from sklearn.preprocessing import QuantileTransformer, LabelEncoder
9
- from torch.utils.data import DataLoader, TensorDataset
10
- from sklearn.metrics import confusion_matrix
11
- from sklearn.utils.class_weight import compute_class_weight
12
- import pandas as pd
13
- import optuna
14
- from sklearn.metrics import accuracy_score, f1_score
15
- import joblib
16
-
17
-
18
- import sys
19
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ models ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
20
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
21
- models_path = os.path.abspath(os.path.join(current_file_dir, '../../models'))
22
- sys.path.insert(0, models_path)
23
- from ft_transformer import FTTransformer
24
- from resnet_like import ResNetLike
25
- from deepgbm import DeepGBM
26
- import warnings
27
- warnings.filterwarnings('ignore')
28
-
29
-
30
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
31
- seed = 42
32
- random.seed(seed)
33
- np.random.seed(seed)
34
-
35
- # PyTorch ์‹œ๋“œ ๊ณ ์ •
36
- torch.manual_seed(seed)
37
- torch.cuda.manual_seed(seed)
38
- torch.cuda.manual_seed_all(seed) # Multi-GPU ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ์‹œ๋“œ ์ ์šฉ
39
-
40
- # PyTorch ์—ฐ์‚ฐ์˜ ๊ฒฐ์ •์  ๋ชจ๋“œ ์„ค์ •
41
- torch.backends.cudnn.deterministic = True # ์‹คํ–‰๋งˆ๋‹ค ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ
42
- torch.backends.cudnn.benchmark = True # ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™” (๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅธ ์—ฐ์‚ฐ ์ˆ˜ํ–‰)
43
-
44
-
45
- def add_derived_features(df: pd.DataFrame) -> pd.DataFrame:
46
- """
47
- ์ œ๊ฑฐํ–ˆ๋˜ ํŒŒ์ƒ ๋ณ€์ˆ˜๋“ค์„ ๋ณต๊ตฌ
48
-
49
- Args:
50
- df: ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
51
-
52
- Returns:
53
- ํŒŒ์ƒ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
54
- """
55
- df = df.copy()
56
- df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
57
- df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
58
- df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
59
- df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
60
- df['ground_temp - temp_C'] = df['groundtemp'] - df['temp_C']
61
- return df
62
-
63
- def preprocessing(df):
64
- """๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜.
65
-
66
- Args:
67
- df: ์›๋ณธ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
68
-
69
- Returns:
70
- ์ „์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
71
- """
72
- df = df[df.columns].copy()
73
- df['year'] = df['year'].astype('int')
74
- df['month'] = df['month'].astype('int')
75
- df['hour'] = df['hour'].astype('int')
76
- df = add_derived_features(df).copy()
77
- df['multi_class'] = df['multi_class'].astype('int')
78
- df.loc[df['wind_dir']=='์ •์˜จ', 'wind_dir'] = "0"
79
- df['wind_dir'] = df['wind_dir'].astype('int')
80
- df = df[['temp_C', 'precip_mm', 'wind_speed', 'wind_dir', 'hm',
81
- 'vap_pressure', 'dewpoint_C', 'loc_pressure', 'sea_pressure',
82
- 'solarRad', 'snow_cm', 'cloudcover', 'lm_cloudcover', 'low_cloudbase',
83
- 'groundtemp', 'O3', 'NO2', 'PM10', 'PM25', 'year',
84
- 'month', 'hour', 'ground_temp - temp_C', 'hour_sin', 'hour_cos',
85
- 'month_sin', 'month_cos','multi_class']].copy()
86
- return df
87
-
88
-
89
- # ๋ฐ์ดํ„ฐ์…‹ ์ค€๋น„ ํ•จ์ˆ˜
90
- def prepare_dataset(region, data_sample='pure', target='multi', fold=3):
91
-
92
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
93
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
94
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
95
-
96
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
97
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
98
- if data_sample == 'pure':
99
- train_path = dat_path
100
- else:
101
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
102
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
103
- drop_col = ['multi_class','year']
104
- target_col = f'{target}_class'
105
-
106
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
107
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
108
- if data_sample == 'pure':
109
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
110
- else:
111
- region_train = preprocessing(pd.read_csv(train_path))
112
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
113
- region_test = preprocessing(pd.read_csv(test_path))
114
-
115
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
116
- common_columns = region_train.columns.to_list()
117
- train_data = region_train[common_columns]
118
- val_data = region_val[common_columns]
119
- test_data = region_test[common_columns]
120
-
121
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
122
- X_train = train_data.drop(columns=drop_col)
123
- y_train = train_data[target_col]
124
- X_val = val_data.drop(columns=drop_col)
125
- y_val = val_data[target_col]
126
- X_test = test_data.drop(columns=drop_col)
127
- y_test = test_data[target_col]
128
-
129
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
130
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
131
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
132
-
133
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
134
- label_encoders = {}
135
- for col in categorical_cols:
136
- le = LabelEncoder()
137
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
138
- label_encoders[col] = le
139
-
140
- # ๋ณ€ํ™˜ ์ ์šฉ
141
- for col in categorical_cols:
142
- X_train[col] = label_encoders[col].transform(X_train[col])
143
- X_val[col] = label_encoders[col].transform(X_val[col])
144
- X_test[col] = label_encoders[col].transform(X_test[col])
145
-
146
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
147
- scaler = QuantileTransformer(output_distribution='normal')
148
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
149
-
150
- # ๋ณ€ํ™˜ ์ ์šฉ
151
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
152
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
153
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
154
-
155
- return X_train, X_val, X_test, y_train, y_val, y_test, categorical_cols, numerical_cols
156
-
157
-
158
-
159
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜
160
- def prepare_dataloader(region, data_sample='pure', target='multi', fold=3, random_state=None):
161
-
162
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
163
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
164
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
165
-
166
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
167
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
168
- if data_sample == 'pure':
169
- train_path = dat_path
170
- else:
171
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
172
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
173
- drop_col = ['multi_class','year']
174
- target_col = f'{target}_class'
175
-
176
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
177
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
178
- if data_sample == 'pure':
179
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
180
- else:
181
- region_train = preprocessing(pd.read_csv(train_path))
182
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
183
- region_test = preprocessing(pd.read_csv(test_path))
184
-
185
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
186
- common_columns = region_train.columns.to_list()
187
- train_data = region_train[common_columns]
188
- val_data = region_val[common_columns]
189
- test_data = region_test[common_columns]
190
-
191
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
192
- X_train = train_data.drop(columns=drop_col)
193
- y_train = train_data[target_col]
194
- X_val = val_data.drop(columns=drop_col)
195
- y_val = val_data[target_col]
196
- X_test = test_data.drop(columns=drop_col)
197
- y_test = test_data[target_col]
198
-
199
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
200
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
201
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
202
-
203
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
204
- label_encoders = {}
205
- for col in categorical_cols:
206
- le = LabelEncoder()
207
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
208
- label_encoders[col] = le
209
-
210
- # ๋ณ€ํ™˜ ์ ์šฉ
211
- for col in categorical_cols:
212
- X_train[col] = label_encoders[col].transform(X_train[col])
213
- X_val[col] = label_encoders[col].transform(X_val[col])
214
- X_test[col] = label_encoders[col].transform(X_test[col])
215
-
216
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
217
- scaler = QuantileTransformer(output_distribution='normal')
218
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
219
-
220
- # ๋ณ€ํ™˜ ์ ์šฉ
221
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
222
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
223
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
224
-
225
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
226
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
227
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
228
-
229
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
230
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
231
-
232
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
233
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
234
-
235
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
236
- if target == "binary":
237
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
238
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
239
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
240
- elif target == "multi":
241
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
242
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
243
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
244
- else:
245
- raise ValueError("target must be 'binary' or 'multi'")
246
-
247
- # TensorDataset ์ƒ์„ฑ
248
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
249
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
250
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
251
-
252
- # DataLoader ์ƒ์„ฑ
253
- if random_state == None:
254
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
255
- else:
256
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(random_state))
257
- val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
258
- test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
259
-
260
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader
261
-
262
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๋ฒ„์ „)
263
- def prepare_dataloader_with_batchsize(region, data_sample='pure', target='multi', fold=3, random_state=None, batch_size=64):
264
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
265
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
266
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
267
-
268
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
269
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
270
- if data_sample == 'pure':
271
- train_path = dat_path
272
- else:
273
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
274
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
275
- drop_col = ['multi_class','year']
276
- target_col = f'{target}_class'
277
-
278
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
279
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
280
- if data_sample == 'pure':
281
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
282
- else:
283
- region_train = preprocessing(pd.read_csv(train_path))
284
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
285
- region_test = preprocessing(pd.read_csv(test_path))
286
-
287
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
288
- common_columns = region_train.columns.to_list()
289
- train_data = region_train[common_columns]
290
- val_data = region_val[common_columns]
291
- test_data = region_test[common_columns]
292
-
293
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
294
- X_train = train_data.drop(columns=drop_col)
295
- y_train = train_data[target_col]
296
- X_val = val_data.drop(columns=drop_col)
297
- y_val = val_data[target_col]
298
- X_test = test_data.drop(columns=drop_col)
299
- y_test = test_data[target_col]
300
-
301
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
302
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
303
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
304
-
305
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
306
- label_encoders = {}
307
- for col in categorical_cols:
308
- le = LabelEncoder()
309
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
310
- label_encoders[col] = le
311
-
312
- # ๋ณ€ํ™˜ ์ ์šฉ
313
- for col in categorical_cols:
314
- X_train[col] = label_encoders[col].transform(X_train[col])
315
- X_val[col] = label_encoders[col].transform(X_val[col])
316
- X_test[col] = label_encoders[col].transform(X_test[col])
317
-
318
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
319
- scaler = QuantileTransformer(output_distribution='normal')
320
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
321
-
322
- # ๋ณ€ํ™˜ ์ ์šฉ
323
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
324
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
325
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
326
-
327
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
328
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
329
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
330
-
331
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
332
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
333
-
334
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
335
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
336
-
337
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
338
- if target == "binary":
339
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
340
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
341
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
342
- elif target == "multi":
343
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
344
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
345
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
346
- else:
347
- raise ValueError("target must be 'binary' or 'multi'")
348
-
349
- # TensorDataset ์ƒ์„ฑ
350
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
351
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
352
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
353
-
354
- # DataLoader ์ƒ์„ฑ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ)
355
- if random_state == None:
356
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
357
- else:
358
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(random_state))
359
- val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
360
- test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
361
-
362
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader, y_train, scaler
363
-
364
-
365
- def calculate_csi(y_true, pred):
366
-
367
- cm = confusion_matrix(y_true, pred) # ๋ณ€์ˆ˜ ์ด๋ฆ„์„ cm์œผ๋กœ ๋ณ€๊ฒฝ
368
- # ํ˜ผ๋™ ํ–‰๋ ฌ์—์„œ H, F, M ์ถ”์ถœ
369
- H = (cm[0, 0] + cm[1, 1])
370
-
371
- F = (cm[1, 0] + cm[2, 0] +
372
- cm[0, 1] + cm[2, 1])
373
-
374
- M = (cm[0, 2] + cm[1, 2])
375
-
376
- # CSI ๊ณ„์‚ฐ
377
- CSI = H / (H + F + M + 1e-10)
378
- return CSI
379
-
380
- def sample_weight(y_train):
381
- class_weights = compute_class_weight(
382
- class_weight='balanced',
383
- classes=np.unique(y_train), # ๊ณ ์œ  ํด๋ž˜์Šค
384
- y=y_train # ํ•™์Šต ๋ฐ์ดํ„ฐ ๋ ˆ์ด๋ธ”
385
- )
386
- sample_weights = np.array([class_weights[label] for label in y_train])
387
-
388
- return sample_weights
389
-
390
- # ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ •์˜
391
- def objective(trial, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
392
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
393
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
394
- val_scores = []
395
-
396
- # --- 1. ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰ ๋ฒ”์œ„ ์ •์˜ (์ˆ˜์ •๋จ) ---
397
- if model_choose == "ft_transformer":
398
- d_token = trial.suggest_int("d_token", 64, 256, step=32)
399
- n_blocks = trial.suggest_int("n_blocks", 2, 6) # ๊นŠ์ด ์ถ•์†Œ๋กœ ๊ณผ์ ํ•ฉ ๋ฐฉ์ง€
400
- n_heads = trial.suggest_categorical("n_heads", [4, 8])
401
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
402
- if d_token % n_heads != 0:
403
- d_token = (d_token // n_heads) * n_heads
404
-
405
- attention_dropout = trial.suggest_float("attention_dropout", 0.1, 0.4)
406
- ffn_dropout = trial.suggest_float("ffn_dropout", 0.1, 0.4)
407
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True) # ๋ฒ”์œ„ ํ™•๋Œ€
408
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
409
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
410
-
411
- elif model_choose == 'resnet_like':
412
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
413
- d_hidden = trial.suggest_int("d_hidden", 64, 512, step=64)
414
- n_blocks = trial.suggest_int("n_blocks", 2, 5) # ๋„ˆ๋ฌด ๊นŠ์ง€ ์•Š๊ฒŒ ์กฐ์ ˆ
415
- dropout_first = trial.suggest_float("dropout_first", 0.1, 0.4)
416
- dropout_second = trial.suggest_float("dropout_second", 0.0, 0.2)
417
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
418
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
419
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
420
-
421
- elif model_choose == 'deepgbm':
422
- # DeepGBM์˜ ๊ฒฝ์šฐ ๋ชจ๋ธ ํŠน์„ฑ์— ๋งž์ถฐ ResNet ๋ธ”๋ก ๋ฐ ์ž„๋ฒ ๋”ฉ ์ฐจ์› ์กฐ์ ˆ
423
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
424
- d_hidden = trial.suggest_int("d_hidden", 64, 256, step=64)
425
- n_blocks = trial.suggest_int("n_blocks", 2, 6)
426
- dropout = trial.suggest_float("dropout", 0.1, 0.4)
427
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
428
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
429
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
430
-
431
- # --- 2. Fold๋ณ„ ํ•™์Šต ๋ฐ ๊ต์ฐจ ๊ฒ€์ฆ ---
432
- for fold in range(1, n_folds + 1):
433
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, _ = prepare_dataloader_with_batchsize(
434
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
435
- )
436
-
437
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
438
- if model_choose == "ft_transformer":
439
- model = FTTransformer(
440
- num_features=len(numerical_cols),
441
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
442
- d_token=d_token,
443
- n_blocks=n_blocks,
444
- n_heads=n_heads,
445
- attention_dropout=attention_dropout,
446
- ffn_dropout=ffn_dropout,
447
- num_classes=3
448
- ).to(device)
449
- elif model_choose == 'resnet_like':
450
- input_dim = len(numerical_cols) + len(categorical_cols)
451
- model = ResNetLike(
452
- input_dim=input_dim,
453
- d_main=d_main,
454
- d_hidden=d_hidden,
455
- n_blocks=n_blocks,
456
- dropout_first=dropout_first,
457
- dropout_second=dropout_second,
458
- num_classes=3
459
- ).to(device)
460
- elif model_choose == 'deepgbm':
461
- model = DeepGBM(
462
- num_features=len(numerical_cols),
463
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
464
- d_main=d_main,
465
- d_hidden=d_hidden,
466
- n_blocks=n_blocks,
467
- dropout=dropout,
468
- num_classes=3
469
- ).to(device)
470
-
471
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
472
- if target == 'multi':
473
- class_weights = compute_class_weight(
474
- class_weight='balanced',
475
- classes=np.unique(y_train),
476
- y=y_train
477
- )
478
- # ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜ ๋กœ๊ทธ ์ถœ๋ ฅ
479
- unique_classes = np.unique(y_train)
480
- class_counts = {cls: np.sum(y_train == cls) for cls in unique_classes}
481
- print(f" Fold {fold} - ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜: {dict(zip(unique_classes, class_weights))} (ํด๋ž˜์Šค๋ณ„ ์ƒ˜ํ”Œ ์ˆ˜: {class_counts})")
482
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
483
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
484
- else:
485
- criterion = nn.BCEWithLogitsLoss()
486
- optimizer = optim.AdamW(model.parameters(), lr=lr, weight_decay=weight_decay)
487
-
488
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ ์ถ”๊ฐ€: ์„ฑ๋Šฅ ์ •์ฒด ์‹œ LR์„ 0.5๋ฐฐ ๊ฐ์†Œ (๊ฒ€์ฆ CSI ๊ธฐ์ค€)
489
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
490
-
491
- # ํ•™์Šต ์„ค์ • (์—ํญ ๋ฐ ํŽ˜์ด์…˜์Šค ์ƒํ–ฅ)
492
- epochs = 200
493
- patience = 12 # ๋”ฅ๋Ÿฌ๋‹์˜ ์ •์ฒด ๊ตฌ๊ฐ„์„ ๊ณ ๋ คํ•˜์—ฌ ์†Œํญ ์ƒํ–ฅ
494
- best_fold_csi = 0
495
- counter = 0
496
-
497
- for epoch in range(epochs):
498
- model.train()
499
- for x_num_batch, x_cat_batch, y_batch in train_loader:
500
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
501
-
502
- optimizer.zero_grad()
503
- y_pred = model(x_num_batch, x_cat_batch)
504
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
505
- loss.backward()
506
- optimizer.step()
507
-
508
- # Validation ํ‰๊ฐ€
509
- model.eval()
510
- y_pred_val, y_true_val = [], []
511
- with torch.no_grad():
512
- for x_num_batch, x_cat_batch, y_batch in val_loader:
513
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
514
- output = model(x_num_batch, x_cat_batch)
515
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
516
-
517
- y_pred_val.extend(pred.cpu().numpy())
518
- y_true_val.extend(y_batch.cpu().numpy())
519
-
520
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
521
- val_csi = calculate_csi(y_true_val, y_pred_val)
522
- scheduler.step(val_csi)
523
-
524
- # Optuna Pruning ์ ์šฉ (์ฒซ ๋ฒˆ์งธ Fold์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ ํŒ๋‹จ ๊ฐ•ํ™”)
525
- trial.report(val_csi, epoch)
526
- if trial.should_prune():
527
- raise optuna.exceptions.TrialPruned()
528
-
529
- # Early Stopping ์ฒดํฌ
530
- if val_csi > best_fold_csi:
531
- best_fold_csi = val_csi
532
- counter = 0
533
- else:
534
- counter += 1
535
-
536
- if counter >= patience:
537
- break
538
-
539
- val_scores.append(best_fold_csi)
540
-
541
- # ๋ชจ๋“  fold์˜ ํ‰๊ท  ์„ฑ๋Šฅ ๋ฐ˜ํ™˜
542
- return np.mean(val_scores)
543
-
544
-
545
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ํ•จ์ˆ˜
546
- def train_final_model(best_params, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
547
- """
548
- ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
549
-
550
- Args:
551
- best_params: ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ
552
- model_choose: ๋ชจ๋ธ ์„ ํƒ ('ft_transformer', 'resnet_like', 'deepgbm')
553
- region: ์ง€์—ญ๋ช…
554
- data_sample: ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ ํƒ€์ž… ('pure', 'smote', etc.)
555
- target: ํƒ€๊ฒŸ ํƒ€์ž… ('multi', 'binary')
556
- n_folds: ๊ต์ฐจ ๊ฒ€์ฆ fold ์ˆ˜
557
- random_state: ๋žœ๋ค ์‹œ๋“œ
558
-
559
- Returns:
560
- ์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ ๋ฆฌ์ŠคํŠธ
561
- """
562
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
563
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
564
-
565
- models = []
566
- scalers = [] # scaler ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€
567
-
568
- print("์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘...")
569
-
570
- for fold in range(1, n_folds + 1):
571
- print(f"Fold {fold} ํ•™์Šต ์ค‘...")
572
-
573
- # ์ตœ์ ํ™”๋œ batch_size ์‚ฌ์šฉ
574
- batch_size = best_params.get("batch_size", 64)
575
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, scaler = prepare_dataloader_with_batchsize(
576
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
577
- )
578
-
579
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
580
- if model_choose == "ft_transformer":
581
- d_token = best_params["d_token"]
582
- n_heads = best_params.get("n_heads", 8)
583
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
584
- if d_token % n_heads != 0:
585
- d_token = (d_token // n_heads) * n_heads
586
-
587
- model = FTTransformer(
588
- num_features=len(numerical_cols),
589
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
590
- d_token=d_token,
591
- n_blocks=best_params["n_blocks"],
592
- n_heads=n_heads,
593
- attention_dropout=best_params["attention_dropout"],
594
- ffn_dropout=best_params["ffn_dropout"],
595
- num_classes=3
596
- ).to(device)
597
- elif model_choose == 'resnet_like':
598
- input_dim = len(numerical_cols) + len(categorical_cols)
599
- model = ResNetLike(
600
- input_dim=input_dim,
601
- d_main=best_params["d_main"],
602
- d_hidden=best_params["d_hidden"],
603
- n_blocks=best_params["n_blocks"],
604
- dropout_first=best_params["dropout_first"],
605
- dropout_second=best_params["dropout_second"],
606
- num_classes=3
607
- ).to(device)
608
- elif model_choose == 'deepgbm':
609
- model = DeepGBM(
610
- num_features=len(numerical_cols),
611
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
612
- d_main=best_params["d_main"],
613
- d_hidden=best_params["d_hidden"],
614
- n_blocks=best_params["n_blocks"],
615
- dropout=best_params["dropout"],
616
- num_classes=3
617
- ).to(device)
618
- else:
619
- raise ValueError(f"Unknown model_choose: {model_choose}")
620
-
621
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
622
- if target == 'multi':
623
- class_weights = compute_class_weight(
624
- class_weight='balanced',
625
- classes=np.unique(y_train),
626
- y=y_train
627
- )
628
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
629
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
630
- else:
631
- criterion = nn.BCEWithLogitsLoss()
632
- optimizer = optim.AdamW(model.parameters(), lr=best_params["lr"], weight_decay=best_params["weight_decay"])
633
-
634
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ
635
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
636
-
637
- # ํ•™์Šต ์„ค์ •
638
- epochs = 200
639
- patience = 12
640
- best_fold_csi = 0
641
- counter = 0
642
- best_model = None
643
-
644
- for epoch in range(epochs):
645
- model.train()
646
- for x_num_batch, x_cat_batch, y_batch in train_loader:
647
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
648
-
649
- optimizer.zero_grad()
650
- y_pred = model(x_num_batch, x_cat_batch)
651
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
652
- loss.backward()
653
- optimizer.step()
654
-
655
- # Validation ํ‰๊ฐ€
656
- model.eval()
657
- y_pred_val, y_true_val = [], []
658
- with torch.no_grad():
659
- for x_num_batch, x_cat_batch, y_batch in val_loader:
660
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
661
- output = model(x_num_batch, x_cat_batch)
662
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
663
-
664
- y_pred_val.extend(pred.cpu().numpy())
665
- y_true_val.extend(y_batch.cpu().numpy())
666
-
667
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
668
- val_csi = calculate_csi(y_true_val, y_pred_val)
669
- scheduler.step(val_csi)
670
-
671
- # Early Stopping ์ฒดํฌ
672
- if val_csi > best_fold_csi:
673
- best_fold_csi = val_csi
674
- counter = 0
675
- best_model = copy.deepcopy(model)
676
- else:
677
- counter += 1
678
-
679
- if counter >= patience:
680
- print(f" Early stopping at epoch {epoch+1}, Best CSI: {best_fold_csi:.4f}")
681
- break
682
-
683
- if best_model is None:
684
- best_model = model
685
-
686
- scalers.append(scaler) # scaler ์ €์žฅ (fold ์ˆœ์„œ๋Œ€๋กœ)
687
- models.append(best_model)
688
- print(f" Fold {fold} ํ•™์Šต ์™„๋ฃŒ (๊ฒ€์ฆ CSI: {best_fold_csi:.4f})")
689
-
690
- # ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •
691
- save_dir = f'../save_model/{model_choose}_optima'
692
- os.makedirs(save_dir, exist_ok=True)
693
-
694
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ
695
- if data_sample == 'pure':
696
- model_filename = f'{model_choose}_pure_{region}.pkl'
697
- else:
698
- model_filename = f'{model_choose}_{data_sample}_{region}.pkl'
699
-
700
- model_path = f'{save_dir}/{model_filename}'
701
-
702
- # ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„ ํ•œ ๋ฒˆ์— ์ €์žฅ
703
- joblib.dump(models, model_path)
704
- print(f"\n๋ชจ๋“  ๋ชจ๋ธ ์ €์žฅ ์™„๋ฃŒ: {model_path} (์ด {len(models)}๊ฐœ fold)")
705
-
706
- # Scaler ๋ณ„๋„ ์ €์žฅ
707
- scaler_save_dir = f'../save_model/{model_choose}_optima/scaler'
708
- os.makedirs(scaler_save_dir, exist_ok=True)
709
-
710
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ (๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํŒจํ„ด)
711
- if data_sample == 'pure':
712
- scaler_filename = f'{model_choose}_pure_{region}_scaler.pkl'
713
- else:
714
- scaler_filename = f'{model_choose}_{data_sample}_{region}_scaler.pkl'
715
-
716
- scaler_path = f'{scaler_save_dir}/{scaler_filename}'
717
- joblib.dump(scalers, scaler_path)
718
- print(f"Scaler ์ €์žฅ ์™„๋ฃŒ: {scaler_path} (์ด {len(scalers)}๊ฐœ fold)")
719
-
720
- return model_path
721
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_busan.py DELETED
@@ -1,98 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="busan"),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_pure_busan_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_paths = train_final_model(
76
- best_params=best_params,
77
- model_choose="deepgbm",
78
- region="busan",
79
- data_sample='pure',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
87
- for path in model_paths:
88
- print(f" - {path}")
89
-
90
- except Exception as e:
91
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
92
- import traceback
93
- traceback.print_exc()
94
-
95
- # ์ •์ƒ ์ข…๋ฃŒ
96
- import sys
97
- sys.exit(0)
98
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_daegu.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daegu"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_pure_daegu_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daegu",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_daejeon.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daejeon"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_pure_daejeon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daejeon",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_gwangju.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="gwangju"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_pure_gwangju_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="gwangju",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_incheon.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="incheon"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_pure_incheon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="incheon",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_pure/deepgbm_pure_seoul.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="seoul"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_pure_seoul_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="seoul",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_pure/utils.py DELETED
@@ -1,720 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.optim as optim
4
- import numpy as np
5
- import random
6
- import os
7
- import copy
8
- from sklearn.preprocessing import QuantileTransformer, LabelEncoder
9
- from torch.utils.data import DataLoader, TensorDataset
10
- from sklearn.metrics import confusion_matrix
11
- from sklearn.utils.class_weight import compute_class_weight
12
- import pandas as pd
13
- import optuna
14
- from sklearn.metrics import accuracy_score, f1_score
15
- import joblib
16
-
17
-
18
- import sys
19
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ models ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
20
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
21
- models_path = os.path.abspath(os.path.join(current_file_dir, '../../models'))
22
- sys.path.insert(0, models_path)
23
- from ft_transformer import FTTransformer
24
- from resnet_like import ResNetLike
25
- from deepgbm import DeepGBM
26
- import warnings
27
- warnings.filterwarnings('ignore')
28
-
29
-
30
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
31
- seed = 42
32
- random.seed(seed)
33
- np.random.seed(seed)
34
-
35
- # PyTorch ์‹œ๋“œ ๊ณ ์ •
36
- torch.manual_seed(seed)
37
- torch.cuda.manual_seed(seed)
38
- torch.cuda.manual_seed_all(seed) # Multi-GPU ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ์‹œ๋“œ ์ ์šฉ
39
-
40
- # PyTorch ์—ฐ์‚ฐ์˜ ๊ฒฐ์ •์  ๋ชจ๋“œ ์„ค์ •
41
- torch.backends.cudnn.deterministic = True # ์‹คํ–‰๋งˆ๋‹ค ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ
42
- torch.backends.cudnn.benchmark = True # ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™” (๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅธ ์—ฐ์‚ฐ ์ˆ˜ํ–‰)
43
-
44
-
45
- def add_derived_features(df: pd.DataFrame) -> pd.DataFrame:
46
- """
47
- ์ œ๊ฑฐํ–ˆ๋˜ ํŒŒ์ƒ ๋ณ€์ˆ˜๋“ค์„ ๋ณต๊ตฌ
48
-
49
- Args:
50
- df: ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
51
-
52
- Returns:
53
- ํŒŒ์ƒ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
54
- """
55
- df = df.copy()
56
- df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
57
- df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
58
- df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
59
- df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
60
- df['ground_temp - temp_C'] = df['groundtemp'] - df['temp_C']
61
- return df
62
-
63
- def preprocessing(df):
64
- """๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜.
65
-
66
- Args:
67
- df: ์›๋ณธ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
68
-
69
- Returns:
70
- ์ „์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
71
- """
72
- df = df[df.columns].copy()
73
- df['year'] = df['year'].astype('int')
74
- df['month'] = df['month'].astype('int')
75
- df['hour'] = df['hour'].astype('int')
76
- df = add_derived_features(df).copy()
77
- df['multi_class'] = df['multi_class'].astype('int')
78
- df.loc[df['wind_dir']=='์ •์˜จ', 'wind_dir'] = "0"
79
- df['wind_dir'] = df['wind_dir'].astype('int')
80
- df = df[['temp_C', 'precip_mm', 'wind_speed', 'wind_dir', 'hm',
81
- 'vap_pressure', 'dewpoint_C', 'loc_pressure', 'sea_pressure',
82
- 'solarRad', 'snow_cm', 'cloudcover', 'lm_cloudcover', 'low_cloudbase',
83
- 'groundtemp', 'O3', 'NO2', 'PM10', 'PM25', 'year',
84
- 'month', 'hour', 'ground_temp - temp_C', 'hour_sin', 'hour_cos',
85
- 'month_sin', 'month_cos','multi_class']].copy()
86
- return df
87
-
88
-
89
- # ๋ฐ์ดํ„ฐ์…‹ ์ค€๋น„ ํ•จ์ˆ˜
90
- def prepare_dataset(region, data_sample='pure', target='multi', fold=3):
91
-
92
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
93
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
94
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
95
-
96
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
97
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
98
- if data_sample == 'pure':
99
- train_path = dat_path
100
- else:
101
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
102
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
103
- drop_col = ['multi_class','year']
104
- target_col = f'{target}_class'
105
-
106
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
107
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
108
- if data_sample == 'pure':
109
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
110
- else:
111
- region_train = preprocessing(pd.read_csv(train_path))
112
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
113
- region_test = preprocessing(pd.read_csv(test_path))
114
-
115
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
116
- common_columns = region_train.columns.to_list()
117
- train_data = region_train[common_columns]
118
- val_data = region_val[common_columns]
119
- test_data = region_test[common_columns]
120
-
121
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
122
- X_train = train_data.drop(columns=drop_col)
123
- y_train = train_data[target_col]
124
- X_val = val_data.drop(columns=drop_col)
125
- y_val = val_data[target_col]
126
- X_test = test_data.drop(columns=drop_col)
127
- y_test = test_data[target_col]
128
-
129
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
130
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
131
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
132
-
133
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
134
- label_encoders = {}
135
- for col in categorical_cols:
136
- le = LabelEncoder()
137
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
138
- label_encoders[col] = le
139
-
140
- # ๋ณ€ํ™˜ ์ ์šฉ
141
- for col in categorical_cols:
142
- X_train[col] = label_encoders[col].transform(X_train[col])
143
- X_val[col] = label_encoders[col].transform(X_val[col])
144
- X_test[col] = label_encoders[col].transform(X_test[col])
145
-
146
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
147
- scaler = QuantileTransformer(output_distribution='normal')
148
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
149
-
150
- # ๋ณ€ํ™˜ ์ ์šฉ
151
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
152
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
153
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
154
-
155
- return X_train, X_val, X_test, y_train, y_val, y_test, categorical_cols, numerical_cols
156
-
157
-
158
-
159
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜
160
- def prepare_dataloader(region, data_sample='pure', target='multi', fold=3, random_state=None):
161
-
162
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
163
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
164
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
165
-
166
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
167
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
168
- if data_sample == 'pure':
169
- train_path = dat_path
170
- else:
171
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
172
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
173
- drop_col = ['multi_class','year']
174
- target_col = f'{target}_class'
175
-
176
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
177
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
178
- if data_sample == 'pure':
179
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
180
- else:
181
- region_train = preprocessing(pd.read_csv(train_path))
182
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
183
- region_test = preprocessing(pd.read_csv(test_path))
184
-
185
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
186
- common_columns = region_train.columns.to_list()
187
- train_data = region_train[common_columns]
188
- val_data = region_val[common_columns]
189
- test_data = region_test[common_columns]
190
-
191
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
192
- X_train = train_data.drop(columns=drop_col)
193
- y_train = train_data[target_col]
194
- X_val = val_data.drop(columns=drop_col)
195
- y_val = val_data[target_col]
196
- X_test = test_data.drop(columns=drop_col)
197
- y_test = test_data[target_col]
198
-
199
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
200
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
201
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
202
-
203
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
204
- label_encoders = {}
205
- for col in categorical_cols:
206
- le = LabelEncoder()
207
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
208
- label_encoders[col] = le
209
-
210
- # ๋ณ€ํ™˜ ์ ์šฉ
211
- for col in categorical_cols:
212
- X_train[col] = label_encoders[col].transform(X_train[col])
213
- X_val[col] = label_encoders[col].transform(X_val[col])
214
- X_test[col] = label_encoders[col].transform(X_test[col])
215
-
216
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
217
- scaler = QuantileTransformer(output_distribution='normal')
218
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
219
-
220
- # ๋ณ€ํ™˜ ์ ์šฉ
221
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
222
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
223
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
224
-
225
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
226
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
227
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
228
-
229
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
230
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
231
-
232
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
233
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
234
-
235
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
236
- if target == "binary":
237
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
238
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
239
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
240
- elif target == "multi":
241
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
242
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
243
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
244
- else:
245
- raise ValueError("target must be 'binary' or 'multi'")
246
-
247
- # TensorDataset ์ƒ์„ฑ
248
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
249
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
250
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
251
-
252
- # DataLoader ์ƒ์„ฑ
253
- if random_state == None:
254
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
255
- else:
256
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(random_state))
257
- val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
258
- test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
259
-
260
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader
261
-
262
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๋ฒ„์ „)
263
- def prepare_dataloader_with_batchsize(region, data_sample='pure', target='multi', fold=3, random_state=None, batch_size=64):
264
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
265
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
266
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
267
-
268
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
269
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
270
- if data_sample == 'pure':
271
- train_path = dat_path
272
- else:
273
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
274
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
275
- drop_col = ['multi_class','year']
276
- target_col = f'{target}_class'
277
-
278
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
279
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
280
- if data_sample == 'pure':
281
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
282
- else:
283
- region_train = preprocessing(pd.read_csv(train_path))
284
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
285
- region_test = preprocessing(pd.read_csv(test_path))
286
-
287
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
288
- common_columns = region_train.columns.to_list()
289
- train_data = region_train[common_columns]
290
- val_data = region_val[common_columns]
291
- test_data = region_test[common_columns]
292
-
293
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
294
- X_train = train_data.drop(columns=drop_col)
295
- y_train = train_data[target_col]
296
- X_val = val_data.drop(columns=drop_col)
297
- y_val = val_data[target_col]
298
- X_test = test_data.drop(columns=drop_col)
299
- y_test = test_data[target_col]
300
-
301
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
302
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
303
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
304
-
305
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
306
- label_encoders = {}
307
- for col in categorical_cols:
308
- le = LabelEncoder()
309
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
310
- label_encoders[col] = le
311
-
312
- # ๋ณ€ํ™˜ ์ ์šฉ
313
- for col in categorical_cols:
314
- X_train[col] = label_encoders[col].transform(X_train[col])
315
- X_val[col] = label_encoders[col].transform(X_val[col])
316
- X_test[col] = label_encoders[col].transform(X_test[col])
317
-
318
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
319
- scaler = QuantileTransformer(output_distribution='normal')
320
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
321
-
322
- # ๋ณ€ํ™˜ ์ ์šฉ
323
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
324
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
325
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
326
-
327
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
328
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
329
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
330
-
331
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
332
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
333
-
334
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
335
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
336
-
337
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
338
- if target == "binary":
339
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
340
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
341
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
342
- elif target == "multi":
343
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
344
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
345
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
346
- else:
347
- raise ValueError("target must be 'binary' or 'multi'")
348
-
349
- # TensorDataset ์ƒ์„ฑ
350
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
351
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
352
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
353
-
354
- # DataLoader ์ƒ์„ฑ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ)
355
- if random_state == None:
356
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
357
- else:
358
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(random_state))
359
- val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
360
- test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
361
-
362
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader, y_train, scaler
363
-
364
-
365
- def calculate_csi(y_true, pred):
366
-
367
- cm = confusion_matrix(y_true, pred) # ๋ณ€์ˆ˜ ์ด๋ฆ„์„ cm์œผ๋กœ ๋ณ€๊ฒฝ
368
- # ํ˜ผ๋™ ํ–‰๋ ฌ์—์„œ H, F, M ์ถ”์ถœ
369
- H = (cm[0, 0] + cm[1, 1])
370
-
371
- F = (cm[1, 0] + cm[2, 0] +
372
- cm[0, 1] + cm[2, 1])
373
-
374
- M = (cm[0, 2] + cm[1, 2])
375
-
376
- # CSI ๊ณ„์‚ฐ
377
- CSI = H / (H + F + M + 1e-10)
378
- return CSI
379
-
380
- def sample_weight(y_train):
381
- class_weights = compute_class_weight(
382
- class_weight='balanced',
383
- classes=np.unique(y_train), # ๊ณ ์œ  ํด๋ž˜์Šค
384
- y=y_train # ํ•™์Šต ๋ฐ์ดํ„ฐ ๋ ˆ์ด๋ธ”
385
- )
386
- sample_weights = np.array([class_weights[label] for label in y_train])
387
-
388
- return sample_weights
389
-
390
- # ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ •์˜
391
- def objective(trial, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
392
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
393
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
394
- val_scores = []
395
-
396
- # --- 1. ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰ ๋ฒ”์œ„ ์ •์˜ (์ˆ˜์ •๋จ) ---
397
- if model_choose == "ft_transformer":
398
- d_token = trial.suggest_int("d_token", 64, 256, step=32)
399
- n_blocks = trial.suggest_int("n_blocks", 2, 6) # ๊นŠ์ด ์ถ•์†Œ๋กœ ๊ณผ์ ํ•ฉ ๋ฐฉ์ง€
400
- n_heads = trial.suggest_categorical("n_heads", [4, 8])
401
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
402
- if d_token % n_heads != 0:
403
- d_token = (d_token // n_heads) * n_heads
404
-
405
- attention_dropout = trial.suggest_float("attention_dropout", 0.1, 0.4)
406
- ffn_dropout = trial.suggest_float("ffn_dropout", 0.1, 0.4)
407
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True) # ๋ฒ”์œ„ ํ™•๋Œ€
408
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
409
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
410
-
411
- elif model_choose == 'resnet_like':
412
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
413
- d_hidden = trial.suggest_int("d_hidden", 64, 512, step=64)
414
- n_blocks = trial.suggest_int("n_blocks", 2, 5) # ๋„ˆ๋ฌด ๊นŠ์ง€ ์•Š๊ฒŒ ์กฐ์ ˆ
415
- dropout_first = trial.suggest_float("dropout_first", 0.1, 0.4)
416
- dropout_second = trial.suggest_float("dropout_second", 0.0, 0.2)
417
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
418
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
419
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
420
-
421
- elif model_choose == 'deepgbm':
422
- # DeepGBM์˜ ๊ฒฝ์šฐ ๋ชจ๋ธ ํŠน์„ฑ์— ๋งž์ถฐ ResNet ๋ธ”๋ก ๋ฐ ์ž„๋ฒ ๋”ฉ ์ฐจ์› ์กฐ์ ˆ
423
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
424
- d_hidden = trial.suggest_int("d_hidden", 64, 256, step=64)
425
- n_blocks = trial.suggest_int("n_blocks", 2, 6)
426
- dropout = trial.suggest_float("dropout", 0.1, 0.4)
427
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
428
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
429
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
430
-
431
- # --- 2. Fold๋ณ„ ํ•™์Šต ๋ฐ ๊ต์ฐจ ๊ฒ€์ฆ ---
432
- for fold in range(1, n_folds + 1):
433
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, _ = prepare_dataloader_with_batchsize(
434
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
435
- )
436
-
437
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
438
- if model_choose == "ft_transformer":
439
- model = FTTransformer(
440
- num_features=len(numerical_cols),
441
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
442
- d_token=d_token,
443
- n_blocks=n_blocks,
444
- n_heads=n_heads,
445
- attention_dropout=attention_dropout,
446
- ffn_dropout=ffn_dropout,
447
- num_classes=3
448
- ).to(device)
449
- elif model_choose == 'resnet_like':
450
- input_dim = len(numerical_cols) + len(categorical_cols)
451
- model = ResNetLike(
452
- input_dim=input_dim,
453
- d_main=d_main,
454
- d_hidden=d_hidden,
455
- n_blocks=n_blocks,
456
- dropout_first=dropout_first,
457
- dropout_second=dropout_second,
458
- num_classes=3
459
- ).to(device)
460
- elif model_choose == 'deepgbm':
461
- model = DeepGBM(
462
- num_features=len(numerical_cols),
463
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
464
- d_main=d_main,
465
- d_hidden=d_hidden,
466
- n_blocks=n_blocks,
467
- dropout=dropout,
468
- num_classes=3
469
- ).to(device)
470
-
471
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
472
- if target == 'multi':
473
- class_weights = compute_class_weight(
474
- class_weight='balanced',
475
- classes=np.unique(y_train),
476
- y=y_train
477
- )
478
- # ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜ ๋กœ๊ทธ ์ถœ๋ ฅ
479
- unique_classes = np.unique(y_train)
480
- class_counts = {cls: np.sum(y_train == cls) for cls in unique_classes}
481
- print(f" Fold {fold} - ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜: {dict(zip(unique_classes, class_weights))} (ํด๋ž˜์Šค๋ณ„ ์ƒ˜ํ”Œ ์ˆ˜: {class_counts})")
482
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
483
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
484
- else:
485
- criterion = nn.BCEWithLogitsLoss()
486
- optimizer = optim.AdamW(model.parameters(), lr=lr, weight_decay=weight_decay)
487
-
488
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ ์ถ”๊ฐ€: ์„ฑ๋Šฅ ์ •์ฒด ์‹œ LR์„ 0.5๋ฐฐ ๊ฐ์†Œ (๊ฒ€์ฆ CSI ๊ธฐ์ค€)
489
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
490
-
491
- # ํ•™์Šต ์„ค์ • (์—ํญ ๋ฐ ํŽ˜์ด์…˜์Šค ์ƒํ–ฅ)
492
- epochs = 200
493
- patience = 12 # ๋”ฅ๋Ÿฌ๋‹์˜ ์ •์ฒด ๊ตฌ๊ฐ„์„ ๊ณ ๋ คํ•˜์—ฌ ์†Œํญ ์ƒํ–ฅ
494
- best_fold_csi = 0
495
- counter = 0
496
-
497
- for epoch in range(epochs):
498
- model.train()
499
- for x_num_batch, x_cat_batch, y_batch in train_loader:
500
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
501
-
502
- optimizer.zero_grad()
503
- y_pred = model(x_num_batch, x_cat_batch)
504
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
505
- loss.backward()
506
- optimizer.step()
507
-
508
- # Validation ํ‰๊ฐ€
509
- model.eval()
510
- y_pred_val, y_true_val = [], []
511
- with torch.no_grad():
512
- for x_num_batch, x_cat_batch, y_batch in val_loader:
513
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
514
- output = model(x_num_batch, x_cat_batch)
515
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
516
-
517
- y_pred_val.extend(pred.cpu().numpy())
518
- y_true_val.extend(y_batch.cpu().numpy())
519
-
520
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
521
- val_csi = calculate_csi(y_true_val, y_pred_val)
522
- scheduler.step(val_csi)
523
-
524
- # Optuna Pruning ์ ์šฉ (์ฒซ ๋ฒˆ์งธ Fold์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ ํŒ๋‹จ ๊ฐ•ํ™”)
525
- trial.report(val_csi, epoch)
526
- if trial.should_prune():
527
- raise optuna.exceptions.TrialPruned()
528
-
529
- # Early Stopping ์ฒดํฌ
530
- if val_csi > best_fold_csi:
531
- best_fold_csi = val_csi
532
- counter = 0
533
- else:
534
- counter += 1
535
-
536
- if counter >= patience:
537
- break
538
-
539
- val_scores.append(best_fold_csi)
540
-
541
- # ๋ชจ๋“  fold์˜ ํ‰๊ท  ์„ฑ๋Šฅ ๋ฐ˜ํ™˜
542
- return np.mean(val_scores)
543
-
544
-
545
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ํ•จ์ˆ˜
546
- def train_final_model(best_params, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
547
- """
548
- ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
549
-
550
- Args:
551
- best_params: ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ
552
- model_choose: ๋ชจ๋ธ ์„ ํƒ ('ft_transformer', 'resnet_like', 'deepgbm')
553
- region: ์ง€์—ญ๋ช…
554
- data_sample: ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ ํƒ€์ž… ('pure', 'smote', etc.)
555
- target: ํƒ€๊ฒŸ ํƒ€์ž… ('multi', 'binary')
556
- n_folds: ๊ต์ฐจ ๊ฒ€์ฆ fold ์ˆ˜
557
- random_state: ๋žœ๋ค ์‹œ๋“œ
558
-
559
- Returns:
560
- ์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ ๋ฆฌ์ŠคํŠธ
561
- """
562
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
563
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
564
-
565
- models = []
566
- scalers = [] # scaler ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€
567
-
568
- print("์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘...")
569
-
570
- for fold in range(1, n_folds + 1):
571
- print(f"Fold {fold} ํ•™์Šต ์ค‘...")
572
-
573
- # ์ตœ์ ํ™”๋œ batch_size ์‚ฌ์šฉ
574
- batch_size = best_params.get("batch_size", 64)
575
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, scaler = prepare_dataloader_with_batchsize(
576
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
577
- )
578
-
579
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
580
- if model_choose == "ft_transformer":
581
- d_token = best_params["d_token"]
582
- n_heads = best_params.get("n_heads", 8)
583
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
584
- if d_token % n_heads != 0:
585
- d_token = (d_token // n_heads) * n_heads
586
-
587
- model = FTTransformer(
588
- num_features=len(numerical_cols),
589
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
590
- d_token=d_token,
591
- n_blocks=best_params["n_blocks"],
592
- n_heads=n_heads,
593
- attention_dropout=best_params["attention_dropout"],
594
- ffn_dropout=best_params["ffn_dropout"],
595
- num_classes=3
596
- ).to(device)
597
- elif model_choose == 'resnet_like':
598
- input_dim = len(numerical_cols) + len(categorical_cols)
599
- model = ResNetLike(
600
- input_dim=input_dim,
601
- d_main=best_params["d_main"],
602
- d_hidden=best_params["d_hidden"],
603
- n_blocks=best_params["n_blocks"],
604
- dropout_first=best_params["dropout_first"],
605
- dropout_second=best_params["dropout_second"],
606
- num_classes=3
607
- ).to(device)
608
- elif model_choose == 'deepgbm':
609
- model = DeepGBM(
610
- num_features=len(numerical_cols),
611
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
612
- d_main=best_params["d_main"],
613
- d_hidden=best_params["d_hidden"],
614
- n_blocks=best_params["n_blocks"],
615
- dropout=best_params["dropout"],
616
- num_classes=3
617
- ).to(device)
618
- else:
619
- raise ValueError(f"Unknown model_choose: {model_choose}")
620
-
621
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
622
- if target == 'multi':
623
- class_weights = compute_class_weight(
624
- class_weight='balanced',
625
- classes=np.unique(y_train),
626
- y=y_train
627
- )
628
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
629
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
630
- else:
631
- criterion = nn.BCEWithLogitsLoss()
632
- optimizer = optim.AdamW(model.parameters(), lr=best_params["lr"], weight_decay=best_params["weight_decay"])
633
-
634
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ
635
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
636
-
637
- # ํ•™์Šต ์„ค์ •
638
- epochs = 200
639
- patience = 12
640
- best_fold_csi = 0
641
- counter = 0
642
- best_model = None
643
-
644
- for epoch in range(epochs):
645
- model.train()
646
- for x_num_batch, x_cat_batch, y_batch in train_loader:
647
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
648
-
649
- optimizer.zero_grad()
650
- y_pred = model(x_num_batch, x_cat_batch)
651
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
652
- loss.backward()
653
- optimizer.step()
654
-
655
- # Validation ํ‰๊ฐ€
656
- model.eval()
657
- y_pred_val, y_true_val = [], []
658
- with torch.no_grad():
659
- for x_num_batch, x_cat_batch, y_batch in val_loader:
660
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
661
- output = model(x_num_batch, x_cat_batch)
662
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
663
-
664
- y_pred_val.extend(pred.cpu().numpy())
665
- y_true_val.extend(y_batch.cpu().numpy())
666
-
667
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
668
- val_csi = calculate_csi(y_true_val, y_pred_val)
669
- scheduler.step(val_csi)
670
-
671
- # Early Stopping ์ฒดํฌ
672
- if val_csi > best_fold_csi:
673
- best_fold_csi = val_csi
674
- counter = 0
675
- best_model = copy.deepcopy(model)
676
- else:
677
- counter += 1
678
-
679
- if counter >= patience:
680
- print(f" Early stopping at epoch {epoch+1}, Best CSI: {best_fold_csi:.4f}")
681
- break
682
-
683
- if best_model is None:
684
- best_model = model
685
-
686
- scalers.append(scaler) # scaler ์ €์žฅ (fold ์ˆœ์„œ๋Œ€๋กœ)
687
- models.append(best_model)
688
- print(f" Fold {fold} ํ•™์Šต ์™„๋ฃŒ (๊ฒ€์ฆ CSI: {best_fold_csi:.4f})")
689
-
690
- # ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •
691
- save_dir = f'../save_model/{model_choose}_optima'
692
- os.makedirs(save_dir, exist_ok=True)
693
-
694
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ
695
- if data_sample == 'pure':
696
- model_filename = f'{model_choose}_pure_{region}.pkl'
697
- else:
698
- model_filename = f'{model_choose}_{data_sample}_{region}.pkl'
699
-
700
- model_path = f'{save_dir}/{model_filename}'
701
-
702
- # ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„ ํ•œ ๋ฒˆ์— ์ €์žฅ
703
- joblib.dump(models, model_path)
704
- print(f"\n๋ชจ๋“  ๋ชจ๋ธ ์ €์žฅ ์™„๋ฃŒ: {model_path} (์ด {len(models)}๊ฐœ fold)")
705
-
706
- # Scaler ๋ณ„๋„ ์ €์žฅ
707
- scaler_save_dir = f'../save_model/{model_choose}_optima/scaler'
708
- os.makedirs(scaler_save_dir, exist_ok=True)
709
-
710
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ (๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํŒจํ„ด)
711
- if data_sample == 'pure':
712
- scaler_filename = f'{model_choose}_pure_{region}_scaler.pkl'
713
- else:
714
- scaler_filename = f'{model_choose}_{data_sample}_{region}_scaler.pkl'
715
-
716
- scaler_path = f'{scaler_save_dir}/{scaler_filename}'
717
- joblib.dump(scalers, scaler_path)
718
- print(f"Scaler ์ €์žฅ ์™„๋ฃŒ: {scaler_path} (์ด {len(scalers)}๊ฐœ fold)")
719
-
720
- return model_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_busan.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="busan", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smote_busan_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="busan",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_daegu.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daegu", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smote_daegu_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daegu",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_daejeon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daejeon", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smote_daejeon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daejeon",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_gwangju.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="gwangju", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smote_gwangju_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="gwangju",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_incheon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="incheon", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smote_incheon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="incheon",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smote/deepgbm_smote_seoul.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="seoul", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smote_seoul_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="seoul",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smote/utils.py DELETED
@@ -1,720 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.optim as optim
4
- import numpy as np
5
- import random
6
- import os
7
- import copy
8
- from sklearn.preprocessing import QuantileTransformer, LabelEncoder
9
- from torch.utils.data import DataLoader, TensorDataset
10
- from sklearn.metrics import confusion_matrix
11
- from sklearn.utils.class_weight import compute_class_weight
12
- import pandas as pd
13
- import optuna
14
- from sklearn.metrics import accuracy_score, f1_score
15
- import joblib
16
-
17
-
18
- import sys
19
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ models ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
20
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
21
- models_path = os.path.abspath(os.path.join(current_file_dir, '../../models'))
22
- sys.path.insert(0, models_path)
23
- from ft_transformer import FTTransformer
24
- from resnet_like import ResNetLike
25
- from deepgbm import DeepGBM
26
- import warnings
27
- warnings.filterwarnings('ignore')
28
-
29
-
30
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
31
- seed = 42
32
- random.seed(seed)
33
- np.random.seed(seed)
34
-
35
- # PyTorch ์‹œ๋“œ ๊ณ ์ •
36
- torch.manual_seed(seed)
37
- torch.cuda.manual_seed(seed)
38
- torch.cuda.manual_seed_all(seed) # Multi-GPU ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ์‹œ๋“œ ์ ์šฉ
39
-
40
- # PyTorch ์—ฐ์‚ฐ์˜ ๊ฒฐ์ •์  ๋ชจ๋“œ ์„ค์ •
41
- torch.backends.cudnn.deterministic = True # ์‹คํ–‰๋งˆ๋‹ค ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ
42
- torch.backends.cudnn.benchmark = True # ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™” (๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅธ ์—ฐ์‚ฐ ์ˆ˜ํ–‰)
43
-
44
-
45
- def add_derived_features(df: pd.DataFrame) -> pd.DataFrame:
46
- """
47
- ์ œ๊ฑฐํ–ˆ๋˜ ํŒŒ์ƒ ๋ณ€์ˆ˜๋“ค์„ ๋ณต๊ตฌ
48
-
49
- Args:
50
- df: ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
51
-
52
- Returns:
53
- ํŒŒ์ƒ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
54
- """
55
- df = df.copy()
56
- df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
57
- df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
58
- df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
59
- df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
60
- df['ground_temp - temp_C'] = df['groundtemp'] - df['temp_C']
61
- return df
62
-
63
- def preprocessing(df):
64
- """๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜.
65
-
66
- Args:
67
- df: ์›๋ณธ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
68
-
69
- Returns:
70
- ์ „์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
71
- """
72
- df = df[df.columns].copy()
73
- df['year'] = df['year'].astype('int')
74
- df['month'] = df['month'].astype('int')
75
- df['hour'] = df['hour'].astype('int')
76
- df = add_derived_features(df).copy()
77
- df['multi_class'] = df['multi_class'].astype('int')
78
- df.loc[df['wind_dir']=='์ •์˜จ', 'wind_dir'] = "0"
79
- df['wind_dir'] = df['wind_dir'].astype('int')
80
- df = df[['temp_C', 'precip_mm', 'wind_speed', 'wind_dir', 'hm',
81
- 'vap_pressure', 'dewpoint_C', 'loc_pressure', 'sea_pressure',
82
- 'solarRad', 'snow_cm', 'cloudcover', 'lm_cloudcover', 'low_cloudbase',
83
- 'groundtemp', 'O3', 'NO2', 'PM10', 'PM25', 'year',
84
- 'month', 'hour', 'ground_temp - temp_C', 'hour_sin', 'hour_cos',
85
- 'month_sin', 'month_cos','multi_class']].copy()
86
- return df
87
-
88
-
89
- # ๋ฐ์ดํ„ฐ์…‹ ์ค€๋น„ ํ•จ์ˆ˜
90
- def prepare_dataset(region, data_sample='pure', target='multi', fold=3):
91
-
92
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
93
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
94
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
95
-
96
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
97
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
98
- if data_sample == 'pure':
99
- train_path = dat_path
100
- else:
101
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
102
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
103
- drop_col = ['multi_class','year']
104
- target_col = f'{target}_class'
105
-
106
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
107
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
108
- if data_sample == 'pure':
109
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
110
- else:
111
- region_train = preprocessing(pd.read_csv(train_path))
112
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
113
- region_test = preprocessing(pd.read_csv(test_path))
114
-
115
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
116
- common_columns = region_train.columns.to_list()
117
- train_data = region_train[common_columns]
118
- val_data = region_val[common_columns]
119
- test_data = region_test[common_columns]
120
-
121
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
122
- X_train = train_data.drop(columns=drop_col)
123
- y_train = train_data[target_col]
124
- X_val = val_data.drop(columns=drop_col)
125
- y_val = val_data[target_col]
126
- X_test = test_data.drop(columns=drop_col)
127
- y_test = test_data[target_col]
128
-
129
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
130
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
131
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
132
-
133
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
134
- label_encoders = {}
135
- for col in categorical_cols:
136
- le = LabelEncoder()
137
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
138
- label_encoders[col] = le
139
-
140
- # ๋ณ€ํ™˜ ์ ์šฉ
141
- for col in categorical_cols:
142
- X_train[col] = label_encoders[col].transform(X_train[col])
143
- X_val[col] = label_encoders[col].transform(X_val[col])
144
- X_test[col] = label_encoders[col].transform(X_test[col])
145
-
146
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
147
- scaler = QuantileTransformer(output_distribution='normal')
148
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
149
-
150
- # ๋ณ€ํ™˜ ์ ์šฉ
151
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
152
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
153
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
154
-
155
- return X_train, X_val, X_test, y_train, y_val, y_test, categorical_cols, numerical_cols
156
-
157
-
158
-
159
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜
160
- def prepare_dataloader(region, data_sample='pure', target='multi', fold=3, random_state=None):
161
-
162
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
163
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
164
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
165
-
166
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
167
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
168
- if data_sample == 'pure':
169
- train_path = dat_path
170
- else:
171
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
172
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
173
- drop_col = ['multi_class','year']
174
- target_col = f'{target}_class'
175
-
176
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
177
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
178
- if data_sample == 'pure':
179
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
180
- else:
181
- region_train = preprocessing(pd.read_csv(train_path))
182
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
183
- region_test = preprocessing(pd.read_csv(test_path))
184
-
185
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
186
- common_columns = region_train.columns.to_list()
187
- train_data = region_train[common_columns]
188
- val_data = region_val[common_columns]
189
- test_data = region_test[common_columns]
190
-
191
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
192
- X_train = train_data.drop(columns=drop_col)
193
- y_train = train_data[target_col]
194
- X_val = val_data.drop(columns=drop_col)
195
- y_val = val_data[target_col]
196
- X_test = test_data.drop(columns=drop_col)
197
- y_test = test_data[target_col]
198
-
199
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
200
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
201
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
202
-
203
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
204
- label_encoders = {}
205
- for col in categorical_cols:
206
- le = LabelEncoder()
207
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
208
- label_encoders[col] = le
209
-
210
- # ๋ณ€ํ™˜ ์ ์šฉ
211
- for col in categorical_cols:
212
- X_train[col] = label_encoders[col].transform(X_train[col])
213
- X_val[col] = label_encoders[col].transform(X_val[col])
214
- X_test[col] = label_encoders[col].transform(X_test[col])
215
-
216
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
217
- scaler = QuantileTransformer(output_distribution='normal')
218
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
219
-
220
- # ๋ณ€ํ™˜ ์ ์šฉ
221
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
222
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
223
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
224
-
225
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
226
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
227
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
228
-
229
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
230
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
231
-
232
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
233
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
234
-
235
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
236
- if target == "binary":
237
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
238
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
239
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
240
- elif target == "multi":
241
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
242
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
243
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
244
- else:
245
- raise ValueError("target must be 'binary' or 'multi'")
246
-
247
- # TensorDataset ์ƒ์„ฑ
248
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
249
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
250
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
251
-
252
- # DataLoader ์ƒ์„ฑ
253
- if random_state == None:
254
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
255
- else:
256
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(random_state))
257
- val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
258
- test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
259
-
260
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader
261
-
262
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๋ฒ„์ „)
263
- def prepare_dataloader_with_batchsize(region, data_sample='pure', target='multi', fold=3, random_state=None, batch_size=64):
264
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
265
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
266
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
267
-
268
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
269
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
270
- if data_sample == 'pure':
271
- train_path = dat_path
272
- else:
273
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
274
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
275
- drop_col = ['multi_class','year']
276
- target_col = f'{target}_class'
277
-
278
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
279
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
280
- if data_sample == 'pure':
281
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
282
- else:
283
- region_train = preprocessing(pd.read_csv(train_path))
284
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
285
- region_test = preprocessing(pd.read_csv(test_path))
286
-
287
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
288
- common_columns = region_train.columns.to_list()
289
- train_data = region_train[common_columns]
290
- val_data = region_val[common_columns]
291
- test_data = region_test[common_columns]
292
-
293
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
294
- X_train = train_data.drop(columns=drop_col)
295
- y_train = train_data[target_col]
296
- X_val = val_data.drop(columns=drop_col)
297
- y_val = val_data[target_col]
298
- X_test = test_data.drop(columns=drop_col)
299
- y_test = test_data[target_col]
300
-
301
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
302
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
303
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
304
-
305
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
306
- label_encoders = {}
307
- for col in categorical_cols:
308
- le = LabelEncoder()
309
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
310
- label_encoders[col] = le
311
-
312
- # ๋ณ€ํ™˜ ์ ์šฉ
313
- for col in categorical_cols:
314
- X_train[col] = label_encoders[col].transform(X_train[col])
315
- X_val[col] = label_encoders[col].transform(X_val[col])
316
- X_test[col] = label_encoders[col].transform(X_test[col])
317
-
318
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
319
- scaler = QuantileTransformer(output_distribution='normal')
320
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
321
-
322
- # ๋ณ€ํ™˜ ์ ์šฉ
323
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
324
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
325
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
326
-
327
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
328
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
329
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
330
-
331
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
332
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
333
-
334
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
335
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
336
-
337
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
338
- if target == "binary":
339
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
340
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
341
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
342
- elif target == "multi":
343
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
344
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
345
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
346
- else:
347
- raise ValueError("target must be 'binary' or 'multi'")
348
-
349
- # TensorDataset ์ƒ์„ฑ
350
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
351
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
352
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
353
-
354
- # DataLoader ์ƒ์„ฑ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ)
355
- if random_state == None:
356
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
357
- else:
358
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(random_state))
359
- val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
360
- test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
361
-
362
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader, y_train, scaler
363
-
364
-
365
- def calculate_csi(y_true, pred):
366
-
367
- cm = confusion_matrix(y_true, pred) # ๋ณ€์ˆ˜ ์ด๋ฆ„์„ cm์œผ๋กœ ๋ณ€๊ฒฝ
368
- # ํ˜ผ๋™ ํ–‰๋ ฌ์—์„œ H, F, M ์ถ”์ถœ
369
- H = (cm[0, 0] + cm[1, 1])
370
-
371
- F = (cm[1, 0] + cm[2, 0] +
372
- cm[0, 1] + cm[2, 1])
373
-
374
- M = (cm[0, 2] + cm[1, 2])
375
-
376
- # CSI ๊ณ„์‚ฐ
377
- CSI = H / (H + F + M + 1e-10)
378
- return CSI
379
-
380
- def sample_weight(y_train):
381
- class_weights = compute_class_weight(
382
- class_weight='balanced',
383
- classes=np.unique(y_train), # ๊ณ ์œ  ํด๋ž˜์Šค
384
- y=y_train # ํ•™์Šต ๋ฐ์ดํ„ฐ ๋ ˆ์ด๋ธ”
385
- )
386
- sample_weights = np.array([class_weights[label] for label in y_train])
387
-
388
- return sample_weights
389
-
390
- # ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ •์˜
391
- def objective(trial, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
392
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
393
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
394
- val_scores = []
395
-
396
- # --- 1. ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰ ๋ฒ”์œ„ ์ •์˜ (์ˆ˜์ •๋จ) ---
397
- if model_choose == "ft_transformer":
398
- d_token = trial.suggest_int("d_token", 64, 256, step=32)
399
- n_blocks = trial.suggest_int("n_blocks", 2, 6) # ๊นŠ์ด ์ถ•์†Œ๋กœ ๊ณผ์ ํ•ฉ ๋ฐฉ์ง€
400
- n_heads = trial.suggest_categorical("n_heads", [4, 8])
401
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
402
- if d_token % n_heads != 0:
403
- d_token = (d_token // n_heads) * n_heads
404
-
405
- attention_dropout = trial.suggest_float("attention_dropout", 0.1, 0.4)
406
- ffn_dropout = trial.suggest_float("ffn_dropout", 0.1, 0.4)
407
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True) # ๋ฒ”์œ„ ํ™•๋Œ€
408
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
409
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
410
-
411
- elif model_choose == 'resnet_like':
412
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
413
- d_hidden = trial.suggest_int("d_hidden", 64, 512, step=64)
414
- n_blocks = trial.suggest_int("n_blocks", 2, 5) # ๋„ˆ๋ฌด ๊นŠ์ง€ ์•Š๊ฒŒ ์กฐ์ ˆ
415
- dropout_first = trial.suggest_float("dropout_first", 0.1, 0.4)
416
- dropout_second = trial.suggest_float("dropout_second", 0.0, 0.2)
417
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
418
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
419
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
420
-
421
- elif model_choose == 'deepgbm':
422
- # DeepGBM์˜ ๊ฒฝ์šฐ ๋ชจ๋ธ ํŠน์„ฑ์— ๋งž์ถฐ ResNet ๋ธ”๋ก ๋ฐ ์ž„๋ฒ ๋”ฉ ์ฐจ์› ์กฐ์ ˆ
423
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
424
- d_hidden = trial.suggest_int("d_hidden", 64, 256, step=64)
425
- n_blocks = trial.suggest_int("n_blocks", 2, 6)
426
- dropout = trial.suggest_float("dropout", 0.1, 0.4)
427
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
428
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
429
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
430
-
431
- # --- 2. Fold๋ณ„ ํ•™์Šต ๋ฐ ๊ต์ฐจ ๊ฒ€์ฆ ---
432
- for fold in range(1, n_folds + 1):
433
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, _ = prepare_dataloader_with_batchsize(
434
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
435
- )
436
-
437
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
438
- if model_choose == "ft_transformer":
439
- model = FTTransformer(
440
- num_features=len(numerical_cols),
441
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
442
- d_token=d_token,
443
- n_blocks=n_blocks,
444
- n_heads=n_heads,
445
- attention_dropout=attention_dropout,
446
- ffn_dropout=ffn_dropout,
447
- num_classes=3
448
- ).to(device)
449
- elif model_choose == 'resnet_like':
450
- input_dim = len(numerical_cols) + len(categorical_cols)
451
- model = ResNetLike(
452
- input_dim=input_dim,
453
- d_main=d_main,
454
- d_hidden=d_hidden,
455
- n_blocks=n_blocks,
456
- dropout_first=dropout_first,
457
- dropout_second=dropout_second,
458
- num_classes=3
459
- ).to(device)
460
- elif model_choose == 'deepgbm':
461
- model = DeepGBM(
462
- num_features=len(numerical_cols),
463
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
464
- d_main=d_main,
465
- d_hidden=d_hidden,
466
- n_blocks=n_blocks,
467
- dropout=dropout,
468
- num_classes=3
469
- ).to(device)
470
-
471
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
472
- if target == 'multi':
473
- class_weights = compute_class_weight(
474
- class_weight='balanced',
475
- classes=np.unique(y_train),
476
- y=y_train
477
- )
478
- # ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜ ๋กœ๊ทธ ์ถœ๋ ฅ
479
- unique_classes = np.unique(y_train)
480
- class_counts = {cls: np.sum(y_train == cls) for cls in unique_classes}
481
- print(f" Fold {fold} - ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜: {dict(zip(unique_classes, class_weights))} (ํด๋ž˜์Šค๋ณ„ ์ƒ˜ํ”Œ ์ˆ˜: {class_counts})")
482
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
483
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
484
- else:
485
- criterion = nn.BCEWithLogitsLoss()
486
- optimizer = optim.AdamW(model.parameters(), lr=lr, weight_decay=weight_decay)
487
-
488
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ ์ถ”๊ฐ€: ์„ฑ๋Šฅ ์ •์ฒด ์‹œ LR์„ 0.5๋ฐฐ ๊ฐ์†Œ (๊ฒ€์ฆ CSI ๊ธฐ์ค€)
489
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
490
-
491
- # ํ•™์Šต ์„ค์ • (์—ํญ ๋ฐ ํŽ˜์ด์…˜์Šค ์ƒํ–ฅ)
492
- epochs = 200
493
- patience = 12 # ๋”ฅ๋Ÿฌ๋‹์˜ ์ •์ฒด ๊ตฌ๊ฐ„์„ ๊ณ ๋ คํ•˜์—ฌ ์†Œํญ ์ƒํ–ฅ
494
- best_fold_csi = 0
495
- counter = 0
496
-
497
- for epoch in range(epochs):
498
- model.train()
499
- for x_num_batch, x_cat_batch, y_batch in train_loader:
500
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
501
-
502
- optimizer.zero_grad()
503
- y_pred = model(x_num_batch, x_cat_batch)
504
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
505
- loss.backward()
506
- optimizer.step()
507
-
508
- # Validation ํ‰๊ฐ€
509
- model.eval()
510
- y_pred_val, y_true_val = [], []
511
- with torch.no_grad():
512
- for x_num_batch, x_cat_batch, y_batch in val_loader:
513
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
514
- output = model(x_num_batch, x_cat_batch)
515
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
516
-
517
- y_pred_val.extend(pred.cpu().numpy())
518
- y_true_val.extend(y_batch.cpu().numpy())
519
-
520
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
521
- val_csi = calculate_csi(y_true_val, y_pred_val)
522
- scheduler.step(val_csi)
523
-
524
- # Optuna Pruning ์ ์šฉ (์ฒซ ๋ฒˆ์งธ Fold์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ ํŒ๋‹จ ๊ฐ•ํ™”)
525
- trial.report(val_csi, epoch)
526
- if trial.should_prune():
527
- raise optuna.exceptions.TrialPruned()
528
-
529
- # Early Stopping ์ฒดํฌ
530
- if val_csi > best_fold_csi:
531
- best_fold_csi = val_csi
532
- counter = 0
533
- else:
534
- counter += 1
535
-
536
- if counter >= patience:
537
- break
538
-
539
- val_scores.append(best_fold_csi)
540
-
541
- # ๋ชจ๋“  fold์˜ ํ‰๊ท  ์„ฑ๋Šฅ ๋ฐ˜ํ™˜
542
- return np.mean(val_scores)
543
-
544
-
545
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ํ•จ์ˆ˜
546
- def train_final_model(best_params, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
547
- """
548
- ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
549
-
550
- Args:
551
- best_params: ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ
552
- model_choose: ๋ชจ๋ธ ์„ ํƒ ('ft_transformer', 'resnet_like', 'deepgbm')
553
- region: ์ง€์—ญ๋ช…
554
- data_sample: ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ ํƒ€์ž… ('pure', 'smote', etc.)
555
- target: ํƒ€๊ฒŸ ํƒ€์ž… ('multi', 'binary')
556
- n_folds: ๊ต์ฐจ ๊ฒ€์ฆ fold ์ˆ˜
557
- random_state: ๋žœ๋ค ์‹œ๋“œ
558
-
559
- Returns:
560
- ์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ ๋ฆฌ์ŠคํŠธ
561
- """
562
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
563
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
564
-
565
- models = []
566
- scalers = [] # scaler ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€
567
-
568
- print("์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘...")
569
-
570
- for fold in range(1, n_folds + 1):
571
- print(f"Fold {fold} ํ•™์Šต ์ค‘...")
572
-
573
- # ์ตœ์ ํ™”๋œ batch_size ์‚ฌ์šฉ
574
- batch_size = best_params.get("batch_size", 64)
575
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, scaler = prepare_dataloader_with_batchsize(
576
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
577
- )
578
-
579
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
580
- if model_choose == "ft_transformer":
581
- d_token = best_params["d_token"]
582
- n_heads = best_params.get("n_heads", 8)
583
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
584
- if d_token % n_heads != 0:
585
- d_token = (d_token // n_heads) * n_heads
586
-
587
- model = FTTransformer(
588
- num_features=len(numerical_cols),
589
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
590
- d_token=d_token,
591
- n_blocks=best_params["n_blocks"],
592
- n_heads=n_heads,
593
- attention_dropout=best_params["attention_dropout"],
594
- ffn_dropout=best_params["ffn_dropout"],
595
- num_classes=3
596
- ).to(device)
597
- elif model_choose == 'resnet_like':
598
- input_dim = len(numerical_cols) + len(categorical_cols)
599
- model = ResNetLike(
600
- input_dim=input_dim,
601
- d_main=best_params["d_main"],
602
- d_hidden=best_params["d_hidden"],
603
- n_blocks=best_params["n_blocks"],
604
- dropout_first=best_params["dropout_first"],
605
- dropout_second=best_params["dropout_second"],
606
- num_classes=3
607
- ).to(device)
608
- elif model_choose == 'deepgbm':
609
- model = DeepGBM(
610
- num_features=len(numerical_cols),
611
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
612
- d_main=best_params["d_main"],
613
- d_hidden=best_params["d_hidden"],
614
- n_blocks=best_params["n_blocks"],
615
- dropout=best_params["dropout"],
616
- num_classes=3
617
- ).to(device)
618
- else:
619
- raise ValueError(f"Unknown model_choose: {model_choose}")
620
-
621
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
622
- if target == 'multi':
623
- class_weights = compute_class_weight(
624
- class_weight='balanced',
625
- classes=np.unique(y_train),
626
- y=y_train
627
- )
628
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
629
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
630
- else:
631
- criterion = nn.BCEWithLogitsLoss()
632
- optimizer = optim.AdamW(model.parameters(), lr=best_params["lr"], weight_decay=best_params["weight_decay"])
633
-
634
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ
635
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
636
-
637
- # ํ•™์Šต ์„ค์ •
638
- epochs = 200
639
- patience = 12
640
- best_fold_csi = 0
641
- counter = 0
642
- best_model = None
643
-
644
- for epoch in range(epochs):
645
- model.train()
646
- for x_num_batch, x_cat_batch, y_batch in train_loader:
647
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
648
-
649
- optimizer.zero_grad()
650
- y_pred = model(x_num_batch, x_cat_batch)
651
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
652
- loss.backward()
653
- optimizer.step()
654
-
655
- # Validation ํ‰๊ฐ€
656
- model.eval()
657
- y_pred_val, y_true_val = [], []
658
- with torch.no_grad():
659
- for x_num_batch, x_cat_batch, y_batch in val_loader:
660
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
661
- output = model(x_num_batch, x_cat_batch)
662
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
663
-
664
- y_pred_val.extend(pred.cpu().numpy())
665
- y_true_val.extend(y_batch.cpu().numpy())
666
-
667
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
668
- val_csi = calculate_csi(y_true_val, y_pred_val)
669
- scheduler.step(val_csi)
670
-
671
- # Early Stopping ์ฒดํฌ
672
- if val_csi > best_fold_csi:
673
- best_fold_csi = val_csi
674
- counter = 0
675
- best_model = copy.deepcopy(model)
676
- else:
677
- counter += 1
678
-
679
- if counter >= patience:
680
- print(f" Early stopping at epoch {epoch+1}, Best CSI: {best_fold_csi:.4f}")
681
- break
682
-
683
- if best_model is None:
684
- best_model = model
685
-
686
- scalers.append(scaler) # scaler ์ €์žฅ (fold ์ˆœ์„œ๋Œ€๋กœ)
687
- models.append(best_model)
688
- print(f" Fold {fold} ํ•™์Šต ์™„๋ฃŒ (๊ฒ€์ฆ CSI: {best_fold_csi:.4f})")
689
-
690
- # ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •
691
- save_dir = f'../save_model/{model_choose}_optima'
692
- os.makedirs(save_dir, exist_ok=True)
693
-
694
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ
695
- if data_sample == 'pure':
696
- model_filename = f'{model_choose}_pure_{region}.pkl'
697
- else:
698
- model_filename = f'{model_choose}_{data_sample}_{region}.pkl'
699
-
700
- model_path = f'{save_dir}/{model_filename}'
701
-
702
- # ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„ ํ•œ ๋ฒˆ์— ์ €์žฅ
703
- joblib.dump(models, model_path)
704
- print(f"\n๋ชจ๋“  ๋ชจ๋ธ ์ €์žฅ ์™„๋ฃŒ: {model_path} (์ด {len(models)}๊ฐœ fold)")
705
-
706
- # Scaler ๋ณ„๋„ ์ €์žฅ
707
- scaler_save_dir = f'../save_model/{model_choose}_optima/scaler'
708
- os.makedirs(scaler_save_dir, exist_ok=True)
709
-
710
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ (๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํŒจํ„ด)
711
- if data_sample == 'pure':
712
- scaler_filename = f'{model_choose}_pure_{region}_scaler.pkl'
713
- else:
714
- scaler_filename = f'{model_choose}_{data_sample}_{region}_scaler.pkl'
715
-
716
- scaler_path = f'{scaler_save_dir}/{scaler_filename}'
717
- joblib.dump(scalers, scaler_path)
718
- print(f"Scaler ์ €์žฅ ์™„๋ฃŒ: {scaler_path} (์ด {len(scalers)}๊ฐœ fold)")
719
-
720
- return model_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_busan.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="busan", data_sample='smotenc_ctgan20000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smotenc_ctgan20000_busan_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="busan",
80
- data_sample='smotenc_ctgan20000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_daegu.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daegu", data_sample='smotenc_ctgan20000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smotenc_ctgan20000_daegu_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daegu",
80
- data_sample='smotenc_ctgan20000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_daejeon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="daejeon", data_sample='smotenc_ctgan20000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smotenc_ctgan20000_daejeon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="daejeon",
80
- data_sample='smotenc_ctgan20000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_gwangju.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="gwangju", data_sample='smotenc_ctgan20000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smotenc_ctgan20000_gwangju_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="gwangju",
80
- data_sample='smotenc_ctgan20000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_incheon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="incheon", data_sample='smotenc_ctgan20000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smotenc_ctgan20000_incheon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="incheon",
80
- data_sample='smotenc_ctgan20000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/deepgbm_smotenc_ctgan20000_seoul.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="deepgbm", region="seoul", data_sample='smotenc_ctgan20000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/deepgbm_smotenc_ctgan20000_seoul_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="deepgbm",
79
- region="seoul",
80
- data_sample='smotenc_ctgan20000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/deepgbm_smotenc_ctgan20000/utils.py DELETED
@@ -1,720 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.optim as optim
4
- import numpy as np
5
- import random
6
- import os
7
- import copy
8
- from sklearn.preprocessing import QuantileTransformer, LabelEncoder
9
- from torch.utils.data import DataLoader, TensorDataset
10
- from sklearn.metrics import confusion_matrix
11
- from sklearn.utils.class_weight import compute_class_weight
12
- import pandas as pd
13
- import optuna
14
- from sklearn.metrics import accuracy_score, f1_score
15
- import joblib
16
-
17
-
18
- import sys
19
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ models ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
20
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
21
- models_path = os.path.abspath(os.path.join(current_file_dir, '../../models'))
22
- sys.path.insert(0, models_path)
23
- from ft_transformer import FTTransformer
24
- from resnet_like import ResNetLike
25
- from deepgbm import DeepGBM
26
- import warnings
27
- warnings.filterwarnings('ignore')
28
-
29
-
30
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
31
- seed = 42
32
- random.seed(seed)
33
- np.random.seed(seed)
34
-
35
- # PyTorch ์‹œ๋“œ ๊ณ ์ •
36
- torch.manual_seed(seed)
37
- torch.cuda.manual_seed(seed)
38
- torch.cuda.manual_seed_all(seed) # Multi-GPU ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ์‹œ๋“œ ์ ์šฉ
39
-
40
- # PyTorch ์—ฐ์‚ฐ์˜ ๊ฒฐ์ •์  ๋ชจ๋“œ ์„ค์ •
41
- torch.backends.cudnn.deterministic = True # ์‹คํ–‰๋งˆ๋‹ค ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ
42
- torch.backends.cudnn.benchmark = True # ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™” (๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅธ ์—ฐ์‚ฐ ์ˆ˜ํ–‰)
43
-
44
-
45
- def add_derived_features(df: pd.DataFrame) -> pd.DataFrame:
46
- """
47
- ์ œ๊ฑฐํ–ˆ๋˜ ํŒŒ์ƒ ๋ณ€์ˆ˜๋“ค์„ ๋ณต๊ตฌ
48
-
49
- Args:
50
- df: ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
51
-
52
- Returns:
53
- ํŒŒ์ƒ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
54
- """
55
- df = df.copy()
56
- df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
57
- df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
58
- df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
59
- df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
60
- df['ground_temp - temp_C'] = df['groundtemp'] - df['temp_C']
61
- return df
62
-
63
- def preprocessing(df):
64
- """๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜.
65
-
66
- Args:
67
- df: ์›๋ณธ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
68
-
69
- Returns:
70
- ์ „์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
71
- """
72
- df = df[df.columns].copy()
73
- df['year'] = df['year'].astype('int')
74
- df['month'] = df['month'].astype('int')
75
- df['hour'] = df['hour'].astype('int')
76
- df = add_derived_features(df).copy()
77
- df['multi_class'] = df['multi_class'].astype('int')
78
- df.loc[df['wind_dir']=='์ •์˜จ', 'wind_dir'] = "0"
79
- df['wind_dir'] = df['wind_dir'].astype('int')
80
- df = df[['temp_C', 'precip_mm', 'wind_speed', 'wind_dir', 'hm',
81
- 'vap_pressure', 'dewpoint_C', 'loc_pressure', 'sea_pressure',
82
- 'solarRad', 'snow_cm', 'cloudcover', 'lm_cloudcover', 'low_cloudbase',
83
- 'groundtemp', 'O3', 'NO2', 'PM10', 'PM25', 'year',
84
- 'month', 'hour', 'ground_temp - temp_C', 'hour_sin', 'hour_cos',
85
- 'month_sin', 'month_cos','multi_class']].copy()
86
- return df
87
-
88
-
89
- # ๋ฐ์ดํ„ฐ์…‹ ์ค€๋น„ ํ•จ์ˆ˜
90
- def prepare_dataset(region, data_sample='pure', target='multi', fold=3):
91
-
92
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
93
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
94
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
95
-
96
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
97
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
98
- if data_sample == 'pure':
99
- train_path = dat_path
100
- else:
101
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
102
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
103
- drop_col = ['multi_class','year']
104
- target_col = f'{target}_class'
105
-
106
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
107
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
108
- if data_sample == 'pure':
109
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
110
- else:
111
- region_train = preprocessing(pd.read_csv(train_path))
112
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
113
- region_test = preprocessing(pd.read_csv(test_path))
114
-
115
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
116
- common_columns = region_train.columns.to_list()
117
- train_data = region_train[common_columns]
118
- val_data = region_val[common_columns]
119
- test_data = region_test[common_columns]
120
-
121
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
122
- X_train = train_data.drop(columns=drop_col)
123
- y_train = train_data[target_col]
124
- X_val = val_data.drop(columns=drop_col)
125
- y_val = val_data[target_col]
126
- X_test = test_data.drop(columns=drop_col)
127
- y_test = test_data[target_col]
128
-
129
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
130
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
131
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
132
-
133
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
134
- label_encoders = {}
135
- for col in categorical_cols:
136
- le = LabelEncoder()
137
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
138
- label_encoders[col] = le
139
-
140
- # ๋ณ€ํ™˜ ์ ์šฉ
141
- for col in categorical_cols:
142
- X_train[col] = label_encoders[col].transform(X_train[col])
143
- X_val[col] = label_encoders[col].transform(X_val[col])
144
- X_test[col] = label_encoders[col].transform(X_test[col])
145
-
146
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
147
- scaler = QuantileTransformer(output_distribution='normal')
148
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
149
-
150
- # ๋ณ€ํ™˜ ์ ์šฉ
151
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
152
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
153
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
154
-
155
- return X_train, X_val, X_test, y_train, y_val, y_test, categorical_cols, numerical_cols
156
-
157
-
158
-
159
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜
160
- def prepare_dataloader(region, data_sample='pure', target='multi', fold=3, random_state=None):
161
-
162
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
163
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
164
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
165
-
166
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
167
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
168
- if data_sample == 'pure':
169
- train_path = dat_path
170
- else:
171
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
172
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
173
- drop_col = ['multi_class','year']
174
- target_col = f'{target}_class'
175
-
176
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
177
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
178
- if data_sample == 'pure':
179
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
180
- else:
181
- region_train = preprocessing(pd.read_csv(train_path))
182
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
183
- region_test = preprocessing(pd.read_csv(test_path))
184
-
185
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
186
- common_columns = region_train.columns.to_list()
187
- train_data = region_train[common_columns]
188
- val_data = region_val[common_columns]
189
- test_data = region_test[common_columns]
190
-
191
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
192
- X_train = train_data.drop(columns=drop_col)
193
- y_train = train_data[target_col]
194
- X_val = val_data.drop(columns=drop_col)
195
- y_val = val_data[target_col]
196
- X_test = test_data.drop(columns=drop_col)
197
- y_test = test_data[target_col]
198
-
199
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
200
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
201
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
202
-
203
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
204
- label_encoders = {}
205
- for col in categorical_cols:
206
- le = LabelEncoder()
207
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
208
- label_encoders[col] = le
209
-
210
- # ๋ณ€ํ™˜ ์ ์šฉ
211
- for col in categorical_cols:
212
- X_train[col] = label_encoders[col].transform(X_train[col])
213
- X_val[col] = label_encoders[col].transform(X_val[col])
214
- X_test[col] = label_encoders[col].transform(X_test[col])
215
-
216
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
217
- scaler = QuantileTransformer(output_distribution='normal')
218
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
219
-
220
- # ๋ณ€ํ™˜ ์ ์šฉ
221
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
222
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
223
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
224
-
225
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
226
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
227
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
228
-
229
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
230
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
231
-
232
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
233
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
234
-
235
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
236
- if target == "binary":
237
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
238
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
239
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
240
- elif target == "multi":
241
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
242
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
243
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
244
- else:
245
- raise ValueError("target must be 'binary' or 'multi'")
246
-
247
- # TensorDataset ์ƒ์„ฑ
248
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
249
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
250
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
251
-
252
- # DataLoader ์ƒ์„ฑ
253
- if random_state == None:
254
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
255
- else:
256
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(random_state))
257
- val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
258
- test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
259
-
260
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader
261
-
262
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๋ฒ„์ „)
263
- def prepare_dataloader_with_batchsize(region, data_sample='pure', target='multi', fold=3, random_state=None, batch_size=64):
264
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
265
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
266
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
267
-
268
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
269
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
270
- if data_sample == 'pure':
271
- train_path = dat_path
272
- else:
273
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
274
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
275
- drop_col = ['multi_class','year']
276
- target_col = f'{target}_class'
277
-
278
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
279
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
280
- if data_sample == 'pure':
281
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
282
- else:
283
- region_train = preprocessing(pd.read_csv(train_path))
284
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
285
- region_test = preprocessing(pd.read_csv(test_path))
286
-
287
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
288
- common_columns = region_train.columns.to_list()
289
- train_data = region_train[common_columns]
290
- val_data = region_val[common_columns]
291
- test_data = region_test[common_columns]
292
-
293
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
294
- X_train = train_data.drop(columns=drop_col)
295
- y_train = train_data[target_col]
296
- X_val = val_data.drop(columns=drop_col)
297
- y_val = val_data[target_col]
298
- X_test = test_data.drop(columns=drop_col)
299
- y_test = test_data[target_col]
300
-
301
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
302
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
303
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
304
-
305
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
306
- label_encoders = {}
307
- for col in categorical_cols:
308
- le = LabelEncoder()
309
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
310
- label_encoders[col] = le
311
-
312
- # ๋ณ€ํ™˜ ์ ์šฉ
313
- for col in categorical_cols:
314
- X_train[col] = label_encoders[col].transform(X_train[col])
315
- X_val[col] = label_encoders[col].transform(X_val[col])
316
- X_test[col] = label_encoders[col].transform(X_test[col])
317
-
318
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
319
- scaler = QuantileTransformer(output_distribution='normal')
320
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
321
-
322
- # ๋ณ€ํ™˜ ์ ์šฉ
323
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
324
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
325
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
326
-
327
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
328
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
329
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
330
-
331
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
332
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
333
-
334
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
335
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
336
-
337
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
338
- if target == "binary":
339
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
340
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
341
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
342
- elif target == "multi":
343
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
344
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
345
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
346
- else:
347
- raise ValueError("target must be 'binary' or 'multi'")
348
-
349
- # TensorDataset ์ƒ์„ฑ
350
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
351
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
352
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
353
-
354
- # DataLoader ์ƒ์„ฑ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ)
355
- if random_state == None:
356
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
357
- else:
358
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(random_state))
359
- val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
360
- test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
361
-
362
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader, y_train, scaler
363
-
364
-
365
- def calculate_csi(y_true, pred):
366
-
367
- cm = confusion_matrix(y_true, pred) # ๋ณ€์ˆ˜ ์ด๋ฆ„์„ cm์œผ๋กœ ๋ณ€๊ฒฝ
368
- # ํ˜ผ๋™ ํ–‰๋ ฌ์—์„œ H, F, M ์ถ”์ถœ
369
- H = (cm[0, 0] + cm[1, 1])
370
-
371
- F = (cm[1, 0] + cm[2, 0] +
372
- cm[0, 1] + cm[2, 1])
373
-
374
- M = (cm[0, 2] + cm[1, 2])
375
-
376
- # CSI ๊ณ„์‚ฐ
377
- CSI = H / (H + F + M + 1e-10)
378
- return CSI
379
-
380
- def sample_weight(y_train):
381
- class_weights = compute_class_weight(
382
- class_weight='balanced',
383
- classes=np.unique(y_train), # ๊ณ ์œ  ํด๋ž˜์Šค
384
- y=y_train # ํ•™์Šต ๋ฐ์ดํ„ฐ ๋ ˆ์ด๋ธ”
385
- )
386
- sample_weights = np.array([class_weights[label] for label in y_train])
387
-
388
- return sample_weights
389
-
390
- # ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ •์˜
391
- def objective(trial, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
392
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
393
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
394
- val_scores = []
395
-
396
- # --- 1. ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰ ๋ฒ”์œ„ ์ •์˜ (์ˆ˜์ •๋จ) ---
397
- if model_choose == "ft_transformer":
398
- d_token = trial.suggest_int("d_token", 64, 256, step=32)
399
- n_blocks = trial.suggest_int("n_blocks", 2, 6) # ๊นŠ์ด ์ถ•์†Œ๋กœ ๊ณผ์ ํ•ฉ ๋ฐฉ์ง€
400
- n_heads = trial.suggest_categorical("n_heads", [4, 8])
401
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
402
- if d_token % n_heads != 0:
403
- d_token = (d_token // n_heads) * n_heads
404
-
405
- attention_dropout = trial.suggest_float("attention_dropout", 0.1, 0.4)
406
- ffn_dropout = trial.suggest_float("ffn_dropout", 0.1, 0.4)
407
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True) # ๋ฒ”์œ„ ํ™•๋Œ€
408
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
409
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
410
-
411
- elif model_choose == 'resnet_like':
412
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
413
- d_hidden = trial.suggest_int("d_hidden", 64, 512, step=64)
414
- n_blocks = trial.suggest_int("n_blocks", 2, 5) # ๋„ˆ๋ฌด ๊นŠ์ง€ ์•Š๊ฒŒ ์กฐ์ ˆ
415
- dropout_first = trial.suggest_float("dropout_first", 0.1, 0.4)
416
- dropout_second = trial.suggest_float("dropout_second", 0.0, 0.2)
417
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
418
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
419
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
420
-
421
- elif model_choose == 'deepgbm':
422
- # DeepGBM์˜ ๊ฒฝ์šฐ ๋ชจ๋ธ ํŠน์„ฑ์— ๋งž์ถฐ ResNet ๋ธ”๋ก ๋ฐ ์ž„๋ฒ ๋”ฉ ์ฐจ์› ์กฐ์ ˆ
423
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
424
- d_hidden = trial.suggest_int("d_hidden", 64, 256, step=64)
425
- n_blocks = trial.suggest_int("n_blocks", 2, 6)
426
- dropout = trial.suggest_float("dropout", 0.1, 0.4)
427
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
428
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
429
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
430
-
431
- # --- 2. Fold๋ณ„ ํ•™์Šต ๋ฐ ๊ต์ฐจ ๊ฒ€์ฆ ---
432
- for fold in range(1, n_folds + 1):
433
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, _ = prepare_dataloader_with_batchsize(
434
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
435
- )
436
-
437
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
438
- if model_choose == "ft_transformer":
439
- model = FTTransformer(
440
- num_features=len(numerical_cols),
441
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
442
- d_token=d_token,
443
- n_blocks=n_blocks,
444
- n_heads=n_heads,
445
- attention_dropout=attention_dropout,
446
- ffn_dropout=ffn_dropout,
447
- num_classes=3
448
- ).to(device)
449
- elif model_choose == 'resnet_like':
450
- input_dim = len(numerical_cols) + len(categorical_cols)
451
- model = ResNetLike(
452
- input_dim=input_dim,
453
- d_main=d_main,
454
- d_hidden=d_hidden,
455
- n_blocks=n_blocks,
456
- dropout_first=dropout_first,
457
- dropout_second=dropout_second,
458
- num_classes=3
459
- ).to(device)
460
- elif model_choose == 'deepgbm':
461
- model = DeepGBM(
462
- num_features=len(numerical_cols),
463
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
464
- d_main=d_main,
465
- d_hidden=d_hidden,
466
- n_blocks=n_blocks,
467
- dropout=dropout,
468
- num_classes=3
469
- ).to(device)
470
-
471
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
472
- if target == 'multi':
473
- class_weights = compute_class_weight(
474
- class_weight='balanced',
475
- classes=np.unique(y_train),
476
- y=y_train
477
- )
478
- # ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜ ๋กœ๊ทธ ์ถœ๋ ฅ
479
- unique_classes = np.unique(y_train)
480
- class_counts = {cls: np.sum(y_train == cls) for cls in unique_classes}
481
- print(f" Fold {fold} - ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜: {dict(zip(unique_classes, class_weights))} (ํด๋ž˜์Šค๋ณ„ ์ƒ˜ํ”Œ ์ˆ˜: {class_counts})")
482
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
483
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
484
- else:
485
- criterion = nn.BCEWithLogitsLoss()
486
- optimizer = optim.AdamW(model.parameters(), lr=lr, weight_decay=weight_decay)
487
-
488
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ ์ถ”๊ฐ€: ์„ฑ๋Šฅ ์ •์ฒด ์‹œ LR์„ 0.5๋ฐฐ ๊ฐ์†Œ (๊ฒ€์ฆ CSI ๊ธฐ์ค€)
489
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
490
-
491
- # ํ•™์Šต ์„ค์ • (์—ํญ ๋ฐ ํŽ˜์ด์…˜์Šค ์ƒํ–ฅ)
492
- epochs = 200
493
- patience = 12 # ๋”ฅ๋Ÿฌ๋‹์˜ ์ •์ฒด ๊ตฌ๊ฐ„์„ ๊ณ ๋ คํ•˜์—ฌ ์†Œํญ ์ƒํ–ฅ
494
- best_fold_csi = 0
495
- counter = 0
496
-
497
- for epoch in range(epochs):
498
- model.train()
499
- for x_num_batch, x_cat_batch, y_batch in train_loader:
500
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
501
-
502
- optimizer.zero_grad()
503
- y_pred = model(x_num_batch, x_cat_batch)
504
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
505
- loss.backward()
506
- optimizer.step()
507
-
508
- # Validation ํ‰๊ฐ€
509
- model.eval()
510
- y_pred_val, y_true_val = [], []
511
- with torch.no_grad():
512
- for x_num_batch, x_cat_batch, y_batch in val_loader:
513
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
514
- output = model(x_num_batch, x_cat_batch)
515
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
516
-
517
- y_pred_val.extend(pred.cpu().numpy())
518
- y_true_val.extend(y_batch.cpu().numpy())
519
-
520
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
521
- val_csi = calculate_csi(y_true_val, y_pred_val)
522
- scheduler.step(val_csi)
523
-
524
- # Optuna Pruning ์ ์šฉ (์ฒซ ๋ฒˆ์งธ Fold์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ ํŒ๋‹จ ๊ฐ•ํ™”)
525
- trial.report(val_csi, epoch)
526
- if trial.should_prune():
527
- raise optuna.exceptions.TrialPruned()
528
-
529
- # Early Stopping ์ฒดํฌ
530
- if val_csi > best_fold_csi:
531
- best_fold_csi = val_csi
532
- counter = 0
533
- else:
534
- counter += 1
535
-
536
- if counter >= patience:
537
- break
538
-
539
- val_scores.append(best_fold_csi)
540
-
541
- # ๋ชจ๋“  fold์˜ ํ‰๊ท  ์„ฑ๋Šฅ ๋ฐ˜ํ™˜
542
- return np.mean(val_scores)
543
-
544
-
545
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ํ•จ์ˆ˜
546
- def train_final_model(best_params, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
547
- """
548
- ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
549
-
550
- Args:
551
- best_params: ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ
552
- model_choose: ๋ชจ๋ธ ์„ ํƒ ('ft_transformer', 'resnet_like', 'deepgbm')
553
- region: ์ง€์—ญ๋ช…
554
- data_sample: ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ ํƒ€์ž… ('pure', 'smote', etc.)
555
- target: ํƒ€๊ฒŸ ํƒ€์ž… ('multi', 'binary')
556
- n_folds: ๊ต์ฐจ ๊ฒ€์ฆ fold ์ˆ˜
557
- random_state: ๋žœ๋ค ์‹œ๋“œ
558
-
559
- Returns:
560
- ์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ ๋ฆฌ์ŠคํŠธ
561
- """
562
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
563
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
564
-
565
- models = []
566
- scalers = [] # scaler ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€
567
-
568
- print("์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘...")
569
-
570
- for fold in range(1, n_folds + 1):
571
- print(f"Fold {fold} ํ•™์Šต ์ค‘...")
572
-
573
- # ์ตœ์ ํ™”๋œ batch_size ์‚ฌ์šฉ
574
- batch_size = best_params.get("batch_size", 64)
575
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, scaler = prepare_dataloader_with_batchsize(
576
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
577
- )
578
-
579
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
580
- if model_choose == "ft_transformer":
581
- d_token = best_params["d_token"]
582
- n_heads = best_params.get("n_heads", 8)
583
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
584
- if d_token % n_heads != 0:
585
- d_token = (d_token // n_heads) * n_heads
586
-
587
- model = FTTransformer(
588
- num_features=len(numerical_cols),
589
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
590
- d_token=d_token,
591
- n_blocks=best_params["n_blocks"],
592
- n_heads=n_heads,
593
- attention_dropout=best_params["attention_dropout"],
594
- ffn_dropout=best_params["ffn_dropout"],
595
- num_classes=3
596
- ).to(device)
597
- elif model_choose == 'resnet_like':
598
- input_dim = len(numerical_cols) + len(categorical_cols)
599
- model = ResNetLike(
600
- input_dim=input_dim,
601
- d_main=best_params["d_main"],
602
- d_hidden=best_params["d_hidden"],
603
- n_blocks=best_params["n_blocks"],
604
- dropout_first=best_params["dropout_first"],
605
- dropout_second=best_params["dropout_second"],
606
- num_classes=3
607
- ).to(device)
608
- elif model_choose == 'deepgbm':
609
- model = DeepGBM(
610
- num_features=len(numerical_cols),
611
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
612
- d_main=best_params["d_main"],
613
- d_hidden=best_params["d_hidden"],
614
- n_blocks=best_params["n_blocks"],
615
- dropout=best_params["dropout"],
616
- num_classes=3
617
- ).to(device)
618
- else:
619
- raise ValueError(f"Unknown model_choose: {model_choose}")
620
-
621
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
622
- if target == 'multi':
623
- class_weights = compute_class_weight(
624
- class_weight='balanced',
625
- classes=np.unique(y_train),
626
- y=y_train
627
- )
628
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
629
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
630
- else:
631
- criterion = nn.BCEWithLogitsLoss()
632
- optimizer = optim.AdamW(model.parameters(), lr=best_params["lr"], weight_decay=best_params["weight_decay"])
633
-
634
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ
635
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
636
-
637
- # ํ•™์Šต ์„ค์ •
638
- epochs = 200
639
- patience = 12
640
- best_fold_csi = 0
641
- counter = 0
642
- best_model = None
643
-
644
- for epoch in range(epochs):
645
- model.train()
646
- for x_num_batch, x_cat_batch, y_batch in train_loader:
647
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
648
-
649
- optimizer.zero_grad()
650
- y_pred = model(x_num_batch, x_cat_batch)
651
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
652
- loss.backward()
653
- optimizer.step()
654
-
655
- # Validation ํ‰๊ฐ€
656
- model.eval()
657
- y_pred_val, y_true_val = [], []
658
- with torch.no_grad():
659
- for x_num_batch, x_cat_batch, y_batch in val_loader:
660
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
661
- output = model(x_num_batch, x_cat_batch)
662
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
663
-
664
- y_pred_val.extend(pred.cpu().numpy())
665
- y_true_val.extend(y_batch.cpu().numpy())
666
-
667
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
668
- val_csi = calculate_csi(y_true_val, y_pred_val)
669
- scheduler.step(val_csi)
670
-
671
- # Early Stopping ์ฒดํฌ
672
- if val_csi > best_fold_csi:
673
- best_fold_csi = val_csi
674
- counter = 0
675
- best_model = copy.deepcopy(model)
676
- else:
677
- counter += 1
678
-
679
- if counter >= patience:
680
- print(f" Early stopping at epoch {epoch+1}, Best CSI: {best_fold_csi:.4f}")
681
- break
682
-
683
- if best_model is None:
684
- best_model = model
685
-
686
- scalers.append(scaler) # scaler ์ €์žฅ (fold ์ˆœ์„œ๋Œ€๋กœ)
687
- models.append(best_model)
688
- print(f" Fold {fold} ํ•™์Šต ์™„๋ฃŒ (๊ฒ€์ฆ CSI: {best_fold_csi:.4f})")
689
-
690
- # ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •
691
- save_dir = f'../save_model/{model_choose}_optima'
692
- os.makedirs(save_dir, exist_ok=True)
693
-
694
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ
695
- if data_sample == 'pure':
696
- model_filename = f'{model_choose}_pure_{region}.pkl'
697
- else:
698
- model_filename = f'{model_choose}_{data_sample}_{region}.pkl'
699
-
700
- model_path = f'{save_dir}/{model_filename}'
701
-
702
- # ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„ ํ•œ ๋ฒˆ์— ์ €์žฅ
703
- joblib.dump(models, model_path)
704
- print(f"\n๋ชจ๋“  ๋ชจ๋ธ ์ €์žฅ ์™„๋ฃŒ: {model_path} (์ด {len(models)}๊ฐœ fold)")
705
-
706
- # Scaler ๋ณ„๋„ ์ €์žฅ
707
- scaler_save_dir = f'../save_model/{model_choose}_optima/scaler'
708
- os.makedirs(scaler_save_dir, exist_ok=True)
709
-
710
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ (๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํŒจํ„ด)
711
- if data_sample == 'pure':
712
- scaler_filename = f'{model_choose}_pure_{region}_scaler.pkl'
713
- else:
714
- scaler_filename = f'{model_choose}_{data_sample}_{region}_scaler.pkl'
715
-
716
- scaler_path = f'{scaler_save_dir}/{scaler_filename}'
717
- joblib.dump(scalers, scaler_path)
718
- print(f"Scaler ์ €์žฅ ์™„๋ฃŒ: {scaler_path} (์ด {len(scalers)}๊ฐœ fold)")
719
-
720
- return model_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_busan.py DELETED
@@ -1,96 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="busan", data_sample='ctgan10000'),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_ctgan10000_busan_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_path = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="busan",
79
- data_sample='ctgan10000',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
87
-
88
- except Exception as e:
89
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
90
- import traceback
91
- traceback.print_exc()
92
-
93
- # ์ •์ƒ ์ข…๋ฃŒ
94
- import sys
95
- sys.exit(0)
96
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_daegu.py DELETED
@@ -1,96 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="daegu", data_sample='ctgan10000'),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_ctgan10000_daegu_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_path = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="daegu",
79
- data_sample='ctgan10000',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
87
-
88
- except Exception as e:
89
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
90
- import traceback
91
- traceback.print_exc()
92
-
93
- # ์ •์ƒ ์ข…๋ฃŒ
94
- import sys
95
- sys.exit(0)
96
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_daejeon.py DELETED
@@ -1,96 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="daejeon", data_sample='ctgan10000'),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_ctgan10000_daejeon_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_path = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="daejeon",
79
- data_sample='ctgan10000',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
87
-
88
- except Exception as e:
89
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
90
- import traceback
91
- traceback.print_exc()
92
-
93
- # ์ •์ƒ ์ข…๋ฃŒ
94
- import sys
95
- sys.exit(0)
96
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_gwangju.py DELETED
@@ -1,96 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="gwangju", data_sample='ctgan10000'),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_ctgan10000_gwangju_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_path = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="gwangju",
79
- data_sample='ctgan10000',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
87
-
88
- except Exception as e:
89
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
90
- import traceback
91
- traceback.print_exc()
92
-
93
- # ์ •์ƒ ์ข…๋ฃŒ
94
- import sys
95
- sys.exit(0)
96
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_incheon.py DELETED
@@ -1,96 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="incheon", data_sample='ctgan10000'),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_ctgan10000_incheon_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_path = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="incheon",
79
- data_sample='ctgan10000',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
87
-
88
- except Exception as e:
89
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
90
- import traceback
91
- traceback.print_exc()
92
-
93
- # ์ •์ƒ ์ข…๋ฃŒ
94
- import sys
95
- sys.exit(0)
96
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_ctgan10000/ft_transformer_ctgan10000_seoul.py DELETED
@@ -1,96 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="seoul", data_sample='ctgan10000'),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_ctgan10000_seoul_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_path = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="seoul",
79
- data_sample='ctgan10000',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
87
-
88
- except Exception as e:
89
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
90
- import traceback
91
- traceback.print_exc()
92
-
93
- # ์ •์ƒ ์ข…๋ฃŒ
94
- import sys
95
- sys.exit(0)
96
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_ctgan10000/utils.py DELETED
@@ -1,720 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.optim as optim
4
- import numpy as np
5
- import random
6
- import os
7
- import copy
8
- from sklearn.preprocessing import QuantileTransformer, LabelEncoder
9
- from torch.utils.data import DataLoader, TensorDataset
10
- from sklearn.metrics import confusion_matrix
11
- from sklearn.utils.class_weight import compute_class_weight
12
- import pandas as pd
13
- import optuna
14
- from sklearn.metrics import accuracy_score, f1_score
15
- import joblib
16
-
17
-
18
- import sys
19
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ models ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
20
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
21
- models_path = os.path.abspath(os.path.join(current_file_dir, '../../models'))
22
- sys.path.insert(0, models_path)
23
- from ft_transformer import FTTransformer
24
- from resnet_like import ResNetLike
25
- from deepgbm import DeepGBM
26
- import warnings
27
- warnings.filterwarnings('ignore')
28
-
29
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
30
- seed = 42
31
- random.seed(seed)
32
- np.random.seed(seed)
33
-
34
- # PyTorch ์‹œ๋“œ ๊ณ ์ •
35
- torch.manual_seed(seed)
36
- torch.cuda.manual_seed(seed)
37
- torch.cuda.manual_seed_all(seed) # Multi-GPU ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ์‹œ๋“œ ์ ์šฉ
38
-
39
- # PyTorch ์—ฐ์‚ฐ์˜ ๊ฒฐ์ •์  ๋ชจ๋“œ ์„ค์ •
40
- torch.backends.cudnn.deterministic = True # ์‹คํ–‰๋งˆ๋‹ค ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ
41
- torch.backends.cudnn.benchmark = True # ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™” (๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅธ ์—ฐ์‚ฐ ์ˆ˜ํ–‰)
42
-
43
-
44
- def add_derived_features(df: pd.DataFrame) -> pd.DataFrame:
45
- """
46
- ์ œ๊ฑฐํ–ˆ๋˜ ํŒŒ์ƒ ๋ณ€์ˆ˜๋“ค์„ ๋ณต๊ตฌ
47
-
48
- Args:
49
- df: ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
50
-
51
- Returns:
52
- ํŒŒ์ƒ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
53
- """
54
- df = df.copy()
55
- df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
56
- df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
57
- df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
58
- df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
59
- df['ground_temp - temp_C'] = df['groundtemp'] - df['temp_C']
60
- return df
61
-
62
- def preprocessing(df):
63
- """๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜.
64
-
65
- Args:
66
- df: ์›๋ณธ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
67
-
68
- Returns:
69
- ์ „์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
70
- """
71
- df = df[df.columns].copy()
72
- df['year'] = df['year'].astype('int')
73
- df['month'] = df['month'].astype('int')
74
- df['hour'] = df['hour'].astype('int')
75
- df = add_derived_features(df).copy()
76
- df['multi_class'] = df['multi_class'].astype('int')
77
- df.loc[df['wind_dir']=='์ •์˜จ', 'wind_dir'] = "0"
78
- df['wind_dir'] = df['wind_dir'].astype('int')
79
- df = df[['temp_C', 'precip_mm', 'wind_speed', 'wind_dir', 'hm',
80
- 'vap_pressure', 'dewpoint_C', 'loc_pressure', 'sea_pressure',
81
- 'solarRad', 'snow_cm', 'cloudcover', 'lm_cloudcover', 'low_cloudbase',
82
- 'groundtemp', 'O3', 'NO2', 'PM10', 'PM25', 'year',
83
- 'month', 'hour', 'ground_temp - temp_C', 'hour_sin', 'hour_cos',
84
- 'month_sin', 'month_cos','multi_class']].copy()
85
- return df
86
-
87
-
88
- # ๋ฐ์ดํ„ฐ์…‹ ์ค€๋น„ ํ•จ์ˆ˜
89
- def prepare_dataset(region, data_sample='pure', target='multi', fold=3):
90
-
91
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
92
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
93
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
94
-
95
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
96
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
97
- if data_sample == 'pure':
98
- train_path = dat_path
99
- else:
100
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
101
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
102
- drop_col = ['multi_class','year']
103
- target_col = f'{target}_class'
104
-
105
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
106
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
107
- if data_sample == 'pure':
108
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
109
- else:
110
- region_train = preprocessing(pd.read_csv(train_path))
111
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
112
- region_test = preprocessing(pd.read_csv(test_path))
113
-
114
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
115
- common_columns = region_train.columns.to_list()
116
- train_data = region_train[common_columns]
117
- val_data = region_val[common_columns]
118
- test_data = region_test[common_columns]
119
-
120
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
121
- X_train = train_data.drop(columns=drop_col)
122
- y_train = train_data[target_col]
123
- X_val = val_data.drop(columns=drop_col)
124
- y_val = val_data[target_col]
125
- X_test = test_data.drop(columns=drop_col)
126
- y_test = test_data[target_col]
127
-
128
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
129
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
130
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
131
-
132
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
133
- label_encoders = {}
134
- for col in categorical_cols:
135
- le = LabelEncoder()
136
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
137
- label_encoders[col] = le
138
-
139
- # ๋ณ€ํ™˜ ์ ์šฉ
140
- for col in categorical_cols:
141
- X_train[col] = label_encoders[col].transform(X_train[col])
142
- X_val[col] = label_encoders[col].transform(X_val[col])
143
- X_test[col] = label_encoders[col].transform(X_test[col])
144
-
145
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
146
- scaler = QuantileTransformer(output_distribution='normal')
147
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
148
-
149
- # ๋ณ€ํ™˜ ์ ์šฉ
150
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
151
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
152
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
153
-
154
- return X_train, X_val, X_test, y_train, y_val, y_test, categorical_cols, numerical_cols
155
-
156
-
157
-
158
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜
159
- def prepare_dataloader(region, data_sample='pure', target='multi', fold=3, random_state=None):
160
-
161
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
162
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
163
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
164
-
165
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
166
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
167
- if data_sample == 'pure':
168
- train_path = dat_path
169
- else:
170
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
171
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
172
- drop_col = ['multi_class','year']
173
- target_col = f'{target}_class'
174
-
175
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
176
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
177
- if data_sample == 'pure':
178
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
179
- else:
180
- region_train = preprocessing(pd.read_csv(train_path))
181
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
182
- region_test = preprocessing(pd.read_csv(test_path))
183
-
184
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
185
- common_columns = region_train.columns.to_list()
186
- train_data = region_train[common_columns]
187
- val_data = region_val[common_columns]
188
- test_data = region_test[common_columns]
189
-
190
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
191
- X_train = train_data.drop(columns=drop_col)
192
- y_train = train_data[target_col]
193
- X_val = val_data.drop(columns=drop_col)
194
- y_val = val_data[target_col]
195
- X_test = test_data.drop(columns=drop_col)
196
- y_test = test_data[target_col]
197
-
198
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
199
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
200
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
201
-
202
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
203
- label_encoders = {}
204
- for col in categorical_cols:
205
- le = LabelEncoder()
206
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
207
- label_encoders[col] = le
208
-
209
- # ๋ณ€ํ™˜ ์ ์šฉ
210
- for col in categorical_cols:
211
- X_train[col] = label_encoders[col].transform(X_train[col])
212
- X_val[col] = label_encoders[col].transform(X_val[col])
213
- X_test[col] = label_encoders[col].transform(X_test[col])
214
-
215
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
216
- scaler = QuantileTransformer(output_distribution='normal')
217
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
218
-
219
- # ๋ณ€ํ™˜ ์ ์šฉ
220
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
221
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
222
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
223
-
224
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
225
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
226
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
227
-
228
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
229
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
230
-
231
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
232
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
233
-
234
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
235
- if target == "binary":
236
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
237
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
238
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
239
- elif target == "multi":
240
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
241
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
242
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
243
- else:
244
- raise ValueError("target must be 'binary' or 'multi'")
245
-
246
- # TensorDataset ์ƒ์„ฑ
247
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
248
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
249
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
250
-
251
- # DataLoader ์ƒ์„ฑ
252
- if random_state == None:
253
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
254
- else:
255
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(random_state))
256
- val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
257
- test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
258
-
259
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader
260
-
261
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๋ฒ„์ „)
262
- def prepare_dataloader_with_batchsize(region, data_sample='pure', target='multi', fold=3, random_state=None, batch_size=64):
263
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
264
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
265
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
266
-
267
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
268
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
269
- if data_sample == 'pure':
270
- train_path = dat_path
271
- else:
272
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
273
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
274
- drop_col = ['multi_class','year']
275
- target_col = f'{target}_class'
276
-
277
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
278
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
279
- if data_sample == 'pure':
280
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
281
- else:
282
- region_train = preprocessing(pd.read_csv(train_path))
283
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
284
- region_test = preprocessing(pd.read_csv(test_path))
285
-
286
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
287
- common_columns = region_train.columns.to_list()
288
- train_data = region_train[common_columns]
289
- val_data = region_val[common_columns]
290
- test_data = region_test[common_columns]
291
-
292
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
293
- X_train = train_data.drop(columns=drop_col)
294
- y_train = train_data[target_col]
295
- X_val = val_data.drop(columns=drop_col)
296
- y_val = val_data[target_col]
297
- X_test = test_data.drop(columns=drop_col)
298
- y_test = test_data[target_col]
299
-
300
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
301
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
302
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
303
-
304
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
305
- label_encoders = {}
306
- for col in categorical_cols:
307
- le = LabelEncoder()
308
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
309
- label_encoders[col] = le
310
-
311
- # ๋ณ€ํ™˜ ์ ์šฉ
312
- for col in categorical_cols:
313
- X_train[col] = label_encoders[col].transform(X_train[col])
314
- X_val[col] = label_encoders[col].transform(X_val[col])
315
- X_test[col] = label_encoders[col].transform(X_test[col])
316
-
317
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
318
- scaler = QuantileTransformer(output_distribution='normal')
319
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
320
-
321
- # ๋ณ€ํ™˜ ์ ์šฉ
322
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
323
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
324
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
325
-
326
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
327
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
328
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
329
-
330
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
331
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
332
-
333
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
334
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
335
-
336
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
337
- if target == "binary":
338
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
339
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
340
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
341
- elif target == "multi":
342
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
343
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
344
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
345
- else:
346
- raise ValueError("target must be 'binary' or 'multi'")
347
-
348
- # TensorDataset ์ƒ์„ฑ
349
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
350
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
351
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
352
-
353
- # DataLoader ์ƒ์„ฑ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ)
354
- if random_state == None:
355
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
356
- else:
357
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(random_state))
358
- val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
359
- test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
360
-
361
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader, y_train, scaler
362
-
363
-
364
- def calculate_csi(y_true, pred):
365
-
366
- cm = confusion_matrix(y_true, pred) # ๋ณ€์ˆ˜ ์ด๋ฆ„์„ cm์œผ๋กœ ๋ณ€๊ฒฝ
367
- # ํ˜ผ๋™ ํ–‰๋ ฌ์—์„œ H, F, M ์ถ”์ถœ
368
- H = (cm[0, 0] + cm[1, 1])
369
-
370
- F = (cm[1, 0] + cm[2, 0] +
371
- cm[0, 1] + cm[2, 1])
372
-
373
- M = (cm[0, 2] + cm[1, 2])
374
-
375
- # CSI ๊ณ„์‚ฐ
376
- CSI = H / (H + F + M + 1e-10)
377
- return CSI
378
-
379
- def sample_weight(y_train):
380
- class_weights = compute_class_weight(
381
- class_weight='balanced',
382
- classes=np.unique(y_train), # ๊ณ ์œ  ํด๋ž˜์Šค
383
- y=y_train # ํ•™์Šต ๋ฐ์ดํ„ฐ ๋ ˆ์ด๋ธ”
384
- )
385
- sample_weights = np.array([class_weights[label] for label in y_train])
386
-
387
- return sample_weights
388
-
389
- # ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ •์˜
390
- def objective(trial, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
391
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
392
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
393
- val_scores = []
394
-
395
- # --- 1. ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰ ๋ฒ”์œ„ ์ •์˜ (์ˆ˜์ •๋จ) ---
396
- if model_choose == "ft_transformer":
397
- d_token = trial.suggest_int("d_token", 64, 256, step=32)
398
- n_blocks = trial.suggest_int("n_blocks", 2, 6) # ๊นŠ์ด ์ถ•์†Œ๋กœ ๊ณผ์ ํ•ฉ ๋ฐฉ์ง€
399
- n_heads = trial.suggest_categorical("n_heads", [4, 8])
400
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
401
- if d_token % n_heads != 0:
402
- d_token = (d_token // n_heads) * n_heads
403
-
404
- attention_dropout = trial.suggest_float("attention_dropout", 0.1, 0.4)
405
- ffn_dropout = trial.suggest_float("ffn_dropout", 0.1, 0.4)
406
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True) # ๋ฒ”์œ„ ํ™•๋Œ€
407
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
408
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
409
-
410
- elif model_choose == 'resnet_like':
411
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
412
- d_hidden = trial.suggest_int("d_hidden", 64, 512, step=64)
413
- n_blocks = trial.suggest_int("n_blocks", 2, 5) # ๋„ˆ๋ฌด ๊นŠ์ง€ ์•Š๊ฒŒ ์กฐ์ ˆ
414
- dropout_first = trial.suggest_float("dropout_first", 0.1, 0.4)
415
- dropout_second = trial.suggest_float("dropout_second", 0.0, 0.2)
416
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
417
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
418
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
419
-
420
- elif model_choose == 'deepgbm':
421
- # DeepGBM์˜ ๊ฒฝ์šฐ ๋ชจ๋ธ ํŠน์„ฑ์— ๋งž์ถฐ ResNet ๋ธ”๋ก ๋ฐ ์ž„๋ฒ ๋”ฉ ์ฐจ์› ์กฐ์ ˆ
422
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
423
- d_hidden = trial.suggest_int("d_hidden", 64, 256, step=64)
424
- n_blocks = trial.suggest_int("n_blocks", 2, 6)
425
- dropout = trial.suggest_float("dropout", 0.1, 0.4)
426
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
427
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
428
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
429
-
430
- # --- 2. Fold๋ณ„ ํ•™์Šต ๋ฐ ๊ต์ฐจ ๊ฒ€์ฆ ---
431
- for fold in range(1, n_folds + 1):
432
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, _ = prepare_dataloader_with_batchsize(
433
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
434
- )
435
-
436
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
437
- if model_choose == "ft_transformer":
438
- model = FTTransformer(
439
- num_features=len(numerical_cols),
440
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
441
- d_token=d_token,
442
- n_blocks=n_blocks,
443
- n_heads=n_heads,
444
- attention_dropout=attention_dropout,
445
- ffn_dropout=ffn_dropout,
446
- num_classes=3
447
- ).to(device)
448
- elif model_choose == 'resnet_like':
449
- input_dim = len(numerical_cols) + len(categorical_cols)
450
- model = ResNetLike(
451
- input_dim=input_dim,
452
- d_main=d_main,
453
- d_hidden=d_hidden,
454
- n_blocks=n_blocks,
455
- dropout_first=dropout_first,
456
- dropout_second=dropout_second,
457
- num_classes=3
458
- ).to(device)
459
- elif model_choose == 'deepgbm':
460
- model = DeepGBM(
461
- num_features=len(numerical_cols),
462
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
463
- d_main=d_main,
464
- d_hidden=d_hidden,
465
- n_blocks=n_blocks,
466
- dropout=dropout,
467
- num_classes=3
468
- ).to(device)
469
-
470
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
471
- if target == 'multi':
472
- class_weights = compute_class_weight(
473
- class_weight='balanced',
474
- classes=np.unique(y_train),
475
- y=y_train
476
- )
477
- # ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜ ๋กœ๊ทธ ์ถœ๋ ฅ
478
- unique_classes = np.unique(y_train)
479
- class_counts = {cls: np.sum(y_train == cls) for cls in unique_classes}
480
- print(f" Fold {fold} - ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜: {dict(zip(unique_classes, class_weights))} (ํด๋ž˜์Šค๋ณ„ ์ƒ˜ํ”Œ ์ˆ˜: {class_counts})")
481
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
482
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
483
- else:
484
- criterion = nn.BCEWithLogitsLoss()
485
- optimizer = optim.AdamW(model.parameters(), lr=lr, weight_decay=weight_decay)
486
-
487
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ ์ถ”๊ฐ€: ์„ฑ๋Šฅ ์ •์ฒด ์‹œ LR์„ 0.5๋ฐฐ ๊ฐ์†Œ (๊ฒ€์ฆ CSI ๊ธฐ์ค€)
488
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
489
-
490
- # ํ•™์Šต ์„ค์ • (์—ํญ ๋ฐ ํŽ˜์ด์…˜์Šค ์ƒํ–ฅ)
491
- epochs = 200
492
- patience = 12 # ๋”ฅ๋Ÿฌ๋‹์˜ ์ •์ฒด ๊ตฌ๊ฐ„์„ ๊ณ ๋ คํ•˜์—ฌ ์†Œํญ ์ƒํ–ฅ
493
- best_fold_csi = 0
494
- counter = 0
495
-
496
- for epoch in range(epochs):
497
- model.train()
498
- for x_num_batch, x_cat_batch, y_batch in train_loader:
499
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
500
-
501
- optimizer.zero_grad()
502
- y_pred = model(x_num_batch, x_cat_batch)
503
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
504
- loss.backward()
505
- optimizer.step()
506
-
507
- # Validation ํ‰๊ฐ€
508
- model.eval()
509
- y_pred_val, y_true_val = [], []
510
- with torch.no_grad():
511
- for x_num_batch, x_cat_batch, y_batch in val_loader:
512
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
513
- output = model(x_num_batch, x_cat_batch)
514
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
515
-
516
- y_pred_val.extend(pred.cpu().numpy())
517
- y_true_val.extend(y_batch.cpu().numpy())
518
-
519
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
520
- val_csi = calculate_csi(y_true_val, y_pred_val)
521
- scheduler.step(val_csi)
522
-
523
- # Optuna Pruning ์ ์šฉ (์ฒซ ๋ฒˆ์งธ Fold์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ ํŒ๋‹จ ๊ฐ•ํ™”)
524
- trial.report(val_csi, epoch)
525
- if trial.should_prune():
526
- raise optuna.exceptions.TrialPruned()
527
-
528
- # Early Stopping ์ฒดํฌ
529
- if val_csi > best_fold_csi:
530
- best_fold_csi = val_csi
531
- counter = 0
532
- else:
533
- counter += 1
534
-
535
- if counter >= patience:
536
- break
537
-
538
- val_scores.append(best_fold_csi)
539
-
540
- # ๋ชจ๋“  fold์˜ ํ‰๊ท  ์„ฑ๋Šฅ ๋ฐ˜ํ™˜
541
- return np.mean(val_scores)
542
-
543
-
544
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ํ•จ์ˆ˜
545
- def train_final_model(best_params, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
546
- """
547
- ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
548
-
549
- Args:
550
- best_params: ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ
551
- model_choose: ๋ชจ๋ธ ์„ ํƒ ('ft_transformer', 'resnet_like', 'deepgbm')
552
- region: ์ง€์—ญ๋ช…
553
- data_sample: ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ ํƒ€์ž… ('pure', 'smote', etc.)
554
- target: ํƒ€๊ฒŸ ํƒ€์ž… ('multi', 'binary')
555
- n_folds: ๊ต์ฐจ ๊ฒ€์ฆ fold ์ˆ˜
556
- random_state: ๋žœ๋ค ์‹œ๋“œ
557
-
558
- Returns:
559
- ์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ ๋ฆฌ์ŠคํŠธ
560
- """
561
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
562
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
563
-
564
- models = []
565
- scalers = [] # scaler ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€
566
-
567
- print("์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘...")
568
-
569
- for fold in range(1, n_folds + 1):
570
- print(f"Fold {fold} ํ•™์Šต ์ค‘...")
571
-
572
- # ์ตœ์ ํ™”๋œ batch_size ์‚ฌ์šฉ
573
- batch_size = best_params.get("batch_size", 64)
574
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, scaler = prepare_dataloader_with_batchsize(
575
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
576
- )
577
-
578
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
579
- if model_choose == "ft_transformer":
580
- d_token = best_params["d_token"]
581
- n_heads = best_params.get("n_heads", 8)
582
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
583
- if d_token % n_heads != 0:
584
- d_token = (d_token // n_heads) * n_heads
585
-
586
- model = FTTransformer(
587
- num_features=len(numerical_cols),
588
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
589
- d_token=d_token,
590
- n_blocks=best_params["n_blocks"],
591
- n_heads=n_heads,
592
- attention_dropout=best_params["attention_dropout"],
593
- ffn_dropout=best_params["ffn_dropout"],
594
- num_classes=3
595
- ).to(device)
596
- elif model_choose == 'resnet_like':
597
- input_dim = len(numerical_cols) + len(categorical_cols)
598
- model = ResNetLike(
599
- input_dim=input_dim,
600
- d_main=best_params["d_main"],
601
- d_hidden=best_params["d_hidden"],
602
- n_blocks=best_params["n_blocks"],
603
- dropout_first=best_params["dropout_first"],
604
- dropout_second=best_params["dropout_second"],
605
- num_classes=3
606
- ).to(device)
607
- elif model_choose == 'deepgbm':
608
- model = DeepGBM(
609
- num_features=len(numerical_cols),
610
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
611
- d_main=best_params["d_main"],
612
- d_hidden=best_params["d_hidden"],
613
- n_blocks=best_params["n_blocks"],
614
- dropout=best_params["dropout"],
615
- num_classes=3
616
- ).to(device)
617
- else:
618
- raise ValueError(f"Unknown model_choose: {model_choose}")
619
-
620
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
621
- if target == 'multi':
622
- class_weights = compute_class_weight(
623
- class_weight='balanced',
624
- classes=np.unique(y_train),
625
- y=y_train
626
- )
627
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
628
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
629
- else:
630
- criterion = nn.BCEWithLogitsLoss()
631
- optimizer = optim.AdamW(model.parameters(), lr=best_params["lr"], weight_decay=best_params["weight_decay"])
632
-
633
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ
634
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
635
-
636
- # ํ•™์Šต ์„ค์ •
637
- epochs = 200
638
- patience = 12
639
- best_fold_csi = 0
640
- counter = 0
641
- best_model = None
642
-
643
- for epoch in range(epochs):
644
- model.train()
645
- for x_num_batch, x_cat_batch, y_batch in train_loader:
646
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
647
-
648
- optimizer.zero_grad()
649
- y_pred = model(x_num_batch, x_cat_batch)
650
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
651
- loss.backward()
652
- optimizer.step()
653
-
654
- # Validation ํ‰๊ฐ€
655
- model.eval()
656
- y_pred_val, y_true_val = [], []
657
- with torch.no_grad():
658
- for x_num_batch, x_cat_batch, y_batch in val_loader:
659
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
660
- output = model(x_num_batch, x_cat_batch)
661
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
662
-
663
- y_pred_val.extend(pred.cpu().numpy())
664
- y_true_val.extend(y_batch.cpu().numpy())
665
-
666
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
667
- val_csi = calculate_csi(y_true_val, y_pred_val)
668
- scheduler.step(val_csi)
669
-
670
- # Early Stopping ์ฒดํฌ
671
- if val_csi > best_fold_csi:
672
- best_fold_csi = val_csi
673
- counter = 0
674
- best_model = copy.deepcopy(model)
675
- else:
676
- counter += 1
677
-
678
- if counter >= patience:
679
- print(f" Early stopping at epoch {epoch+1}, Best CSI: {best_fold_csi:.4f}")
680
- break
681
-
682
- if best_model is None:
683
- best_model = model
684
-
685
- scalers.append(scaler) # scaler ์ €์žฅ (fold ์ˆœ์„œ๋Œ€๋กœ)
686
- models.append(best_model)
687
- print(f" Fold {fold} ํ•™์Šต ์™„๋ฃŒ (๊ฒ€์ฆ CSI: {best_fold_csi:.4f})")
688
-
689
- # ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •
690
- save_dir = f'../save_model/{model_choose}_optima'
691
- os.makedirs(save_dir, exist_ok=True)
692
-
693
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ
694
- if data_sample == 'pure':
695
- model_filename = f'{model_choose}_pure_{region}.pkl'
696
- else:
697
- model_filename = f'{model_choose}_{data_sample}_{region}.pkl'
698
-
699
- model_path = f'{save_dir}/{model_filename}'
700
-
701
- # ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„ ํ•œ ๋ฒˆ์— ์ €์žฅ
702
- joblib.dump(models, model_path)
703
- print(f"\n๋ชจ๋“  ๋ชจ๋ธ ์ €์žฅ ์™„๋ฃŒ: {model_path} (์ด {len(models)}๊ฐœ fold)")
704
-
705
- # Scaler ๋ณ„๋„ ์ €์žฅ
706
- scaler_save_dir = f'../save_model/{model_choose}_optima/scaler'
707
- os.makedirs(scaler_save_dir, exist_ok=True)
708
-
709
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ (๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํŒจํ„ด)
710
- if data_sample == 'pure':
711
- scaler_filename = f'{model_choose}_pure_{region}_scaler.pkl'
712
- else:
713
- scaler_filename = f'{model_choose}_{data_sample}_{region}_scaler.pkl'
714
-
715
- scaler_path = f'{scaler_save_dir}/{scaler_filename}'
716
- joblib.dump(scalers, scaler_path)
717
- print(f"Scaler ์ €์žฅ ์™„๋ฃŒ: {scaler_path} (์ด {len(scalers)}๊ฐœ fold)")
718
-
719
- return model_path
720
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_busan.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="busan"),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_pure_busan_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_paths = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="busan",
79
- data_sample='pure',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
87
- for path in model_paths:
88
- print(f" - {path}")
89
-
90
- except Exception as e:
91
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
92
- import traceback
93
- traceback.print_exc()
94
-
95
- # ์ •์ƒ ์ข…๋ฃŒ
96
- import sys
97
- sys.exit(0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_daegu.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="daegu"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_pure_daegu_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="daegu",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_daejeon.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="daejeon"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_pure_daejeon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="daejeon",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_gwangju.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="gwangju"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_pure_gwangju_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="gwangju",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_incheon.py DELETED
@@ -1,99 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="incheon"),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_pure_incheon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_paths = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="incheon",
80
- data_sample='pure',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
88
- for path in model_paths:
89
- print(f" - {path}")
90
-
91
- except Exception as e:
92
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
93
- import traceback
94
- traceback.print_exc()
95
-
96
- # ์ •์ƒ ์ข…๋ฃŒ
97
- import sys
98
- sys.exit(0)
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_pure/ft_transforemer_pure_seoul.py DELETED
@@ -1,98 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
16
- def print_trial_callback(study, trial):
17
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
18
- print(f"\n{'='*80}")
19
- print(f"Trial {trial.number} ์™„๋ฃŒ")
20
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
21
- print(f" Parameters: {trial.params}")
22
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
23
- print(f" Best Trial: {study.best_trial.number}")
24
- print(f" Best Parameters: {study.best_params}")
25
- print(f"{'='*80}\n")
26
-
27
-
28
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
29
- study = optuna.create_study(
30
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
31
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
32
- )
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="seoul"),
37
- n_trials=100,
38
- callbacks=[print_trial_callback]
39
- )
40
-
41
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
42
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
43
- print(f"Best CSI Score: {study.best_value:.4f}")
44
- print(f"Best Hyperparameters: {study.best_params}")
45
-
46
- try:
47
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
48
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
49
-
50
- if len(csi_scores) > 0:
51
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
52
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
53
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
54
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
55
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
56
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
57
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
58
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
59
-
60
- # Study ๊ฐ์ฒด ์ €์žฅ
61
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
62
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
63
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
64
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
65
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_pure_seoul_trials.pkl")
66
- joblib.dump(study, study_path)
67
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
68
-
69
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
70
- print("\n" + "="*50)
71
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
72
- print("="*50)
73
-
74
- best_params = study.best_params
75
- model_paths = train_final_model(
76
- best_params=best_params,
77
- model_choose="ft_transformer",
78
- region="seoul",
79
- data_sample='pure',
80
- target='multi',
81
- n_folds=3,
82
- random_state=seed
83
- )
84
-
85
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
86
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ:")
87
- for path in model_paths:
88
- print(f" - {path}")
89
-
90
- except Exception as e:
91
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
92
- import traceback
93
- traceback.print_exc()
94
-
95
- # ์ •์ƒ ์ข…๋ฃŒ
96
- import sys
97
- sys.exit(0)
98
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_pure/utils.py DELETED
@@ -1,720 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.optim as optim
4
- import numpy as np
5
- import random
6
- import os
7
- import copy
8
- from sklearn.preprocessing import QuantileTransformer, LabelEncoder
9
- from torch.utils.data import DataLoader, TensorDataset
10
- from sklearn.metrics import confusion_matrix
11
- from sklearn.utils.class_weight import compute_class_weight
12
- import pandas as pd
13
- import optuna
14
- from sklearn.metrics import accuracy_score, f1_score
15
- import joblib
16
-
17
-
18
- import sys
19
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ models ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
20
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
21
- models_path = os.path.abspath(os.path.join(current_file_dir, '../../models'))
22
- sys.path.insert(0, models_path)
23
- from ft_transformer import FTTransformer
24
- from resnet_like import ResNetLike
25
- from deepgbm import DeepGBM
26
- import warnings
27
- warnings.filterwarnings('ignore')
28
-
29
-
30
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
31
- seed = 42
32
- random.seed(seed)
33
- np.random.seed(seed)
34
-
35
- # PyTorch ์‹œ๋“œ ๊ณ ์ •
36
- torch.manual_seed(seed)
37
- torch.cuda.manual_seed(seed)
38
- torch.cuda.manual_seed_all(seed) # Multi-GPU ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ์‹œ๋“œ ์ ์šฉ
39
-
40
- # PyTorch ์—ฐ์‚ฐ์˜ ๊ฒฐ์ •์  ๋ชจ๋“œ ์„ค์ •
41
- torch.backends.cudnn.deterministic = True # ์‹คํ–‰๋งˆ๋‹ค ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ
42
- torch.backends.cudnn.benchmark = True # ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™” (๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅธ ์—ฐ์‚ฐ ์ˆ˜ํ–‰)
43
-
44
-
45
- def add_derived_features(df: pd.DataFrame) -> pd.DataFrame:
46
- """
47
- ์ œ๊ฑฐํ–ˆ๋˜ ํŒŒ์ƒ ๋ณ€์ˆ˜๋“ค์„ ๋ณต๊ตฌ
48
-
49
- Args:
50
- df: ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
51
-
52
- Returns:
53
- ํŒŒ์ƒ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
54
- """
55
- df = df.copy()
56
- df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
57
- df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
58
- df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
59
- df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
60
- df['ground_temp - temp_C'] = df['groundtemp'] - df['temp_C']
61
- return df
62
-
63
- def preprocessing(df):
64
- """๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜.
65
-
66
- Args:
67
- df: ์›๋ณธ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
68
-
69
- Returns:
70
- ์ „์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
71
- """
72
- df = df[df.columns].copy()
73
- df['year'] = df['year'].astype('int')
74
- df['month'] = df['month'].astype('int')
75
- df['hour'] = df['hour'].astype('int')
76
- df = add_derived_features(df).copy()
77
- df['multi_class'] = df['multi_class'].astype('int')
78
- df.loc[df['wind_dir']=='์ •์˜จ', 'wind_dir'] = "0"
79
- df['wind_dir'] = df['wind_dir'].astype('int')
80
- df = df[['temp_C', 'precip_mm', 'wind_speed', 'wind_dir', 'hm',
81
- 'vap_pressure', 'dewpoint_C', 'loc_pressure', 'sea_pressure',
82
- 'solarRad', 'snow_cm', 'cloudcover', 'lm_cloudcover', 'low_cloudbase',
83
- 'groundtemp', 'O3', 'NO2', 'PM10', 'PM25', 'year',
84
- 'month', 'hour', 'ground_temp - temp_C', 'hour_sin', 'hour_cos',
85
- 'month_sin', 'month_cos','multi_class']].copy()
86
- return df
87
-
88
-
89
- # ๋ฐ์ดํ„ฐ์…‹ ์ค€๋น„ ํ•จ์ˆ˜
90
- def prepare_dataset(region, data_sample='pure', target='multi', fold=3):
91
-
92
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
93
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
94
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
95
-
96
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
97
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
98
- if data_sample == 'pure':
99
- train_path = dat_path
100
- else:
101
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
102
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
103
- drop_col = ['multi_class','year']
104
- target_col = f'{target}_class'
105
-
106
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
107
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
108
- if data_sample == 'pure':
109
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
110
- else:
111
- region_train = preprocessing(pd.read_csv(train_path))
112
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
113
- region_test = preprocessing(pd.read_csv(test_path))
114
-
115
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
116
- common_columns = region_train.columns.to_list()
117
- train_data = region_train[common_columns]
118
- val_data = region_val[common_columns]
119
- test_data = region_test[common_columns]
120
-
121
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
122
- X_train = train_data.drop(columns=drop_col)
123
- y_train = train_data[target_col]
124
- X_val = val_data.drop(columns=drop_col)
125
- y_val = val_data[target_col]
126
- X_test = test_data.drop(columns=drop_col)
127
- y_test = test_data[target_col]
128
-
129
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
130
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
131
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
132
-
133
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
134
- label_encoders = {}
135
- for col in categorical_cols:
136
- le = LabelEncoder()
137
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
138
- label_encoders[col] = le
139
-
140
- # ๋ณ€ํ™˜ ์ ์šฉ
141
- for col in categorical_cols:
142
- X_train[col] = label_encoders[col].transform(X_train[col])
143
- X_val[col] = label_encoders[col].transform(X_val[col])
144
- X_test[col] = label_encoders[col].transform(X_test[col])
145
-
146
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
147
- scaler = QuantileTransformer(output_distribution='normal')
148
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
149
-
150
- # ๋ณ€ํ™˜ ์ ์šฉ
151
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
152
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
153
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
154
-
155
- return X_train, X_val, X_test, y_train, y_val, y_test, categorical_cols, numerical_cols
156
-
157
-
158
-
159
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜
160
- def prepare_dataloader(region, data_sample='pure', target='multi', fold=3, random_state=None):
161
-
162
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
163
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
164
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
165
-
166
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
167
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
168
- if data_sample == 'pure':
169
- train_path = dat_path
170
- else:
171
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
172
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
173
- drop_col = ['multi_class','year']
174
- target_col = f'{target}_class'
175
-
176
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
177
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
178
- if data_sample == 'pure':
179
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
180
- else:
181
- region_train = preprocessing(pd.read_csv(train_path))
182
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
183
- region_test = preprocessing(pd.read_csv(test_path))
184
-
185
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
186
- common_columns = region_train.columns.to_list()
187
- train_data = region_train[common_columns]
188
- val_data = region_val[common_columns]
189
- test_data = region_test[common_columns]
190
-
191
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
192
- X_train = train_data.drop(columns=drop_col)
193
- y_train = train_data[target_col]
194
- X_val = val_data.drop(columns=drop_col)
195
- y_val = val_data[target_col]
196
- X_test = test_data.drop(columns=drop_col)
197
- y_test = test_data[target_col]
198
-
199
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
200
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
201
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
202
-
203
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
204
- label_encoders = {}
205
- for col in categorical_cols:
206
- le = LabelEncoder()
207
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
208
- label_encoders[col] = le
209
-
210
- # ๋ณ€ํ™˜ ์ ์šฉ
211
- for col in categorical_cols:
212
- X_train[col] = label_encoders[col].transform(X_train[col])
213
- X_val[col] = label_encoders[col].transform(X_val[col])
214
- X_test[col] = label_encoders[col].transform(X_test[col])
215
-
216
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
217
- scaler = QuantileTransformer(output_distribution='normal')
218
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
219
-
220
- # ๋ณ€ํ™˜ ์ ์šฉ
221
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
222
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
223
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
224
-
225
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
226
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
227
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
228
-
229
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
230
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
231
-
232
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
233
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
234
-
235
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
236
- if target == "binary":
237
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
238
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
239
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
240
- elif target == "multi":
241
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
242
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
243
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
244
- else:
245
- raise ValueError("target must be 'binary' or 'multi'")
246
-
247
- # TensorDataset ์ƒ์„ฑ
248
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
249
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
250
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
251
-
252
- # DataLoader ์ƒ์„ฑ
253
- if random_state == None:
254
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
255
- else:
256
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(random_state))
257
- val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
258
- test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
259
-
260
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader
261
-
262
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๋ฒ„์ „)
263
- def prepare_dataloader_with_batchsize(region, data_sample='pure', target='multi', fold=3, random_state=None, batch_size=64):
264
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
265
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
266
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
267
-
268
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
269
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
270
- if data_sample == 'pure':
271
- train_path = dat_path
272
- else:
273
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
274
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
275
- drop_col = ['multi_class','year']
276
- target_col = f'{target}_class'
277
-
278
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
279
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
280
- if data_sample == 'pure':
281
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
282
- else:
283
- region_train = preprocessing(pd.read_csv(train_path))
284
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
285
- region_test = preprocessing(pd.read_csv(test_path))
286
-
287
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
288
- common_columns = region_train.columns.to_list()
289
- train_data = region_train[common_columns]
290
- val_data = region_val[common_columns]
291
- test_data = region_test[common_columns]
292
-
293
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
294
- X_train = train_data.drop(columns=drop_col)
295
- y_train = train_data[target_col]
296
- X_val = val_data.drop(columns=drop_col)
297
- y_val = val_data[target_col]
298
- X_test = test_data.drop(columns=drop_col)
299
- y_test = test_data[target_col]
300
-
301
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
302
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
303
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
304
-
305
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
306
- label_encoders = {}
307
- for col in categorical_cols:
308
- le = LabelEncoder()
309
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
310
- label_encoders[col] = le
311
-
312
- # ๋ณ€ํ™˜ ์ ์šฉ
313
- for col in categorical_cols:
314
- X_train[col] = label_encoders[col].transform(X_train[col])
315
- X_val[col] = label_encoders[col].transform(X_val[col])
316
- X_test[col] = label_encoders[col].transform(X_test[col])
317
-
318
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
319
- scaler = QuantileTransformer(output_distribution='normal')
320
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
321
-
322
- # ๋ณ€ํ™˜ ์ ์šฉ
323
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
324
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
325
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
326
-
327
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
328
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
329
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
330
-
331
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
332
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
333
-
334
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
335
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
336
-
337
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
338
- if target == "binary":
339
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
340
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
341
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
342
- elif target == "multi":
343
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
344
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
345
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
346
- else:
347
- raise ValueError("target must be 'binary' or 'multi'")
348
-
349
- # TensorDataset ์ƒ์„ฑ
350
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
351
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
352
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
353
-
354
- # DataLoader ์ƒ์„ฑ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ)
355
- if random_state == None:
356
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
357
- else:
358
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(random_state))
359
- val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
360
- test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
361
-
362
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader, y_train, scaler
363
-
364
-
365
- def calculate_csi(y_true, pred):
366
-
367
- cm = confusion_matrix(y_true, pred) # ๋ณ€์ˆ˜ ์ด๋ฆ„์„ cm์œผ๋กœ ๋ณ€๊ฒฝ
368
- # ํ˜ผ๋™ ํ–‰๋ ฌ์—์„œ H, F, M ์ถ”์ถœ
369
- H = (cm[0, 0] + cm[1, 1])
370
-
371
- F = (cm[1, 0] + cm[2, 0] +
372
- cm[0, 1] + cm[2, 1])
373
-
374
- M = (cm[0, 2] + cm[1, 2])
375
-
376
- # CSI ๊ณ„์‚ฐ
377
- CSI = H / (H + F + M + 1e-10)
378
- return CSI
379
-
380
- def sample_weight(y_train):
381
- class_weights = compute_class_weight(
382
- class_weight='balanced',
383
- classes=np.unique(y_train), # ๊ณ ์œ  ํด๋ž˜์Šค
384
- y=y_train # ํ•™์Šต ๋ฐ์ดํ„ฐ ๋ ˆ์ด๋ธ”
385
- )
386
- sample_weights = np.array([class_weights[label] for label in y_train])
387
-
388
- return sample_weights
389
-
390
- # ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ •์˜
391
- def objective(trial, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
392
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
393
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
394
- val_scores = []
395
-
396
- # --- 1. ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰ ๋ฒ”์œ„ ์ •์˜ (์ˆ˜์ •๋จ) ---
397
- if model_choose == "ft_transformer":
398
- d_token = trial.suggest_int("d_token", 64, 256, step=32)
399
- n_blocks = trial.suggest_int("n_blocks", 2, 6) # ๊นŠ์ด ์ถ•์†Œ๋กœ ๊ณผ์ ํ•ฉ ๋ฐฉ์ง€
400
- n_heads = trial.suggest_categorical("n_heads", [4, 8])
401
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
402
- if d_token % n_heads != 0:
403
- d_token = (d_token // n_heads) * n_heads
404
-
405
- attention_dropout = trial.suggest_float("attention_dropout", 0.1, 0.4)
406
- ffn_dropout = trial.suggest_float("ffn_dropout", 0.1, 0.4)
407
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True) # ๋ฒ”์œ„ ํ™•๋Œ€
408
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
409
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
410
-
411
- elif model_choose == 'resnet_like':
412
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
413
- d_hidden = trial.suggest_int("d_hidden", 64, 512, step=64)
414
- n_blocks = trial.suggest_int("n_blocks", 2, 5) # ๋„ˆ๋ฌด ๊นŠ์ง€ ์•Š๊ฒŒ ์กฐ์ ˆ
415
- dropout_first = trial.suggest_float("dropout_first", 0.1, 0.4)
416
- dropout_second = trial.suggest_float("dropout_second", 0.0, 0.2)
417
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
418
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
419
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
420
-
421
- elif model_choose == 'deepgbm':
422
- # DeepGBM์˜ ๊ฒฝ์šฐ ๋ชจ๋ธ ํŠน์„ฑ์— ๋งž์ถฐ ResNet ๋ธ”๋ก ๋ฐ ์ž„๋ฒ ๋”ฉ ์ฐจ์› ์กฐ์ ˆ
423
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
424
- d_hidden = trial.suggest_int("d_hidden", 64, 256, step=64)
425
- n_blocks = trial.suggest_int("n_blocks", 2, 6)
426
- dropout = trial.suggest_float("dropout", 0.1, 0.4)
427
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
428
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
429
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
430
-
431
- # --- 2. Fold๋ณ„ ํ•™์Šต ๋ฐ ๊ต์ฐจ ๊ฒ€์ฆ ---
432
- for fold in range(1, n_folds + 1):
433
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, _ = prepare_dataloader_with_batchsize(
434
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
435
- )
436
-
437
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
438
- if model_choose == "ft_transformer":
439
- model = FTTransformer(
440
- num_features=len(numerical_cols),
441
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
442
- d_token=d_token,
443
- n_blocks=n_blocks,
444
- n_heads=n_heads,
445
- attention_dropout=attention_dropout,
446
- ffn_dropout=ffn_dropout,
447
- num_classes=3
448
- ).to(device)
449
- elif model_choose == 'resnet_like':
450
- input_dim = len(numerical_cols) + len(categorical_cols)
451
- model = ResNetLike(
452
- input_dim=input_dim,
453
- d_main=d_main,
454
- d_hidden=d_hidden,
455
- n_blocks=n_blocks,
456
- dropout_first=dropout_first,
457
- dropout_second=dropout_second,
458
- num_classes=3
459
- ).to(device)
460
- elif model_choose == 'deepgbm':
461
- model = DeepGBM(
462
- num_features=len(numerical_cols),
463
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
464
- d_main=d_main,
465
- d_hidden=d_hidden,
466
- n_blocks=n_blocks,
467
- dropout=dropout,
468
- num_classes=3
469
- ).to(device)
470
-
471
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
472
- if target == 'multi':
473
- class_weights = compute_class_weight(
474
- class_weight='balanced',
475
- classes=np.unique(y_train),
476
- y=y_train
477
- )
478
- # ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜ ๋กœ๊ทธ ์ถœ๋ ฅ
479
- unique_classes = np.unique(y_train)
480
- class_counts = {cls: np.sum(y_train == cls) for cls in unique_classes}
481
- print(f" Fold {fold} - ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜: {dict(zip(unique_classes, class_weights))} (ํด๋ž˜์Šค๋ณ„ ์ƒ˜ํ”Œ ์ˆ˜: {class_counts})")
482
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
483
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
484
- else:
485
- criterion = nn.BCEWithLogitsLoss()
486
- optimizer = optim.AdamW(model.parameters(), lr=lr, weight_decay=weight_decay)
487
-
488
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ ์ถ”๊ฐ€: ์„ฑ๋Šฅ ์ •์ฒด ์‹œ LR์„ 0.5๋ฐฐ ๊ฐ์†Œ (๊ฒ€์ฆ CSI ๊ธฐ์ค€)
489
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
490
-
491
- # ํ•™์Šต ์„ค์ • (์—ํญ ๋ฐ ํŽ˜์ด์…˜์Šค ์ƒํ–ฅ)
492
- epochs = 200
493
- patience = 12 # ๋”ฅ๋Ÿฌ๋‹์˜ ์ •์ฒด ๊ตฌ๊ฐ„์„ ๊ณ ๋ คํ•˜์—ฌ ์†Œํญ ์ƒํ–ฅ
494
- best_fold_csi = 0
495
- counter = 0
496
-
497
- for epoch in range(epochs):
498
- model.train()
499
- for x_num_batch, x_cat_batch, y_batch in train_loader:
500
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
501
-
502
- optimizer.zero_grad()
503
- y_pred = model(x_num_batch, x_cat_batch)
504
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
505
- loss.backward()
506
- optimizer.step()
507
-
508
- # Validation ํ‰๊ฐ€
509
- model.eval()
510
- y_pred_val, y_true_val = [], []
511
- with torch.no_grad():
512
- for x_num_batch, x_cat_batch, y_batch in val_loader:
513
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
514
- output = model(x_num_batch, x_cat_batch)
515
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
516
-
517
- y_pred_val.extend(pred.cpu().numpy())
518
- y_true_val.extend(y_batch.cpu().numpy())
519
-
520
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
521
- val_csi = calculate_csi(y_true_val, y_pred_val)
522
- scheduler.step(val_csi)
523
-
524
- # Optuna Pruning ์ ์šฉ (์ฒซ ๋ฒˆ์งธ Fold์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ ํŒ๋‹จ ๊ฐ•ํ™”)
525
- trial.report(val_csi, epoch)
526
- if trial.should_prune():
527
- raise optuna.exceptions.TrialPruned()
528
-
529
- # Early Stopping ์ฒดํฌ
530
- if val_csi > best_fold_csi:
531
- best_fold_csi = val_csi
532
- counter = 0
533
- else:
534
- counter += 1
535
-
536
- if counter >= patience:
537
- break
538
-
539
- val_scores.append(best_fold_csi)
540
-
541
- # ๋ชจ๋“  fold์˜ ํ‰๊ท  ์„ฑ๋Šฅ ๋ฐ˜ํ™˜
542
- return np.mean(val_scores)
543
-
544
-
545
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ํ•จ์ˆ˜
546
- def train_final_model(best_params, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
547
- """
548
- ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
549
-
550
- Args:
551
- best_params: ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ
552
- model_choose: ๋ชจ๋ธ ์„ ํƒ ('ft_transformer', 'resnet_like', 'deepgbm')
553
- region: ์ง€์—ญ๋ช…
554
- data_sample: ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ ํƒ€์ž… ('pure', 'smote', etc.)
555
- target: ํƒ€๊ฒŸ ํƒ€์ž… ('multi', 'binary')
556
- n_folds: ๊ต์ฐจ ๊ฒ€์ฆ fold ์ˆ˜
557
- random_state: ๋žœ๋ค ์‹œ๋“œ
558
-
559
- Returns:
560
- ์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ ๋ฆฌ์ŠคํŠธ
561
- """
562
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
563
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
564
-
565
- models = []
566
- scalers = [] # scaler ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€
567
-
568
- print("์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘...")
569
-
570
- for fold in range(1, n_folds + 1):
571
- print(f"Fold {fold} ํ•™์Šต ์ค‘...")
572
-
573
- # ์ตœ์ ํ™”๋œ batch_size ์‚ฌ์šฉ
574
- batch_size = best_params.get("batch_size", 64)
575
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, scaler = prepare_dataloader_with_batchsize(
576
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
577
- )
578
-
579
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
580
- if model_choose == "ft_transformer":
581
- d_token = best_params["d_token"]
582
- n_heads = best_params.get("n_heads", 8)
583
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
584
- if d_token % n_heads != 0:
585
- d_token = (d_token // n_heads) * n_heads
586
-
587
- model = FTTransformer(
588
- num_features=len(numerical_cols),
589
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
590
- d_token=d_token,
591
- n_blocks=best_params["n_blocks"],
592
- n_heads=n_heads,
593
- attention_dropout=best_params["attention_dropout"],
594
- ffn_dropout=best_params["ffn_dropout"],
595
- num_classes=3
596
- ).to(device)
597
- elif model_choose == 'resnet_like':
598
- input_dim = len(numerical_cols) + len(categorical_cols)
599
- model = ResNetLike(
600
- input_dim=input_dim,
601
- d_main=best_params["d_main"],
602
- d_hidden=best_params["d_hidden"],
603
- n_blocks=best_params["n_blocks"],
604
- dropout_first=best_params["dropout_first"],
605
- dropout_second=best_params["dropout_second"],
606
- num_classes=3
607
- ).to(device)
608
- elif model_choose == 'deepgbm':
609
- model = DeepGBM(
610
- num_features=len(numerical_cols),
611
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
612
- d_main=best_params["d_main"],
613
- d_hidden=best_params["d_hidden"],
614
- n_blocks=best_params["n_blocks"],
615
- dropout=best_params["dropout"],
616
- num_classes=3
617
- ).to(device)
618
- else:
619
- raise ValueError(f"Unknown model_choose: {model_choose}")
620
-
621
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
622
- if target == 'multi':
623
- class_weights = compute_class_weight(
624
- class_weight='balanced',
625
- classes=np.unique(y_train),
626
- y=y_train
627
- )
628
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
629
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
630
- else:
631
- criterion = nn.BCEWithLogitsLoss()
632
- optimizer = optim.AdamW(model.parameters(), lr=best_params["lr"], weight_decay=best_params["weight_decay"])
633
-
634
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ
635
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
636
-
637
- # ํ•™์Šต ์„ค์ •
638
- epochs = 200
639
- patience = 12
640
- best_fold_csi = 0
641
- counter = 0
642
- best_model = None
643
-
644
- for epoch in range(epochs):
645
- model.train()
646
- for x_num_batch, x_cat_batch, y_batch in train_loader:
647
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
648
-
649
- optimizer.zero_grad()
650
- y_pred = model(x_num_batch, x_cat_batch)
651
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
652
- loss.backward()
653
- optimizer.step()
654
-
655
- # Validation ํ‰๊ฐ€
656
- model.eval()
657
- y_pred_val, y_true_val = [], []
658
- with torch.no_grad():
659
- for x_num_batch, x_cat_batch, y_batch in val_loader:
660
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
661
- output = model(x_num_batch, x_cat_batch)
662
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
663
-
664
- y_pred_val.extend(pred.cpu().numpy())
665
- y_true_val.extend(y_batch.cpu().numpy())
666
-
667
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
668
- val_csi = calculate_csi(y_true_val, y_pred_val)
669
- scheduler.step(val_csi)
670
-
671
- # Early Stopping ์ฒดํฌ
672
- if val_csi > best_fold_csi:
673
- best_fold_csi = val_csi
674
- counter = 0
675
- best_model = copy.deepcopy(model)
676
- else:
677
- counter += 1
678
-
679
- if counter >= patience:
680
- print(f" Early stopping at epoch {epoch+1}, Best CSI: {best_fold_csi:.4f}")
681
- break
682
-
683
- if best_model is None:
684
- best_model = model
685
-
686
- scalers.append(scaler) # scaler ์ €์žฅ (fold ์ˆœ์„œ๋Œ€๋กœ)
687
- models.append(best_model)
688
- print(f" Fold {fold} ํ•™์Šต ์™„๋ฃŒ (๊ฒ€์ฆ CSI: {best_fold_csi:.4f})")
689
-
690
- # ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •
691
- save_dir = f'../save_model/{model_choose}_optima'
692
- os.makedirs(save_dir, exist_ok=True)
693
-
694
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ
695
- if data_sample == 'pure':
696
- model_filename = f'{model_choose}_pure_{region}.pkl'
697
- else:
698
- model_filename = f'{model_choose}_{data_sample}_{region}.pkl'
699
-
700
- model_path = f'{save_dir}/{model_filename}'
701
-
702
- # ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„ ํ•œ ๋ฒˆ์— ์ €์žฅ
703
- joblib.dump(models, model_path)
704
- print(f"\n๋ชจ๋“  ๋ชจ๋ธ ์ €์žฅ ์™„๋ฃŒ: {model_path} (์ด {len(models)}๊ฐœ fold)")
705
-
706
- # Scaler ๋ณ„๋„ ์ €์žฅ
707
- scaler_save_dir = f'../save_model/{model_choose}_optima/scaler'
708
- os.makedirs(scaler_save_dir, exist_ok=True)
709
-
710
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ (๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํŒจํ„ด)
711
- if data_sample == 'pure':
712
- scaler_filename = f'{model_choose}_pure_{region}_scaler.pkl'
713
- else:
714
- scaler_filename = f'{model_choose}_{data_sample}_{region}_scaler.pkl'
715
-
716
- scaler_path = f'{scaler_save_dir}/{scaler_filename}'
717
- joblib.dump(scalers, scaler_path)
718
- print(f"Scaler ์ €์žฅ ์™„๋ฃŒ: {scaler_path} (์ด {len(scalers)}๊ฐœ fold)")
719
-
720
- return model_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_busan.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="busan", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_smote_busan_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="busan",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_daegu.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="daegu", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_smote_daegu_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="daegu",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_daejeon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="daejeon", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_smote_daejeon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="daejeon",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_gwangju.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="gwangju", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_smote_gwangju_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="gwangju",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_incheon.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="incheon", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_smote_incheon_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="incheon",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smote/ft_transformer_smote_seoul.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="seoul", data_sample='smote'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_smote_seoul_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="seoul",
80
- data_sample='smote',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smote/utils.py DELETED
@@ -1,719 +0,0 @@
1
- import torch
2
- import torch.nn as nn
3
- import torch.optim as optim
4
- import numpy as np
5
- import random
6
- import os
7
- import copy
8
- from sklearn.preprocessing import QuantileTransformer, LabelEncoder
9
- from torch.utils.data import DataLoader, TensorDataset
10
- from sklearn.metrics import confusion_matrix
11
- from sklearn.utils.class_weight import compute_class_weight
12
- import pandas as pd
13
- import optuna
14
- from sklearn.metrics import accuracy_score, f1_score
15
- import joblib
16
-
17
-
18
- import sys
19
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ models ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
20
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
21
- models_path = os.path.abspath(os.path.join(current_file_dir, '../../models'))
22
- sys.path.insert(0, models_path)
23
- from ft_transformer import FTTransformer
24
- from resnet_like import ResNetLike
25
- from deepgbm import DeepGBM
26
- import warnings
27
- warnings.filterwarnings('ignore')
28
-
29
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
30
- seed = 42
31
- random.seed(seed)
32
- np.random.seed(seed)
33
-
34
- # PyTorch ์‹œ๋“œ ๊ณ ์ •
35
- torch.manual_seed(seed)
36
- torch.cuda.manual_seed(seed)
37
- torch.cuda.manual_seed_all(seed) # Multi-GPU ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ์‹œ๋“œ ์ ์šฉ
38
-
39
- # PyTorch ์—ฐ์‚ฐ์˜ ๊ฒฐ์ •์  ๋ชจ๋“œ ์„ค์ •
40
- torch.backends.cudnn.deterministic = True # ์‹คํ–‰๋งˆ๋‹ค ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ
41
- torch.backends.cudnn.benchmark = True # ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™” (๊ฐ€๋Šฅํ•œ ํ•œ ๋น ๋ฅธ ์—ฐ์‚ฐ ์ˆ˜ํ–‰)
42
-
43
-
44
- def add_derived_features(df: pd.DataFrame) -> pd.DataFrame:
45
- """
46
- ์ œ๊ฑฐํ–ˆ๋˜ ํŒŒ์ƒ ๋ณ€์ˆ˜๋“ค์„ ๋ณต๊ตฌ
47
-
48
- Args:
49
- df: ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
50
-
51
- Returns:
52
- ํŒŒ์ƒ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
53
- """
54
- df = df.copy()
55
- df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
56
- df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
57
- df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
58
- df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
59
- df['ground_temp - temp_C'] = df['groundtemp'] - df['temp_C']
60
- return df
61
-
62
- def preprocessing(df):
63
- """๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜.
64
-
65
- Args:
66
- df: ์›๋ณธ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
67
-
68
- Returns:
69
- ์ „์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„
70
- """
71
- df = df[df.columns].copy()
72
- df['year'] = df['year'].astype('int')
73
- df['month'] = df['month'].astype('int')
74
- df['hour'] = df['hour'].astype('int')
75
- df = add_derived_features(df).copy()
76
- df['multi_class'] = df['multi_class'].astype('int')
77
- df.loc[df['wind_dir']=='์ •์˜จ', 'wind_dir'] = "0"
78
- df['wind_dir'] = df['wind_dir'].astype('int')
79
- df = df[['temp_C', 'precip_mm', 'wind_speed', 'wind_dir', 'hm',
80
- 'vap_pressure', 'dewpoint_C', 'loc_pressure', 'sea_pressure',
81
- 'solarRad', 'snow_cm', 'cloudcover', 'lm_cloudcover', 'low_cloudbase',
82
- 'groundtemp', 'O3', 'NO2', 'PM10', 'PM25', 'year',
83
- 'month', 'hour', 'ground_temp - temp_C', 'hour_sin', 'hour_cos',
84
- 'month_sin', 'month_cos','multi_class']].copy()
85
- return df
86
-
87
-
88
- # ๋ฐ์ดํ„ฐ์…‹ ์ค€๋น„ ํ•จ์ˆ˜
89
- def prepare_dataset(region, data_sample='pure', target='multi', fold=3):
90
-
91
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
92
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
93
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
94
-
95
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
96
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
97
- if data_sample == 'pure':
98
- train_path = dat_path
99
- else:
100
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
101
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
102
- drop_col = ['multi_class','year']
103
- target_col = f'{target}_class'
104
-
105
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
106
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
107
- if data_sample == 'pure':
108
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
109
- else:
110
- region_train = preprocessing(pd.read_csv(train_path))
111
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
112
- region_test = preprocessing(pd.read_csv(test_path))
113
-
114
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
115
- common_columns = region_train.columns.to_list()
116
- train_data = region_train[common_columns]
117
- val_data = region_val[common_columns]
118
- test_data = region_test[common_columns]
119
-
120
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
121
- X_train = train_data.drop(columns=drop_col)
122
- y_train = train_data[target_col]
123
- X_val = val_data.drop(columns=drop_col)
124
- y_val = val_data[target_col]
125
- X_test = test_data.drop(columns=drop_col)
126
- y_test = test_data[target_col]
127
-
128
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
129
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
130
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
131
-
132
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
133
- label_encoders = {}
134
- for col in categorical_cols:
135
- le = LabelEncoder()
136
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
137
- label_encoders[col] = le
138
-
139
- # ๋ณ€ํ™˜ ์ ์šฉ
140
- for col in categorical_cols:
141
- X_train[col] = label_encoders[col].transform(X_train[col])
142
- X_val[col] = label_encoders[col].transform(X_val[col])
143
- X_test[col] = label_encoders[col].transform(X_test[col])
144
-
145
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
146
- scaler = QuantileTransformer(output_distribution='normal')
147
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
148
-
149
- # ๋ณ€ํ™˜ ์ ์šฉ
150
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
151
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
152
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
153
-
154
- return X_train, X_val, X_test, y_train, y_val, y_test, categorical_cols, numerical_cols
155
-
156
-
157
-
158
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜
159
- def prepare_dataloader(region, data_sample='pure', target='multi', fold=3, random_state=None):
160
-
161
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
162
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
163
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
164
-
165
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
166
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
167
- if data_sample == 'pure':
168
- train_path = dat_path
169
- else:
170
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
171
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
172
- drop_col = ['multi_class','year']
173
- target_col = f'{target}_class'
174
-
175
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
176
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
177
- if data_sample == 'pure':
178
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
179
- else:
180
- region_train = preprocessing(pd.read_csv(train_path))
181
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
182
- region_test = preprocessing(pd.read_csv(test_path))
183
-
184
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
185
- common_columns = region_train.columns.to_list()
186
- train_data = region_train[common_columns]
187
- val_data = region_val[common_columns]
188
- test_data = region_test[common_columns]
189
-
190
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
191
- X_train = train_data.drop(columns=drop_col)
192
- y_train = train_data[target_col]
193
- X_val = val_data.drop(columns=drop_col)
194
- y_val = val_data[target_col]
195
- X_test = test_data.drop(columns=drop_col)
196
- y_test = test_data[target_col]
197
-
198
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
199
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
200
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
201
-
202
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
203
- label_encoders = {}
204
- for col in categorical_cols:
205
- le = LabelEncoder()
206
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
207
- label_encoders[col] = le
208
-
209
- # ๋ณ€ํ™˜ ์ ์šฉ
210
- for col in categorical_cols:
211
- X_train[col] = label_encoders[col].transform(X_train[col])
212
- X_val[col] = label_encoders[col].transform(X_val[col])
213
- X_test[col] = label_encoders[col].transform(X_test[col])
214
-
215
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
216
- scaler = QuantileTransformer(output_distribution='normal')
217
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
218
-
219
- # ๋ณ€ํ™˜ ์ ์šฉ
220
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
221
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
222
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
223
-
224
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
225
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
226
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
227
-
228
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
229
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
230
-
231
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
232
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
233
-
234
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
235
- if target == "binary":
236
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
237
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
238
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
239
- elif target == "multi":
240
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
241
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
242
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
243
- else:
244
- raise ValueError("target must be 'binary' or 'multi'")
245
-
246
- # TensorDataset ์ƒ์„ฑ
247
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
248
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
249
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
250
-
251
- # DataLoader ์ƒ์„ฑ
252
- if random_state == None:
253
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
254
- else:
255
- train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, generator=torch.Generator().manual_seed(random_state))
256
- val_loader = DataLoader(val_dataset, batch_size=64, shuffle=False)
257
- test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
258
-
259
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader
260
-
261
- # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ dataloader ์ƒ์„ฑ ํ•จ์ˆ˜ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€ ๋ฒ„์ „)
262
- def prepare_dataloader_with_batchsize(region, data_sample='pure', target='multi', fold=3, random_state=None, batch_size=64):
263
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
264
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
265
- data_base_dir = os.path.abspath(os.path.join(current_file_dir, '../../../data'))
266
-
267
- # ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ์ง€์ •
268
- dat_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_train.csv")
269
- if data_sample == 'pure':
270
- train_path = dat_path
271
- else:
272
- train_path = os.path.join(data_base_dir, f'data_oversampled/{data_sample}/{data_sample}_{fold}_{region}.csv')
273
- test_path = os.path.join(data_base_dir, f"data_for_modeling/{region}_test.csv")
274
- drop_col = ['multi_class','year']
275
- target_col = f'{target}_class'
276
-
277
- # ๋ฐ์ดํ„ฐ ๋กœ๋“œ
278
- region_dat = preprocessing(pd.read_csv(dat_path, index_col=0))
279
- if data_sample == 'pure':
280
- region_train = region_dat.loc[~region_dat['year'].isin([2021-fold]), :]
281
- else:
282
- region_train = preprocessing(pd.read_csv(train_path))
283
- region_val = region_dat.loc[region_dat['year'].isin([2021-fold]), :]
284
- region_test = preprocessing(pd.read_csv(test_path))
285
-
286
- # ์ปฌ๋Ÿผ ์ •๋ ฌ (์ผ๊ด€์„ฑ ์œ ์ง€)
287
- common_columns = region_train.columns.to_list()
288
- train_data = region_train[common_columns]
289
- val_data = region_val[common_columns]
290
- test_data = region_test[common_columns]
291
-
292
- # ์„ค๋ช…๋ณ€์ˆ˜ & ํƒ€๊ฒŸ ๋ถ„๋ฆฌ
293
- X_train = train_data.drop(columns=drop_col)
294
- y_train = train_data[target_col]
295
- X_val = val_data.drop(columns=drop_col)
296
- y_val = val_data[target_col]
297
- X_test = test_data.drop(columns=drop_col)
298
- y_test = test_data[target_col]
299
-
300
- # ๋ฒ”์ฃผํ˜• & ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
301
- categorical_cols = X_train.select_dtypes(include=['object', 'category', 'int64']).columns
302
- numerical_cols = X_train.select_dtypes(include=['float64']).columns
303
-
304
- # ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ Label Encoding
305
- label_encoders = {}
306
- for col in categorical_cols:
307
- le = LabelEncoder()
308
- le.fit(X_train[col]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
309
- label_encoders[col] = le
310
-
311
- # ๋ณ€ํ™˜ ์ ์šฉ
312
- for col in categorical_cols:
313
- X_train[col] = label_encoders[col].transform(X_train[col])
314
- X_val[col] = label_encoders[col].transform(X_val[col])
315
- X_test[col] = label_encoders[col].transform(X_test[col])
316
-
317
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜ Quantile Transformation
318
- scaler = QuantileTransformer(output_distribution='normal')
319
- scaler.fit(X_train[numerical_cols]) # Train ๋ฐ์ดํ„ฐ ๊ธฐ์ค€์œผ๋กœ ํ•™์Šต
320
-
321
- # ๋ณ€ํ™˜ ์ ์šฉ
322
- X_train[numerical_cols] = scaler.transform(X_train[numerical_cols])
323
- X_val[numerical_cols] = scaler.transform(X_val[numerical_cols])
324
- X_test[numerical_cols] = scaler.transform(X_test[numerical_cols])
325
-
326
- # ์—ฐ์†ํ˜• ๋ณ€์ˆ˜์™€ ๋ฒ”์ฃผํ˜• ๋ณ€์ˆ˜ ๋ถ„๋ฆฌ
327
- X_train_num = torch.tensor(X_train[numerical_cols].values, dtype=torch.float32)
328
- X_train_cat = torch.tensor(X_train[categorical_cols].values, dtype=torch.long)
329
-
330
- X_val_num = torch.tensor(X_val[numerical_cols].values, dtype=torch.float32)
331
- X_val_cat = torch.tensor(X_val[categorical_cols].values, dtype=torch.long)
332
-
333
- X_test_num = torch.tensor(X_test[numerical_cols].values, dtype=torch.float32)
334
- X_test_cat = torch.tensor(X_test[categorical_cols].values, dtype=torch.long)
335
-
336
- # ๋ ˆ์ด๋ธ” ๋ณ€ํ™˜
337
- if target == "binary":
338
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32) # ์ด์ง„ ๋ถ„๋ฅ˜ โ†’ float32
339
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.float32)
340
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32)
341
- elif target == "multi":
342
- y_train_tensor = torch.tensor(y_train.values, dtype=torch.long) # ๋‹ค์ค‘ ๋ถ„๋ฅ˜ โ†’ long
343
- y_val_tensor = torch.tensor(y_val.values, dtype=torch.long)
344
- y_test_tensor = torch.tensor(y_test.values, dtype=torch.long)
345
- else:
346
- raise ValueError("target must be 'binary' or 'multi'")
347
-
348
- # TensorDataset ์ƒ์„ฑ
349
- train_dataset = TensorDataset(X_train_num, X_train_cat, y_train_tensor)
350
- val_dataset = TensorDataset(X_val_num, X_val_cat, y_val_tensor)
351
- test_dataset = TensorDataset(X_test_num, X_test_cat, y_test_tensor)
352
-
353
- # DataLoader ์ƒ์„ฑ (batch_size ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ)
354
- if random_state == None:
355
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
356
- else:
357
- train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(random_state))
358
- val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
359
- test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
360
-
361
- return X_train, categorical_cols, numerical_cols, train_loader, val_loader, test_loader, y_train, scaler
362
-
363
-
364
- def calculate_csi(y_true, pred):
365
-
366
- cm = confusion_matrix(y_true, pred) # ๋ณ€์ˆ˜ ์ด๋ฆ„์„ cm์œผ๋กœ ๋ณ€๊ฒฝ
367
- # ํ˜ผ๋™ ํ–‰๋ ฌ์—์„œ H, F, M ์ถ”์ถœ
368
- H = (cm[0, 0] + cm[1, 1])
369
-
370
- F = (cm[1, 0] + cm[2, 0] +
371
- cm[0, 1] + cm[2, 1])
372
-
373
- M = (cm[0, 2] + cm[1, 2])
374
-
375
- # CSI ๊ณ„์‚ฐ
376
- CSI = H / (H + F + M + 1e-10)
377
- return CSI
378
-
379
- def sample_weight(y_train):
380
- class_weights = compute_class_weight(
381
- class_weight='balanced',
382
- classes=np.unique(y_train), # ๊ณ ์œ  ํด๋ž˜์Šค
383
- y=y_train # ํ•™์Šต ๋ฐ์ดํ„ฐ ๋ ˆ์ด๋ธ”
384
- )
385
- sample_weights = np.array([class_weights[label] for label in y_train])
386
-
387
- return sample_weights
388
-
389
- # ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™” ํ•จ์ˆ˜ ์ •์˜
390
- def objective(trial, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
391
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
392
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
393
- val_scores = []
394
-
395
- # --- 1. ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ํƒ์ƒ‰ ๋ฒ”์œ„ ์ •์˜ (์ˆ˜์ •๋จ) ---
396
- if model_choose == "ft_transformer":
397
- d_token = trial.suggest_int("d_token", 64, 256, step=32)
398
- n_blocks = trial.suggest_int("n_blocks", 2, 6) # ๊นŠ์ด ์ถ•์†Œ๋กœ ๊ณผ์ ํ•ฉ ๋ฐฉ์ง€
399
- n_heads = trial.suggest_categorical("n_heads", [4, 8])
400
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
401
- if d_token % n_heads != 0:
402
- d_token = (d_token // n_heads) * n_heads
403
-
404
- attention_dropout = trial.suggest_float("attention_dropout", 0.1, 0.4)
405
- ffn_dropout = trial.suggest_float("ffn_dropout", 0.1, 0.4)
406
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True) # ๋ฒ”์œ„ ํ™•๋Œ€
407
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
408
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
409
-
410
- elif model_choose == 'resnet_like':
411
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
412
- d_hidden = trial.suggest_int("d_hidden", 64, 512, step=64)
413
- n_blocks = trial.suggest_int("n_blocks", 2, 5) # ๋„ˆ๋ฌด ๊นŠ์ง€ ์•Š๊ฒŒ ์กฐ์ ˆ
414
- dropout_first = trial.suggest_float("dropout_first", 0.1, 0.4)
415
- dropout_second = trial.suggest_float("dropout_second", 0.0, 0.2)
416
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
417
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
418
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
419
-
420
- elif model_choose == 'deepgbm':
421
- # DeepGBM์˜ ๊ฒฝ์šฐ ๋ชจ๋ธ ํŠน์„ฑ์— ๋งž์ถฐ ResNet ๋ธ”๋ก ๋ฐ ์ž„๋ฒ ๋”ฉ ์ฐจ์› ์กฐ์ ˆ
422
- d_main = trial.suggest_int("d_main", 64, 256, step=32)
423
- d_hidden = trial.suggest_int("d_hidden", 64, 256, step=64)
424
- n_blocks = trial.suggest_int("n_blocks", 2, 6)
425
- dropout = trial.suggest_float("dropout", 0.1, 0.4)
426
- lr = trial.suggest_float("lr", 1e-5, 1e-2, log=True)
427
- weight_decay = trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True) # ๋” ๊ณต๊ฒฉ์ ์ธ ๋ฒ”์œ„๋กœ ํ™•์žฅ
428
- batch_size = trial.suggest_categorical("batch_size", [32, 64, 128, 256]) # Batch Size ์ถ”๊ฐ€
429
-
430
- # --- 2. Fold๋ณ„ ํ•™์Šต ๋ฐ ๊ต์ฐจ ๊ฒ€์ฆ ---
431
- for fold in range(1, n_folds + 1):
432
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, _ = prepare_dataloader_with_batchsize(
433
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
434
- )
435
-
436
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
437
- if model_choose == "ft_transformer":
438
- model = FTTransformer(
439
- num_features=len(numerical_cols),
440
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
441
- d_token=d_token,
442
- n_blocks=n_blocks,
443
- n_heads=n_heads,
444
- attention_dropout=attention_dropout,
445
- ffn_dropout=ffn_dropout,
446
- num_classes=3
447
- ).to(device)
448
- elif model_choose == 'resnet_like':
449
- input_dim = len(numerical_cols) + len(categorical_cols)
450
- model = ResNetLike(
451
- input_dim=input_dim,
452
- d_main=d_main,
453
- d_hidden=d_hidden,
454
- n_blocks=n_blocks,
455
- dropout_first=dropout_first,
456
- dropout_second=dropout_second,
457
- num_classes=3
458
- ).to(device)
459
- elif model_choose == 'deepgbm':
460
- model = DeepGBM(
461
- num_features=len(numerical_cols),
462
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
463
- d_main=d_main,
464
- d_hidden=d_hidden,
465
- n_blocks=n_blocks,
466
- dropout=dropout,
467
- num_classes=3
468
- ).to(device)
469
-
470
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
471
- if target == 'multi':
472
- class_weights = compute_class_weight(
473
- class_weight='balanced',
474
- classes=np.unique(y_train),
475
- y=y_train
476
- )
477
- # ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜ ๋กœ๊ทธ ์ถœ๋ ฅ
478
- unique_classes = np.unique(y_train)
479
- class_counts = {cls: np.sum(y_train == cls) for cls in unique_classes}
480
- print(f" Fold {fold} - ํด๋ž˜์Šค๋ณ„ ๊ฐ€์ค‘์น˜: {dict(zip(unique_classes, class_weights))} (ํด๋ž˜์Šค๋ณ„ ์ƒ˜ํ”Œ ์ˆ˜: {class_counts})")
481
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
482
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
483
- else:
484
- criterion = nn.BCEWithLogitsLoss()
485
- optimizer = optim.AdamW(model.parameters(), lr=lr, weight_decay=weight_decay)
486
-
487
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ ์ถ”๊ฐ€: ์„ฑ๋Šฅ ์ •์ฒด ์‹œ LR์„ 0.5๋ฐฐ ๊ฐ์†Œ (๊ฒ€์ฆ CSI ๊ธฐ์ค€)
488
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
489
-
490
- # ํ•™์Šต ์„ค์ • (์—ํญ ๋ฐ ํŽ˜์ด์…˜์Šค ์ƒํ–ฅ)
491
- epochs = 200
492
- patience = 12 # ๋”ฅ๋Ÿฌ๋‹์˜ ์ •์ฒด ๊ตฌ๊ฐ„์„ ๊ณ ๋ คํ•˜์—ฌ ์†Œํญ ์ƒํ–ฅ
493
- best_fold_csi = 0
494
- counter = 0
495
-
496
- for epoch in range(epochs):
497
- model.train()
498
- for x_num_batch, x_cat_batch, y_batch in train_loader:
499
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
500
-
501
- optimizer.zero_grad()
502
- y_pred = model(x_num_batch, x_cat_batch)
503
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
504
- loss.backward()
505
- optimizer.step()
506
-
507
- # Validation ํ‰๊ฐ€
508
- model.eval()
509
- y_pred_val, y_true_val = [], []
510
- with torch.no_grad():
511
- for x_num_batch, x_cat_batch, y_batch in val_loader:
512
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
513
- output = model(x_num_batch, x_cat_batch)
514
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
515
-
516
- y_pred_val.extend(pred.cpu().numpy())
517
- y_true_val.extend(y_batch.cpu().numpy())
518
-
519
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
520
- val_csi = calculate_csi(y_true_val, y_pred_val)
521
- scheduler.step(val_csi)
522
-
523
- # Optuna Pruning ์ ์šฉ (์ฒซ ๋ฒˆ์งธ Fold์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ ํŒ๋‹จ ๊ฐ•ํ™”)
524
- trial.report(val_csi, epoch)
525
- if trial.should_prune():
526
- raise optuna.exceptions.TrialPruned()
527
-
528
- # Early Stopping ์ฒดํฌ
529
- if val_csi > best_fold_csi:
530
- best_fold_csi = val_csi
531
- counter = 0
532
- else:
533
- counter += 1
534
-
535
- if counter >= patience:
536
- break
537
-
538
- val_scores.append(best_fold_csi)
539
-
540
- # ๋ชจ๋“  fold์˜ ํ‰๊ท  ์„ฑ๋Šฅ ๋ฐ˜ํ™˜
541
- return np.mean(val_scores)
542
-
543
-
544
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ํ•จ์ˆ˜
545
- def train_final_model(best_params, model_choose, region, data_sample='pure', target='multi', n_folds=3, random_state=42):
546
- """
547
- ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ์„ ํ•™์Šตํ•˜๊ณ  ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
548
-
549
- Args:
550
- best_params: ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ ๋”•์…”๋„ˆ๋ฆฌ
551
- model_choose: ๋ชจ๋ธ ์„ ํƒ ('ft_transformer', 'resnet_like', 'deepgbm')
552
- region: ์ง€์—ญ๋ช…
553
- data_sample: ๋ฐ์ดํ„ฐ ์ƒ˜ํ”Œ ํƒ€์ž… ('pure', 'smote', etc.)
554
- target: ํƒ€๊ฒŸ ํƒ€์ž… ('multi', 'binary')
555
- n_folds: ๊ต์ฐจ ๊ฒ€์ฆ fold ์ˆ˜
556
- random_state: ๋žœ๋ค ์‹œ๋“œ
557
-
558
- Returns:
559
- ์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ ๋ฆฌ์ŠคํŠธ
560
- """
561
- # GPU ์‚ฌ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํ™•์ธ ๋ฐ device ์„ค์ •
562
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
563
-
564
- models = []
565
- scalers = [] # scaler ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€
566
-
567
- print("์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘...")
568
-
569
- for fold in range(1, n_folds + 1):
570
- print(f"Fold {fold} ํ•™์Šต ์ค‘...")
571
-
572
- # ์ตœ์ ํ™”๋œ batch_size ์‚ฌ์šฉ
573
- batch_size = best_params.get("batch_size", 64)
574
- X_train_df, categorical_cols, numerical_cols, train_loader, val_loader, _, y_train, scaler = prepare_dataloader_with_batchsize(
575
- region, data_sample=data_sample, target=target, fold=fold, random_state=random_state, batch_size=batch_size
576
- )
577
-
578
- # ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
579
- if model_choose == "ft_transformer":
580
- d_token = best_params["d_token"]
581
- n_heads = best_params.get("n_heads", 8)
582
- # d_token์€ n_heads์˜ ๋ฐฐ์ˆ˜์—ฌ์•ผ ํ•จ (FT-Transformer์˜ ๊ตฌ์กฐ์  ์ œ์•ฝ ๋Œ€์‘)
583
- if d_token % n_heads != 0:
584
- d_token = (d_token // n_heads) * n_heads
585
-
586
- model = FTTransformer(
587
- num_features=len(numerical_cols),
588
- cat_cardinalities=[len(X_train_df[col].unique()) for col in categorical_cols],
589
- d_token=d_token,
590
- n_blocks=best_params["n_blocks"],
591
- n_heads=n_heads,
592
- attention_dropout=best_params["attention_dropout"],
593
- ffn_dropout=best_params["ffn_dropout"],
594
- num_classes=3
595
- ).to(device)
596
- elif model_choose == 'resnet_like':
597
- input_dim = len(numerical_cols) + len(categorical_cols)
598
- model = ResNetLike(
599
- input_dim=input_dim,
600
- d_main=best_params["d_main"],
601
- d_hidden=best_params["d_hidden"],
602
- n_blocks=best_params["n_blocks"],
603
- dropout_first=best_params["dropout_first"],
604
- dropout_second=best_params["dropout_second"],
605
- num_classes=3
606
- ).to(device)
607
- elif model_choose == 'deepgbm':
608
- model = DeepGBM(
609
- num_features=len(numerical_cols),
610
- cat_features=[len(X_train_df[col].unique()) for col in categorical_cols],
611
- d_main=best_params["d_main"],
612
- d_hidden=best_params["d_hidden"],
613
- n_blocks=best_params["n_blocks"],
614
- dropout=best_params["dropout"],
615
- num_classes=3
616
- ).to(device)
617
- else:
618
- raise ValueError(f"Unknown model_choose: {model_choose}")
619
-
620
- # ํด๋ž˜์Šค ๊ฐ€์ค‘์น˜ ๊ณ„์‚ฐ ๋ฐ ์†์‹ค ํ•จ์ˆ˜ ์„ค์ • (Label Smoothing ์ ์šฉ)
621
- if target == 'multi':
622
- class_weights = compute_class_weight(
623
- class_weight='balanced',
624
- classes=np.unique(y_train),
625
- y=y_train
626
- )
627
- class_weights_tensor = torch.tensor(class_weights, dtype=torch.float32).to(device)
628
- criterion = nn.CrossEntropyLoss(weight=class_weights_tensor, label_smoothing=0.0) # Label Smoothing ์ถ”๊ฐ€
629
- else:
630
- criterion = nn.BCEWithLogitsLoss()
631
- optimizer = optim.AdamW(model.parameters(), lr=best_params["lr"], weight_decay=best_params["weight_decay"])
632
-
633
- # ํ•™์Šต๋ฅ  ์Šค์ผ€์ค„๋Ÿฌ
634
- scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=3)
635
-
636
- # ํ•™์Šต ์„ค์ •
637
- epochs = 200
638
- patience = 12
639
- best_fold_csi = 0
640
- counter = 0
641
- best_model = None
642
-
643
- for epoch in range(epochs):
644
- model.train()
645
- for x_num_batch, x_cat_batch, y_batch in train_loader:
646
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
647
-
648
- optimizer.zero_grad()
649
- y_pred = model(x_num_batch, x_cat_batch)
650
- loss = criterion(y_pred, y_batch if target == 'multi' else y_batch.float())
651
- loss.backward()
652
- optimizer.step()
653
-
654
- # Validation ํ‰๊ฐ€
655
- model.eval()
656
- y_pred_val, y_true_val = [], []
657
- with torch.no_grad():
658
- for x_num_batch, x_cat_batch, y_batch in val_loader:
659
- x_num_batch, x_cat_batch, y_batch = x_num_batch.to(device), x_cat_batch.to(device), y_batch.to(device)
660
- output = model(x_num_batch, x_cat_batch)
661
- pred = output.argmax(dim=1) if target == 'multi' else (torch.sigmoid(output) >= 0.5).long()
662
-
663
- y_pred_val.extend(pred.cpu().numpy())
664
- y_true_val.extend(y_batch.cpu().numpy())
665
-
666
- # CSI ๊ณ„์‚ฐ ๋ฐ ์Šค์ผ€์ค„๋Ÿฌ ์—…๋ฐ์ดํŠธ
667
- val_csi = calculate_csi(y_true_val, y_pred_val)
668
- scheduler.step(val_csi)
669
-
670
- # Early Stopping ์ฒดํฌ
671
- if val_csi > best_fold_csi:
672
- best_fold_csi = val_csi
673
- counter = 0
674
- best_model = copy.deepcopy(model)
675
- else:
676
- counter += 1
677
-
678
- if counter >= patience:
679
- print(f" Early stopping at epoch {epoch+1}, Best CSI: {best_fold_csi:.4f}")
680
- break
681
-
682
- if best_model is None:
683
- best_model = model
684
-
685
- scalers.append(scaler) # scaler ์ €์žฅ (fold ์ˆœ์„œ๋Œ€๋กœ)
686
- models.append(best_model)
687
- print(f" Fold {fold} ํ•™์Šต ์™„๋ฃŒ (๊ฒ€์ฆ CSI: {best_fold_csi:.4f})")
688
-
689
- # ๋ชจ๋ธ ์ €์žฅ ๊ฒฝ๋กœ ์„ค์ •
690
- save_dir = f'../save_model/{model_choose}_optima'
691
- os.makedirs(save_dir, exist_ok=True)
692
-
693
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ
694
- if data_sample == 'pure':
695
- model_filename = f'{model_choose}_pure_{region}.pkl'
696
- else:
697
- model_filename = f'{model_choose}_{data_sample}_{region}.pkl'
698
-
699
- model_path = f'{save_dir}/{model_filename}'
700
-
701
- # ๋ฆฌ์ŠคํŠธ์— ๋‹ด์•„ ํ•œ ๋ฒˆ์— ์ €์žฅ
702
- joblib.dump(models, model_path)
703
- print(f"\n๋ชจ๋“  ๋ชจ๋ธ ์ €์žฅ ์™„๋ฃŒ: {model_path} (์ด {len(models)}๊ฐœ fold)")
704
-
705
- # Scaler ๋ณ„๋„ ์ €์žฅ
706
- scaler_save_dir = f'../save_model/{model_choose}_optima/scaler'
707
- os.makedirs(scaler_save_dir, exist_ok=True)
708
-
709
- # ํŒŒ์ผ๋ช… ์ƒ์„ฑ (๋ชจ๋ธ๊ณผ ๋™์ผํ•œ ํŒจํ„ด)
710
- if data_sample == 'pure':
711
- scaler_filename = f'{model_choose}_pure_{region}_scaler.pkl'
712
- else:
713
- scaler_filename = f'{model_choose}_{data_sample}_{region}_scaler.pkl'
714
-
715
- scaler_path = f'{scaler_save_dir}/{scaler_filename}'
716
- joblib.dump(scalers, scaler_path)
717
- print(f"Scaler ์ €์žฅ ์™„๋ฃŒ: {scaler_path} (์ด {len(scalers)}๊ฐœ fold)")
718
-
719
- return model_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Analysis_code/5.optima/ft_transformer_smotenc_ctgan20000/ft_transformer_smotenc_ctgan20000_busan.py DELETED
@@ -1,97 +0,0 @@
1
- import optuna
2
- import numpy as np
3
- import random
4
- import pandas as pd
5
- import joblib
6
- import os
7
- import torch
8
- from utils import *
9
- # Python ๋ฐ Numpy ์‹œ๋“œ ๊ณ ์ •
10
- seed = 42
11
- random.seed(seed)
12
- np.random.seed(seed)
13
-
14
-
15
- # 1. Study ์ƒ์„ฑ ์‹œ 'maximize'๋กœ ์„ค์ •
16
- study = optuna.create_study(
17
- direction="maximize", # CSI ์ ์ˆ˜๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์œผ๋ฏ€๋กœ maximize
18
- pruner=optuna.pruners.MedianPruner(n_warmup_steps=10) # ์ดˆ๋ฐ˜ 10์—ํญ์€ ์ง€์ผœ๋ณด๊ณ  ์ดํ›„ ๊ฐ€์ง€์น˜๊ธฐ
19
- )
20
- # Trial ์™„๋ฃŒ ์‹œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅํ•˜๋Š” callback ํ•จ์ˆ˜
21
- def print_trial_callback(study, trial):
22
- """๊ฐ trial ์™„๋ฃŒ ์‹œ best value๋ฅผ ํฌํ•จํ•œ ์ƒ์„ธ ์ •๋ณด ์ถœ๋ ฅ"""
23
- print(f"\n{'='*80}")
24
- print(f"Trial {trial.number} ์™„๋ฃŒ")
25
- print(f" Value (CSI): {trial.value:.6f}" if trial.value is not None else f" Value: {trial.value}")
26
- print(f" Parameters: {trial.params}")
27
- print(f" Best Value (CSI): {study.best_value:.6f}" if study.best_value is not None else f" Best Value: {study.best_value}")
28
- print(f" Best Trial: {study.best_trial.number}")
29
- print(f" Best Parameters: {study.best_params}")
30
- print(f"{'='*80}\n")
31
-
32
-
33
-
34
- # 2. ์ตœ์ ํ™” ์‹คํ–‰
35
- study.optimize(
36
- lambda trial: objective(trial, model_choose="ft_transformer", region="busan", data_sample='smotenc_ctgan20000'),
37
- n_trials=100
38
- ,
39
- callbacks=[print_trial_callback]
40
- )
41
-
42
- # 3. ๊ฒฐ๊ณผ ํ™•์ธ ๋ฐ ์š”์•ฝ
43
- print(f"\n์ตœ์ ํ™” ์™„๋ฃŒ.")
44
- print(f"Best CSI Score: {study.best_value:.4f}")
45
- print(f"Best Hyperparameters: {study.best_params}")
46
-
47
- try:
48
- # ๋ชจ๋“  trial์˜ CSI ์ ์ˆ˜ ์ถ”์ถœ
49
- csi_scores = [trial.value for trial in study.trials if trial.value is not None]
50
-
51
- if len(csi_scores) > 0:
52
- print(f"\n์ตœ์ ํ™” ๊ณผ์ • ์š”์•ฝ:")
53
- print(f" - ์ด ์‹œ๋„ ํšŸ์ˆ˜: {len(study.trials)}")
54
- print(f" - ์„ฑ๊ณตํ•œ ์‹œ๋„: {len(csi_scores)}")
55
- print(f" - ์ตœ์ดˆ CSI: {csi_scores[0]:.4f}")
56
- print(f" - ์ตœ์ข… CSI: {csi_scores[-1]:.4f}")
57
- print(f" - ์ตœ๊ณ  CSI: {max(csi_scores):.4f}")
58
- print(f" - ์ตœ์ € CSI: {min(csi_scores):.4f}")
59
- print(f" - ํ‰๊ท  CSI: {np.mean(csi_scores):.4f}")
60
-
61
- # Study ๊ฐ์ฒด ์ €์žฅ
62
- # ํŒŒ์ผ ์œ„์น˜ ๊ธฐ๋ฐ˜์œผ๋กœ base ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ ์„ค์ •
63
- current_file_dir = os.path.dirname(os.path.abspath(__file__))
64
- base_dir = os.path.dirname(os.path.dirname(current_file_dir)) # 5.optima ๋””๋ ‰ํ† ๋ฆฌ
65
- os.makedirs(os.path.join(base_dir, "optimization_history"), exist_ok=True)
66
- study_path = os.path.join(base_dir, "optimization_history/ft_transformer_smotenc_ctgan20000_busan_trials.pkl")
67
- joblib.dump(study, study_path)
68
- print(f"\n์ตœ์ ํ™” Study ๊ฐ์ฒด๊ฐ€ {study_path}์— ์ €์žฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
69
-
70
- # ์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ
71
- print("\n" + "="*50)
72
- print("์ตœ์ ํ™”๋œ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ์‹œ์ž‘")
73
- print("="*50)
74
-
75
- best_params = study.best_params
76
- model_path = train_final_model(
77
- best_params=best_params,
78
- model_choose="ft_transformer",
79
- region="busan",
80
- data_sample='smotenc_ctgan20000',
81
- target='multi',
82
- n_folds=3,
83
- random_state=seed
84
- )
85
-
86
- print(f"\n์ตœ์ข… ๋ชจ๋ธ ํ•™์Šต ๋ฐ ์ €์žฅ ์™„๋ฃŒ!")
87
- print(f"์ €์žฅ๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ: {model_path}")
88
-
89
- except Exception as e:
90
- print(f"\nโš ๏ธ ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ถ„์„ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
91
- import traceback
92
- traceback.print_exc()
93
-
94
- # ์ •์ƒ ์ข…๋ฃŒ
95
- import sys
96
- sys.exit(0)
97
-