File size: 4,539 Bytes
533c071
 
 
 
 
0de191c
 
 
 
 
 
 
eb23b52
0de191c
533c071
 
 
 
eb23b52
533c071
 
0de191c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533c071
0de191c
 
 
 
 
 
 
 
 
 
 
533c071
0de191c
 
 
 
 
 
533c071
0de191c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533c071
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# 스트림릿으로 모델을 예측하는 앱을 만들어보자

import streamlit as st
import pandas as pd
import joblib

import plotly.express as px
import numpy as np

# 데이터 로드
@st.cache_data
def load_data():
    df = pd.read_csv('healthcare.csv', index_col=0)
    return df

# 모델 로드
@st.cache_resource
def load_model():
    model = joblib.load('healthcare_model.pkl')
    return model

def create_charts(df):
    st.header('📊 데이터 분석')
    
    # 1. 흡연 여부에 따른 보험 청구액 분포
    st.subheader('흡연 여부에 따른 보험 청구액 분포')
    fig = px.box(df, x='Smoker', y='InsuranceClaim', color='Smoker')
    st.plotly_chart(fig)
    
    # 2. 나이와 보험 청구액의 관계
    st.subheader('나이와 보험 청구액의 관계')
    fig = px.scatter(df, x='Age', y='InsuranceClaim', color='Gender',
                    title='나이별 보험 청구액 분포',
                    labels={'InsuranceClaim': '보험 청구액', 'Age': '나이'})
    st.plotly_chart(fig)
    
    # 3. BMI 구간별 평균 보험 청구액
    st.subheader('BMI 구간별 평균 보험 청구액')
    df['BMI_Category'] = pd.cut(df['BMI'], 
                               bins=[0, 18.5, 25, 30, 100],
                               labels=['저체중', '정상', '과체중', '비만'])
    bmi_avg = df.groupby('BMI_Category')['InsuranceClaim'].mean().reset_index()
    fig = px.bar(bmi_avg, x='BMI_Category', y='InsuranceClaim',
                 title='BMI 구간별 평균 보험 청구액',
                 labels={'InsuranceClaim': '평균 보험 청구액', 'BMI_Category': 'BMI 구간'})
    st.plotly_chart(fig)
    
    # 4. 지역별 평균 보험 청구액
    st.subheader('지역별 평균 보험 청구액')
    region_avg = df.groupby('Region')['InsuranceClaim'].mean().reset_index()
    fig = px.pie(region_avg, values='InsuranceClaim', names='Region',
                 title='지역별 평균 보험 청구액 비율')
    st.plotly_chart(fig)
    
    # 5. 주요 통계 지표
    st.subheader('💡 주요 통계 지표')
    col1, col2, col3 = st.columns(3)
    with col1:
        st.metric("평균 보험 청구액", f"${df['InsuranceClaim'].mean():,.2f}")
    with col2:
        st.metric("최대 보험 청구액", f"${df['InsuranceClaim'].max():,.2f}")
    with col3:
        st.metric("최소 보험 청구액", f"${df['InsuranceClaim'].min():,.2f}")

def main():
    st.title('🏥 의료 보험 청구액 예측 서비스')
    
    # 데이터 로드
    df = load_data()
    
    # 탭 생성
    tab1, tab2 = st.tabs(["예측하기", "데이터 분석"])
    
    with tab1:
        # 사이드바에 입력 폼 생성
        st.sidebar.header('환자 정보 입력')
        
        age = st.sidebar.number_input('나이', min_value=0, max_value=100, value=30)
        gender = st.sidebar.selectbox('성별', ['Male', 'Female'])
        bmi = st.sidebar.number_input('BMI', min_value=10.0, max_value=50.0, value=25.0)
        region = st.sidebar.selectbox('지역', ['North', 'South', 'East', 'West'])
        smoker = st.sidebar.selectbox('흡연 여부', ['Yes', 'No'])
        num_visits = st.sidebar.number_input('방문 횟수', min_value=0, max_value=20, value=5)
        
        # 예측 버튼
        if st.sidebar.button('예측하기'):
            # 입력 데이터 구성
            input_data = {
                'Age': age,
                'Gender': gender,
                'BMI': bmi,
                'Region': region,
                'Smoker': smoker,
                'NumVisits': num_visits
            }
            
            # 모델 로드 및 예측
            model = load_model()
            prediction = predict_insurance_claim(input_data, model)
            
            # 결과 표시
            st.header('예측 결과')
            st.write(f'예상 보험 청구액: ${prediction:,.2f}')
            
            # 예측 결과 설명
            st.info("""
            💡 예측 결과 설명:
            - 이 예측은 환자의 기본 정보를 바탕으로 계산되었습니다.
            - 실제 청구액은 구체적인 진료 내용에 따라 달라질 수 있습니다.
            - 이 예측은 참고용으로만 사용해주세요.
            """)
    
    with tab2:
        create_charts(df)

def predict_insurance_claim(data, pipeline):
    new_df = pd.DataFrame([data])
    prediction = pipeline.predict(new_df)
    return prediction[0]

if __name__ == '__main__':
    main()