패스트캠퍼스에서 Upastage AI Lab 1기 과정을 진행하면서
모듈 스터디 1차(2주간 진행한 스터디그룹)를 하게 되었는데
이번에 Baseline code를 다 작성하여 제출까지 완료하였고
팀 내에서도 결과 공유를 완료했다!
스터디 내용에 대해 보고서를 적어야 하는데 적으면서 내가 스터디 한 내용을 담아보려 한다
보고서 목차는 다음과 같다.
[보고서 목차]
1. 개요
2. 스터디 그룹 주제
- 메인 주제 + 세부 주제
3. 스터디 그룹 학습 내용
- 개인이 공부 한 내용
- 그룹원들과 진행 한 내용
4. 스터디 그룹 멘토링
- 그룹 질문과 답변
- 개인 질문과 답변
5. 마무리
- 회고 및 느낀 점 등
- 개요
기존에 Upastage AI Lab 1기에서도 스터디 그룹을 진행했었으나
ML 강의를 수강완료했고 DL 강의 수강도 시작함과 동시에
[구성원들 간에 서로 다른 관점과 경험을 공유함으로써 상호 학습을 촉진]을 목적으로
모듈 스터디 1차를 시작하게 되었습니다.
기존의 스터디 그룹과 다른 점은 설문조사를 통해 주제별로 팀을 구성하여
좀 더 능동적인 스터디를 하는 것이 차이점이라 볼 수 있겠습니다.
- 스터디 그룹 주제
메인 주제는 다중 분류(Multi-class classification)입니다.
Kaggle에서 해당 분야로 진행 중인 대회를 찾았으며(Multi-Class Prediction of Cirrhosis Outcomes (Kaggle Playground Series) 모듈 스터디 1차 기간 동안 팀원 개인별로 Baseline code를 작성 완료하는 것이 목표입니다.
개인별로 작성한 Baseline code로 제출파일(submission.csv)을 생성하여 대회에 제출하는 것이 세부 목적이라 할 수 있겠습니다.
- 스터디 그룹 학습 내용
- 개인이 공부한 내용
먼저 제 팀(9팀)의 목표가 Multi-Class Prediction of Cirrhosis Outcomes 대회를 참여하여 해당 대회 데이터를 바탕으로
Baseline code를 작성하는 것이므로
저만의 Baseline code를 작성하기 위해 Votes 수가 많은 공유된 code들을 몇 개 선정하여 공부를 진행하였습니다. 공부 방법은 클론 코딩이었으며 이해가 되지 않는 내용은 Chat-GPT 4에 질문하여 이해하였습니다.
* 참고한 Baseline code들
- https://www.kaggle.com/code/markuslill/s3e26-xgbclassifer/notebook
- https://www.kaggle.com/code/ashishkumarak/ps3e26-liver-cirrhosis-survival-prediction/notebook#💽-Importing-the-data https://www.kaggle.com/code/arunklenin/ps3e26-cirrhosis-survial-prediction-multiclass
- https://www.kaggle.com/code/ravi20076/playgrounds3e26-eda-baseline
- https://www.kaggle.com/datasets/joebeachcapital/cirrhosis-patient-survival-prediction
Cirrhosis Patient Survival Prediction
Utilize 17 clinical features to predict survival of patient with liver cirrhosis
www.kaggle.com
처음에는 공유된 Baseline code들을 클론 코딩하면서 저만의 Baseline code를 작성하려 했지만,
나중에 완성된 Baseline code를 보니 참고했던 코드들과 싱크로율이 너무 높았고
백지에서 시작한 게 아닌 다른 누군가의 코드를 복붙 해서 퍼즐처럼 만들었다는 느낌이 강하게 들었습니다.
그래서 작성한 Baseline을 전면 초기화하고 새로운 Baseline을 작성하려 하니
어디서부터 시작해야 할지 막막했습니다.... 데이터 불러오기 그리고 가벼운 데이터 탐색 등까지는
코드를 구현할 수 있었으나 피처엔지니어링, ML 부분 코딩은 전혀 작성하지 못했습니다.
따라서 정말 간단하고 쉬운 코드부터 시작하자는 마음으로
저번 ML 팀프로젝트 발표에서 다른 팀들 발표 때 들었던 AutoML을 사용해 보기로 생각하고
H2O Automl을 사용한 Baseline code를 작성하였습니다.
H2O Automl 사이트와 Chat-GPT 4에게 이론적인 부분을 배웠으며
코드 구현까지는 얼마 걸리지 않았습니다.
아래는 사용한 코드의 일부분입니다.
H2O Automl을 사용해 보면서 느낀 장점은 다음과 같습니다.
- 사용 편의성
- ML 모델을 쉽게 만들고 최적화할 수 있음 - 전체 ML 파이프 라인 자동 생성
- 다양한 ML 알고리즘 중에서 최적의 모델 자동으로 선택
- k-fold 교차 검증을 자동으로 수행함으로써 모델의 과적합 방지
- 여러 모델의 예측을 결합하여 최종 예측 생성 (모델 stacking)
단점은 다음과 같습니다.
- 커스텀 한계 (개인적으로 제일 아쉬운 부분)
- 모델 학습에 관여를 크게 못함
- 모델 튜닝 및 최적화 어려움
- 결과 해석의 어려움
- 왜 그렇게 결정 내렸는지 설명해야 하는 상황에서 문제
결과는 생각보다 나쁘지도 좋지도 않았습니다.
- 사용하기엔 편리해 보이지만, 익숙하지 않아 좋은 성능을 내긴 어려웠음
- Public Score 0.44264
이렇게 마무리되었는데, 말 그대로 Auto였기 때문에 제가 조절할 수 있는 부분이 적어 아쉬워서
Optuna + (Randomforest + LGBM + XGBoost)을 적용한 Baseline code를 추가로 작성하였습니다.
작성한 코드 일부분은 다음과 같습니다.
FEATS = ['N_Days', 'Drug', 'Age', 'Sex', 'Ascites', 'Hepatomegaly', 'Spiders', 'Edema', 'Bilirubin', 'Cholesterol', 'Albumin', 'Copper', 'Alk_Phos', 'SGOT', 'Tryglicerides', 'Platelets', 'Prothrombin', 'Stage']
TARGET = 'Status'
le = LabelEncoder()
for col in df_train.columns[df_train.dtypes == 'object']:
if col in df_test.columns: # 테스트 데이터에 해당 열이 있는지 확인
le.fit(df_train[col]) # 학습 데이터를 기준으로 인코딩을 학습
df_train[col] = le.transform(df_train[col]) # 학습 데이터의 변환
df_test[col] = le.transform(df_test[col]) # 테스트 데이터의 변환
else:
df_train[col] = le.fit_transform(df_train[col])
X_train, X_val, y_train, y_val= train_test_split(df_train[FEATS], df_train[TARGET],
test_size=0.2, random_state=42)
def xgb_objective(trial):
params_xgb = {
'n_estimators': trial.suggest_int('n_estimators', 100, 500),
'max_depth': trial.suggest_int('max_depth', 1, 10),
'learning_rate': trial.suggest_uniform('learning_rate', 0.01, 0.1),
'min_child_weight': trial.suggest_int('min_child_weight', 1, 10),
'subsample': trial.suggest_uniform('subsample', 0.5, 1),
'colsample_bytree': trial.suggest_uniform('colsample_bytree', 0.5, 1),
'gamma': trial.suggest_uniform('gamma', 0, 0.5)
}
model = XGBClassifier(**params_xgb, random_state=42)
model.fit(X_train, y_train, eval_set=[(X_val, y_val)], early_stopping_rounds=10, verbose=False)
return model.score(X_val, y_val) # X_valid -> X_val로 수정
study = optuna.create_study(direction='maximize')
study.optimize(xgb_objective, n_trials=50)
xgb_best_params = study.best_params
def lgbm_objective(trial):
params_lgbm = {
'num_leaves': trial.suggest_int('num_leaves', 31, 256),
'boosting_type': 'gbdt',
'objective': 'multiclass',
'metric': 'multi_logloss',
'max_depth': trial.suggest_int('max_depth', -1, 50),
'learning_rate': trial.suggest_loguniform('learning_rate', 0.01, 0.1),
'feature_fraction': trial.suggest_uniform('feature_fraction', 0.4, 1.0),
'bagging_fraction': trial.suggest_uniform('bagging_fraction', 0.4, 1.0),
'bagging_freq': trial.suggest_int('bagging_freq', 1, 7),
'verbose': 0
}
model = lgb.LGBMClassifier(**params_lgbm)
model.fit(X_train, y_train, eval_set=[(X_val, y_val)], early_stopping_rounds=10, verbose=False)
return model.score(X_val, y_val) # X_valid -> X_val로 수정
study = optuna.create_study(direction='maximize')
study.optimize(lgbm_objective, n_trials=50)
lgbm_best_params = study.best_params
base_models = [
('rf', RandomForestClassifier(random_state=42)),
('xgb', XGBClassifier(**xgb_best_params, random_state=42)),
('lgbm', lgb.LGBMClassifier(**lgbm_best_params))
]
from sklearn.linear_model import LogisticRegression
final_model = LogisticRegression()
from sklearn.ensemble import StackingClassifier
stacking_clf = StackingClassifier(estimators=base_models, final_estimator=final_model)
stacking_clf.fit(X_train, y_train)
stacking_preds = stacking_clf.predict_proba(df_test[FEATS])
train_preds = pd.DataFrame(stacking_preds, columns=['Status_C', 'Status_CL', 'Status_D'])
submission = pd.read_csv("/kaggle/input/playground-series-s3e26/sample_submission.csv")
submission.loc[:, 'Status_C'] = stacking_preds[:, 0]
submission.loc[:, 'Status_CL'] = stacking_preds[:, 1]
submission.loc[:, 'Status_D'] = stacking_preds[:, 2]
print(submission)
output_path = 'submission_stacking.csv'
submission.to_csv(output_path, index=False)
Optuna로 하이퍼파라미터 튜닝을 하고 그 값을 XGBoost와 LGBM에 활용하였으며
총 3개의 ML 모델을 사용한 뒤 스태킹 방법으로 앙상블 하였습니다.
결과는 Public Score 0.43411로 이전에 H2O Automl보다는 나은 성능을 보여줬습니다.
- 스터디그룹 학습 내용
- 그룹원들과 진행한 내용
팀원들과는 요일을 정하여 zoom 소회의실에서 회의를 하였으며
공부하거나 진행한 내용을 Notion에 작성하여 공유했습니다.
각자 Baseline code를 작성하면서 부딪힌 문제점에 대해 공유하고 해결책을 제시하였습니다.
예를 들면 Baseline code의 기본적인 작성 양식, 추가적으로 사용한 Data 유무 등이 있겠습니다.
Kaggle 대회 참여가 많은 분이 팀장을 맡아주셔서 개인적으로 도움이 많이 되었습니다!
- 스터디그룹 멘토링
- 그룹 질문과 답변
- 개인 질문과 답변
그룹 질문에서는 NN을 사용하면서 생긴 코드 작동문제, 후처리와 Logloss의 관계 등의 질문이 있었고
개인적인 질문으로는 이론적인 부분보다는 다음과 같은 질문을 던졌습니다.
- 참고자료에 있는 Baseline 참고해서 클론 코딩하는 중인데 이 방법이 옳은 방법인가?
- 클론코딩하면서 만들다 보니 simple하지 않고 너무 too much가 되어가는 중이라 고민
- 처음부터 클론 코딩 하지 말고 처음 보는 데이터 받아서 분석하는 것처럼 작성해야 하는가?
- Baseline code가 모든 대회에 다 사용할 수 있게 만드는 건지 궁금함. 맞다면 뼈대만 기본적으로 만드는 게 옳은 방법인가? ex) 아주 기본적인 라이브러리 import, 데이터 load후 탐색, 모델링, 모델 평가 및 선택, 최종 모델 훈련 및 예측, 제출 파일 생성 및 제출. 이 순서대로 작성하는 게 맞는지 의문
팀원들과 강사님의 답변으로 의문이 해소되었는데....
결국은 이론적인 부분 이해 부족 문제, 경험 부족 문제로 개인적으로 결론을 내렸습니다.
또한 여러 ML 모델들을 사용하고 하이퍼파라미터를 최적화하고 모델 앙상블을 하는 것도 좋지만
피처엔지니어링 차이가 큰 점수차이로 이어진다고 경험으로 느꼈지만
아직 데이터 분석에 대한 이해가 떨어져서 인지 제대로 시도하지 못했습니다.
이 부분은 추후 관련 부분 공부를 한 뒤에 해볼 생각입니다.
- 마무리
- 회고 및 느낀 점
- 이때까지 다른 사람이 작성한 Baseline code를 수정하는 방법으로 대회 참여를 했었는데, 그래서인지 저만의 Baseline code를 만드는 게 쉽지 않다고 느꼈습니다.
- 하지만 한번 작성해 두면, 해당 코드를 베이스로 확장해서 사용하면 좋을 거라 생각됩니다.
- 처음 작성하는 Baseline이기에 부족한 점이 많아 공부하면서 보완해 갈 예정입니다.
- 피처 엔지니어링에 대한 부분을 신경 쓰지 못해 아쉽고 개인적으로 공부한 뒤에 추가할 예정입니다.
1차 모듈 스터디를 마치면서 보고서를 이렇게 적어 보았는데
역시나 공부를 하면 할수록 부족한 점이 많다고 느끼고 약간의 번아웃? 도 오는 것 같다
비전공자로써 부트캠프에서 개발자로 거듭나기 위해 노력하고 있지만
이 노력의 불씨가 꺼지지 않게 계속 긴장하면서 공부해야 할 듯하다
강한 놈이 이기는 게 아니라 끝까지 가는 놈이 이긴다고 하니까.....
Upstage Ai Lab 1기 과정 끝까지 악으로 깡으로 버틴다는 마인드 장착이다!!
다른 교육생 분들도 화이팅입니다!!!

'스터디그룹 대회참여 > 모듈 스터디 1차(Kaggle 대회 참여)' 카테고리의 다른 글
Multi-Class Prediction of Cirrhosis Outcomes (Kaggle Playground Series) 대회 참여(feat. 스터디그룹) (0) | 2023.12.19 |
---|