์น๊ฐ๋ฐ์๋ก์ AI๋ฅผ ํ์ตํ๊ณ ํ์ฉํ๋ ์ค ๋ฌธ๋ ๊ถ๊ธํด์ก์ต๋๋ค.
"AI/ML ์์ง๋์ด๋ค์ ์์ ๋ค์ด ๋ง๋ ๋ณต์กํ ๋ชจ๋ธ์ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ป๊ฒ ํ์ธํ๊ณ ๊ณต์ ํ ๊น?" ๊ทธ๋ฆฌ๊ณ "๋น๊ฐ๋ฐ์๋ค์ ์ด๋ป๊ฒ AI๋ฅผ ํ์ฉํด ์ํ๋ ๊ฒ์ ๋ง๋ค์ด๋ผ๊น?"
์ด ๊ถ๊ธ์ฆ์ผ๋ก '์คํ๋ฅดํ์์ ์ฃผ๊ดํ๋ AI์ 100์ธ์ ์ฉ์ฌ๋ค - ํด์ปคํค'์ ์ฐธ๊ฐํด ๋ดค์ด์.
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ก์ AI ์ํ๊ณ์ ๋ฐ์ ๋ด๊ฐ๋ณด๊ณ ์ถ์์ต๋๋ค.

ํด์ปคํค์์ ๋ง๋ Streamlit
ํด์ปคํค์ ์ฐธ๊ฐํ๋ฉด์ ์ฒ์์ผ๋ก Streamlit์ด๋ผ๋ ํ๋ ์์ํฌ๋ฅผ ์ ํ๊ฒ ๋์์ต๋๋ค.
AI/ML ๊ฐ๋ฐ์๋ค ์ฌ์ด์์๋ ๊ฝค ์ ๋ช ํ ๋๊ตฌ๋๋ผ๊ตฌ์?!
์ฒ์์๋ 'Django๋ React, Next ๊ฐ์ ์น ํ๋ ์์ํฌ์ ์ผ์ข ์ธ๊ฐ?' ํ๊ณ ์๊ฐํ์ง๋ง, ์ค์ ๋ก๋ ์ข ๋ค๋ฅธ ์ฉ๋๋ก ์ฌ์ฉ๋๊ณ ์์์ต๋๋ค.
Streamlit์ ํ์ด์ฌ ๊ฐ๋ฐ์, ํนํ ๋ฐ์ดํฐ๋ ML ์์ง๋์ด๊ฐ ๋ณต์กํ ์น ๊ฐ๋ฐ ์ง์ ์์ด๋ ๋ฐ์ดํฐ ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น ๋ฅด๊ฒ ์ ์ํ ์ ์๊ฒ ๋์์ฃผ๋ ํ๋ ์์ํฌ์์ต๋๋ค.
ํ์ด์ฌ ์ฝ๋๋ง์ผ๋ก ์น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ถํ ์ ์๋ค๋, ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ก์ ์๋นํ ํฅ๋ฏธ๋ก์ด ๊ฐ๋ ์ด์์ด์.
AI ์์ง๋์ด์ ๋น๊ฐ๋ฐ์์ ํ์ฉ๋ฒ
ํด์ปคํค์์ ๊ด์ฐฐํ ๋ฐ๋ก๋, AI/ML ์์ง๋์ด๋ค์ด Streamlit์ ์ฌ์ฉํ๋ ์ฃผ๋ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์์ต๋๋ค.
- ๋น ๋ฅธ ํ๋กํ ํ์ดํ: ๋ณต์กํ ๋ชจ๋ธ์ ๊ฒฐ๊ณผ๋ฅผ ์ฆ์ ์๊ฐํํ๊ณ ์ํธ์์ฉ ๊ฐ๋ฅํ ํํ๋ก ๋ง๋ค ์ ์์ต๋๋ค.
- ํ์ ์ฉ์ด์ฑ: ๋น๊ธฐ์ ์ ํ์๋ค์๊ฒ ๋ชจ๋ธ์ ๋์์ ์ง๊ด์ ์ผ๋ก ์ค๋ช ํ ์ ์์ต๋๋ค.
- ๋ฐฐํฌ ์ฉ์ด์ฑ: ๋ช ๋ฒ์ ํด๋ฆญ๋ง์ผ๋ก ์น์ ๊ณต๊ฐํ ์ ์์ด ๊ณต์ ๊ฐ ์ฝ์ต๋๋ค.
๊ฐ์ฅ ๋๋ผ์ ๋ ์ ์ ๋น๊ฐ๋ฐ์๋ค๋ ์ด ๋๊ตฌ๋ฅผ ํ์ฉํด ์์ ๋ง์ AI ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค์ด๋ด์๋ค๋ ์ฌ์ค์ ๋๋ค..!!
๋ง์ผํฐ, ๋์์ด๋, ์ฌ์ง์ด ์์ฌ๋ ๊ต์ฌ์ ๊ฐ์ ์ ํ ๋ค๋ฅธ ๋๋ฉ์ธ์ ์ ๋ฌธ๊ฐ๋ถ๋ค๋ ๊ฐ๋จํ ํ์ด์ฌ ์ฝ๋๋ฅผ ๋ฐฐ์ ์์ ์ ์์ด๋์ด๋ฅผ ๊ตฌํํ์ จ์ต๋๋ค!!
๋ด ๊ฒฝํ! Streamlit์ผ๋ก ์๋น์ค ๊ตฌ์ถํ๊ธฐ
์ ๋ ํ์ ์ฌ์ฉํ๋ React, Vue ์ง์์ด ์๋ Streamlit์ ์ฌ์ฉํด ๊ฐ๋จํ ์์ด๋์ด ๊ตฌํ์ ๋ณด๊ธฐ๋ก ํ์ต๋๋ค. ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ก์ HTML, CSS, JavaScript์ ์ต์ํ ์ ์๊ฒ๋ ๊ต์ฅํ ์ฌ๋ฐ์์ด์!
๊ธฐ๋ณธ์ ์ธ ์ค์ ์ ๋๋ผ์ธ ์ ๋๋ก ๊ฐ๋จํ์ต๋๋ค. (์ค๋ช ์ ์ํ ์ฝ๋๋ก ์ค์ Github์ ๊ฒ์ํ ์ฝ๋์๋ ์ ํ ๋ค๋ฆ ๋๋ค!)
import streamlit as st
import pandas as pd
import custom_nlp_model # ๋ด ์ปค์คํ
๋ชจ๋ธ
st.title("ํ
์คํธ ๊ฐ์ ๋ถ์๊ธฐ")
user_input = st.text_area("๋ถ์ํ ํ
์คํธ๋ฅผ ์
๋ ฅํ์ธ์:")
if st.button("๋ถ์ํ๊ธฐ"):
result = custom_nlp_model.analyze_sentiment(user_input)
st.write(f"ํ์ฌ ์ํฉ ๋ถ์: {result['sentiment']}")
st.bar_chart(result['confidence_scores'])
์ด ์ฝ๋๋ง์ผ๋ก ์๋ํ๋ ์น ์ฑ์ด ์์ฑ๋์์ต๋๋ค! React ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ฑํ๊ณ , CSS๋ฅผ ์์ฑํ๊ณ , ์ํ ๊ด๋ฆฌ๋ฅผ ์ค์ ํ๋ ๋ฑ์ ์์ ์์ด ๋ง์ด์ฃ . ์๋ ๋ฐฐํฌ๋ ๋๋์ฑ ์ฌ์ ์ต๋๋ค!!
์น๊ฐ๋ฐ์๋ก์จ ๋๋ ๋ถํธํ ์
๊ทธ๋ฌ๋ ํ๋ก์ ํธ๊ฐ ์งํ๋ ์๋ก, ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ก์์ ๋ณธ๋ฅ์ด.. ์กฐ๊ธ์ฉ.. ๊นจ์ด๋ฌ์ต๋๋ค. "์ด ๋ฒํผ์ ์คํ์ผ์ ๋ฐ๊พธ๊ณ ์ถ์๋ฐ...", "์ด ์ฐจํธ๋ฅผ ๋ ์ธํฐ๋ํฐ๋ธํ๊ฒ ๋ง๋ค ์ ์์๊น?", "ํ์ด์ง ์ ํ ์ ๋๋ฉ์ด์ ์ ์ด๋ป๊ฒ ์ถ๊ฐํ์ง?" ๊ฐ์ ์๊ฐ๋ค์ด ๋ค๊ธฐ ์์ํ์ด์.
Streamlit์ ๊ธฐ๋ณธ์ ์ธ ์คํ์ผ๋ง ์ต์ ์ ์ ๊ณตํ์ง๋ง, ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๊ฐ ๊ธฐ๋ํ๋ ์์ค์ ์ปค์คํฐ๋ง์ด์ง์ ์ด๋ ค์ ์ต๋๋ค. ๊ฒฐ๊ตญ HTML๊ณผ CSS๋ฅผ ์ง์ ์ฝ์ ํ๊ธฐ ์์ํ์ต๋๋ค. (์ ์ด์ ๋ชฉ์ ์ด ์ด์๊ฒ ๊พธ๋ฏธ๋ ํ๋ ์์ํฌ๊ฐ ์๋๋๋ค!! Streamlit์ด ์๋ชป๋๊ฒ ์๋์์!!)
custom_html = """
<div class="result-card" style="border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); padding: 20px; margin: 20px 0;">
<h3 style="color: #333; font-family: 'Segoe UI', sans-serif;">๋ถ์ ๊ฒฐ๊ณผ</h3>
<div class="sentiment-meter" style="background: linear-gradient(to right, #ff4b4b, #ffff4b, #4bff4b); height: 20px; border-radius: 10px;">
<div class="marker" style="position: relative; left: {}%; transform: translateX(-50%); width: 10px; height: 30px; background-color: #333; border-radius: 5px;"></div>
</div>
</div>
"""
st.markdown(custom_html.format(sentiment_score * 100), unsafe_allow_html=True)
์ด๋ฐ ๋ฐฉ์์ ์๋์ ํ์ง๋ง, ์ต์ํ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ๊ฐ๋ฐ ๋ฐฉ์๊ณผ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ์์ต๋๋ค. ๋ง์น ์ค๋๋ ์น์ฌ์ดํธ๋ฅผ ์ ์ง๋ณด์ํ๋ ๋๋์ด์์ด์.
ํ์ด์ง๋ค์ด์ ๊ณผ DOM ์ปจํธ๋กค
ํนํ ๊ณ ์ ํ๋ ๋ถ๋ถ์ ํ์ด์ง๋ค์ด์ ๊ณผ DOM ์ปจํธ๋กค์ด์์ต๋๋ค.
React๋ Vue์์๋ ์ํ ๊ด๋ฆฌ์ ์ปดํฌ๋ํธ ๋ผ์ดํ์ฌ์ดํด์ ํตํด ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ ๊ธฐ๋ฅ๋ค์ด Streamlit์์๋ ์๋นํ ๋ฒ๊ฑฐ๋ก์ ์ต๋๋ค.
(๋ฌผ๋ก ์ ๊ฐ ์ ๋๋ก ์ฐพ์๋ณด์ง ๋ชปํ ๊ฒ์ผ ์๋ ์์ต๋๋ค!!)
์๋ฅผ ๋ค์ด, ๋ถ์ ๊ฒฐ๊ณผ๋ฅผ ํ์ด์ง๋ก ๋๋์ด ํ์ํ๋ ค๋ฉด ์ด๋ฐ ์์ผ๋ก ์ ๊ทผํด์ผ ํ์ต๋๋ค.
(๋ฐฐํฌํ ์ฝ๋์๋ ์ฐจ์ด๊ฐ ์์ต๋๋ค! - ํ์ด์ง๋ค์ด์ ์ ๊ฑฐ)
import streamlit as st
import pandas as pd
# ์ธ์
์ํ๋ฅผ ์ฌ์ฉํ ํ์ด์ง๋ค์ด์
if 'page_number' not in st.session_state:
st.session_state.page_number = 0
# ๋ฐ์ดํฐ ๋ก๋
data = pd.read_csv("large_results.csv")
items_per_page = 10
total_pages = len(data) // items_per_page + (1 if len(data) % items_per_page > 0 else 0)
# ํ์ฌ ํ์ด์ง ๋ฐ์ดํฐ ๊ณ์ฐ
start_idx = st.session_state.page_number * items_per_page
end_idx = min(start_idx + items_per_page, len(data))
current_page_data = data.iloc[start_idx:end_idx]
# ํ์ฌ ํ์ด์ง ๋ฐ์ดํฐ ํ์
st.write(f"๊ฒฐ๊ณผ {start_idx+1}–{end_idx} / ์ด {len(data)}๊ฐ")
st.table(current_page_data)
# ํ์ด์ง๋ค์ด์
์ปจํธ๋กค
col1, col2 = st.columns(2)
if col1.button("์ด์ ํ์ด์ง") and st.session_state.page_number > 0:
st.session_state.page_number -= 1
st.experimental_rerun()
if col2.button("๋ค์ ํ์ด์ง") and st.session_state.page_number < total_pages - 1:
st.session_state.page_number += 1
st.experimental_rerun()
์ด ๋ฐฉ์์ ์๋์ ํ์ง๋ง, ํ์ด์ง ์ ํ ์ ์ ์ฒด ์ฑ์ด ์๋ก๊ณ ์นจ๋์ด ์ฌ์ฉ์ ๊ฒฝํ์ด ๋งค๋๋ฝ์ง ์์์ต๋๋ค.
React์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋ useState์ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ผ๋ก ๊ฐ๋จํ ํด๊ฒฐํ ์ ์๋ ๋ฌธ์ ๊ฐ ํจ์ฌ ๋ณต์กํด์ง ๋๋์ด์์ฃ .
์น๊ณผ AI์ ์ ์
ํด์ปคํค๊ณผ ํ ํ๋ก์ ํธ๋ฅผ ํตํด ๋๋ ์ ์, Streamlit์ด '์น ๊ฐ๋ฐ'๊ณผ 'AI/ML ๊ฐ๋ฐ' ์ฌ์ด์ ๊ฐ๊ทน์ ๋ฉ์ฐ๊ธฐ ์ํ ๋๊ตฌ๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์๋ฒฝํ ํ๋ก ํธ์๋ ์๋ฃจ์ ์ ์๋์ง๋ง, AI/ML ์์ง๋์ด์ ๋น๊ฐ๋ฐ์๋ค์ด ์์ ์ ์์ด๋์ด๋ฅผ ๋น ๋ฅด๊ฒ ์๊ฐํํ๊ณ ๊ณต์ ํ๋ ๋ฐ๋ ํ์ํ ๋๊ตฌ์์ด์.
์์์๋ ์ธ๊ธํ์ง๋ง ์ ์๊ฒ ๊ฐ์ฅ ๋๋ผ์ ๋ ์ ์ ๋น๊ฐ๋ฐ์๋ค๋ Streamlit์ ํตํด ์์ ์ ์์ด๋์ด๋ฅผ AI ์ํ๊ณ ์์์ ๊ตฌํํด๋ณผ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์์ด๋์ด๊ฐ ์์ง๋ง ๊ธฐ์ ์ ์ฅ๋ฒฝ ๋๋ฌธ์ ์คํํ์ง ๋ชปํ๋ ์ฌ๋๋ค์ด, ์ด์ ๋ ๊ฐ๋จํ ํ์ด์ฌ ์ฝ๋๋ง์ผ๋ก๋ ์์ ์ ์์ด๋์ด๋ฅผ ํ๋กํ ํ์ ์ผ๋ก ๋ง๋ค์ด ์ด๊ธฐ ๊ฒ์ฆ์ ํ ์ ์๊ฒ ๋ ๊ฒ์ด์ฃ .
์ด๋ฐ ์ด๊ธฐ ๊ฒ์ฆ ๊ณผ์ ์์ ๊ฐ๋ฅ์ฑ์ด ํ์ธ๋๋ฉด, ๊ทธ ํ์๋ ์ค์ค๋ก ๋ ๊น๊ฒ ํ์ตํ๊ฑฐ๋ ์ ๋ฌธ๊ฐ๋ฅผ ์ฐพ์ ํ์ ํจ์ผ๋ก์จ ๋ ์์ฑ๋ ๋์ ์๋น์ค๋ก ๋ฐ์ ์ํฌ ์ ์๊ฒ ๋ฉ๋๋ค. ์ง์ ์ฅ๋ฒฝ์ด ๋ฎ์์ง๋ฉด์ AI ๊ธฐ์ ์ ํ์ฉํ๋ ์ ๊ทผ์ฑ์ด ํฌ๊ฒ ํฅ์๋ ๊ฒ์ ๋๋ค! ์ด๋ ๋ง์น ์๋ํ๋ ์ค๋ ์์์น๋ฑ์ ์๋น์ค๊ฐ ์น ๊ฐ๋ฐ์ ๋ชจ๋ฅด๋ ์ฌ๋๋ค์๊ฒ ์น์ฌ์ดํธ ์ ์์ ๋ฌธ์ ์ด์ด์ค ๊ฒ๊ณผ ๋น์ทํ ๋ณํ๋ผ๊ณ ์๊ฐํฉ๋๋ค.
Streamlit์ ์ง์ง ๋ชฉ์
์ด๋ฒ ํด์ปคํค์ ๊ฒฝํํ๋ฉฐ ์๊ฐํ๊ฑด, Streamlit์ ํ๋ก ํธ์๋, ์น ๊ฐ๋ฐ ๋๊ตฌ์ ๊ด์ ์์ ๋ฐ๋ผ๋ณด๋ ๊ฒ ์์ฒด๊ฐ ์๋ชป๋ ์ ๊ทผ์ด๋ผ๋ ์ ์ ๋๋ค! Streamlit์ ์ ์ด์ ํ๋ คํ UI/UX๋ ๋ณต์กํ ์ธํฐ๋์ ์ ์ํ ๋๊ตฌ๊ฐ ์๋๋๋ค.
์ฌ์ค, ์คํ์ผ๋ง์ด๋ ํ์ด์ง๋ค์ด์ ์ ํ๊ณ๋ Streamlit์ '๋จ์ '์ด๋ผ๊ธฐ๋ณด๋ค๋ ๊ทธ๋ฅ ์ด ๋๊ตฌ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ธฐ๋ฅ์ ๋๋ค.
์ด๊ฑด ๋ง์น ๋ง์น๋ก ๋์ฌ๋ฅผ ๋ฐ์ผ๋ ค๊ณ ํ๋ฉด์ ๋ง์น๊ฐ ๋์๋ค๊ณ ๋งํ๋ ๊ฒ๊ณผ ๋น์ทํ๋ค ์๊ฐํด์.
Streamlit์ ์ง์ง ๋ชฉ์ ์ ML ์์ง๋์ด๋ค์ด ์์ ์ด ๋ง๋ ๋ชจ๋ธ์ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ์๊ฐํํ๊ณ ์ํธ์์ฉํ ์ ์๊ฒ ํ๋ ๊ฒ์ด์์ต๋๋ค.
ML ์์ง๋์ด๋ค์๊ฒ ์๋ฒฝํ UI๋ณด๋ค ๋ชจ๋ธ์ ์ฑ๋ฅ๊ณผ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ๊ฒ์ด ํจ์ฌ ์ค์ํ๋๊น์.
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์์ธ ์ ๋ก์๋ ์ฒ์์ ์ด ์ ์ ๋๊ธฐ๊ฐ ํ๋ค์์ต๋๋ค. ๋ชจ๋ ๊ฒ์ '์ข์ UI/UX'์ ๊ด์ ์์๋ง ๋ฐ๋ผ๋ดค๊ฑฐ๋ ์. ํ์ง๋ง ํด์ปคํค์ ํตํด AI/ML ์์ง๋์ด์ ์ด์ผ๊ธฐ๋ ๋ค์ํ ์ฌ๋๋ค๊ณผ ๋ํํ๋ฉด์, ๊ทธ๋ค์๊ฒ ํ์ํ๊ฒ ํ๋ คํ ์ ๋๋ฉ์ด์ ์ด๋ ์๋ฒฝํ ๋ฐ์ํ ๋์์ธ์ด ์๋๋ผ '๋ชจ๋ธ์ด ์ ๋๋ก ์๋ํ๋์ง ๋น ๋ฅด๊ฒ ํ์ธํ๊ณ ํ์๋ค๊ณผ ๊ณต์ ํ ์ ์๋ ๋ฐฉ๋ฒ'์ด๋ผ๋ ๊ฑธ ๊นจ๋ฌ์์ต๋๋ค.
๊ทธ๋์ Streamlit์ ML ์์ง๋์ด๋ค์ด ์น ๊ฐ๋ฐ ์์ด๋ ์์ ์ ์์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๊ณ ๊ณต์ ํ ์ ์๊ฒ ๋ง๋ค์ด์ฃผ๋, ์ ํํ ๊ทธ ๋ชฉ์ ์ ์ต์ ํ๋ ๋๊ตฌ์ ๋๋ค!!