StuDyata.zip

[코드잇 스프린트] 스프린트 미션 04 - 파이썬으로 건강검진 데이터 분석해보기 본문

Codeit Sprint/Sprint Mission

[코드잇 스프린트] 스프린트 미션 04 - 파이썬으로 건강검진 데이터 분석해보기

자유를원해 2026. 3. 31. 21:44

이 글은 코드잇 스프린트 데이터 분석가 과정 학습 기록입니다.

🩻2024 건강검진 데이터 EDA, 전처리부터 주요 패턴 분석까지 정리

이번 네 번째 스프린트 미션에서는 2024년 건강검진정보 데이터를 활용해 탐색적 데이터 분석을 진행했다. 이번 미션은 단순히 분포만 확인하는 수준의 EDA라기보다, 건강검진 데이터라는 특성에 맞게 어떤 값을 그대로 두고, 어떤 값을 수정하거나 제거해야 하는지 기준을 세우는 과정이 특히 중요했던 미션이었다. 실제로 데이터를 처음 봤을 때는 컬럼 수가 아주 많은 편은 아니었지만, 각 변수의 의미가 단순하지 않았고 코드값으로 저장된 변수, 건강 상태를 직접 반영하는 수치형 변수, 그리고 이상치처럼 보이지만 실제로는 충분히 관측 가능한 건강 위험 수치들이 섞여 있었다.

 

무엇보다 이번 데이터는 일반적인 소비 데이터나 서비스 로그 데이터처럼 단순히 큰 값, 작은 값을 보고 판단할 수 있는 구조가 아니었다. 예를 들어 혈압이나 혈당은 값이 높거나 낮다고 해서 바로 오류라고 볼 수 없고, 오히려 실제 건강 이상 상태를 보여주는 중요한 신호일 수 있다. 반대로 겉으로 보기엔 숫자 하나 차이처럼 보여도 어떤 값은 실제 검진 환경에서 나오기 어려운 수준이라 제거가 필요할 수 있었다. 그래서 이번 미션에서는 단순히 결측값을 채우고 그래프를 그리는 데서 끝나는 것이 아니라, 데이터의 의미를 먼저 이해하고 그에 맞는 전처리 기준을 세운 뒤, 그 다음에 분석 흐름을 설계하는 방식으로 진행했다.

⛳️분석 방향과 목표

이번 분석의 전체 목표는 건강검진 데이터에서 주요 건강지표의 분포와 집단별 차이를 탐색적으로 확인하는 것이었다. 하지만 데이터 안에는 시력, 청력, 성별, 연령대, 지역, 음주, 흡연, 혈압, 혈당, 신장, 체중, 허리둘레처럼 정말 다양한 변수가 포함되어 있었기 때문에, 처음부터 모든 변수를 동일한 비중으로 다루기보다는 어떤 축으로 분석을 전개할지 먼저 정리하는 과정이 필요했다. 보고서에서도 최종적으로는 BMI, 혈압, 식전혈당, 흡연상태, 성별, 연령대 중심으로 분석을 진행했는데, 이건 단순히 눈에 띄는 변수들을 고른 게 아니라 건강위험과 직접 연결해 해석할 수 있는 변수들을 중심축으로 삼은 결과였다.

 

개인적으로도 이 단계가 되게 중요했다. 처음 데이터를 보면 이것도 해보고 싶고 저것도 해보고 싶어서 자꾸 분석 범위가 넓어지기 쉬운데, 그렇게 가면 그래프는 많아져도 결국 흐름이 약해진다. 그래서 이번 미션에서는 '건강 이상 신호가 어떤 집단에서 두드러지는가'라는 방향을 먼저 잡고, 그 기준에서 의미 있는 변수들을 중심으로 정리하는 식으로 가닥을 잡았다. 이 덕분에 이후 분석도 BMI 분포, 고혈압 위험, 혈당 이상, 생활습관과 건강지표의 관계처럼 비교적 명확한 주제로 이어갈 수 있었다.

🧬데이터 구조 먼저 뜯어보기

본격적인 전처리에 들어가기 전에 우선 데이터 구조부터 확인했다. 데이터는 총 100만 건 규모에 17개 컬럼으로 구성되어 있었고, 겉으로 보면 대부분 숫자형처럼 보였지만 실제 의미는 그렇지 않은 컬럼들이 꽤 있었다. 예를 들어 성별코드, 연령대코드, 시도코드, 흡연상태, 음주여부 같은 변수들은 숫자로 저장되어 있어도 연속적인 수치를 뜻하는 것이 아니라 특정 범주를 구분하기 위한 코드값이었다.

 

이 과정에서 느낀 건, 데이터 분석에서 '형식상 숫자'와 '의미상 숫자'는 전혀 다르다는 점이었다. 예를 들어 성별코드 1, 2는 숫자가 아니라 남성과 여성을 구분하는 라벨이고, 흡연상태 1, 2, 3도 크기의 개념이 아니라 비흡연, 금연, 흡연이라는 범주 구분이다. 이런 걸 그대로 숫자로 두고 평균을 내거나 수치형 차트로 그리면 해석 자체가 어색해진다.

🪫결측값 처리하기

데이터 구조를 확인한 뒤에는 결측값 현황부터 확인했다. 결측은 허리둘레, 시력_좌, 시력_우, 청력_좌, 청력_우, 수축기혈압, 이완기혈압, 식전혈당, 흡연상태, 음주여부에서 확인되었다. 다행히 결측 비율 자체가 아주 큰 편은 아니었지만, 그렇다고 무조건 삭제로 가기에는 아까운 데이터였고, 무엇보다 변수 성격이 제각각이라 한 가지 방식으로 통일해서 처리하면 안 되는 구조였다.

 

처음엔 결측이 많지 않으니 그냥 중앙값이나 최빈값으로 한 번에 채우면 되지 않을까 싶기도 했는데, 조금만 들여다보니 그렇게 처리하면 오히려 데이터의 집단별 차이를 망가뜨릴 수 있겠다는 생각이 들었다. 특히 건강 데이터는 연령과 성별에 따라 기본 분포가 달라질 가능성이 크기 때문에, 전체 평균 하나로 채우는 방식은 간단하긴 해도 설명력이 너무 약했다. 그래서 이번 전처리에서는 변수 하나하나의 성격에 맞게 결측 처리 기준을 다르게 잡는 게 핵심이었다.

 

📍범주형 변수 결측값은 최빈값으로

청력_좌, 청력_우, 흡연상태, 음주여부는 상태를 구분하는 범주형 변수였다. 이런 변수는 숫자로 저장되어 있더라도 평균이나 중앙값으로 처리하는 게 전혀 의미가 없기 때문에, 보고서에서는 각 변수의 최빈값으로 결측을 대체하는 방향을 택했다. 결측 비율도 크지 않았고, 최빈값 대체는 전체 범주 분포를 크게 훼손하지 않으면서 분석을 이어가기 위한 가장 기본적이고 안정적인 방법이라고 판단한 것이다. 이 부분은 사실 전처리에서는 되게 기본적인 선택처럼 보일 수도 있는데, 오히려 그래서 더 중요했다. 왜냐하면 범주형 변수는 괜히 복잡하게 처리하려 들수록 의미가 흔들리기 쉽기 때문이다. 예를 들어 흡연상태 결측을 무리하게 다른 변수와 연결해 추정하려고 하기보다는, 현재 데이터 분포를 최대한 덜 해치는 방식으로 채우는 게 더 낫다고 봤다.

 

📍수치형 변수 결측값은 집단별 중앙값으로

허리둘레, 수축기혈압, 이완기혈압, 식전혈당은 모두 건강 상태를 대표하는 수치형 변수였다. 그런데 이런 변수들은 개인의 건강 상태뿐 아니라 성별과 연령에 따라 기본적인 분포가 달라질 가능성이 높다. 허리둘레는 성별에 따라 체형 차이가 존재할 수 있고, 혈압과 혈당 역시 연령이 높아질수록 값의 분포가 달라지는 게 자연스럽다. 그래서 보고서에서는 이 변수들의 결측을 전체 평균이나 전체 중앙값으로 채우는 대신, 같은 성별코드와 같은 연령대코드를 가진 집단 내 중앙값으로 대체했다.

 

이 방식이 인상적이었던 이유는 단순히 중앙값을 썼다가 아니라, 누구의 중앙값을 쓸 것인가를 고민했다는 점 때문이다. 결측이 발생한 행의 값을 전체 인구 집단 하나의 대표값으로 채우는 건 편하지만, 그 사람이 속한 연령대와 성별의 특성을 날려버릴 수 있다. 반면 같은 성별, 같은 연령대 안에서 중앙값을 구하면 적어도 그 사람과 비슷한 집단의 분포를 바탕으로 값을 보정하게 된다. 건강 데이터처럼 집단별 차이가 분명할 가능성이 큰 경우에는 이런 방식이 훨씬 설득력 있었다. 평균이 아니라 중앙값을 선택한 것도 극단값의 영향을 줄이기 위한 판단이었다.

 

📍시력 변수는 따로 처리

시력_좌, 시력_우는 겉으로 보면 수치형 변수지만, 일반적인 연속형 변수처럼 다루기엔 애매한 부분이 있었다. 데이터 설명에 따르면 시력은 0.1에서 2.5 사이 값으로 기록되며, 실명은 9.9로 표기된다. 여기서 9.9는 단순히 엄청 큰 시력 수치가 아니라, 일반적인 시력값과 다른 의미를 가진 특수 코드값이었다. 그래서 보고서에서는 시력 변수 결측값을 대체할 때, 9.9를 포함하지 않고 나머지 값들만으로 중앙값을 계산한 뒤 결측을 채웠다. 만약 9.9를 일반 수치처럼 포함해서 중앙값이나 평균을 구하면, 실명이라는 특수한 상태를 일반 시력 분포 안에 억지로 섞어버리는 셈이 된다.

💡이상치 처리하기

결측값 처리 다음으로는 이상치 처리를 진행했다. 그런데 이번 미션에서 가장 오래 걸리고, 제일 많이 고민했던 부분도 아마 여기였던 것 같다. 일반적인 EDA에서는 박스플롯이나 IQR 기준으로 이상치를 찾고 일정 기준 아래/위 값을 제거하는 식으로 비교적 단순하게 접근할 수 있다. 하지만 건강검진 데이터는 그 방식이 잘 안 통했다. 왜냐하면 통계적으로 드문 값이 실제로는 건강위험 상태를 반영하는 중요한 값일 수 있기 때문이다.

 

이상치 처리에서 내가 계속 붙잡고 있었던 질문은 결국 하나였다. 이 값이 분포상 이상한 값인가, 아니면 실제로 위험한 건강 상태를 보여주는 값인가? 예를 들어 혈압 180, 혈당 300 같은 값은 흔하지 않지만 실제로 충분히 관측 가능한 건강 위험 수치다. 이런 걸 단순히 상한선을 넘었다는 이유만으로 삭제해버리면, 분석에서 가장 중요한 고위험 집단이 사라질 수 있다. 그래서 이번 미션에서는 이상치를 통계로만 보지 않고, 건강지표로서 해석 가능한지까지 같이 본다는 원칙을 세우고 진행했다. 그리고 이 판단의 근거를 위해 질병관리청 국가건강정보포털 자료를 함께 참고했으며 필요한 값을 바로 확인하기 위해 Plotly Express 라이브러리의 상자그림을 통해 우선적으로 확인하였다.

 

📍신장 이상치 판단

신장은 IQR 기준으로 135 미만(130cm)과 190 초과(195cm)가 이상치로 나타났다.

신장 변수 박스플롯

 

우선 195cm는 평균보다 큰 값이긴 하지만 성인 남성에게서 현실적으로 충분히 관측 가능한 수준이라고 봤다. 실제로 195cm 데이터 92건은 특정 비현실적인 연령대에 몰려 있지 않았고, 여러 성인 연령대에서 모두 남성에게 관측되었다. 반면 130cm는 다른 판단이 필요했다. 질병관리청 자료에서는 성인의 평균 신장을 남자 173.4cm, 여자 160.7cm 수준으로 설명하고 있는데, 이를 고려하면 130cm는 단순히 평균보다 작은 정도가 아니라 일반적인 성인 검진 데이터 분포에서 지나치게 낮은 값으로 볼 수 있었다. 그래서 130cm는 입력 또는 기록 오류 가능성이 높다고 판단해 제거했다.

 

📍체중 이상치 판단

체중은 IQR 기준으로 105kg 초과가 이상치로 나타났고 최대값은 135kg이었다.

체중 변수 박스플롯

 

하지만 체중은 그 자체만으로 오류 여부를 판단하기보다 신장과 함께 봐야 하는 변수라고 생각했다. 질병관리청 국가건강정보포털의 비만 관련 자료에서도 비만 정도를 평가할 때 단순 체중이 아니라 BMI를 활용해 키와 몸무게를 함께 고려한다고 설명하고 있다. 즉 체중이 크다고 해서 무조건 이상치로 제거하는 것은 적절하지 않았다. 비만이나 고도비만 상태에서는 110~135kg 같은 체중도 실제로 충분히 관측 가능하기 때문이다. 그래서 체중은 분포상 드문 값이라 하더라도 실제 건강 상태를 반영하는 집단일 가능성이 높다고 보고 전부 유지했다.

 

이 판단은 이후 BMI를 활용한 분석과도 자연스럽게 이어졌다. 체중 상단 구간을 정리해버리면 비만도 분포가 인위적으로 줄어들고, BMI와 혈압·혈당 관계를 보는 분석 역시 약해질 수 있다. 그래서 체중은 '통계적으로 드물다'와 '실제로 잘못됐다'를 분리해서 본 사례였다.

 

📍허리둘레 이상치 판단

허리둘레 역시 박스플롯상 이상치가 비교적 많이 나타난 변수였다.

허리둘레 변수 박스플롯

 

질병관리청 자료에 따르면 허리둘레는 복부비만 판단에 활용되는 대표적인 지표이며, 복부비만 기준은 남성 90cm 이상, 여성 85cm 이상으로 제시된다. 즉 허리둘레가 높은 값이라는 사실 자체 건강위험 신호일 수는 있어도, 곧바로 오류라고 보긴 어렵다. 그래서 허리둘레는 이상치 전체를 제거하기보다, 실제 성인 건강검진 값으로 보기 어려운 극단값만 최소한으로 제거하는 방향으로 갔다. 데이터를 직접 확인해보니 6.8, 10, 43, 44, 45.3, 170, 210, 999 같은 값이 포함되어 있었고, 이런 값들은 다른 허리둘레 분포와 비교해도 지나치게 동떨어져 있었다. 그래서 최종적으로는 50 미만, 150 초과 값을 이상치로 보고 제거했다.

 

질병관리청 복부비만 기준을 참고했지만 그 기준을 그대로 삭제 기준으로 쓰진 않았다. 즉 '90 이상이면 다 이상치' 같은 식으로 가지 않고, 건강지표라는 특성을 인정한 상태에서 명백한 입력 오류 가능성이 높은 값만 보수적으로 정리했다.

 

📍혈압 이상치 판단

혈압 변수는 수축기혈압과 이완기혈압으로 나누어 해석했다.

혈압 변수 박스플롯

 

질병관리청 자료에 따르면 고혈압은 일반적으로 수축기혈압 140mmHg 이상 또는 이완기혈압 90mmHg 이상으로 본다. 또 고혈압 환자의 운동 관련 자료에서는 수축기혈압이 200을 초과하거나 이완기혈압이 115를 초과하는 경우 운동을 금하고, 180/110 이상이면 약물치료 후 근력운동을 추가하도록 제시하고 있다. 이 내용을 보면 상한선을 넘는 높은 혈압값도 실제로 건강관리 상황에서 충분히 다뤄지는 수치다. 그래서 수축기혈압과 이완기혈압의 높은 값은 IQR상 이상치로 보여도 제거하지 않고 유지했다.

 

낮은 값도 마찬가지였다. 질병관리청 자료에서는 일반적으로 수축기혈압 90 미만 또는 이완기혈압 60 미만을 저혈압으로 설명하지만, 동시에 저혈압은 수치만으로 단정하는 것이 아니라 혈압이 떨어지는 속도와 증상 여부 등을 함께 고려해야 한다고 설명한다. 따라서 수축기혈압 최저값인 60mmHg도 매우 낮은 값이긴 하지만, 실제 저혈압 상태를 반영할 가능성이 있어 제거하지 않았다. 다만 이완기혈압의 경우 30mmHg 미만 값은 건강검진 환경에서 정상 측정값으로 보기 어려운 수준이라고 판단해 총 3건만 제거했다.

 

즉 혈압은 질병관리청 기준을 바탕으로 위험한 고혈압/저혈압 수치와 오류 가능성이 높은 극단값을 구분한 뒤, 실제 건강 상태를 반영할 수 있는 값은 최대한 유지하는 방향으로 처리했다.

 

📍식전혈당 이상치 판단

식전혈당 역시 건강 상태를 직접 반영하는 핵심 변수였다.

식전혈당 변수 박스플롯

 

질병관리청 자료에 따르면 정상 공복혈당은 100mg/dL 미만, 공복혈당장애는 100~125mg/dL, 당뇨병 진단 기준은 8시간 이상 공복 후 혈장 포도당 126mg/dL 이상으로 제시된다. 따라서 126을 넘는 높은 식전혈당값은 실제 당뇨병 또는 고혈당 상태를 반영할 가능성이 높기 때문에, 단순히 boxplot 상단 이상치라고 해서 제거할 수 없었다. 더 나아가 질병관리청 고혈당 자료에서는 250mg/dL 이상, 심한 경우 300 이상, 600 이상까지도 임상적으로 관측 가능한 고혈당 상태를 설명하고 있다. 그래서 이번 전처리에서는 300, 400, 500, 600대 혈당값도 실제 고혈당 상태를 반영할 수 있다고 보고 유지했다. 다만 700mg/dL 이상은 일반 건강검진 데이터에서 매우 드물고, 자료에서도 직접적인 해석 기준을 찾기 어려운 초극단값으로 판단해 제거했다.

 

낮은 혈당값 역시 동일하게 판단했다. 질병관리청 자료에서는 저혈당을 보통 70mg/dL 미만으로 설명하고, 45~50mg/dL 이하에서도 증상과 함께 판단해야 한다고 안내하고 있다. 즉 혈당이 낮다는 이유만으로 바로 오류라고 할 수는 없지만, 40mg/dL 미만의 값들은 일반적인 건강검진 데이터와 비교했을 때 지나치게 낮은 수준으로 보였다. 실제 데이터에서도 17, 20, 23, 25, 28, 29, 30, 32, 33, 36, 39 같은 값이 확인되었고, 이 값들은 일반적인 저혈당 범위를 넘어선 극단값으로 판단되어 제거했다. 식전혈당도 질병관리청의 당뇨, 고혈당, 저혈당 기준을 함께 참고하면서 실제 건강위험값은 남기고, 해석이 어려운 극단값만 최소한으로 제거하는 방식으로 정리했다.

🔧범주형 코드값 점검하기

수치형 변수 정리가 끝난 뒤에는 범주형 변수 코드값도 하나씩 점검했다.

청력 범주값 확인

 

기준년도, 시도코드, 성별코드, 연령대코드, 청력_좌, 청력_우, 흡연상태, 음주여부를 확인한 결과 대부분은 설명에 제시된 코드 범위 내에 있었지만, 청력_좌와 청력_우에서는 1과 2 외에 정의되지 않은 값 3이 존재하는 것이 확인됐다. 이 값을 오류 코드로 판단하고, 삭제하지 않고 각 변수의 최빈값으로 대체했다. 약 2,300건 정도가 있었기 때문에 전부 삭제하면 데이터 손실이 커질 수 있었고, 범주형 변수라는 점에서 결측 처리와 같은 방식으로 접근하는 것이 가장 일관적이라고 보았다. 전처리는 결측값과 이상치만 보는 게 아니라, 코드 체계 자체가 설명과 맞는지도 확인해야 한다는 걸 다시 느꼈다.

🔠문자열 변환과 파생변수 생성하기

이후에는 숫자 코드로 저장되어 있던 범주형 변수들을 파이썬의 map을 이용하여 해석 가능한 문자열로 변환했다. 성별코드는 남성/여성, 흡연상태는 비흡연/금연/흡연, 음주여부는 비음주/음주, 시도코드는 실제 시도명, 연령대코드는 연령대 문자열로 바꿨다. 이 작업은 분석 자체를 바꾸는 처리는 아니지만, 이후 시각화와 결과 해석 단계에서 가독성을 크게 높여주는 과정이었다. 숫자 1, 2, 3으로 된 범주를 그래프에 그대로 두는 것보다, 실제 의미를 가진 라벨로 바꾸는 게 훨씬 해석이 직관적이기 때문이다.

 

그리고 이번 미션의 핵심 파생변수인 BMI도 이 단계에서 생성했다. BMI는 체중(kg)을 신장(m)의 제곱으로 나눈 값으로, 단순 체중보다 건강위험과 연결해 해석하기 좋은 대표 지표이다. 이후 성별·연령대별 BMI 변화, 비만도 분포, BMI와 혈압/혈당 관계를 분석하는 데 이 변수가 핵심 축이 됐다.

🔍전처리 후 데이터 상태 확인하기

전처리를 마친 뒤에는 바로 분석으로 넘어가지 않고, 기술통계량을 다시 확인하면서 데이터 상태를 점검했다.

수치형 변수 기술통계량 확인

 

최종 분석에 사용된 데이터는 999,716건이었고, 신장, 체중, 허리둘레, 시력, 혈압, 식전혈당 등의 수치형 변수에 대해 평균, 중앙값, 사분위수, 최소·최대값을 확인했다. 보고서 기준으로 신장과 체중은 평균과 중앙값 차이가 크지 않아 비교적 안정적인 분포를 보였고, 허리둘레와 혈압, 식전혈당은 일부 높은 값이 포함된 우측 치우침 경향을 확인할 수 있었다.

범주형 변수 기술통계량 확인

 

범주형 변수도 함께 확인했는데, 거주지는 경기도 비중이 가장 높았고, 성별은 남성이 약간 더 많았으며, 연령대는 50~54세 구간이 가장 많았다. 청력은 정상 범주가 대부분이었고, 생활습관 변수에서는 비흡연 비중이 가장 높았으며 음주는 음주 응답 비중이 더 높게 나타났다.

📊주요 변수 분포 확인하기

본격적인 주요 분석에 들어가기 전에는 히스토그램과 박스플롯을 통해 신체계측 변수, 혈압·혈당 변수, 성별·연령대, 생활습관 변수의 분포를 먼저 살폈다.

신장, 체중, 허리둘레 분포 히스토그램

 

신장은 150~175cm 구간에 관측치가 집중된 비교적 안정적인 분포를 보였고, 체중과 허리둘레는 오른쪽 꼬리가 긴 분포를 보여 일부 고위험 집단이 존재함을 확인할 수 있었다.

수축기혈압, 이완기혈압, 식전혈당 분포 히스토그램

 

혈압과 식전혈당 역시 중심 구간에 자료가 밀집되어 있으면서, 상단 방향으로 꼬리가 길게 이어지는 구조를 보였다. 특히 식전혈당은 우측 치우침이 더 뚜렷해, 정상 범위 부근에 관측치가 몰려 있으면서도 일부 고혈당 집단이 분명 존재한다는 점이 드러났다.

 

이 분포 확인 단계가 중요했던 이유는, 바로 여기서 이후 분석의 축이 더 선명해졌다. 단순히 전체 평균만 보면 혈압이나 혈당이 생각보다 안정적으로 보일 수 있지만, 분포를 보면 실제로는 우측 꼬리에 고위험군이 꽤 포함되어 있다. 그래서 이번 미션은 평균 비교만으로는 부족하고, 집단별 차이와 위험 비중을 함께 보는 방식으로 가야 한다는 방향이 여기서 다시 확인됐다.

🩺핵심 분석 1: BMI를 중심으로 본 비만도 분포와 집단 차이

보고서의 주요 분석 첫 번째 축은 비만도였다.

성별·연령대별 평균 BMI 라인 그래프

 

먼저 성별·연령대별 평균 BMI를 라인 그래프로 비교했는데, 남성은 젊은 성인기부터 중년 초반까지 BMI가 높게 나타난 뒤 이후 완만하게 감소하는 흐름을 보였고, 여성은 20대 초반에는 BMI가 낮게 시작하지만 연령 증가에 따라 점진적으로 상승하는 패턴이 나타났다. 특히 여성은 70대 이후 남성과 비슷하거나 일부 구간에서는 더 높은 수준까지 올라가는 흐름이 확인됐다.

 

이 결과가 흥미로웠던 건 단순히 남성이 BMI가 높다로 끝나지 않는다는 점이었다. 실제로는 남성과 여성이 연령에 따라 서로 다른 변화 곡선을 보였다. 남성은 비교적 이른 시기에 높았다가 내려오고, 여성은 늦게까지 조금씩 증가하는 모습이었다. 즉 BMI를 단일 평균으로만 보면 놓칠 수 있는 차이가 분명 존재했다. 이 부분은 성별과 연령을 함께 묶어서 봐야 하는 이유를 잘 보여줬다.

연령대별 비만도 비중 누적 막대 그래프

 

이어서 연령대별 비만도 비중도 누적 막대그래프로 확인했다. 20대 초반은 정상체중 비중이 높고 비만 비중이 낮았지만, 30대 이후로 갈수록 정상체중 비중은 줄고 과체중 및 비만 비중이 커지는 경향이 나타났다. 특히 35~49세 구간에서는 비만 비중이 눈에 띄게 높아져 중년 전후 구간에서 체중 관리 위험이 상대적으로 커질 수 있음을 시사했다. 반면 80대 이후에는 저체중 비율이 다시 증가하는 양상도 확인됐다. 결국 비만 경향은 청년층보다는 중년층에서 두드러지고, 초고령층에서는 다시 저체중 비중이 올라가는 식으로 연령대별 체격 분포가 달라진다는 것을 읽을 수 있었다.

🩸핵심 분석 2: 고혈압 위험 패턴 확인

두 번째 분석 축은 고혈압이었다. 질병관리청 기준에 따라 수축기혈압 140mmHg 이상 또는 이완기혈압 90mmHg 이상을 고혈압으로 정의하고, 성별·연령대별 고혈압 비율을 확인했다.

성별·연령대별 고혈압 비율 라인 그래프

 

그 결과 남성과 여성 모두 연령이 증가할수록 고혈압 비율이 뚜렷하게 상승했다. 하지만 그 증가 양상은 성별에 따라 차이가 있었다. 남성은 20대부터 여성보다 높은 고혈압 비율을 보이며 비교적 이른 시기부터 증가세가 나타났고, 40~60대 구간에서도 여성보다 높은 수준을 유지했다. 반면 여성은 젊은 연령대에서는 낮은 비율을 보이지만, 60대 이후 급격히 상승해 70대 이후에는 남성을 넘어서는 구간이 나타났다. 실제로는 젊은~중년층에서는 남성의 위험이 더 높고, 고령층에서는 여성의 증가폭이 더 가파른 구조였다. 즉 고혈압 위험은 연령만으로도, 성별만으로도 다 설명되지 않고 두 변수를 함께 봐야 패턴이 보인다는 걸 확인할 수 있었다.

BMI 구간별 평균 혈압 라인 그래프

 

이어서 BMI 구간별 평균 혈압도 함께 비교했다. 저체중에서 정상, 과체중, 1단계 비만, 고도비만으로 갈수록 수축기혈압과 이완기혈압이 모두 꾸준히 상승했고, 특히 수축기혈압의 상승 경향이 더 뚜렷하게 나타났다. 이는 BMI가 단순한 체격 지표를 넘어서 혈압 부담과 밀접하게 연결될 수 있다는 점을 보여주는 결과였다. 결국 비만도 증가는 단순히 몸무게의 문제가 아니라 심혈관계 건강과도 이어지는 해석이 가능했다.

💉핵심 분석 3: 혈당 이상 및 당뇨 위험 패턴

세 번째 축은 혈당이었다. 질병관리청 기준에 따라 식전혈당을 100mg/dL 미만은 정상, 100~125mg/dL는 공복혈당장애, 126mg/dL 이상은 당뇨병 의심 구간으로 나누고, 비만도별 혈당 상태 비율을 비교했다.

비만도별 혈당 상태 비율 누적 막대 그래프

 

결과적으로 BMI가 높아질수록 정상 혈당 비율은 감소하고, 공복혈당장애 및 당뇨 의심 비율은 증가하는 뚜렷한 패턴이 나타났다. 저체중 집단에서는 정상 혈당 비중이 가장 높고 당뇨 의심 비율은 가장 낮았으며, 과체중 이상부터는 공복혈당장애 비율이 커지고 비만 집단에서는 정상 비율이 크게 낮아지는 대신 공복혈당장애와 당뇨 의심 비중이 함께 증가했다.

 

이 분석은 앞서 본 BMI와 혈압 관계와도 자연스럽게 연결됐다. BMI가 높아질수록 혈압이 올라가는 경향이 있었는데, 혈당 역시 비슷하게 불리한 방향으로 이동했다. 결국 BMI는 이번 데이터에서 혈압과 혈당 모두와 연결되는 중요한 설명 변수였다. 단순히 비만도 분포를 확인하는 데서 그치는 게 아니라, 비만도가 여러 건강위험 지표를 동시에 설명하는 축으로 작동한다는 점을 확인한 게 이번 분석의 핵심 중 하나였다.

💊핵심 분석 4: 생활습관 변수와 건강지표의 연관성

마지막으로는 흡연 상태와 음주 여부 같은 생활습관 변수를 건강지표와 연결해 봤다.

흡연 상태별 고혈압 및 당뇨의심 비율 막대 그래프

 

먼저 흡연 상태별 고혈압 및 당뇨 의심 비율을 비교한 결과, 비흡연 집단이 가장 낮은 비율을 보였고 금연 및 흡연 집단에서는 상대적으로 더 높은 수준이 나타났다. 특히 고혈압 비율은 금연 집단에서 가장 높고, 흡연 집단이 그다음, 비흡연 집단이 가장 낮았다. 당뇨 의심 비율 역시 비흡연보다 금연과 흡연 집단에서 높게 나타났다.

 

다만 이 부분은 금연 집단의 비율이 가장 높게 나타났다고 해서 금연이 더 위험하다라고 해석하면 안 된다. 실제로는 건강 이상을 경험한 뒤 금연한 사람, 즉 원래 건강위험이 높은 집단이 금연 범주에 포함되어 있을 수 있기 때문이다.

음주 여부별 고혈압 및 당뇨의심 비율 막대 그래프

 

음주 여부별 고혈압 및 당뇨 의심 비율도 비교했는데, 이번 데이터에서는 비음주 집단에서 음주 집단보다 두 위험 지표가 모두 더 높게 나타났다. 이것 역시 단순히 술을 안 마실수록 더 위험하다라고 해석할 수는 없고, 건강상 이유로 금주하고 있는 사람이나 질환 위험으로 생활습관을 조절 중인 사람이 비음주 집단에 포함되어 있을 가능성을 고려해야 했다. 결국 생활습관 변수는 분명 의미 있는 보조 변수이지만, 교차표나 비율 비교만으로 인과를 단정하기는 어렵다는 점까지 같이 확인했다.

💎이번 스프린트 미션에서 남은 것

이번 미션은 겉으로 보기엔 건강검진 데이터를 활용한 EDA였지만, 실제로는 전처리 기준을 세우는 과정 자체가 분석의 절반 이상이었던 미션이었다. 결측값 하나를 채울 때도 변수의 의미를 봐야 했고, 이상치 하나를 제거할 때도 통계 기준만으로는 부족했다. 특히 혈압, 혈당, 허리둘레처럼 건강위험을 직접 보여주는 변수들은 상자그림에 이상치가 많이 찍힌다고 해서 쉽게 잘라낼 수 있는 값들이 아니었다.

 

그리고 이번 분석을 정리하면서 다시 느낀 건, 좋은 EDA는 결국 결과만 화려한 게 아니라 처리 기준이 납득 가능해야 한다는 점이다. 왜 어떤 결측은 최빈값으로 채웠는지, 왜 어떤 값은 유지했고 어떤 값은 제거했는지, 왜 BMI를 새로 만들었는지, 왜 성별과 연령대를 함께 비교했는지 이런 것들이 연결되어 있어야 분석 전체 흐름이 살아난다. 이번 미션은 그런 점에서 데이터 하나하나를 쉽게 넘기지 않고 기준을 세워가며 정리해본 경험이었다. 다만 이상치 처리 기준은 변수의 의미와 건강검진 데이터의 특성을 고려해 보수적으로 설정하였으나, 일부 기준은 의학적 진단 기준이 아니라 분석 목적에 따른 정제 기준이므로 기준 설정 방식에 따라 결과가 달라질 수 있다는 한계가 있다.