healthcare-app / app.py
blockenters's picture
add
eb23b52
# 스트림릿으로 모델을 예측하는 앱을 만들어보자
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()