플라스크를 사용하여 ML 모형을 배치하는 절대 초보자 안내서(제1부분)

데이터사이언스 키티는 이제 그녀의 모델로 심장병을 예측할 수 있기 때문에 매우 기뻐하며 코를 골았다.그녀는 현재 이 모델을 한 사이트에 사용하기를 희망하고 있으며, 호만스는 이 사이트에 입력을 제공하고, 데이터를 제출한 후에 예측을 받을 것이다.이것은 모델이 반드시 상호작용 매체와 결합해야 한다는 것을 의미한다.hoomans는 표에 입력을 하고 모델은 표 데이터에 따라 예측을 한다.근데 어떻게 하지?
Kitty는 그녀의 친구인 ML 엔지니어 Doge가 만능 전문가라는 것을 기억한다.도그는 키티에게 "당신의 모형을 어떻게 배치하는지 가르쳐 드릴게요."라고 보증했다.데이터 과학 키티는 지금 매우 곤혹스럽다."배치란 무엇인가, 강아지?"

기본 원리를 설명하기 위해 도표를 한 장 더 그렸다.

1단계: 가상 환경 및 플라스크 설치


어떤 종류의 Python 개발이든 가상 환경을 구축하는 것이 우선입니다. 이 환경에서 선택한 Python 버전의 모든 도구와 의존 항목을 관리할 것입니다.Python 자체 venv 모듈을 사용하여 가상 환경을 관리합니다.이 기능을 사용할 수도 있고, Python 가상 환경이나pyenv를 선택할 수도 있으며, 아래 링크에서 설치할 수도 있습니다 -

  • https://github.com/pyenv/pyenv

  • https://github.com/pyenv/pyenv-virtualenv - 이 플러그인은 클래스 Unix 시스템에서 여러 개의 Python 가상 환경을 더욱 쉽게 관리할 수 있습니다.
    Conda를 사용하여 가상 환경을 설정할 수도 있습니다.
  • 가상 환경을 설정한 후 official documentation에서 Flask를 설치할 수 있습니다.

    2단계: 모델 로드


    Kitty는 심장병을 예측하는 모델을 joblib 파일로 가지고 있다.모델 파일의 Python 버전이 Flask 버전과 동일한지 확인해야 합니다.동일한 Python 버전을 확보하는 두 가지 방법이 있습니다.

    1


    Colab에서 전체 머신 러닝 프로젝트를 실행한 경우 Colab 단원에서 다음 명령을 실행하고 Flask 프로젝트에 특정 버전의 Python 가상 환경을 설치하기만 하면 됩니다.
    !python --version
    
    

    2


    모델을 생성하고 Jupyter 노트에서 joblib 파일을 추출할 수 있습니다.이렇게 하면 모델 파일과 Flask 항목이 같은 Python 버전으로 유지됩니다.
    이것은 키티가 joblib의python 버전과doge가 그녀를 위해 디자인한 시스템에 대한 문제를 해결했다.프로젝트 디렉터리에서 먼저 app라는 파일을 만듭니다.py, 그리고 플라스크 골격부터 다음 코드 줄을 작성합니다.
    
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route("/")
    def hello_world():
        return "<p>Hello, World!</p>"
    
    if __name__ == "__main__":
        app.run()
    
    다음 명령을 실행하면 http://localhost:5000/ 텍스트가 "Hello, World!"인 웹 페이지를 볼 수 있습니다.
    
    python app.py
    
    
    똑똑히 보기 위해서, Doge는 joblib 파일을 'Resource' 라는 폴더에 저장합니다.응용 프로그램에서 모델을 불러오려면, 불러오는 함수를 가져와 pipeline이라는 변수에 저장합니다.
    from joblib import load 
    pipeline = load("resource/diseaseprediction.joblib")
    
    
    우리는 응용 프로그램 기능을 사용하여 html 페이지로 돌아갈 수 있다.우리가 해야 할 일은 바로 창작이다
    def hello_world():
        return render_template('home.html')
    
    
    Flask로 함수render 템플릿을 가져오면 지금 시작할 수 있습니다.

    3단계: 입력을 위한 템플릿 작성


    이것은 전체 과정 중 가장 지루한 부분이다.우리는render 템플릿('홈.html')을 작성했지만 보여줄 html이 없습니다.Flask 프로젝트에서 모든 웹 페이지를 포함하는'templates'라는 디렉터리를 만들어야 합니다.이 프로젝트에 대해 우리는 홈페이지만 필요합니다.우리는 반드시 W3Schools 이 기본적인 구조를 완성해야 한다.
    사용자 입력은 Kitty 모델의 특징 열입니다. 이것은 폼에 13개의 필드가 있음을 의미합니다.나는 모든 입력의 값 유형을 검사했는데, 이를 바탕으로 표의 코드는 다음과 같다.
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    
    <h2 style="text-align:center">Do I have heart disease?</h2>
    
    <p style="text-align:center">Fill out this form and check!</p>
    <div>
        <form>
            <div>
                <div>
                    <label for="age">Age</label>
                </div>
                <div>
                    <input type="text" id="age" name="age" placeholder="Your Age" required>
                </div>
            </div>
            <div>
                <div>
                    <label for="sex">Sex</label>
                </div>
                <div>
                    <input type="radio" id="sex" name="sex" value="1">
                    <label for="sex">Male</label><br>
                </div>
                <div>
                    <input type="radio" id="sex" name="sex" value="0" required>
                    <label for="sex">Female</label><br>
                </div>
            </div>
            <div>
                <div>
                    <label for="cp">Chest Pain Type</label>
                </div>
                <div>
                    <select id="cp" name="cp" required>
                        <option value="0">None</option>
                        <option value="1">Mild</option>
                        <option value="2">Medium</option>
                        <option value="3">Severe</option>
                    </select>
                </div>
            </div>
            <div>
                <div>
                    <label for="rbp">Resting Blood Pressure</label>
                </div>
                <div>
                    <input type="text" id="trestbps" name="trestbps" placeholder="Your bp in mm Hg" required>
                </div>
            </div>
            <div>
                <div>
                    <label for="chol">Cholesterol</label>
                </div>
                <div>
                    <input type="text" id="chol" name="chol" placeholder="Your serum cholestoral in mg/dl" required>
                </div>
            </div>
            <div>
                <div>
                    <label for="fbs">Fasting Blood Sugar</label>
                </div>
                <div>
                    <input type="radio" id="fbs" name="fbs" value="1" required>
                    <label for="fbs">Diabetic</label><br>
                </div>
                <div>
                    <input type="radio" id="fbs" name="fbs" value="0">
                    <label for="fbs">Non diabatic</label><br>
                </div>
            </div>
            <div>
                <div
                    <label for="restecg">Resting Electrocardiographic Results</label>
                </div>
                <div
                    <select id="restecg" name="restecg" required>
                        <option value="0">None</option>
                        <option value="1">Medium</option>
                        <option value="2">Severe</option>
                    </select>
                </div>
            </div>
            <div>
                <div>
                    <label for="thalach">Maximum Heart Rate Achieved</label>
                </div>
                <div
                    <input type="text" id="thalach" name="thalach" placeholder="Your maximum achieved heart rate" required>
                </div>
            </div>
            <div
                <div>
                    <label for="exang">Exercise Induced Angina</label>
                </div>
                <div>
                    <input type="radio" id="exang" name="exang" value="1">
                    <label for="exang">Yes</label><br>
                </div>
                <div>
                    <input type="radio" id="exang" name="exang" value="0" required>
                    <label for="exang">No</label><br>
                </div>
            </div>
            <div>
                <div>
                    <label for="oldpeak">OldPeak (floating point value)</label>
                </div>
                <div>
                    <input type="text" id="oldpeak" name="oldpeak"
                           placeholder="ST depression induced by exercise relative to rest" required>
                </div>
            </div>
            <div>
                <div>
                    <label for="slope">The Slope of the Peak Exercise ST Segment</label>
                </div>
                <div>
                    <select id="slope" name="slope" required>
                        <option value="0">None</option>
                        <option value="1">Medium</option>
                        <option value="2">Severe</option>
                    </select>
                </div>
            </div>
            <div>
                <div>
                    <label for="ca">Number of Major Vessels (0-3)</label>
                </div>
                <div>
                    <select id="ca" name="ca" required>
                        <option value="0">0</option>
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                    </select>
                </div>
            </div>
            <div>
                <div>
                    <label for="thal">Thal: 3 = normal; 6 = fixed defect; 7 = reversable defect</label>
                </div>
                <div>
                    <select id="thal" name="thal" required>
                        <option value="0">0</option>
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        <option value="4">4</option>
                        <option value="5">5</option>
                        <option value="6">6</option>
                        <option value="7">7</option>
                    </select>
                </div>
            </div>
    
            <div>
                <button type="submit">Submit Data</button>
            </div>
        </form>
    
    </div>
    
    </body>
    </html>
    
    
    이 html 파일의 출력은 다음과 같다-

    그것은 우리가 스타일링을 하지 않았기 때문에 너무 소박해 보였다.그것도 힘든 거 알아요.Doge는 템플릿의 기본성을 유지하기 위해 학교에서 폼 템플릿을 검색했다.이 사이트가 없으면 html과 CSS를 배우는 것은 doge에 어렵지 않다.양식 템플릿 링크 - https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_contact_form.우리의 목표는 모델을 배치하는 것이기 때문에, 우리는 모든 13개의 데이터를 이 표에 발표하여, 우리가 이전에 불러온 모델의 입력으로 추출하고 사용할 수 있도록 확보해야 한다.다음 두 가지 작업을 수행하여 다음을 확인합니다.
    [양식] 탭에서 데이터 게시의 대상을 설정합니다.이것은 한 페이지의 웹 응용 프로그램이기 때문에form action 속성은 이 응용 프로그램이 실행하는 주소입니다. 즉 http://localhost:5000/method 속성은post 형식입니다.
    모델의 입력은 데이터 프레임이다.따라서 모든 데이터를 지정한 열과 일치시켜야 한다.id,name, for 속성을 원시 데이터 상자 열 이름으로 설정하고value 속성 (태그 선택) 을 이 열의 유한한 예상값으로 설정하면, 폼은immutablemultidict 형식의 대상, 즉 Flask 폼 이미지를 생성할 수 있습니다.우리는 다음 절에서 이 대상을 처리할 것이지만, 지금은 코드 세션으로만 설명할 것이다.

    데이터가 집중된'cp'열은 0, 1, 2 또는 3을 얻을 수 있으며 이를 텍스트 값으로 비추겠습니다.사이트에서 우리는 가치 속성이 무엇을 포함하는가가 아니라 이 점을 볼 수 있다.모든 CSS 클래스와 스타일링 소스를 통합한 후 html은 다음과 같이 보입니다.우리는 곧 도착한다, 그래!
    
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
        <style>
            * {
                box-sizing: border-box;
            }
    
            input[type=text], select, textarea {
                width: 100%;
                padding: 12px;
                border: 1px solid #ccc;
                border-radius: 4px;
                resize: vertical;
            }
    
            label {
                padding: 12px 12px 12px 0;
                display: inline-block;
            }
    
            input[type=submit]:hover {
                background-color: #45a049;
            }
    
            .container {
                border-radius: 5px;
                background-color: #f2f2f2;
                padding: 20px;
            }
    
            .col-25 {
                float: left;
                width: 25%;
                margin-top: 6px;
            }
    
            .col-75 {
                float: left;
                width: 75%;
                margin-top: 6px;
            }
    
            /* Clear floats after the columns */
            .row:after {
                content: "";
                display: table;
                clear: both;
            }
    
            .center {
                display: flex;
                justify-content: center;
                align-items: center;
                height: 200px;
            }
    
            /* Responsive layout - when the screen is less than 600px wide, make the two columns stack on top of each other instead of next to each other */
            @media screen and (max-width: 600px) {
                .col-25, .col-75, input[type=submit] {
                    width: 100%;
                    margin-top: 0;
                }
            }
        </style>
    </head>
    <body>
    
    <h2 style="text-align:center">Do I have heart disease?</h2>
    
    <p style="text-align:center">Fill out this form and check!</p>
    <div class="container">
        <form action="http://localhost:5000/" method="post">
            <div class="row">
                <div class="col-25">
                    <label for="age">Age</label>
                </div>
                <div class="col-75">
                    <input type="text" id="age" name="age" placeholder="Your Age" required>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="sex">Sex</label>
                </div>
                <div class="col-25">
                    <input type="radio" id="sex" name="sex" value="1">
                    <label for="sex">Male</label><br>
                </div>
                <div class="col-25">
                    <input type="radio" id="sex" name="sex" value="0" required>
                    <label for="sex">Female</label><br>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="cp">Chest Pain Type</label>
                </div>
                <div class="col-75">
                    <select id="cp" name="cp" required>
                        <option value="0">None</option>
                        <option value="1">Mild</option>
                        <option value="2">Medium</option>
                        <option value="3">Severe</option>
                    </select>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="rbp">Resting Blood Pressure</label>
                </div>
                <div class="col-75">
                    <input type="text" id="trestbps" name="trestbps" placeholder="Your bp in mm Hg" required>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="chol">Cholesterol</label>
                </div>
                <div class="col-75">
                    <input type="text" id="chol" name="chol" placeholder="Your serum cholestoral in mg/dl" required>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="fbs">Fasting Blood Sugar</label>
                </div>
                <div class="col-25">
                    <input type="radio" id="fbs" name="fbs" value="1" required>
                    <label for="fbs">Diabetic</label><br>
                </div>
                <div class="col-25">
                    <input type="radio" id="fbs" name="fbs" value="0">
                    <label for="fbs">Non diabatic</label><br>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="restecg">Resting Electrocardiographic Results</label>
                </div>
                <div class="col-75">
                    <select id="restecg" name="restecg" required>
                        <option value="0">None</option>
                        <option value="1">Medium</option>
                        <option value="2">Severe</option>
                    </select>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="thalach">Maximum Heart Rate Achieved</label>
                </div>
                <div class="col-75">
                    <input type="text" id="thalach" name="thalach" placeholder="Your maximum achieved heart rate" required>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="exang">Exercise Induced Angina</label>
                </div>
                <div class="col-25">
                    <input type="radio" id="exang" name="exang" value="1">
                    <label for="exang">Yes</label><br>
                </div>
                <div class="col-25">
                    <input type="radio" id="exang" name="exang" value="0" required>
                    <label for="exang">No</label><br>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="oldpeak">OldPeak (floating point value)</label>
                </div>
                <div class="col-75">
                    <input type="text" id="oldpeak" name="oldpeak"
                           placeholder="ST depression induced by exercise relative to rest" required>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="slope">The Slope of the Peak Exercise ST Segment</label>
                </div>
                <div class="col-75">
                    <select id="slope" name="slope" required>
                        <option value="0">None</option>
                        <option value="1">Medium</option>
                        <option value="2">Severe</option>
                    </select>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="ca">Number of Major Vessels (0-3)</label>
                </div>
                <div class="col-75">
                    <select id="ca" name="ca" required>
                        <option value="0">0</option>
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                    </select>
                </div>
            </div>
            <div class="row">
                <div class="col-25">
                    <label for="thal">Thal: 3 = normal; 6 = fixed defect; 7 = reversable defect</label>
                </div>
                <div class="col-75">
                    <select id="thal" name="thal" required>
                        <option value="0">0</option>
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        <option value="4">4</option>
                        <option value="5">5</option>
                        <option value="6">6</option>
                        <option value="7">7</option>
                    </select>
                </div>
            </div>
    
            <div class="center">
                <button class="w3-button w3-green" type="submit">Submit Data</button>
            </div>
        </form>
    
    </div>
    
    </body>
    </html>
    
    
    이제 좀 화려해 보여요.

    4단계: 입력 처리


    우리는 이미 표 데이터를 수집했다.우리는 이 표를 모델에 입력해야만 그것이 예측할 수 있다.이것을 위해 함수를 하나 작성합시다.우선, 우리는 폼이 제출 단추를 눌렀을 때 만들어진 대상 유형을 검사할 것입니다.Pro tip은python과javascript로 코드를 작성할 때 내장된 'type' 함수를 통해 대상을 전달합니다.이렇게 하면 처리할 객체 유형이 생성됩니다.
    @app.route('/', methods=['GET', 'POST'])
    def inputForm():
        print("type", type(request.form))
    # type ImmutableMultiDict
    
    
    우리는 이 대상을 사전으로 변환한 다음에 데이터 프레임으로 변환할 수 있다.이 데이터 프레임은 모델의 입력입니다.출력을 'prediction' 이라는 변수에 저장할 것입니다.
    전체 함수는 다음과 같다.
    
    import pandas as pd
    
    @app.route('/', methods=['GET', 'POST'])
    def inputForm():
        print("type", type(request.form.to_dict(flat=False))) #changing to a dictionary
        print("checking form", request.form.to_dict()) #dictionary to datframe
        data = request.form.to_dict() 
        df = pd.DataFrame(data, index=[0]) 
        print("prediction", pipeline.predict(df)) 
        if pipeline.predict(df) == [1]: 
        prediction = "You are in risk of heart disease" 
        elif pipeline.predict(df) == [0]: 
        prediction = "You don't have risk of heart disease" 
        else: prediction = "Can't predict anything" 
        return render_template('home.html', prediction = prediction, show_predictions_modal = True )
    
    

    5단계: 예측 제시


    "우리는 예측이 있지만, 지금 어떻게 증명합니까?"키티는 도그에게 물었다.도그는 그녀에게 이미 배상을 받았다고 보증했다.도그는 "우리의 html에 제출 버튼을 누르면 팝업 모드를 추가할 것"이라고 말했다.
    우리 먼저 모드를 팝업합니다.도그는 짜증이 나서 다시 W3학교https://www.w3schools.com/w3css/tryit.asp?filename=tryw3css_modal2로 가서'결과 보기'라는 모델을 만들었다.
    이 모드의 단추 동작은 프로그램에서 되돌아오는 예측 변수를 보여 줍니다.py 파일.render 템플릿 함수에 로고도 설정했습니다.예측이 끝난 후에 우리는 조건부로 모형을 나타낼 것이다.제출 단추를 누르면 모드를 볼 수 있습니다.그것을 클릭하면 예측을 볼 수 있습니다.
    
    {% if show_predictions_modal %}
            <div class="center">
                <button onclick="document.getElementById('id01').style.display='block'" class="w3-button w3-black"
                        type="submit">See
                    Result
                </button>
            </div>
            <div id="id01" class="w3-modal">
                <div class="w3-modal-content">
                    <div class="w3-container">
                            <span onclick="document.getElementById('id01').style.display='none'"
                                  class="w3-button w3-display-topright">&times;</span>
                        <div class="w3-container">
                            <p style="text-align:center">{{ prediction }}</p>
                        </div>
                    </div>
                </div>
            </div>
        {% endif %}
    
    
    


    전체 프로젝트가 제 GitHub 메모리 라이브러리에 있는 지점 프로젝트 HeartDiseas Predition에 업로드됩니다. 그곳에서 전체 html 코드를 볼 수 있습니다. 왜냐하면 제가 마지막에 통합된 버전을 작성하지 않았기 때문입니다-https://github.com/Afroza2/Production-Based-ML-portfolio/tree/Project_HeartDiseasePrediction.이제 사용자 입력에서 예측 함수 매개 변수로 전달되는 데이터 프레임을 만들 수 있으며 출력은 모드에 표시됩니다.두 번째 부분에서, 나는 당신이 온라인으로 이 프로젝트에 접근할 수 있도록 전체 프로젝트를 Heroku 응용 프로그램으로 위탁 관리하는 방법에 관한 글을 쓸 계획이다.그 전에, 뱅크!

    좋은 웹페이지 즐겨찾기