EMR 기반 질환 예측 모델 개발

kikiru328 | Jul 8, 2025 min read

Python Scikit-learn XGBoost SHAP

한 장 요약본

프로젝트 개요

목록내용
프로젝트명EMR 기반 질환 예측 모델 개발
개발기간2023년 3월 - 2024년 4월 (1년 1개월)
역할데이터 분석 및 연구원 (국립암센터 기관 고유 과제)
기여도데이터 정형화, 분석, 모델링 전담
개발환경(국립암센터 내 서버 연구환경)

비즈니스 배경 및 문제 정의

핵심과제

비정형 EMR 데이터를 활용한 고성능 질환 예측 모델 개발로 의료진 의사결정 지원 모델 개발

의료 EMR 데이터의 특수성:

  • 수기 입력으로 인한 단위/표현 불일치 (키 250cm, 체중 1130kg 등 논리적 오류)
  • 결측치와 이상치가 높은 비율로 존재
  • 의료 도메인 지식이 필수적인 복합적 데이터 구조
  • 예측 근거 설명이 반드시 필요한 의료 AI 특성

기존 연구의 한계점:

  • 동일 주제 기존 논문: ROC-AUC 0.61 수준의 제한적 성능
  • 단순 변수 활용으로 인한 예측력 부족
  • 데이터 전처리 과정의 체계성 부족

핵심 성과 지표

지표달성값측정 방법
예측 성능 향상ROC-AUC 0.87기존 논문 대비 45% 향상 (0.61→0.87)
데이터 정형화약 3,000명 완료비정형 EMR → 정형 데이터 변환
클래스 불균형 해결class_weight 최적화3:7 비율 데이터에서 균형잡힌 예측
프로세스 자동화80% 시간 단축ETL 파이프라인으로 반복 실험 효율화

기술 스택 및 아키텍처

핵심 기술 스택

# 주요 기술 구성
Data Processing      : SQL, Python, Pandas, NumPy, re (정규표현식)
ML/Statistics        : Scikit-learn, XGBoost, 통계분석, Feature Selection
Model Interpretation : SHAP, Feature Importance
Automation           : Python ETL Pipeline, GridSearch

시스템 아키텍처

  graph TD
    A[원시 EMR 데이터] --> B[정규표현식 정형화]
    B --> C[단위 통일 처리]
    C --> D[이상치 탐지 및 제거]
    D --> E[의료진 검증]
    E --> F[파생 변수 생성]
    D --> F
    F --> G[통계적 Feature Selection]
    G --> H[7개 알고리즘 성능 비교]
    H --> I[GridSearch 하이퍼파라미터 최적화]
    I --> J[SHAP 모델 해석성 분석]
    J --> K[최종 예측 모델]
    
    subgraph "ETL Pipeline 자동화"
        B
        C
        D
        F
    end
    
    subgraph "ML Pipeline"
        G
        H
        I
        J
    end
    
    subgraph "Domain Expert Collaboration"
        E
        L[의료진 직접 작성 표]
        M[SQL 테이블 기준]
        L --> E
        M --> E
    end

주요 기술적 도전과 해결책

1. 비정형 EMR 데이터 문제 해결

도전과제

  • 문제: 수기 입력으로 인한 심각한 데이터 품질 문제
  • 복잡성: 단위 불일치, 표현 다양성, 논리적 비약 등 다차원적 문제
  • 영향: 기본적인 분석조차 불가능한 수준의 데이터 노이즈

발견된 데이터 품질 문제 사례

# 실제 발견된 이상치 예시
critical_outliers = [
    "키: 250cm, 체중: 1130kg",
    "혈압: 300/200 mmHg", 
    "나이: 150세",
    "체온: 50도",
    ...
]
# 단위 표현 불일치 예시
unit_inconsistencies = [
    "170cm", "1.7m", "170센티미터",
    "70kg", "70킬로", "70키로그램",...
]

문제 해결 과정

1단계: 체계적 정규표현식 설계


# 1-1. 패턴파악 예시
unit_patterns = {
    'height': r'(\d+\.?\d*)\s*(cm|m|센티미터)',
    'weight': r'(\d+\.?\d*)\s*(kg|g|킬로|키로그램)',
    'volume': r'(\d+\.?\d*)\s*(ml|cc|L|리터)',
    'temperature': r'(\d+\.?\d*)\s*(도|°C|celsius)',
    'blood_pressure': r'(\d+)\s*/\s*(\d+)',
    }

# 1-2. 표준단위 통일 예시   
def normalize_units(self, text, data_type):
    pattern = unit_patterns.get(data_type)
    if not pattern:
        return None
    match = re.search(pattern, str(text).lower())
    if match:
        if data_type == 'height':
            value, unit = match.groups()
            value = float(value)
            # m 단위는 cm로 변환
            return value if 'cm' in unit or '센티' in unit else value * 100
        elif data_type == 'weight':
            value, unit = match.groups()
            value = float(value)
            # g 단위는 kg으로 변환
            return value if 'kg' in unit or '킬로' in unit else value / 1000
        # 다른 데이터 타입들도 유사하게 처리
    return None

2단계: 통계적 이상치 탐지

# 2. IQR 이상치 식별 예시
def statistical_outlier_detection(df, columns):
    outlier_results = {}
    for col in columns:
        Q1 = df[col].quantile(0.25)
        Q3 = df[col].quantile(0.75)
        IQR = Q3 - Q1
        # IQR 방법으로 이상치 경계 설정
        lower_bound = Q1 - 1.5 * IQR
        upper_bound = Q3 + 1.5 * IQR
        # 이상치 식별
        outliers = df[(df[col] < lower_bound) | (df[col] > upper_bound)]
        outlier_results[col] = {
            'count': len(outliers),
            'percentage': len(outliers) / len(df) * 100,
            'outlier_indices': outliers.index.tolist()
        }
    return outlier_results

3단계: 의료진 협업 검증 시스템

  • 정기 대면 미팅
    • 2달 1회
    • 데이터 분석가, 의료진, 연구책임자
    • 이상치 판정, 변수 해석, 일상적 타당성 등
  • 타부서와 협업
    • 사내 메일로 컨택
    • 데이터 검증, 변수 설명, 서버 및 데이터베이스 관리
결과
  • 데이터 품질 개선: 3,000명 환자 데이터 정형화 완료
  • 협업 효율성 향상: 의료진-데이터 분석가 간 효과적 소통 체계 구축

2. 도메인 특화 파생 변수 설계

도전과제

  • 문제: 기존 변수 간 약한 상관성으로 예측 성능 제한 (ROC-AUC 0.61)
  • 복잡성: 의료 도메인 지식이 필수적인 변수 조합 설계
  • 요구사항: 임상적으로 의미있고 통계적으로 유의한 파생 변수 생성

의료 논문 검토 및 변수 설계 과정

1단계: 의학 문헌 조사

# 검토한 의학 논문 기반 주요 지표들 
medical_literature_insights = {
    "BMI"           : "체질량지수 - 비만도 평가의 표준 지표",
    "CCI"           : "Charlson Comorbidity Index - 동반질환 중증도",
    "복합_위험인자"   : "연령+동반질환, 흡연+당뇨 등 상호작용",
    "대사증후군_지표" : "허리둘레, 혈압, 혈당 조합",
    "염증_마커"      : "CRP, ESR 등 염증 수치 조합"
}

2단계: 의료진으로 부터 검증받은 변수 생성 및 설계

# 2-1. 파생변수 생성 및 설계 예시
def create_derived_features(self, df):
    df['BMI'] = df['weight'] / (df['height'] / 100) ** 2
    df['obesity_level'] = df['BMI'].apply(classify_obesity)
    df['CCI'] = calculate_cci(df)
    df['high_risk_age_comorbidity'] = (df['age'] > 65) & (df['CCI'] > 2)
    df['diabetes_smoking_interaction'] = df['diabetes'] & df['smoking']
    df['hypertension_obesity_combo'] = (df['hypertension'] == 1) & (df['BMI'] > 30)
    df['metabolic_syndrome_score'] = calculate_metabolic_syndrome(df)
    df['age_risk_stratification'] = df['age'].apply(stratify_age_risk)
    return df

# 2-2. 파생변수 중 CCI 지수 설계 예시    
def calculate_cci(self, df):
    cci_weights = {
        'myocardial_infarction': 1,
        'congestive_heart_failure': 1,
        'peripheral_vascular_disease': 1,
        'cerebrovascular_disease': 1,
        'dementia': 1,
        'chronic_pulmonary_disease': 1,
        'rheumatic_disease': 1,
        'peptic_ulcer_disease': 1,
        'mild_liver_disease': 1,
        'diabetes': 1,
        'diabetes_with_chronic_complications': 2,
        'hemiplegia_or_paraplegia': 2,
        'renal_disease': 2,
        'any_malignancy': 2,
        'moderate_or_severe_liver_disease': 3,
        'metastatic_solid_tumor': 6,
        'aids_hiv': 6
    }
    cci_score = 0
    for condition, weight in cci_weights.items():
        if condition in df.columns:
            cci_score += df[condition] * weight
    return cci_score

3단계: 통계적 유의성 검증

  • 생성된 파생변수의 통계적 검정 진행
    • Shapiro-Wilk test, t-test, Mann-Whitney U Test 적용
변수 선택
  • 임상적 타당성: 의료진 검증을 통한 변수의 의학적 의미 보장
  • 통계적 유의성: 검증 후 p < 0.05 수준 파생변수 및 변수 선택

3. 클래스 불균형 문제 해결

도전과제

  • 문제: 3:7 비율의 심각한 클래스 불균형
  • 복잡성: 소수 클래스의 패턴을 효과적으로 학습해야 하는 과제
  • 의료 AI 특성: Precision과 Recall 모두 중요한 의료 진단 영역

클래스 불균형 해결 전략

  • 1단계: Compute_class_weight로 class weight 계산
  • 2단계: GridSearch 기반 최적화

4. ETL 파이프라인 자동화

도전과제

  • 문제: 반복 실험마다 수작업 전처리로 인한 시간 소모
  • 복잡성: 다단계 데이터 처리 과정의 일관성 보장 필요
  • 효율성: 연구 생산성 향상을 위한 자동화 체계 구축

자동화 파이프라인 설계

1단계: 모듈화된 ETL 설계

  graph LR
    A[정형화 EMR]
    B[정규화 처리 Scripts]
    C[Config.json]
    D[Custom EMR Table]
    E[정형화]
    A --> E
    E --> D
    C --> B
    B --> E

2단계: 설정 기반 유연성 확보

# config.json 예시
{
    "EMR_PATH": "...",
    "structures": {
        "height": "normalize",
        "weight": "normalize",
        ...
    },
    "derived_variables": [
        "BMI",
         ...
    ],
}

3단계: 설정 기반 학습/검증 일관성 확보

# config.json 예시
{
    ...,
    "models": ["LogisticRegression", "RandomForest", ...],
    "CV": 5,               # Cross Validation
    "classwight": True,
    "gridsearch": True,
    "result": True,        # 결과 Report Table 작성
    "print_image": False,  # 결과 Graph (ROC_AUC) Table 작성
}
성과
  • 처리 시간 약 80% 단축: 20분 → 자동화 3분
  • 일관성 확보: 동일한 전처리 기준으로 재현 가능
  • 오류 감소: 수작업 실수 제거로 데이터 품질 향상

5. 모델 해석성 및 검증

도전과제

  • 문제: 의료 AI 특성상 예측 근거 설명이 필수
  • 복잡성: 통계분석과 ML 모델 간 일관성 있는 해석
  • 신뢰성: 의료진이 신뢰할 수 있는 수준의 설명 가능성

해석 가능성 구현

1단계: SHAP 기반 모델 해석

  • 모든 머신러닝 모델 학습 및 검증에 SHAP 기반 모델 해석을 추가
  • 각 결과 Graph를 참고하여 모델 해석 가능성 확보

2단계: 통계분석과 ML 결과 비교

  • 동일한 전처리 과정으로 정형화된 데이터를 활용
  • LogisticRegression 통계 분석 (statsmodel) 과 비교
성과
  • 예측 성능 개선: 기존 동일 논문 주제와 비교하여 45% 향상 (61% -> 87%)

성능 평가 및 검증

종합 성능 비교

알고리즘ROC-AUC특징
Logistic Regression0.87class_weight + 해석성 우수

비즈니스 임팩트 및 성과

연구 성과

  • 논문 2편 작성: 높은 성능을 바탕으로 한 결과 논문 작성
아쉽게도 논문 2편은 투고되지 않았습니다.
  • 성능 벤치마크: 동일 주제 기존 연구 대비 45% 향상
  • 방법론 확립: EMR 데이터 정형화 및 분석 체계적 프로세스 개발
  • 확장 가능성: 현재 주제에 더불어 멀티모달 연구로 확장

기술적 학습 및 성장

데이터 사이언스 역량

  • 데이터 품질 관리: 의료 데이터 특성을 고려한 전문적 전처리 기법
  • 통계적 분석: 의료 통계학과 머신러닝의 효과적 결합
  • Feature Engineering: 도메인 지식 기반 변수 설계 및 검증
  • 모델 해석: SHAP, 통계분석 등 다각도 해석 기법

도메인 전문성

  • 의료 지식: EMR 구조, 의료 용어, 임상 지표에 대한 이해
  • 협업 스킬: 의료진과의 효과적 소통 및 지식 전달
  • 품질 관리: 의료 데이터의 높은 품질 기준에 맞는 검증 체계

연구 방법론

  • 문헌 조사: 의학 논문 검토를 통한 이론적 기반 구축
  • 실험 설계: 체계적 비교 실험 및 검증 프로세스
  • 결과 해석: 통계적 유의성과 임상적 의미의 균형 있는 해석

결론 및 시사점

기술적 가치

  • 데이터 품질의 중요성: EMR 정형화가 모델 성능의 핵심 결정 요인임을 입증
  • 도메인 지식 활용: 의료진 협업을 통한 파생 변수 설계가 성능 향상의 핵심
  • 해석 가능성: 의료 AI에서 예측 근거 설명의 필수성 및 구현 방법 제시

향후 발전 방향 가능성

  • 멀티모달 확장: 이미지, 텍스트 등 다양한 의료 데이터 통합 분석
  • 실시간 예측: 실시간 EMR 데이터 기반 즉시 위험도 평가 시스템
  • 개인화 의료: 환자별 맞춤형 예측 모델 개발로 정밀 의료 구현