건강정보

수면 무호흡증을 평가 소프트웨어

aiproductmanager 2024. 12. 18. 05:57

 

https://sleep-math.com/

 

SLEEPS

 

sleep-math.com

 

[1]sleep-math.com은 간단한 설문을 통해 수면무호흡증을 비롯한 수면 질환의 위험도를 예측하는 SLEEPS(SimpLe quEstionnairE Predicting Sleep disorders) 알고리즘을 제공합니다.

 이 알고리즘은 약 5,000명의 수면다원검사 데이터를 기반으로 개발되었으며, 9개의 문항을 통해 세 가지 수면 질환(수면무호흡증, 만성불면증, 수면호흡장애를 동반한 불면증)의 위험도를 약 90%의 정확도로 예측합니다. 

설문 문항:

 1. 나이

 2. 성별

 3. 키

 4. 체중

 5. 최근 2주간 수면 시작의 어려움

 6. 수면 유지의 어려움

 7. 기상 시 어려움

 8. 수면 패턴에 대한 만족도

 9. 수면이 일상 기능에 미치는 영향

 

이러한 문항을 통해 개인의 신체 정보와 수면 패턴을 파악하여 수면 질환의 위험도를 평가합니다. 특히, 체중과 나이의 변화에 따른 수면호흡장애 위험도의 변화를 예측할 수 있어, 사용자가 자신의 건강 상태를 지속적으로 모니터링하는 데 도움이 됩니다.

이러한 간단한 설문 방식을 통해 사용자는 병원 방문 없이도 자신의 수면 건강 상태를 평가할 수 있으며, 필요 시 전문의와의 상담을 고려할 수 있습니다.

[ 코드로 유사한 결과나오게 구현해본 사용 예]

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report

def sleep_disorder_predictor():
    print("\n[기계 학습 기반 수면 질환 위험 예측 모델]")

    # 예제 데이터: 나이, 성별(0=여성, 1=남성), BMI, 코골이(0/1), 피로(0/1), 고혈압(0/1)
    data = {
        'Age': [45, 50, 32, 65, 54, 29, 60, 40, 48, 58],
        'Gender': [1, 0, 1, 1, 0, 0, 1, 0, 1, 1],
        'BMI': [30, 28, 25, 35, 29, 22, 33, 27, 31, 34],
        'Snoring': [1, 1, 0, 1, 0, 0, 1, 1, 1, 1],
        'Tiredness': [1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
        'Hypertension': [1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
        'Sleep_Disorder': [1, 1, 0, 1, 0, 0, 1, 0, 1, 1]  # 1: 위험군, 0: 비위험군
    }

    # 데이터프레임 생성
    df = pd.DataFrame(data)

    # 특성(X)과 타겟(y) 설정
    X = df[['Age', 'Gender', 'BMI', 'Snoring', 'Tiredness', 'Hypertension']]
    y = df['Sleep_Disorder']

    # 훈련 및 테스트 데이터셋 분할
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

    # 랜덤 포레스트 모델 생성 및 훈련
    model = RandomForestClassifier(n_estimators=100, random_state=42)
    model.fit(X_train, y_train)

    # 예측 수행
    y_pred = model.predict(X_test)

    # 결과 출력
    print("\n[모델 평가 결과]")
    print(f"정확도: {accuracy_score(y_test, y_pred):.2f}")
    print("분류 보고서:")
    print(classification_report(y_test, y_pred))

    # 사용자 입력을 통한 예측 테스트
    print("\n[수면 질환 위험 예측 테스트]")
    try:
        age = int(input("나이: "))
        gender = int(input("성별 (여성=0, 남성=1): "))
        bmi = float(input("BMI (체질량지수): "))
        snoring = int(input("코골이 여부 (예=1, 아니오=0): "))
        tiredness = int(input("피로감 여부 (예=1, 아니오=0): "))
        hypertension = int(input("고혈압 여부 (예=1, 아니오=0): "))
        
        user_data = pd.DataFrame([[age, gender, bmi, snoring, tiredness, hypertension]], 
                                 columns=['Age', 'Gender', 'BMI', 'Snoring', 'Tiredness', 'Hypertension'])
        prediction = model.predict(user_data)
        
        if prediction[0] == 1:
            print("\n수면 질환 위험군에 해당합니다. 전문의와 상담을 권장합니다.")
        else:
            print("\n수면 질환 위험이 낮은 상태입니다.")
    except ValueError:
        print("\n올바른 입력값을 제공해주세요.")

if __name__ == "__main__":
    sleep_disorder_predictor()

 

[ 오류 수정 코드]

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report

def sleep_disorder_predictor(predefined_inputs=None):
    print("\n[기계 학습 기반 수면 질환 위험 예측 모델]")

    # 예제 데이터: 나이, 성별(0=여성, 1=남성), BMI, 코골이(0/1), 피로(0/1), 고혈압(0/1)
    data = {
        'Age': [45, 50, 32, 65, 54, 29, 60, 40, 48, 58],
        'Gender': [1, 0, 1, 1, 0, 0, 1, 0, 1, 1],
        'BMI': [30, 28, 25, 35, 29, 22, 33, 27, 31, 34],
        'Snoring': [1, 1, 0, 1, 0, 0, 1, 1, 1, 1],
        'Tiredness': [1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
        'Hypertension': [1, 1, 0, 1, 0, 0, 1, 0, 1, 1],
        'Sleep_Disorder': [1, 1, 0, 1, 0, 0, 1, 0, 1, 1]  # 1: 위험군, 0: 비위험군
    }

    # 데이터프레임 생성
    df = pd.DataFrame(data)

    # 특성(X)과 타겟(y) 설정
    X = df[['Age', 'Gender', 'BMI', 'Snoring', 'Tiredness', 'Hypertension']]
    y = df['Sleep_Disorder']

    # 훈련 및 테스트 데이터셋 분할
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

    # 랜덤 포레스트 모델 생성 및 훈련
    model = RandomForestClassifier(n_estimators=100, random_state=42)
    model.fit(X_train, y_train)

    # 예측 수행
    y_pred = model.predict(X_test)

    # 결과 출력
    print("\n[모델 평가 결과]")
    print(f"정확도: {accuracy_score(y_test, y_pred):.2f}")
    print("분류 보고서:")
    print(classification_report(y_test, y_pred))

    # 사용자 입력을 통한 예측 테스트 (미리 정의된 입력 사용)
    print("\n[수면 질환 위험 예측 테스트]")
    try:
        if predefined_inputs is None:
            predefined_inputs = {
                "Age": 45, "Gender": 1, "BMI": 30.0,
                "Snoring": 1, "Tiredness": 1, "Hypertension": 1
            }

        print(f"나이: {predefined_inputs['Age']}, 성별: {predefined_inputs['Gender']}, BMI: {predefined_inputs['BMI']}, ")
        print(f"코골이: {predefined_inputs['Snoring']}, 피로감: {predefined_inputs['Tiredness']}, 고혈압: {predefined_inputs['Hypertension']}")

        user_data = pd.DataFrame([[
            predefined_inputs['Age'], predefined_inputs['Gender'], predefined_inputs['BMI'],
            predefined_inputs['Snoring'], predefined_inputs['Tiredness'], predefined_inputs['Hypertension']
        ]], columns=['Age', 'Gender', 'BMI', 'Snoring', 'Tiredness', 'Hypertension'])

        prediction = model.predict(user_data)

        if prediction[0] == 1:
            print("\n수면 질환 위험군에 해당합니다. 전문의와 상담을 권장합니다.")
        else:
            print("\n수면 질환 위험이 낮은 상태입니다.")
    except Exception as e:
        print(f"\n오류 발생: {e}")

if __name__ == "__main__":
    sleep_disorder_predictor()

[2] STOP-BANG 검사 방식

무호흡증을 판단하는 설문 함수는 STOP-BANG 검사와 같은 표준 설문 형식을 기반으로 할 수 있습니다. STOP-BANG은 수면 무호흡증을 평가하는 데 널리 사용되는 설문입니다.

다음은 Python 코드로 작성된 설문 기반 무호흡증 판단 함수입니다:

코드 설명:

  1. STOP-BANG 질문
    설문 질문은 8가지 요소로 구성됩니다: 코골이, 피로, 무호흡 목격, 혈압, BMI, 나이, 목둘레, 성별.
  2. 점수 계산
    사용자의 응답(예: 1, 아니오: 0)에 따라 점수를 합산합니다.
  3. 위험군 평가
    • 5점 이상: 높은 수면 무호흡증 위험군
    • 3~4점: 중간 정도 위험군
    • 2점 이하: 낮은 위험군

사용 예시:

이 프로그램을 실행하고 질문에 답하면, 총 점수와 무호흡증 위험군을 평가해 줍니다.

1. (S) 코골이가 심한가요? (예=1, 아니오=0): 1
2. (T) 피곤함을 자주 느끼시나요? (예=1, 아니오=0): 1
...
[평가 결과]
총 점수: 6/8
높은 수면 무호흡증 위험군입니다. 전문의와 상담을 권장합니다.

실행:

Python 환경에서 실행하면 즉시 설문을 시작할 수 있습니다.

def assess_sleep_apnea(predefined_inputs=None):
    print("\n[STOP-BANG 무호흡증 설문 평가]")
    print("각 질문에 대해 예(1) 또는 아니오(0)로 답변해 주세요.\n")

    # 질문 리스트
    questions = [
        "(S) 코골이가 심한가요?",  # Snoring
        "(T) 피곤함을 자주 느끼시나요? (주간 졸림 포함)",  # Tiredness
        "(O) 누군가 당신이 수면 중 무호흡을 목격한 적이 있나요?",  # Observed Apnea
        "(P) 혈압이 높거나 치료 중인가요?",  # Pressure
        "(B) 체질량지수(BMI)가 35 이상인가요?",  # BMI > 35
        "(A) 나이가 50세 이상인가요?",  # Age > 50
        "(N) 목둘레가 두꺼운가요? (남성: 43cm 이상, 여성: 41cm 이상)",  # Neck size
        "(G) 성별이 남성인가요?"  # Gender: Male
    ]

    # 점수 입력 받기
    score = 0
    input_counter = 0

    for i, question in enumerate(questions, 1):
        while True:
            try:
                # 입력이 미리 정의되었다면 사용, 그렇지 않으면 기본값 사용
                if predefined_inputs:
                    answer = predefined_inputs[input_counter]
                    print(f"{i}. {question} (예=1, 아니오=0): {answer}")
                    input_counter += 1
                else:
                    answer = int(input(f"{i}. {question} (예=1, 아니오=0): "))

                if answer in [0, 1]:
                    score += answer
                    break
                else:
                    print("올바른 입력이 아닙니다. 1 또는 0을 입력해주세요.")
            except (ValueError, IndexError):
                print("숫자를 입력해주세요. 예=1, 아니오=0")

    # 평가 결과
    print("\n[평가 결과]")
    print(f"총 점수: {score}/8")
    if score >= 5:
        print("높은 수면 무호흡증 위험군입니다. 전문의와 상담을 권장합니다.")
    elif 3 <= score < 5:
        print("중간 정도의 수면 무호흡증 위험군입니다. 추가 검사가 필요할 수 있습니다.")
    else:
        print("낮은 수면 무호흡증 위험군입니다. 하지만 증상이 지속된다면 상담을 고려해 보세요.")

if __name__ == "__main__":
    # 샘플 입력값으로 테스트
    predefined_inputs = [1, 0, 1, 1, 0, 1, 0, 1]  # 예제 입력값
    assess_sleep_apnea(predefined_inputs)