bong9513 commited on
Commit
660afd5
·
verified ·
1 Parent(s): c791ea8

Delete README.md

Browse files
Files changed (1) hide show
  1. README.md +0 -427
README.md DELETED
@@ -1,427 +0,0 @@
1
- ### 가시거리(Visibility) 예측 모델링 프로젝트
2
-
3
- 기상·대기오염 정보(ASOS, DataOn)를 통합해 가시거리(`visi`)를 예측합니다. 불균형 데이터를 SMOTENC/CTGAN으로 보강하고, GBDT(LightGBM/XGBoost)와 탭울러 딥러닝(ResNet-like, FT-Transformer, DeepGBM)을 결합해 다중/이진 분류를 수행합니다.
4
-
5
- ### 기술 스택(Tech Stack)
6
-
7
- - 데이터 처리: `pandas`, `numpy`
8
- - EDA/시각화: `matplotlib`, `seaborn`
9
- - 샘플링/불균형 처리: `imbalanced-learn (SMOTENC)`, `CTGAN`, `Optuna`(CTGAN 하이퍼파라미터), 지역/연도 기반 분할
10
- - 모델링(GBDT): `LightGBM`, `XGBoost`(GPU 옵션 포함, 사용자 정의 CSI 평가)
11
- - 모델링(딥러닝): `PyTorch` 기반 `ResNetLike`, `FTTransformer`, `DeepGBM`
12
- - 최적화: `hyperopt`(LightGBM/XGBoost), `Optuna`(CTGAN)
13
- - 유틸/저장: `joblib`
14
-
15
- ### 시스템 아키텍처(파이프라인)
16
-
17
- 1) 데이터 수집/적재: `data/ASOS`, `data/dataon`
18
- 2) 병합/전처리: `1.data_preprocessing/0.air_data_merge.ipynb` → `1.data_preprocessing/1.data_merge.ipynb` → `1.data_preprocessing/2.eda_preproccesing.ipynb` → `1.data_preprocessing/3.make_train_test.ipynb`
19
- 3) 데이터 증강(불균형 처리): `2.make_oversample_data/` 내 `SMOTENC` → `CTGAN(+Optuna)` → 규칙 기반 필터링
20
- 4) 데이터 분할: 지역별(`*_train.csv`, `*_test.csv`), 연도 기반 3-Fold 홀드아웃
21
- 5) 학습: GBDT(`5.optima/*/`)와 딥러닝 노트북
22
- 6) 평가/분석: 사용자 정의 `CSI` + F1/Accuracy, `visualization/model_visualize.ipynb`, `find_reason/*`(트렌드, 분포 비교)
23
- 7) 앙상블/최종: `model_voting_test_best_sample/ensemble__voting_best_sample.ipynb`, `final_test/final.ipynb`
24
-
25
- ### TL;DR (빠른 시작)
26
-
27
- 1) 파이썬 환경 준비 후 필수 패키지 설치
28
-
29
- ```bash
30
- pip install -U torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
31
- pip install pandas numpy scikit-learn matplotlib seaborn imbalanced-learn optuna ctgan xgboost lightgbm joblib hyperopt
32
- ```
33
-
34
- 2) 데이터 배치
35
- - 원천/중간 산출물을 `data/` 하위에 배치. 학습용 CSV/feather는 `data/data_for_modeling/` 참고.
36
- - 또는 Hugging Face 저장소에서 `data/` 폴더를 다운로드:
37
- ```bash
38
- git clone https://huggingface.co/bong9513/visibility_prediction
39
- # 클론 후 visibility_prediction/data/ 폴더를 프로젝트의 data/ 위치로 복사하거나 사용
40
- ```
41
-
42
- 3) 오버샘플링 수행(SMOTE/CTGAN)
43
-
44
- ```bash
45
- cd Analysis_code/2.make_oversample_data
46
- # SMOTE만 사용하는 경우
47
- python smote_only/smote_sample_1.py
48
- # SMOTENC + CTGAN 사용하는 경우
49
- python smotenc_ctgan/smotenc_ctgan_sample_10000_1.py
50
- ```
51
-
52
- 4) 모델 학습 또는 다운로드
53
- - **옵션 A: 직접 모델 생성**
54
- - GBDT 최적화/학습 예시(서울시):
55
- ```bash
56
- cd Analysis_code/5.optima
57
- python lgb_smote/LGB_smote_seoul.py
58
- python xgb_smote/XGB_smote_seoul.py
59
- ```
60
- - 딥러닝 모델 학습/평가: 노트북 실행(`Analysis_code/` 내 `.ipynb`)
61
- - **옵션 B: 사전 학습된 모델 사용**
62
- - Hugging Face 저장소에서 사전 학습된 모델 다운로드:
63
- ```bash
64
- git clone https://huggingface.co/bong9513/visibility_prediction
65
- # 클론 후 visibility_prediction/save_model/ 폴더를 Analysis_code/save_model/ 위치로 복사
66
- ```
67
-
68
- ---
69
-
70
- ### 프로젝트 구조
71
-
72
- ```
73
- visibility_prediction/
74
- ├── Analysis_code/
75
- │ ├── 1.data_preprocessing/ # 데이터 병합 및 전처리
76
- │ │ ├── 0.air_data_merge.ipynb
77
- │ │ ├── 1.data_merge.ipynb
78
- │ │ ├── 2.eda_preproccesing.ipynb
79
- │ │ └── 3.make_train_test.ipynb
80
- │ ├── 2.make_oversample_data/ # 오버샘플링 (SMOTE/CTGAN)
81
- │ │ ├── smote_only/ # SMOTE만 사용
82
- │ │ ├── only_ctgan/ # CTGAN만 사용
83
- │ │ └── smotenc_ctgan/ # SMOTENC + CTGAN 조합
84
- │ ├── 3.sampled_data_analysis/ # 샘플링 데이터 분석
85
- │ ├── 4.sampling_data_test/ # 샘플링 데이터 성능 테스트
86
- │ ├── 5.optima/ # 모델 최적화 및 학습
87
- │ │ ├── lgb_smote/ # LightGBM (SMOTE)
88
- │ │ ├── lgb_pure/ # LightGBM (원본 데이터)
89
- │ │ ├── lgb_ctgan10000/ # LightGBM (CTGAN 10000)
90
- │ │ ├── lgb_smotenc_ctgan20000/ # LightGBM (SMOTENC+CTGAN 20000)
91
- │ │ ├── xgb_smote/ # XGBoost (SMOTE)
92
- │ │ ├── xgb_pure/ # XGBoost (원본 데이터)
93
- │ │ ├── xgb_ctgan10000/ # XGBoost (CTGAN 10000)
94
- │ │ ├── xgb_smotenc_ctgan20000/ # XGBoost (SMOTENC+CTGAN 20000)
95
- │ │ ├── resnet_like_smote/ # ResNet-like (SMOTE)
96
- │ │ ├── resnet_like_pure/ # ResNet-like (원본 데이터)
97
- │ │ ├── resnet_like_ctgan10000/ # ResNet-like (CTGAN 10000)
98
- │ │ ├── resnet_like_smotenc_ctgan20000/ # ResNet-like (SMOTENC+CTGAN 20000)
99
- │ │ ├── ft_transformer_smote/ # FT-Transformer (SMOTE)
100
- │ │ ├── ft_transformer_pure/ # FT-Transformer (원본 데이터)
101
- │ │ ├── ft_transformer_ctgan10000/ # FT-Transformer (CTGAN 10000)
102
- │ │ ├── ft_transformer_smotenc_ctgan20000/ # FT-Transformer (SMOTENC+CTGAN 20000)
103
- │ │ ├── deepgbm_smote/ # DeepGBM (SMOTE)
104
- │ │ ├── deepgbm_pure/ # DeepGBM (원본 데이터)
105
- │ │ ├── deepgbm_ctgan10000/ # DeepGBM (CTGAN 10000)
106
- │ │ └── deepgbm_smotenc_ctgan20000/ # DeepGBM (SMOTENC+CTGAN 20000)
107
- │ ├── 6.optima_models_analysis/ # 최적화된 모델 분석
108
- │ ├── models/ # 딥러닝 모델 정의 및 저장
109
- │ │ ├── deepgbm.py
110
- │ │ ├── ft_transformer.py
111
- │ │ ├── resnet_like.py
112
- │ │ ├── best_resnet_model.pth
113
- │ │ └── tabnet_model.zip
114
- │ ├── save_model/ # 학습된 모델 저장 (Hugging Face에서 다운로드 가능)
115
- │ ├── optimization_history/ # 최적화 히스토리 (Hugging Face에서 다운로드 가능)
116
- │ ├── visualization/ # 모델 시각화
117
- │ │ └── model_visualize.ipynb
118
- │ ├── find_reason/ # 지역별 트렌드/원인 분석 노트북
119
- │ ├── model_voting_test_best_sample/
120
- │ │ └── ensemble__voting_best_sample.ipynb
121
- │ └── final_test/
122
- │ └── final.ipynb
123
- ├── data/
124
- │ ├── ASOS/ # 기상 데이터
125
- │ ├── dataon/ # 대기오염 데이터(대용량 일자별 CSV)
126
- │ ├── data_for_modeling/ # 지역별 train/test CSV 및 feather
127
- │ ├── data_for_demo/
128
- │ ├── data_oversampled/ # 오버샘플링된 데이터
129
- │ │ ├── smote/
130
- │ │ ├── ctgan7000/
131
- │ │ ├── ctgan10000/
132
- │ │ └── ctgan20000/
133
- │ └── oversampled_data_test_for_model/ # 테스트용 오버샘플링 데이터
134
- └── README.md
135
- ```
136
-
137
- ---
138
-
139
- ### 데이터 및 변수(Variables)
140
-
141
- - 목표 변수
142
- - `visi`: 가시거리(연속값). 합성 표본 필터링 규칙에서 확인되는 구간 예시: class 0은 [0,100), class 1은 [100,500), class 2는 그 외 구간으로 사용됩니다.
143
- - `multi_class`: 다중 분류 라벨(정수 0/1/2)
144
- - `binary_class`: 이진 라벨. 규칙: `binary_class = 0 if multi_class == 2 else 1`
145
-
146
- - 주요 피처 그룹(코드 기준)
147
- - 기상(ASOS): `temp_C`, `precip_mm`, `wind_speed`, `wind_dir`(정온→0 치환), `hm`, `vap_pressure`, `dewpoint_C`, `loc_pressure`, `sea_pressure`, `solarRad`, `snow_cm`, `cloudcover`(int), `lm_cloudcover`(int), `low_cloudbase`, `groundtemp`
148
- - 대기오염(DataOn): `O3`, `NO2`, `PM10`, `PM25`
149
- - 시간/주기: `year`(int), `month`(int), `hour`(int), `hour_sin`, `hour_cos`, `month_sin`, `month_cos`
150
- - 파생: `ground_temp - temp_C`(지면-기온 차)
151
-
152
- - 범주형 변수(모델/샘플링 관점)
153
- - `wind_dir`, `cloudcover`, `lm_cloudcover`, 그리고 `int` 타입의 시간 변수(`year`, `month`, `hour`)는 SMOTENC/GBDT에서 범주형으로 취급됨(코드에서 `float64`가 아닌 열 인덱스 자동 탐지)
154
-
155
- - 전처리 규칙(발췌)
156
- - `wind_dir` 중 `'정온'`은 "0"으로 치환 후 정수형 변환
157
- - `cloudcover, lm_cloudcover` 정수형 변환
158
- - 학습 시 타깃/보조 열(`multi_class, binary_class`) 분리 후 필요 시 재계산
159
-
160
- ---
161
-
162
- ### EDA 및 전처리
163
-
164
- - 병합/정리
165
- - 인덱스 열 제거: `Unnamed: 0` 드롭
166
- - 자료형 정합성: `cloudcover`, `lm_cloudcover` 정수형; `year`, `month`, `hour` 정수형
167
- - 특수값 치환: `wind_dir == '정온'` → "0" 후 정수형 변환
168
-
169
- - 특징 공학
170
- - 주기형 인코딩: `hour_sin`, `hour_cos`, `month_sin`, `month_cos`
171
- - 차분형 파생: `ground_temp - temp_C`
172
-
173
- - 분포/트렌드 분석
174
- - 지역별 시계열 트렌드: `Analysis_code/find_reason/*_trend.ipynb` (seoul, incheon, busan, daegu, daejeon, gwangju)
175
- - 분포 비교/변화 감지: `Analysis_code/find_reason/wasserstein_distance.ipynb`(Wasserstein 거리 기반 분포 차이 정량화)
176
-
177
- - 데이터 분할
178
- - 지역 단위 데이터셋(`*_train.csv`, `*_test.csv`)
179
- - 연도 기반 홀드아웃 3-Fold(2018–2020 조합)로 일반화 성능 검증
180
-
181
- ### 불균형 처리 및 합성 샘플링
182
-
183
- - SMOTENC
184
- - 범주형 인덱스: 입력 특성 중 `float64`가 아닌 열의 위치 인덱스 사용
185
- - 샘플링 전략 예시: `{0: 10000, 1: 10000, 2: 기존 개수}` 또는 데이터 규모에 따라 `{0: 500/1000, 1: ceil(n1/100)*100, 2: n2}`
186
- - 재계산: 샘플링 후 `multi_class`에서 `binary_class` 및 주기/차분 파생을 복구
187
-
188
- - CTGAN(+Optuna)
189
- - 클래스 0, 1을 대상으로 Optuna로 `embedding_dim, generator_dim, discriminator_dim, pac, batch_size, discriminator_steps` 탐색 후 합성
190
- - 생성 표본 품질 필터: `class 0 → 0 ≤ visi < 100`, `class 1 → 100 ≤ visi < 500`
191
- - 최종 합본 후 파생/보조 피처(`binary_class`, 주기/차분 항목) 복구
192
-
193
- - 산출물
194
- - `data/data_oversampled/smote/`, `data/data_oversampled/ctgan7000/`, `data/data_oversampled/ctgan10000/`, `data/data_oversampled/ctgan20000/` 하위에 지역별 CSV 저장
195
-
196
- ---
197
-
198
- ### 모델 아키텍처(상세)
199
-
200
- - 딥러닝(tabular)
201
- - `Analysis_code/models/resnet_like.py`
202
- - 입력: `x_num [B, N_num]`, `x_cat [B, N_cat]` → concat → 입력선형(`d_main=128`) → 잔차블록(`n_blocks=4`, `d_hidden=64`, `dropout_first=0.25`) → 출력층
203
- - 출력: `num_classes == 2 → 1 로짓`, `> 2 → K 로짓`
204
- - `Analysis_code/models/ft_transformer.py`
205
- - 수치: Linear(`num_features → d_token=192`), 범주: `cat_cardinalities`별 `nn.Embedding(d_token)` 후 합성
206
- - 인코더: `TransformerEncoderLayer(d_model=d_token, nhead=8, dropout≈0.2)` × `n_blocks=6` → 평균 풀링 → 분류 헤드
207
- - `Analysis_code/models/deepgbm.py`
208
- - 수치 Linear(`d_main=128`) + 범주 임베딩 합산 → 잔차 MLP 블록(`n_blocks=4`, `d_hidden=64`, `dropout≈0.2`) → 분류 헤드
209
-
210
- - GBDT
211
- - LightGBM(`5.optima/lgb_smote/LGB_smote_seoul.py`): `objective='multiclassova'`, `n_estimators≈4000`, 조기종료, GPU 옵션 예시 존재, `hyperopt`로 `max_depth, min_child_weight, num_leaves, subsample, learning_rate` 탐색
212
- - XGBoost(`5.optima/xgb_smote/XGB_smote_seoul.py`): `objective='multi:softprob'`, `tree_method='hist'`, `enable_categorical=True`, GPU 옵션, `hyperopt`로 핵심 하이퍼파라미터 탐색, `eval_metric=CSI`
213
-
214
- ---
215
-
216
- ### 하이퍼파라미터 최적화
217
-
218
- 모든 모델은 CSI(Critical Success Index) 점수를 최대화하는 방향으로 하이퍼파라미터를 최적화합니다. GBDT 모델은 `hyperopt`(TPE 알고리즘)를, 딥러닝 모델은 `Optuna`(TPE sampler)를 사용합니다.
219
-
220
- #### LightGBM 하이퍼파라미터 탐색 범위
221
-
222
- - **최적화 라이브러리**: `hyperopt` (TPE 알고리즘)
223
- - **최적화 시도 횟수**: `max_evals=100`
224
- - **평가 지표**: CSI (3-Fold 교차 검증 평균)
225
- - **탐색 범위**:
226
- - `learning_rate`: `hp.loguniform('learning_rate', np.log(0.01), np.log(0.2))` - 로그 균등 분포, 범위 [0.01, 0.2]
227
- - `max_depth`: `hp.quniform('max_depth', 3, 15, 1)` - 정수형 균등 분포, 범위 [3, 15]
228
- - `num_leaves`: `hp.quniform('num_leaves', 20, 150, 1)` - 정수형 균등 분포, 범위 [20, 150] (2^max_depth보다 작게 설정)
229
- - `min_child_weight`: `hp.quniform('min_child_weight', 1, 20, 1)` - 정수형 균등 분포, 범위 [1, 20]
230
- - `subsample`: `hp.uniform('subsample', 0.6, 1.0)` - 균등 분포, 범위 [0.6, 1.0]
231
- - `colsample_bytree`: `hp.uniform('colsample_bytree', 0.6, 1.0)` - 균등 분포, 범위 [0.6, 1.0]
232
- - `reg_alpha`: `hp.uniform('reg_alpha', 0.0, 1.0)` - 균등 분포, 범위 [0.0, 1.0] (L1 정규화)
233
- - `reg_lambda`: `hp.uniform('reg_lambda', 0.0, 1.0)` - 균등 분포, 범위 [0.0, 1.0] (L2 정규화)
234
- - **고정 파라미터**: `n_estimators=4000`, `early_stopping_rounds=400`, `device='gpu'`, `objective='multiclassova'`, `random_state=42`
235
-
236
- #### XGBoost 하이퍼파라미터 탐색 범위
237
-
238
- - **최적화 라이브러리**: `hyperopt` (TPE 알고리즘)
239
- - **최적화 시도 횟수**: `max_evals=100`
240
- - **평가 지표**: CSI (3-Fold 교차 검증 평균, 사용자 정의 `eval_metric_csi` 함수 사용)
241
- - **탐색 범위**:
242
- - `learning_rate`: `hp.loguniform('learning_rate', np.log(0.01), np.log(0.2))` - 로그 균등 분포, 범위 [0.01, 0.2]
243
- - `max_depth`: `hp.quniform('max_depth', 3, 12, 1)` - 정수형 균등 분포, 범위 [3, 12]
244
- - `min_child_weight`: `hp.quniform('min_child_weight', 1, 20, 1)` - 정수형 균등 분포, 범위 [1, 20]
245
- - `gamma`: `hp.uniform('gamma', 0, 5)` - 균등 분포, 범위 [0, 5] (트리 분할을 위한 최소 손실 감소 값)
246
- - `subsample`: `hp.uniform('subsample', 0.6, 1.0)` - 균등 분포, 범위 [0.6, 1.0]
247
- - `colsample_bytree`: `hp.uniform('colsample_bytree', 0.6, 1.0)` - 균등 분포, 범위 [0.6, 1.0]
248
- - `reg_alpha`: `hp.uniform('reg_alpha', 0.0, 1.0)` - 균등 분포, 범위 [0.0, 1.0] (L1 정규화)
249
- - `reg_lambda`: `hp.uniform('reg_lambda', 0.0, 1.0)` - 균등 분포, 범위 [0.0, 1.0] (L2 정규화)
250
- - **고정 파라미터**: `n_estimators=4000`, `early_stopping_rounds=400`, `tree_method='hist'`, `device='cuda'`, `enable_categorical=True`, `objective='multi:softprob'`, `random_state=42`
251
-
252
- #### FT-Transformer 하이퍼파라미터 탐색 범위
253
-
254
- - **최적화 라이브러리**: `Optuna` (TPE sampler)
255
- - **최적화 시도 횟수**: `n_trials=100`
256
- - **Pruning**: `MedianPruner(n_warmup_steps=10)` - 초반 10 에폭은 관찰 후 이후 가지치기
257
- - **평가 지표**: CSI (3-Fold 교차 검증 평균)
258
- - **탐색 범위**:
259
- - `d_token`: `trial.suggest_int("d_token", 64, 256, step=32)` - 정수형, 범위 [64, 256], 32 단위 증가 (64, 96, 128, 160, 192, 224, 256)
260
- - `n_blocks`: `trial.suggest_int("n_blocks", 2, 6)` - 정수��, 범위 [2, 6] (깊이 축소로 과적합 방지)
261
- - `n_heads`: `trial.suggest_categorical("n_heads", [4, 8])` - 범주형, 선택지 [4, 8]
262
- - `attention_dropout`: `trial.suggest_float("attention_dropout", 0.1, 0.4)` - 실수형, 범위 [0.1, 0.4]
263
- - `ffn_dropout`: `trial.suggest_float("ffn_dropout", 0.1, 0.4)` - 실수형, 범위 [0.1, 0.4]
264
- - `lr` (learning_rate): `trial.suggest_float("lr", 1e-5, 1e-2, log=True)` - 로그 스케일 실수형, 범위 [1e-5, 1e-2]
265
- - `weight_decay`: `trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True)` - 로그 스케일 실수형, 범위 [1e-4, 1e-1]
266
- - `batch_size`: `trial.suggest_categorical("batch_size", [32, 64, 128, 256])` - 범주형, 선택지 [32, 64, 128, 256]
267
- - **구조적 제약**: `d_token`은 `n_heads`의 배수여야 함 (코드에서 자동 조정)
268
- - **고정 파라미터**: `num_classes=3`, `optimizer='AdamW'`, `epochs=200`, `patience=12`, `scheduler='ReduceLROnPlateau'` (factor=0.5, patience=3), `random_state=42`
269
-
270
- #### ResNet-like 하이퍼파라미터 탐색 범위
271
-
272
- - **최적화 라이브러리**: `Optuna` (TPE sampler)
273
- - **최적화 시도 횟수**: `n_trials=100`
274
- - **Pruning**: `MedianPruner(n_warmup_steps=10)` - 초반 10 에폭은 관찰 후 이후 가지치기
275
- - **평가 지표**: CSI (3-Fold 교차 검증 평균)
276
- - **탐색 범위**:
277
- - `d_main`: `trial.suggest_int("d_main", 64, 256, step=32)` - 정수형, 범위 [64, 256], 32 단위 증가 (64, 96, 128, 160, 192, 224, 256)
278
- - `d_hidden`: `trial.suggest_int("d_hidden", 64, 512, step=64)` - 정수형, 범위 [64, 512], 64 단위 증가 (64, 128, 192, 256, 320, 384, 448, 512)
279
- - `n_blocks`: `trial.suggest_int("n_blocks", 2, 5)` - 정수형, 범위 [2, 5] (너무 깊지 않게 조절)
280
- - `dropout_first`: `trial.suggest_float("dropout_first", 0.1, 0.4)` - 실수형, 범위 [0.1, 0.4]
281
- - `dropout_second`: `trial.suggest_float("dropout_second", 0.0, 0.2)` - 실수형, 범위 [0.0, 0.2]
282
- - `lr` (learning_rate): `trial.suggest_float("lr", 1e-5, 1e-2, log=True)` - 로그 스케일 실수형, 범위 [1e-5, 1e-2]
283
- - `weight_decay`: `trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True)` - 로그 스케일 실수형, 범위 [1e-4, 1e-1]
284
- - `batch_size`: `trial.suggest_categorical("batch_size", [32, 64, 128, 256])` - 범주형, 선택지 [32, 64, 128, 256]
285
- - **고정 파라미터**: `num_classes=3`, `optimizer='AdamW'`, `epochs=200`, `patience=12`, `scheduler='ReduceLROnPlateau'` (factor=0.5, patience=3), `random_state=42`
286
-
287
- #### DeepGBM 하이퍼파라미터 탐색 범위
288
-
289
- - **최적화 라이브러리**: `Optuna` (TPE sampler)
290
- - **최적화 시도 횟수**: `n_trials=100`
291
- - **Pruning**: `MedianPruner(n_warmup_steps=10)` - 초반 10 에폭은 관찰 후 이후 가지치기
292
- - **평가 지표**: CSI (3-Fold 교차 검증 평균)
293
- - **탐색 범위**:
294
- - `d_main`: `trial.suggest_int("d_main", 64, 256, step=32)` - 정수형, 범위 [64, 256], 32 단위 증가 (64, 96, 128, 160, 192, 224, 256)
295
- - `d_hidden`: `trial.suggest_int("d_hidden", 64, 256, step=64)` - 정수형, 범위 [64, 256], 64 단위 증가 (64, 128, 192, 256)
296
- - `n_blocks`: `trial.suggest_int("n_blocks", 2, 6)` - 정수형, 범위 [2, 6]
297
- - `dropout`: `trial.suggest_float("dropout", 0.1, 0.4)` - 실수형, 범위 [0.1, 0.4]
298
- - `lr` (learning_rate): `trial.suggest_float("lr", 1e-5, 1e-2, log=True)` - 로그 스케일 실수형, 범위 [1e-5, 1e-2]
299
- - `weight_decay`: `trial.suggest_float("weight_decay", 1e-4, 1e-1, log=True)` - 로그 스케일 실수형, 범위 [1e-4, 1e-1]
300
- - `batch_size`: `trial.suggest_categorical("batch_size", [32, 64, 128, 256])` - 범주형, 선택지 [32, 64, 128, 256]
301
- - **고정 파라미터**: `num_classes=3`, `optimizer='AdamW'`, `epochs=200`, `patience=12`, `scheduler='ReduceLROnPlateau'` (factor=0.5, patience=3), `random_state=42`
302
-
303
- #### 공통 최적화 설정
304
-
305
- - **교차 검증**: 모든 모델은 연도 기반 3-Fold 홀드아웃 교차 검증 사용
306
- - Fold 1: Train [2018, 2019] → Val 2020
307
- - Fold 2: Train [2018, 2020] → Val 2019
308
- - Fold 3: Train [2019, 2020] → Val 2018
309
- - **평가 지표**: CSI (Critical Success Index) - 모든 fold의 평균 CSI를 최적화 목표로 사용
310
- - **최적화 알고리즘**: TPE (Tree-structured Parzen Estimator)
311
- - **재현성**: `random_state=42` 고정
312
-
313
- ---
314
-
315
- ### 학습/검증 전략
316
-
317
- - 연도 기반 홀드아웃 3-Fold(예시)
318
- - Fold1: Train 2018–2019 → Val 2020
319
- - Fold2: Train 2018–2020 → Val 2019
320
- - Fold3: Train 2019–2020 → Val 2018
321
- - 지역 단위로 별도 학습(예: `seoul_train.csv` 등)
322
-
323
- ---
324
-
325
- ### 평가 지표
326
-
327
- - 사용자 정의 CSI(Critical Success Index) 다중분류 버전
328
-
329
- ```python
330
- H = cm[0, 0] + cm[1, 1]
331
- F = (cm[1, 0] + cm[2, 0] + cm[0, 1] + cm[2, 1])
332
- M = (cm[0, 2] + cm[1, 2])
333
- CSI = H / (H + F + M + 1e-10)
334
- ```
335
-
336
- - 그 외: 정확도, F1 등 노트북/스크립트에서 병행 확인
337
-
338
- ---
339
-
340
- ### 실행 방법(상세)
341
-
342
- - 환경 준비
343
- - Python 3.8+ 권장, CUDA 지원 시 GPU 사용 가능(CTGAN/GBDT 속도 향상)
344
- - LightGBM GPU가 미설치라면 `pip install lightgbm`으로 CPU 버전 사용 또는 GPU 빌드 필요
345
-
346
- - 데이터 준비
347
- - `data/ASOS/`: 연도별 기상 원천
348
- - `data/dataon/`: 대기오염 일자별 CSV(대용량)
349
- - `data/data_for_modeling/`: 지역별 학습/평가 세트(`*_train.csv`, `*_test.csv`, `df_*.feather`)
350
- - **Hugging Face에서 다운로드**: 전체 `data/` 폴더를 [Hugging Face 저장소](https://huggingface.co/bong9513/visibility_prediction/tree/main/data)에서 다운로드 가능
351
- ```bash
352
- git clone https://huggingface.co/bong9513/visibility_prediction
353
- # 클론 후 visibility_prediction/data/ 폴더를 프로젝트의 data/ 위치로 복사
354
- ```
355
-
356
- - 전처리/탐색
357
- - `Analysis_code/1.data_preprocessing/0.air_data_merge.ipynb` → `1.data_preprocessing/1.data_merge.ipynb` → `1.data_preprocessing/2.eda_preproccesing.ipynb` → `1.data_preprocessing/3.make_train_test.ipynb`
358
-
359
- - 오버샘플링
360
- - `Analysis_code/2.make_oversample_data/`에서 스크립트 실행(상단 TL;DR 참조)
361
-
362
- - GBDT 최적화/학습
363
- - **옵션 1: 직접 모델 생성**
364
- - `Analysis_code/5.optima/lgb_smote/LGB_smote_seoul.py`, `5.optima/xgb_smote/XGB_smote_seoul.py` 실행하여 모델 학습
365
- - 산출 모델은 `Analysis_code/save_model/` 하위에 `.pkl`로 저장
366
- - 각 모델별로 지역별 스크립트가 존재 (seoul, incheon, busan, daegu, daejeon, gwangju)
367
- - **옵션 2: 사전 학습된 모델 사용**
368
- - Hugging Face 저장소에서 사전 학습된 모델과 최적화 히스토리 다운로드 가능
369
- - `save_model/`: [Hugging Face 저장소](https://huggingface.co/bong9513/visibility_prediction/tree/main/save_model)에서 사전 학습된 모델 다운로드
370
- - `optimization_history/`: [Hugging Face 저장소](https://huggingface.co/bong9513/visibility_prediction/tree/main/optimization_history)에서 최적화 히스토리 파일 다운로드
371
- ```bash
372
- git clone https://huggingface.co/bong9513/visibility_prediction
373
- # 클론 후 visibility_prediction/save_model/ 및 visibility_prediction/optimization_history/ 폴더를
374
- # 각각 Analysis_code/save_model/ 및 Analysis_code/optimization_history/ 위치로 복사
375
- ```
376
-
377
- - 딥러닝 학습
378
- - **옵션 1: 직접 모델 생성**
379
- - `Analysis_code/5.optima/` 하위의 각 모델 폴더(`resnet_like_*`, `ft_transformer_*`, `deepgbm_*`)에서 지역별 스크립트 실행
380
- - 예: `5.optima/resnet_like_smote/resnet_like_smote_seoul.py`
381
- - 모델 정의는 `Analysis_code/models/` 폴더에 있음 (`deepgbm.py`, `ft_transformer.py`, `resnet_like.py`)
382
- - 시각화: `Analysis_code/visualization/model_visualize.ipynb`로 시각화
383
- - **옵션 2: 사전 학습된 모델 사용**
384
- - Hugging Face 저장소의 `save_model/` 폴더에서 사전 학습된 딥러닝 모델 다운로드 가능
385
- - [Hugging Face 저장소](https://huggingface.co/bong9513/visibility_prediction/tree/main/save_model)에서 해당 모델 파일 다운로드 후 사용
386
-
387
- - 앙상블/최종 평가
388
- - `Analysis_code/model_voting_test_best_sample/ensemble__voting_best_sample.ipynb`
389
- - `Analysis_code/final_test/final.ipynb`
390
-
391
- ---
392
-
393
- ### 모델 입출력 규격(요약)
394
-
395
- - 수치 입력 `x_num`: `float32` 텐서 `[batch, num_numeric_features]`
396
- - 범주 입력 `x_cat`: 정수 인덱스 텐서 `[batch, num_categorical_features]`
397
- - 출력: 이진(1 로짓) 또는 다중분류(K 로짓). 손실/임계값은 노트북 내 설정 참고
398
-
399
- ---
400
-
401
- ### 재현성/시드
402
-
403
- - `random_state=42`(SMOTENC), 모델 스크립트 내 `random_state=120` 등의 고정값 사용
404
- - 데이터/하드웨어 차이에 따라 재현률이 다를 수 있으므로 fold/seed를 명시적으로 설정 권장
405
-
406
- ---
407
-
408
- ### 주의/트러블슈팅
409
-
410
- - `5.optima/lgb_smote/LGB_smote_seoul.py`의 `sys.path.append(...)`는 환경 의존적 경로입니다. 일반 환경에서는 제거해도 `from lightgbm import LGBMClassifier`가 동작해야 합니다.
411
- - 스크립트는 상대 경로를 가정합니다. 실행 전 현재 작업 디렉터리가 `Analysis_code/5.optima/` 하위인지 확인하세요.
412
- - `wind_dir`의 `'정온'` 값 치환/형변환이 누락되면 GBDT/XGB에서 오류가 발생할 수 있습니다.
413
- - `dataon/`은 매우 대용량입니다. 메모리 여유를 확보하거나 연도/지역 단위로 처리하세요.
414
-
415
- ---
416
-
417
- ### 의존성
418
-
419
- - Python 3.8+
420
- - PyTorch, pandas, numpy, scikit-learn, imbalanced-learn, optuna, ctgan, xgboost, lightgbm, joblib, matplotlib, seaborn, hyperopt
421
-
422
- ---
423
-
424
- ### 라이선스/인용
425
-
426
- - 라이선스: 추후 업데이트 예정
427
- - 본 프로젝트/결과물을 인용 시 `visibility_prediction` 저장소와 사용된 데이터 소스(ASOS, DataOn)를 명시해 주세요.