두번째 미니 프로젝트를 마치고 나서 쓰는 회고록입니다.
3일 정도의 시간동안 무사히 기획한 방향대로 진행하고, 프로젝트 평가 1위를 할 수 있게 해준 병창님, 경목님 모두 고생하셨습니다!
1. 프로젝트 소개
심장질환 AI 예측
대중이 쉽게 접근 가능한 심장질환 판별 및 발생 확률 제공 웹사이트를 제작하겠다는 목적으로 프로젝트를 진행했습니다.
데이터셋은 캐글의 Personal Key Indicators of Heart Disease 데이터를 활용해서, 다양한 머신러닝을 경험해보면서 웹사이트에 모델을 적용하는 방식으로 적용했습니다.
https://www.kaggle.com/datasets/kamilpytlak/personal-key-indicators-of-heart-disease
진행기간
- 2023년 2월 16일 ~ 2월 19일
팀구성(TEAM 우병목)
- 우상욱 : EDA, 전처리, 머신러닝 모델링, 웹 구현
- 민병창 : EDA, 전처리, 시각화, 머신러닝 학습, 머신러닝 모델링
- 김경목 : EDA, 시각화, 머신러닝 학습, 머신러닝 모델링
기술스택(파이썬 라이브러리 위주 기술)
- 데이터 전처리 : Pandas, Numpy
- 시각화 : Matplotlib, Seaborn
- ML 모델 : Scikit-learn, lighgbm, xgboost, catboost
- 웹 구현: streamlit
- 협업도구 : Github, Notion, Canva
프로젝트 개요
- 데이터 EDA 및 전처리
- 이상치 처리 방식, 다중공선성 판단, 상관관계 시각화, 인코딩 등
- 머신러닝 모델 구현
- 불균형 데이터 리샘플링(SMOTE, SMOTEOMEK)
- 분류 모델 생성
- 중요지표(정확도, 재현율) 기준 모델 간 비교(decision tree, logistic regression, randomforest, lightgbm, xgboost, catboost)
- 상위 모델 2개 선정 및 하이퍼 파라미터 튜닝(환경 제약으로 인한 Google Colab 사용)
- 상위 모델 앙상블(소프트 보팅)
- 웹구현
- streamlit 라이브러리 및 머신러닝 모델 활용 웹 구현
- 사용자 설문 받는 페이지 구현 - 예측 버튼 클릭 후
- 심장질환 확률(predict proba), 심장질환 유무(predict), 개선방향 페이지 생성
- 해당 웹 배포
- https://sangwookwoo-ml-project-predict-heart-diseas-heartdisease-fjfpjg.streamlit.app/
2. 프로젝트 진행과정 및 생각들
데이터 EDA 및 전처리
이 과정에서는 데이터 EDA를 통해서 데이터의 세세한 부분의 관계를 하나하나 살펴보는 과정이였습니다.
팀원 전부 데이터를 보면서, 이상치를 분석하고 살펴보는 과정이였는데 모든 과정을 마무리하고 나니, 인상 깊었던 부분은 다음과 같았습니다.
BMI가 특정 수치를 넘는 그룹들을 계속해서 집단을 줄여가면서 심장질환자의 비율을 나타낸 그래프입니다. 해당 분석에서 저희는 BMI가 70을 넘어서는 분들은 비현실적인 부분도 있고, 갑자기 심질환 비율이 상승하는 과정에서 BMI 70 이상일 때 심질환자 비율이 갑자기 줄어드는 것이 이상하다고 느껴 이를 이상치로 판단하고 이상치 처리 작업을 진행하려 했습니다.
그런데, 어떤 모델에 넣어도 저희 모델의 예측 성능이 하락하면서, 결국 이 작업은 제외했습니다.
이 부분에 대해서는 정말 고민을 많이했는데, 저희가 내린 결론은 BMI가 높을 수록 심질환자가 높을 것이다라는 저희의 가정을 두고 데이터를 바라보지 않았나? 그런 생각들을 했었습니다.
물론 지금의 분석 자체가 틀릴 수도 있고, 다른 변수들이 개입했을 요인도 있겠지만, 이를 통해서 문제를 다각도로 분석하고 해결하는 방법이 중요하다고 생각했습니다.
머신러닝 모델 구현
가장 많이 공을 들인 부분이였습니다. 첫번째로 기존데이터와 resampling한 데이터(smote, smotetomek)를 활용해서 다양한 모델을 돌리고 비교하는 과정이였는데, 이 과정에서 오버샘플링된 데이터가 대부분 예측 성능이 좋은 것을 발견할 수 있었습니다.
반면에 SMOTE 기법으로 처리한 LOGISTIC 회귀모델은 오히려 예측성능이 하락하는 모습을 보입니다. 또한 결정트리의 경우에는 과적합이 심하게 발생하는 것을 알 수 있었습니다. 이 과정을 통해 실질적으로 결과값을 비교하는 과정의 중요성을 알 수 있었습니다.
또한 처음에는 상위 3개 모델 CATBOOST, XGBOOST, 랜덤포레스트 모델들을 사용해서 하이퍼파라미터 튜닝을 제공한 뒤에, 앙상블 모형을 구현해보려했습니다. 하지만 사이킷런 기반의 랜덤포레스트 모델은 가속기로 GPU 옵션을 제공하지 않아서, 하이퍼파라미터 튜닝을 짧은 시간 안에 할 수 없는 상황이였습니다. 그래서 제대로 튜닝된 모델 두개를 앙상블 하는 과정으로 팀원끼리 결정했습니다.
GOOGLE COLAB을 처음 사용해보면서, GPU 옵션을 활용해봤는데 확실히 속도가 상당히 빠른 것을 알 수 있었습니다! 물론 제 개인 PC 환경이 GPU가 좋았다면 더 좋은 퍼포먼스를 보일 수도 있었을 것 같습니다. PC 환경이 좋은데도, 돌릴 모델이 많다면 COLAB을 활용해서 동시에 돌리는 것 또한 괜찮은 방법이 될 것 같습니다.
이후 저희는 XGBOOST와 CATBOOST를 통해서 SOFT VOTING한 앙상블 모형을 만들었고, 유의미한 예측 성능 향상이 있었습니다.
이후 완성된 SOFT VOTING 분류기로 웹을 구현하려고 했는데, 기술적인 문제가 조금 있었습니다.
- xgboost와 catboost는 각각 라이브러리에서 독립적인 모델 저장 기능을 제공하는데, 각각 pickle이나, joblib으로 모델을 저장하면 오류가 발생합니다.
- soft voting한 앙상블 모델은 사이킷런에서 제공하는데 이를 catboost와 xgboost로 앙상블 했을때, joblib이나 pickle로 저장하면, 오류가 발생합니다.
이 부분은 프로젝트 기간 이후 여유가 있을 때, 한번 해결해 볼 예정입니다.
프로젝트의 기간이 짧아서, 이 부분은 일단 스킵했습니다. XGBOOST의 모델만을 활용해서 웹을 구현했습니다.
웹구현
생각보다 streamlit이라는 라이브러리를 활용해서, 짧은 시간에 개발을 마칠 수 있었습니다. 다른 과정은 제외하고, 저희 팀만의 아이디어로 웹 사용자에 대해서 심장질환 확률을 낮추는 개선방향을 제시하는 방법에 대한 아이디어는 독특했다고 생각합니다.
- 사용자가 입력한 정보에, 일정 변수를 조작해서 predict_proba 값을 반환 받습니다.
- 예를 들면 흡연을 했다고 응답한 응답자의 경우에는 다른 조건은 일정한 상태에서 흡연을 하지 않은 걸로 바꾼 후의 예측값을 저장해놓습니다.
- 이후 사용자가 기존 입력한 정보와 기존에 예측한 확률을 비교해서, 심장질환일 확률이 떨어졌다면 그 변수에 대해서 확률을 출력합니다.
제가 이번 프로젝트에서 가장 재밌게 구현한 부분입니다. 팀원 분들의 아이디어가 있었고, 조금 더 확실하게 사람들의 눈에 확실히 보여주는게 중요하다고 생각해서, 하락 정도 또한 제공했습니다. 이 부분에 대해서 기술적으로 어려웠던 점은 없었지만, 무언가 새로운 아이디어나 시도가 굉장히 사이트의 유용성을 높이는데에 큰 기여를 할 수 있다고 느낀 부분이였습니다.
잘했던 점
- 팀원간 역할 분담
무언가 체계적으로 팀원의 역할이 나뉘었던 것 같습니다. 전 팀원이 머신러닝 모델에 집중하면서, 보조적인 역할들이 있었습니다. 예를 들면 저는 웹구현에 치중했고, 병창님은 좀 더 코드를 정리하고 모델의 학습을 통해서 시각화 하는 과정, 그리고 경목님은 저희가 한 EDA 과정들을 분석가의 입장에서, 그리고 청중의 입장에서 보기 좋은 시각화 자료를 만드는 것에 치중했습니다.
팀원 간 협업이 성공적으로 이뤄졌고, 모델을 만들고, 웹을 제작할 때 간간히 어려움도 있었지만, 팀원 간 소통을 통해서 많이 해결한 부분도 있었습니다. - 뚜렷한 목표
저희가 어떤 목적의 웹사이트를 만들어야겠다라는 목적이 있었기 때문에, 한 부분에 매몰되지 않고 조금 더 데이터를 여러 방향에서 분석할 수 있었습니다. 또한 웹사이트 구현이라는 목표가 있었기 때문에, 좀 더 선택할 것들에 집중할 수 있지 않았나 싶습니다.
아쉬웠던 점
- 하이퍼파라미터 튜닝
GPU 옵션을 제공하지 않는 모델들과, 전 팀원이 COLAB을 처음 사용해보는 입장이여서 튜닝에 긴 시간을 쏟지 못했습니다. 이 부분이 조금 더 착실히 진행되었다면 좀 더 모델 간 파라미터를 세밀히 조정할 수 있었을 것 같고, 앙상블에 들어갈 모델들을 조금 더 많이 확보할 수 있었을 것 같습니다. - 데이터베이스
개인적으로 데이터베이스를 활용하지 못한 점이 아쉽습니다. 아직 데이터베이스를 활용할 프로젝트는 아니였지만, 해당 웹페이지에 데이터베이스를 적용해서 사용자의 정보를 그대로 저장해놓는다면, 사용자의 인구통계학적 분포나 질병 유무등을 대시보드로 만들 수 있을 것 같았습니다. 또 심장질환이 예측된 사람에 대해서 사후 서비스를 제공하는 등 조금 더 사이트의 활용방안을 무궁무진하게 넓힐 수 있을 것 같습니다. - 의료기관 지도 시각화
심장질환 관련 의료기관을 지도 시각화해서, 심장질환이라고 분류된 사용자에게 병원 위치를 제공하려고 했습니다.
그런데 공공데이터에 있는 의료기관의 좌표 위치를 변환하는 과정에서, 위치에 다소 오차가 생겨 최대한 정확한 정보를 제공하기 위해서 배제했습니다. 이 부분이 조금 더 성공적이였다면 웹 사용자가 조금 더 나은 경험을 했을 거라고 생각합니다.
마무리하면서
이번 프로젝트는 다음 단계로 나가기 위한 성공적인 프로젝트라고 생각했습니다.
딥러닝 파트와 데이터엔지니어링 파트를 수강하면서, 조금 더 나아지는 프로젝트의 모습을 보면서 다시 한번 회고할 예정입니다.
제가 느끼고, 강사님께서 조언해주신 부분에 대한 피드백은 다음과 같았습니다.
- 발표의 청중과 눈을 맞추며, 그들의 이목을 끄는 것(발표를 재밌게 하는 것도 능력 : 필요하다면 대본에 농담을 적어도 된다)
- 시연 과정을 모두 청중에게 맡기지 말 것(청중에 직접적인 경험도 좋지만, 발표자는 직접 시연할 필요가 있다)
이번 프로젝트에 대한 GIThub 주소 남깁니다:)