ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [django를 활용한 웹사이트 만들기]
    카테고리 없음 2021. 5. 17. 18:57

    저번 학기에는 입원기간 예측 서비스 알고리즘을 개발하고 모델링는 프로젝트를 진행하였습니다. 이어서

    이번 학기에는 사용자로부터 개인 데이터를 입력받아 개발한 모델을 통해 입원 기간을 예측해주는 서비스를 웹사이트를 통해 배포하는 프로젝트를 진행하였습니다. 이해를 위해 데이터와 모델에 대한 간단한 설명을 하겠습니다.

     

    <알고리즘과 모델에 대한 설명>

    • 개발 배경

    - 입원 기간을 예측할 수 없다는 불확실성과 이에 따른 환자의 불안감

    - 미국의 예치금 제도에 따른 높은 입원 부담감 (데이터 특성상 서비스 대상자를 미국 병원 이용자로 한정함)

    - 현 코로나로 인한 병실 부족사태가 심각하며 병원의 비효율적인 환자 관리 시스템

     

    이러한 문제들을 인식하여 이미 존재하는 많은 환자의 데이터를 기반으로 하는 인공지능 모델을 사용하여 환자의 입원 기간을 예측하는 서비스를 만들기로 하였습니다.

    • 데이터와 모델

    예치금 액수, 나이, 방문자 수, 침대 타입, 병원 코드, 입원 기간 등의 18개의 변수가 정리된 31만개의 환자 데이터를 전처리하는 과정을 거치고 종속 변수를 입원 기간으로 설정하여 이를 예측하는 lightGBM 지도 학습 모델을 개발하였습니다.

     

    이제 이 모델을 연동하여 웹페이지를 제작하는 과정을 차례차례 살펴보도록 하겠습니다.

     

     

    <시스템 구조 및 개발 환경>

    • 시스템 구조

    아래의 그림과 같이 입원환자의 데이터를 활용해 머신러닝 기반 학습을 진행하고 이 모델을 Pickle을 이용해 sav 파일로 변환한 후 django를 활용해 웹사이트를 생성하는 것입니다.

    • 개발 환경

    알고리즘은 scikit learn, tensorflow를 활용하여 python 언어로 jupyter notebook 환경에서 개발하였고, 웹사이트는 html, css를 이용하여 django 언어로 sublime text 환경에서 개발하였다. 

     

     

    <Django 프로젝트 만들기>

    1. Django 설치

    • Windows - Powershell에서 pip install django 

    2. Django 프로젝트 생성

    • 프로젝트를 만들고자 하는 폴더로 이동
    • django-admin startproject <프로젝트이름>

    3. Django 서버 실행

    • 앞에서 생성했던 <프로젝트이름> 디렉토리로 이동
    • Windows - Powershell에서 python manage.py runserver

    4. Django 서버 접속

    • 웹브라우저 실행
    • 주소창에 127.0.0.1:8000 또는 localhost:8000 입력 -> It Worked! 화면이 나오면 성공

    5. Django 서버 중단

    • Windows - Powershell에서 Ctrl+C

     

    <디자인과 기능>

    - 초기화면

    아래와 같이 화면 중앙에 우리가 제공하고자 하는 서비스에 대한 기본적인 설명을 적었고, 상단바에는 Home, contact 버튼을 넣었습니다. Predict 버튼은 예측 서비스를 시작하는 버튼으로 가장 눈에 띄게 만들고자 하였습니다.

     

    - 사용자 입력 화면 (Predict 버튼 누른 후)

    사용자로 하여금 자신의 나이, 병원의 잔여 병실, 예치금, 병의 중증도, 진료과, 입원 타입을 입력하게 하였습니다.

    연속 변수인 Age, Extra Roomes, Admission Deposit 변수는 숫자를 입력할 수 있게 하였고 Severity of Illness, Department, Type of Admission는 범주형 변수이므로 custom select 버튼을 통해 사용자가 각 카테고리를 선택할 수 있게 하였습니다.

    각 입력사항에 대한 설명은 ?버튼에 사용자가 커서를 올렸을 때 설명이 보일 수 있도록 하였습니다. 

    - 입원 기간 예측 화면(결과 페이지)

    "Your LOS would be..." 라는 메세지와 함께 최종 예측값인 입원 기간을 출력하도록 하였습니다.

     

    (※참고)웹사이트를 만들어본 경험이 전혀 없어 막막했는데 가장 많이 도움을 받은 사이트는 아래의 programmers 사이트입니다. 장고를 활용하여 웹사이트를 만드는 과정을 가장 기본적인 예제를 통해 영상으로 보여주는 강의입니다.

    https://programmers.co.kr/learn/courses/6

     

    장고를 활용한 웹사이트 만들기

    이 강의는 최신 버전의 장고를 활용하고 있지 않아, 최근 사용되는 장고와 차이가 있습니다. 장고를 배우고 싶으신 분은 다른 튜토리얼 사이트를 이용하시길 추천합니다. 카카오톡 친구해요! 프

    programmers.co.kr

     

    <View에 해당하는 templates>

    각 화면에 따른 html은 아래와 같다. (Sublime Text 프로그램 이용)

    초기화면에 해당하는 index.html, 사용자 입력화면에 해당하는 input.html, 예측 결과 화면에 해당하는 result.html

    은 각각 아래와 같다.

    <!-- ..\mysite_f\templates\index.html -->
    <!DOCTYPE html>
    <html>
    {% load static %}
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" type="text/css" href="{% static 'css/cover.css' %}">
        <title>LOSAI</title>
    </head>
    
    <body class="container">
    
        <header>
            <nav class="navbar">
                <a class="left" href="{% url 'index' %}">LOSAI</a>
                <span class="right">
                    <a href="{% url 'index' %}">HOME </a>
                    <!-- <a href="{% url 'map' %}">MAP </a> -->
                    <a href="{% url 'contact' %}">CONTACT</a>
                </span>
            </nav>
        </header>
        
        <main class="text-center">
            <h1 class="title1">The Length of Stay for Patients</h1>
            <p class="body1">This web-page predicts the length of hospitalization </br>for patients who want to know this in advance.</p>
                <form action = "{% url 'input' %}">
                {% csrf_token %}
                <input class="button1" type="submit" value="Predict">
            </form>
        </main>
        
    </body>
    
    </html>
    <!-- ..\mysite_f\templates\input.html -->
    <!DOCTYPE html>
    <html lang="en" dir="ltr">
    {% load static %}
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="{% static 'css/cover.css' %}">
        <title>LOSAI</title>
    
        <style>
             table {
            width: 40%;
          }
          select {
        
        width: 185px;
        height: 34px;
    }
      </style>
    </head>
    
    <body class="container2">
        <header>
            <nav class="navbar">
                <a class="left" href="{% url 'index' %}">LOSAI</a>
                <span class="right">
                    <a href="{% url 'index' %}">HOME </a>
                    <a href="{% url 'contact' %}">CONTACT </a>
                </span>
            </nav>
        </header>
    
        <div class="body1">
            <h1></br>PREDICTION</h1>
            <form action="{% url 'result' %}">
                {% csrf_token %}
                <table>
                    <tr>
                <td><label for="age"> Age </td><td><input type="text" class="form-control" name="Age" id="age" required></label></td></tr>
                <tr><td>
                <label for="room"> Extra Rooms
                    <input type="button" value="?" style="CURSOR:hand;" title="Number of extra rooms available in the hospital"> </td><td>
                    <input type="text" class="form-control" name="Available_Extra_Rooms_in_HosPital" id="room" required></label></td></tr>
                <tr><td>
                <label for="deposit">Admission Deposit($)
                    <input type="button" value="?" style="CURSOR:hand;" title="Deposit at the Admission Time ($)"></td><td>
                    <input type="text" class="form-control" name="Admission_Deposit" id="deposit" required></label></td></tr>
                <tr><td>
                <label for="severity">Severity of Illness
                    <input type="button" value="?" style="CURSOR:hand;" title="Severity of the illness recorded at the time of admission which gives a medical classification into minor, moderate, and extreme. (This class is meant to provide a basis for evaluating hospital resource use or to establish patient care guidelines.) Each of these categories is matched by 0,1, and 2 in our model."></label></td>
                <td><select name = "severity" class="custom-select d-block w-100" required>
                    <option value>Choose...</option>
                    <option value=0>0</option>
                    <option value=1>1</option>
                    <option value=2>2</option>
                </select>
                </td></tr>
            
                <tr><td>
                <label for="department">Department <input type="button" value="?" style="CURSOR:hand;" title="Department overlooking the case classified as radiotherapy, gynecology, anesthesia, TB & Chest disease and surgery"></label></td>
                <td><select name = "department" class="custom-select d-block w-100" required>
                    <option value>Choose...</option>
                    <option value=0>radiotherapy</option>
                    <option value=1>anesthesia</option>
                    <option value=2>gynecology</option>
                    <option value=3>TB & Chest diease</option>
                    <option value=4>surgery</option>
                </select></td>
                <tr><td>
                <label for="admission">Type of Admission <input type="button" value="?" style="CURSOR:hand;" title="Admission type registered by the hospital indicating the priority of this admission.
    Emergency means that the patient requires immediate medical intervention as a result of severe, life threatening or potentially disabling conditions.
    Urgent means that the patient requires immediate attention for the care and treatment of a physical or mental disorder.
    Trauma means the patient visits a trauma center, a facility licensed or designated by the State or local government authority authorized to do so."></label></td><td>
                <select name = "admission" class="custom-select d-block w-100" required>
                    <option value>Choose...</option>
                    <option value=0>trauma</option>
                    <option value=1>urgent</option>
                    <option value=2>emergency</option>
                </select></td></tr></table>
                <br><br>
                <input class="button1" type="submit" value='Get Prediction' onClick="location.href={% url 'result' %}">
            </form>
    
            
        </div>
    </body>
    
    </html>
    <!-- ..\mysite_f\templates\result.html -->
    <!DOCTYPE html>
    <html lang="en" dir="ltr">
    {% load static %}
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel = "stylesheet" href="{% static 'css/cover.css' %}">
    
        <title>LOSAI</title>
    </head>
    
    <body class = "container">
     
      <header>
            <nav class="navbar">
                <a class="left" href="{% url 'index' %}">LOSAI</a>
                <span class="right">
                    <a href="{% url 'index' %}">HOME </a>
                    <a href="{% url 'contact' %}">CONTACT </a>
                </span>
            </nav>
        </header>
    
    <html lang="en" dir="ltr">
      <body>
      	<br><br>
        <h1>Your LOS would be...</h1>
    
        <a>{{ result|floatformat}} days 
          {{ visitors }}
      </a>
        
      </body>
    </html>
    
    <script>
    function goBack() {
      window.history.go(-2);
    }
    </script>

     

    <Controller에 해당하는 view.py>

    view.py 파일에는 우리가 만든 lightGBM 모델을 활용한 함수가 들어가기 때문에 먼저 이 모델을 .sav 파일로 변환하는 과정에 대해 설명하겠습니다.

    변환 과정

    여기서 lgbm은 lightGBM 모델을 지칭하고 sc는 이 모델에서 사용된 standardscaler를 지칭하는 변수입니다. 이 둘을 모두 pickle을 이용해 dump시키고 view.py에서 위의 두 번째 사진과 같이 load시킵니다. 

     

    전체 view.py 코드는 아래와 같습니다.

    ..\mysite_f\mysite\view.py

    여기서 getPredictions 함수 이외에 getVisitors 함수가 있는 것은 저희가 사용한 모델이 1차적으로 방문자 수를 예측하고 예측받은 방문자 수를 포함한 변수들로 최종 입원 기간을 예측하는 알고리즘이기 때문입니다. 방문자 수는 입원 기간에 의해 영향을 받을 수 있는 종속 관계가 뒤바뀐 변수라고 생각할 수 있지만 방문자 수와 입원 기간 사이의 매우 큰 상관관계를 이용하기 위해 이러한 방법을 사용하였습니다. 먼저 방문자 수를 제외한 나머지 변수들로 방문자 수를 예측하고 예측받은 값과 나머지 변수를 다시 합하여 이들로 입원 기간을 예측하는 것입니다. 

    방문자 수를 예측하는 모델 또한 lightGBM 모델이며 이전과 같은 방식으로 .sav 파일로 변환하여 load시켰습니다.

     

    사용자 입력화면에서 입력받은 값들을 위의 함수들에 적용시켜 결과값을 얻고 result.html에 전달해줍니다. 

    (continued)

     

    <경로 설정>

    view.py의 함수들의 url에 관한 각 경로를 url.py에서 설정해줍니다.

    ..\mysite_f\mysite\url.py

     

Designed by Tistory.