이글은 네이버 부스트캠프 ai tech 변성윤 강사님의 product serving강의를 정리한 글입니다.
문제 혹은 틀린점이 있다면 말씀해주세요. 빠른 시일내에 수정하겠습니다 :)
웹프로그래밍에 대한 지식이 없어도 웹서비스 형태로 프로토타이핑을 할 수 있는
Streamlit이라는 프레임워크에 대해서 학습해보자 !
프로토타입부터 점진적으로 개선하기
Voila의 장점 (이전 강의)
데이터 Product로 중요하게 된다면 프론트엔드/PM 조직과 협업
다른 조직의 도움 없이 빠르게 웹 서비스를 만드는 방법이 무엇일까?
이 문제를 해결하기 위해 등장한 것이 Streamlit !!
주의할 점 : 툴이나 라이브러리에 집착하지 말고, 점진적으로 문제를 해결하는 과정에 집중하기
현재 사용하는 도구의 장단점은 어떤 것이고 새로운 대안이 있을지 항상 생각해보기 !
가으이에선 Voila-Streamlit 순서로 했지만 추후엔 Streamlit부터 시작해도 괜찮음
모든 것은 프로젝트의 요구 조건에 따라 다름!
1) R의 Shiny
2) Flas, Fast API: 백엔드를 직접 구성 + 프론트엔드 작업도 진행
3) Dash: 제일 기능이 풍부한 Python 대시보드 라이브러리
4) Voila: Jupyter Notebook을 바로 시각화 가능
슬로건 : The fastest way to build and share data apps
장점
Streamlit예시
albumentations Demo도 Streamlit으로 만들어짐.(augmentation 효과 보여주는 웹페이지)
Streamlit설치
pip install streamlit
Streamlit실행방법
(CLI) streamlit run streamlit-basic.py
localhost:8501에 접근가능
import streamlit as st
import pandas as pd
import numpy as np
import time
st.title("Title")
st.header("Header")
st.subheader("subheader")
st.write("Write Something")
if st.button("버튼이 클릭되면"):
st.write("클릭 후 보이는 메시지 !")
if st.button("버튼이 클릭되면2"):
st.write("클릭 후 보이는 메세지 2!")
checkbox_btn = st.checkbox('체크박스 버튼')
if checkbox_btn :
st.write("체크박스 버튼 클릭!")
checkbox_btn2 = st.checkbox('체크박스 버튼2', value = True)
if checkbox_btn2 :
st.write('Button2')
st.dataframe: Interactive한 Dataframe, 컬럼 클릭이 가능하고 정렬도 가능
st.table: Static한 Dataframe
df = pd.DataFrame({
'first column':[1,2,3,4,],
'second column':[10,20,30,40,]
})
st.markdown("=======")
st.write(df)
st.dataframe(df)
st.table(df)
st.dataframe(df.style.highlight_max(axis=0))
st.table(df.style.highlight_max(axis=0))
st.metric("Mymetric",42,2)
st.json(df.to_json())
저장할 수도 있음
chart_data = pd.DataFrame(
np.random.randn(20,3),
columns=['a','b','c']
)
st.line_chart(chart_data)
map_data = pd.DataFrame(
np.random.randn(1000,2)/[50,50] + [37.76,-122.4],
columns=['lat','lon']
st.map(map_data)
그 외에도 Plotly Chart등을 쉽게 사용할 수 있음
Chart 문서
A가 선택되면 이 작업을 수행
selected_item = st.radio("Radio Part", ("A","B","C"))
if selected_item == "A":
st.write("A!!!")
elif selected_item == "B":
st.write("B!!!")
elif selected_item == "C":
st.write("C!!!")
option = st.selectbox("Please select in selectbox!',
'J','H','D'))
st.write("You selected:", option)
selectbox의 Output을 변수에 저장해서 확인할 수 있음
multi_select = st.multiselect('Please select Something in multi selectbox!' ,
['A','B','C','D'])
st.write('You selected:', multi_select)
결과물:
[
0:"A"
1:"C"
]
#description, min, max, default
value= st.slider('Select a range of values', 0.0, 100.0, (25.0,75.0))
st.write('Values:',values)
text_input = st.text_input("텍스트를 입력해주세요")
st.write(text_input)
password_input = st.text_input("암호를 입력해주세요",type= "password")
number_input = st.number_input("숫자를 입력해주세요")
st.write(number_input)
st.date_input("날짜를 입력하세요")
st.time_input("시간을 입력하세요")
st.caption("This is caption")
st.code("a= 123")
st.latex("\int a x^2 \,dx")
Sidebar에는 파라미터를 지정하거나, 암호를 설정할 수 있음
st.sidebar.button("hi")
기존 Method앞에 sidebar를 붙이면 sidebar에 보이게 됨
여러 칸으로 나눠서 Component를 추가하고 싶은 경우 활용
col1, col2, col3, col4 = st.columns(4)
col1.write("this is col1")
col2.write("this is col2")
col3.write("this is col3")
col4.write("this is col4")
눌렀을 경우 확장하는 부분이 필요한 경우
with st.expander("클릭하면 열려요"):
st.write("content!")
연산이 진행되는 도중 메세지를 보여주고 싶은 경우
with st.spinner("Please wait.."):
time.sleep(5)
연산 진행 도중 메세지를 보여주고 싶다.
inference, 전처리할때 작업중입니다~ 를 보여주기
ㅋㅋ귀여움 이거
st.balloons()
st.success("Success") #초록
st.info("Info") # 파랑
st.warning("Warning")#노랑
st.error("Error message")#빨강
with st.form(key="입력 form"):
username = st.text_input("User name")
password = st.text_input("Password", type= "password")
st.form_submit_button("login")
200mb 제한 있음
uploaded_file = st.file_uploader("Choose a file", type= ["png","jpg","jpeg"])
정말 많은 Component가 존재함
문서 확인해보면서 실행하기!
Streamlit API Document <- 클릭
Streamlit 치트시트 <- 클릭
Streamlit의 화면에서 무언가 업데이트 되면 전체 Streamlit코드가 다시 실행
1) Code가 수정되는 경우
2) 사용자가 Streamlit의 위젯과 상호작용하는 경우(버튼 클릭, 입력상자에 텍스트 입력시 등)
st.session_state.{session_state_value}
#session_state_value에 저장해서 활용하는 방식
Increment 버튼을 누르면 +1, Decrement 버튼을 누르면 -1이 되는 Counter예제
st.title('Counter Example without session state')
count_value =0
increment = st.button('Increment')
if increment :
count_value +=1
decrement = st.button('Decrement')
if decrement:
count_value -= 1
st.write("Count = ", count_value)
버튼을 누를때마다 계속 다시 실행되므로 count_value는 0.
st.title('Counter Example without session state')
if 'count' not in st.session_state:
st.session_state.count = 0
increment = st.button('Increment')
if increment :
count_value +=1
decrement = st.button('Decrement')
if decrement:
count_value -= 1
st.write("Count = ", count_value)
session_state의 경우 변수의 이름을 확인해야 하는데
if 'count' not in st.session_state: 가 없다면 실행될때마다
st.session_state.count = 0가 실행되서 똑같은 결과를 보여줄 것이다.
st.slider가 변할 경우(on_change) Callback 함수를 사용해서 session_state값을 유지하는 코드 만들기.
매번 다시 실행하는 특성 때문에 데이터도 매번 다시 읽을 수 있음
이런 경우 @st.cache 데코레이터를 사용해 캐싱하면 좋음(캐싱: 성능을 위해 메모리등에 저장하는 행위)
데이터를 읽는 함수를 만들고 데코레이터 적용
DATE_COLUMN = 'data/time'
DATE_URL = ('https~~')
@st.cache
def load_data(nrows):
data = pd.read_csv(DATA_URL, nrows=nrows)
lowercase= lambda x: str(x).lower()
data.rename(lowercase,axis='columns', inplace=True)
data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
return data