В скорошната ни публикация създадохме модел, използвайки PyCaret за машинно обучение с нисък код.



Сега нека видим как да изградим приложение, което да изпълнява изводи върху модела с помощта на Streamlit.

Streamlit е библиотека на Python с отворен код, която улеснява създаването и споделянето на красиви персонализирани уеб приложения за машинно обучение и наука за данни. Само за няколко минути можем да изградим и внедрим мощни приложения за данни.

Нека първо изградим Streamlit Docker контейнер, следвайки официалната документация.

Първо ще създадем локална папка за Streamlit и ще създадем това Dockerfile в папката.

FROM python:3.8-slim
EXPOSE 8501
WORKDIR /app
RUN apt-get update && apt-get install -y \
    build-essential \
    software-properties-common \
    git \
    && rm -rf /var/lib/apt/lists/*
COPY . .
RUN pip3 install -r requirements.txt
ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", 
 "--server.port=8501", "--server.address=0.0.0.0"]

Ние използваме базирано на Python изображение на контейнер 3.8 (работи на Debian), за да изградим нашето изображение на Streamlit. Текущата версия на PyCaret 2.3.10 поддържа до тази версия на Python и Python 3.9 на Ubuntu. Ще ни трябва и PyCaret в това изображение, за да сме сигурни, че можем да стартираме модела, създаден в последния раздел, като използваме контейнера на PyCaret.

Следващият ред в Dockerfile разкрива уникалния порт 8501, необходим за стартиране на Streamlit. След това инсталираме основен софтуер, включително git. Следващият ред копира локалната папка във виртуалната среда. След това стартираме pip, за да инсталираме зависимости, посочени във файла requirements.txt, който ще създадем следващия. Последният ред дефинира входната точка за изображението на контейнера и указва, че искаме да стартираме конкретно приложение Streamlit, дефинирано в src/steamlit_app.py.

Нека дефинираме файла с изисквания за зависимости за инсталиране.

pandas
streamlit
pycaret

Сега сме готови да създадем нашето първо приложение Streamlit, за да извършим същата оценка на нашия модел въз основа на невиждани данни, но този път го правим от уеб приложение вместо от бележник.

import streamlit as st
import pandas as pd
from pycaret.classification import *
from pycaret.utils import check_metric
st.subheader('Unseen Data')
data_unseen = pd.read_csv('work/data_unseen_creditml.csv')
st.write(data_unseen.head())
st.subheader('Predictions')
saved_final_rf = load_model('work/CreditML RF Model 2022-Sep-05')
new_prediction = predict_model(saved_final_rf, data=data_unseen)
st.write(new_prediction.head())
metric = check_metric(new_prediction['default'], new_prediction['Label'], metric = 'Accuracy')
st.write('Model accuracy: ', metric)

Като последна стъпка изграждаме нашия контейнер.

docker build -t streamlit .

Сега сме готови да стартираме контейнера Streamlit. Ние монтираме споделения том, който създадохме по-рано, за да споделяме данните между PyCaret и Streamlit контейнери.

docker run -d -p 8501:8501 -v shared:/app/work streamlit

Ще забележим, че нашият контейнер работи в Docker Desktop. Използваме наличната връзка, когато щракнем върху името на изображението, за да прегледаме нашето приложение.

Сега нека кажем, че искаме да променим кода и да стартираме отново приложението. Ще трябва да изградим отново изображението на контейнера Streamlit. Има по-добър начин. Ние инсталираме VS Code разширения за Docker, което ни позволява да управляваме Docker контейнери в рамките на VS Code и Remote Containers, което ни позволява да се свързваме с контейнер и да изпълняваме VS Code на файлове в контейнера. Щракнете върху иконата на докер в лявата лента на VS Code, след като разширенията са инсталирани. Щракнете с десния бутон върху работещия контейнер на Streamlit и изберете Прикачете код на Visual Studio. Това ще създаде нов прозорец на VSCode и ще настрои контейнера да изпълнява VSCode отдалечено в контейнера.

Щракнете върху иконата на Explorer в лявата лента и Open Folder и изберете /app, за да се свържете с папката контейнер. Ще забележим, че нашите файлове са налични в контейнера, включително монтирания том под папка /work.

Време е да създадете ново приложение Streamlit. Наричаме го credit_check.py и го записваме в папка work, така че да го запазим дори когато контейнерът бъде премахнат. Просто копирайте кода от streamlit_app.py за сега, за да видите как работи този. След това отворете терминален прозорец във VSCode, който е свързан с нашия контейнер. В рамките на този тип streamlit run work/credit_check.py и ще забележите, че терминалът разпознава, че това е приложение, работещо в отдалечен контейнер, където друго вече се изпълнява, така че стартира това ново на друг порт и автоматично го препраща към нашия браузър. умно!

Сега можем да правим промени във файла credit_check.py и докато го запазваме, можем да стартираме отново приложението в нашия браузър, без да се налага да създаваме отново контейнера всеки път. Ето какво ще изградим в около 50 реда код!

Нека започнем с импортиране на Streamlit, Pandas и PyCaret.

import streamlit as st
import pandas as pd
from pycaret.classification import *

След това изграждаме формуляра за въвеждане на данните на кандидата за кредит.

with st.form("my_form"):
    col1, col2 = st.columns(2)
    with col1:
        gender = st.selectbox('Gender', ('Male', 'Female'))
        marital = st.selectbox('Marital status', ('Married', 'Single', 'Other'))
        age = st.slider('Age', 0, 80, 25)
        education = st.selectbox('Education', ('Graduate school', 'University', 'High school', 
            'Others', 'Unknown 1', 'Unknown 2'))
    with col2:
        limit_balance = st.slider('Limit balance', value=30000, min_value=10000, max_value=720000, step=10000)
        clear = st.text_input('Clear', '3,2,2,2,2,3')
        bill = st.text_input('Bill', '26061,25349,27826,27080,30525,29764')        
        pay = st.text_input('Pay', '0,3200,0,3900,0,0')
    submitted = st.form_submit_button("Submit")

След това подготвяме данните, които да подадем към нашия модел.

if submitted:
        gender = 1 if gender == 'Male' else 2
        if education == 'Graduate school': education = 1
        elif education == 'University': education = 2
        elif education == 'High school': education = 3
        elif education == 'Others': education = 4
        elif education == 'Unknown 1': education = 5
        elif education == 'Unknown 2': education = 6
        if marital == 'Married': marital = 1
        elif marital == 'Single': marital = 2
        elif marital == 'Other': marital = 3
        df = pd.DataFrame(columns=['LIMIT_BAL', 'SEX', 
            'EDUCATION', 'MARRIAGE', 'AGE', 
            'PAY_1', 'PAY_2', 'PAY_3', 'PAY_4', 'PAY_5', 'PAY_6',
            'BILL_AMT1', 'BILL_AMT2', ...
            'PAY_AMT1', 'PAY_AMT2', ...]
        clear_list = [int(x) for x in clear.split(',')]
        bill_list = [int(x) for x in bill.split(',')]
        pay_list = [int(x) for x in pay.split(',')]
        df.loc[0] = [limit_balance, gender, education, marital, age] + 
            clear_list + bill_list + pay_list + [0]

Накрая зареждаме модела и изпълняваме прогнозата.

saved_final_rf = load_model('work/CreditML RF Model 2022-Sep-05')
        new_prediction = predict_model(saved_final_rf, data=df)
        score = float(new_prediction.iloc[-1]['Score'])
        prediction = float(new_prediction.iloc[-1]['Label'])
        scol1, scol2 = st.columns(2)
        with scol1:
            st.title('👎 Bad credit' if prediction else '👍 Good credit')
        with scol2:
            st.metric('Accuracy', value=score, delta=round(score-0.8167,4))

Опитайте да изпратите формуляра, като промените стойностите в полето за въвеждане Clear на всичките шест -1 стойности, разделени със запетая, за да посочите, че плащанията са изчистени за последните 6 месеца. Увеличаването на някоя от стойностите в това поле показва, че месечните плащания са забавени с толкова месеца. Когато направите това, прогнозата трябва да се промени на Good Credit резултат. Разбира се, моделът може да бъде допълнително оптимизиран, но тази демонстрация има за цел да илюстрира как да стигнем от изграждането на модел, оценката, до адаптивно приложение за мобилна мрежа, което позволява тестване на прогнозите на нашия модел върху данни от реалния свят или предоставени от потребителя.