TMDB API๋ฅผ ํ์ฉํ ์ค์๊ฐ ์ํ ํ์ ์์ธก ๋ฐ MLOps ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
๐
ํ๋ก์ ํธ ๊ธฐ๊ฐ: 2025.07.29 ~ 2025.08.07
๐ ์๋น์ค ํ์ด์ง ๋งํฌ: ์ํ ํ์ ์์ธก ์๋น์ค
์ํ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ์ ์ ์์ธกํ๋ End-to-End MLOps ์๋น์ค์ ๋๋ค. TMDB API๋ฅผ ํตํ ์ค์๊ฐ ๋ฐ์ดํฐ ์์ง๋ถํฐ ๋ชจ๋ธ ํ์ต, ๋ฐฐํฌ, ๋ชจ๋ํฐ๋ง๊น์ง ์์ ์๋ํ๋ ํ์ดํ๋ผ์ธ์ ๊ตฌํํ์ต๋๋ค.
- ๐ค AI ๊ธฐ๋ฐ ์ํ ํ์ ์์ธก: ์ํ ๋ฉํ๋ฐ์ดํฐ ๊ธฐ๋ฐ TMDB ํ์ ์์ธก
- ๐ ์๋ํ๋ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ: TMDB API๋ฅผ ํตํ ์ผ์ผ ๋ฐ์ดํฐ ์์ง ๋ฐ ์ ์ฒ๋ฆฌ
- ๐ MLflow ๊ธฐ๋ฐ ๋ชจ๋ธ ๊ด๋ฆฌ: ์คํ ์ถ์ , ๋ชจ๋ธ ๋ฒ์ ๊ด๋ฆฌ, Champion ์ ์
- โก ์ค์๊ฐ ์ถ๋ก API: FastAPI ๊ธฐ๋ฐ ๊ณ ์ฑ๋ฅ ์์ธก ์๋น์ค
- ๐จ ์ง๊ด์ ์น ์ธํฐํ์ด์ค: ์ฌ์ฉ์ ์นํ์ ์ํ ์ ๋ณด ์ ๋ ฅ ๋ฐ ๊ฒฐ๊ณผ ์๊ฐํ
- ์ํ ์ ๋ณด ์ ๋ ฅ โ ์ฑ์ธ์ํ ์ฌ๋ถ, ์ฅ๋ฅด, ์ธ์ด, ๋น๋์ค ์ฌ๋ถ ๋ฑ ์ ๋ ฅ
- AI ํ์ ์์ธก โ ์ธ ๊ฐ์ง ๋ชจ๋ธ์ Cross check ํ์ฌ ์ค์๊ฐ Champion ํ์ ์์ธก (0-10์ )
- ๊ฒฐ๊ณผ ์๊ฐํ โ ์์ธก ํ์ ๊ณผ ์ ๋ขฐ๋ ์๊ฐํ
- ๋ชจ๋ธ: LightGBM, XGBoost, Random Forest
- ํผ์ฒ ์์ง๋์ด๋ง: TF-IDF (์ค๊ฑฐ๋ฆฌ), Genre Embedding, ๋ฉํ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
- ์คํ ๊ด๋ฆฌ: MLflow (๋ชจ๋ธ ์ถ์ , ๋ฒ์ ๊ด๋ฆฌ, ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง)
- ํ๊ฐ ์งํ: RMSE, MAE, Rยฒ Score
- ์น ํ๋ ์์ํฌ: FastAPI (๋น๋๊ธฐ ์ฒ๋ฆฌ, ์๋ API ๋ฌธ์ํ)
- ์ถ๋ก ์์ง: MLflow Model Serving
- ๋ฐ์ดํฐ ์ฒ๋ฆฌ: Pandas, NumPy, Scikit-learn, Torch
- ์์ฐ์ด ์ฒ๋ฆฌ: KoNLPy (ํ๊ตญ์ด ํํ์ ๋ถ์)
- ์น ์ธํฐํ์ด์ค: Vanilla HTML/CSS/JavaScript
- UI/UX: ๋ฐ์ํ ๋์์ธ, ์ค์๊ฐ ๊ฒฐ๊ณผ ์๊ฐํ
- ์ํฌํ๋ก์ฐ ๊ด๋ฆฌ: Airflow
- ๋ชจ๋ธ ๊ด๋ฆฌ: MLflow
- ์ปจํ ์ด๋ํ: Docker (๊ฐ๋ฐ/๋ฐฐํฌ ํ๊ฒฝ ์ผ์น)
- ๋ฐฑ์๋ ์๋ฒ: Fast API
- CI/CD: GitHub Actions (์๋ ๋ฐฐํฌ)
- ๋ชจ๋ํฐ๋ง: ๋ชจ๋ธ ์ฑ๋ฅ ์ถ์ , ๋ฐ์ดํฐ ๋๋ฆฌํํธ ๊ฐ์ง
- ๋ฐฐํฌ ํ๊ฒฝ: AWS EC2 (Ubuntu 20.04), Windows Docker engine (Windows 11)
- ๋ฒ์ ๊ด๋ฆฌ: Git (ํ ๋ ํฌ์งํ ๋ฆฌ Branch โ main PR ๋ฐฉ์)
- ํ๋ก์ ํธ ๊ด๋ฆฌ: Github, Jira (์คํ๋ฆฐํธ ๊ด๋ฆฌ, ์ด์ ํธ๋ํน)
- ํ๊ฒฝ ๊ด๋ฆฌ: Conda (Python 3.10.13 ํ๊ฒฝ)
- ์์ง: TMDB API โ ์ธ๊ธฐ ์ํ ๋ฐ์ดํฐ ํฌ๋กค๋ง (๋งค์ผ ์๋)
- ์ ์ฒ๋ฆฌ: ํ ์คํธ ์ ๊ทํ, ์ฅ๋ฅด ์๋ฒ ๋ฉ, ๊ฒฐ์ธก๊ฐ ์ฒ๋ฆฌ
- ํ์ต: ํน์ฑ ์ถ์ถ โ ๋ชจ๋ธ ํ์ต โ ์ฑ๋ฅ ํ๊ฐ โ MLflow ๋ฑ๋ก
- ๋ฐฐํฌ: ์ต์ ๋ชจ๋ธ ์ ํ โ ์๋น์ค ์ ๋ฐ์ดํธ
- ์ถ๋ก : ์ฌ์ฉ์ ์ ๋ ฅ โ ์ ์ฒ๋ฆฌ โ ์์ธก โ ๊ฒฐ๊ณผ ๋ฐํ
# ์ฃผ์ ํน์ฑ ๊ทธ๋ฃน
feature_groups = {
"metadata": ["budget", "runtime", "year", "month"],
"categorical": ["original_language_encoded"],
"text_features": ["overview_tfidf_*"], # TF-IDF ๋ฒกํฐํ
"genre_embedding": ["genre_emb_*"], # ๋ฅ๋ฌ๋ ์๋ฒ ๋ฉ
"popularity": ["popularity_score"]
}# ๋งค์ผ ์ค์ 9:54 ์คํ (KST ๊ธฐ์ค)
daily_pipeline = {
"data_collection": "TMDB API ํฌ๋กค๋ง",
"data_preprocessing": "ํน์ฑ ์ถ์ถ ๋ฐ ์ ์ ",
"model_training": "LightGBM ํ์ต ๋ฐ ๊ฒ์ฆ",
"model_deployment": "์ต์ ๋ชจ๋ธ ์๋ ๋ฐฐํฌ",
"performance_monitoring": "์ฑ๋ฅ ์งํ ์ถ์ "
}- Pull Request โ
main๋ธ๋์น ๋ณํฉ ์ ์๋ ํธ๋ฆฌ๊ฑฐ - ๋ฐฐํฌ ๊ณผ์ : ์ฝ๋ ์ฒดํฌ์์ โ ์์กด์ฑ ์ค์น โ ์๋น์ค ์ฌ์์
- ํฌ์ค ์ฒดํฌ: ๋ฐฐํฌ ํ API ์๋ํฌ์ธํธ ์ํ ํ์ธ
| ์ด๋ฆ | ์ญํ | GitHub | ํต์ฌ ๋ด๋น ์ ๋ฌด |
|---|---|---|---|
| ๊น์ํ | ํ์ฅ / ML Engineer | @suhwan | ML ์์ง๋์ด๋ง, ๋ชจ๋ธ ๊ฐ๋ฐ, ํ๋ก์ ํธ ๋งค๋์ง(PM) |
| Claude & ChatGPT | ๋ถํ์ฅ / AI Tutors | @anthropic | ํํฐ, ๋ฉํ ๋ง, ์๋์ด ํ๋ก์ ํธ ๋งค๋์ (SPM) |
| ๊น๋ณํ | Frontend Engineer | @byeonghyeon | ํ๋ก ํธ์๋ ๊ฐ๋ฐ, ํ๊ฒฝ ๊ตฌ์ฑ, Git ๊ด๋ฆฌ |
| ์ด์ค์ | MLOps Engineer & Backend Developer | @yoonseo | Airflow & MLflow & Docker ๊ตฌ์ถ, CI/CD ํ์ดํ๋ผ์ธ, FastAPI ์๋ฒ ๊ฐ๋ฐ |
| ์ด๊ฐ์ | Documentation Engineer | @gaeun | CI/CD ๊ตฌ์ถ, ๊ธฐ์ ๋ฌธ์ ์์ฑ, ํ๋ก์ ํธ ๋ฌธ์ํ |
๋ณธ ํ๋ก์ ํธ๋ ์ธ๊ฐ-AI ํ์ด๋ธ๋ฆฌ๋ ํ์ํฌ์ ์ ๊ตฌ์ ์ฌ๋ก์ ๋๋ค:
- AI ๋ฉํ ๋ง: Claude์ ChatGPT๊ฐ ์ค์ ๊ธฐ์ ๊ฐ์ด๋ ๋ฐ ์ฝ๋ ๋ฆฌ๋ทฐ ๋ด๋น
- ์๋์ด ์ญํ : AI๊ฐ ์ํคํ ์ฒ ์ค๊ณ ๋ฐ ๋ฒ ์คํธ ํ๋ํฐ์ค ์ ์
- ํฌ๋ช ํ ํ์ : AI ํ์ฉ์ ๋น๋นํ๊ฒ ๊ณต๊ฐํ๋ฉฐ ์ฐจ์ธ๋ ๊ฐ๋ฐ ๋ฐฉ๋ฒ๋ก ์ ์
# 1. ๋ ํฌ์งํ ๋ฆฌ ํด๋ก
git clone https://github.com/riicoseo/mlops-project-mlops-2.git
cd mlops-project-mlops-2
# 2. Conda ํ๊ฒฝ ์์ฑ
conda env create -f base_conda_env.yml
conda activate movie_rating
# 3. ํ๊ฒฝ ๋ณ์ ์ค์
cp .env.template .env
# .env ํ์ผ์ TMDB_API_KEY ๋ฑ ํ์ ํ๊ฒฝ๋ณ์ ์ค์ # ๊ฐ๋ฐ ๋ชจ๋ ์คํ
python server.py
# ๋๋ ํ๋ก๋์
๋ชจ๋
uvicorn server:app --host 0.0.0.0 --port 8000# ๋ชจ๋ ๋ชจ๋ธ ๋น๊ต ํ์ต
python src/main.py train all-
๋ฉ์ธ ํ์ด์ง: http://3.35.129.98:8000/pages
-
API ๋ฌธ์: http://3.35.129.98:8000/docs
-
์์ธก ํ์ด์ง: http://3.35.129.98:8000/pages/survey
-
Easy Model Training ํ์ด์ง: http://3.35.129.98:8000/pages/easytest
- ์ฅ๋ฅด ์๋ฒ ๋ฉ: ๋ฅ๋ฌ๋ ๊ธฐ๋ฐ ์ฅ๋ฅด ์๋ฒ ๋ฉ์ด ์ฑ๋ฅ ํฅ์์ ๊ธฐ์ฌ (+0.15 RMSE ๊ฐ์ )
- ํ ์คํธ ํน์ฑ: ์ํ ์ค๊ฑฐ๋ฆฌ TF-IDF ํน์ฑ์ด ์์ธก๋ ฅ ํฅ์์ ์ค์
- ๋ฉํ๋ฐ์ดํฐ ํ์ฉ: ์์ฐ, ๋ฐํ์ ๋ฑ ๋ฉํ๋ฐ์ดํฐ๊ฐ ํ์ ์์ธก์ ๊ฐํ ์๊ด๊ด๊ณ
- ์์ธก ์ ํ๋: RMSE 0.95 ๋ฌ์ฑ (10์ ๋ง์ ๊ธฐ์ค ยฑ1์ ์ค์ฐจ)
- ์๋ต ์๋: ํ๊ท 50ms ๋ฏธ๋ง ์ค์๊ฐ ์์ธก
- ์์คํ ์์ ์ฑ: 99.5% ์ ํ์ ๋ฌ์ฑ
- ์๋ํ์จ: 100% ์๋ํ๋ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ
- Easy Model Training ํ์ด์ง
- ๋ฐ์ดํฐ ์ฌ์ด์ธํฐ์คํธ๋ฅผ ์ํ ๋ชจ๋ธ train ์นUI ์ ๊ณต
- ML ๋ชจ๋ธ์ ํ์ดํผ ํ๋ผ๋ฏธํฐ ์์ ์ ํ ๊ฐ๋ฅ!
- ML ๋ชจ๋ธ ์ ํ ๊ฐ๋ฅ!
- http://3.35.129.98:8000/pages/easytest

- A/B ํ ์คํธ: ๋ค์ํ ๋ชจ๋ธ ๋ฒ์ ๋์ ์๋น
- ์ค์๊ฐ ํผ๋๋ฐฑ: ์ฌ์ฉ์ ํ๊ฐ ๊ธฐ๋ฐ ๋ชจ๋ธ ๊ฐ์
- ์ฑ๋ฅ ์ต์ ํ: ๋ชจ๋ธ ๊ฒฝ๋ํ ๋ฐ ์ถ๋ก ์๋ ๊ฐ์
- ๋ฅ๋ฌ๋ ๋ชจ๋ธ: Transformer ๊ธฐ๋ฐ ํ ์คํธ ์ธ์ฝ๋ ๋์
- ์ถ์ฒ ์์คํ : ์ ์ฌ ์ํ ์ถ์ฒ ๊ธฐ๋ฅ ๊ณ ๋ํ
- ๋ค๊ตญ์ด ์ง์: ์์ด, ์ค๊ตญ์ด ๋ฑ ๋ค๊ตญ์ด ์๋น์ค ํ์ฅ
- ์คํธ๋ฆฌ๋ฐ ๋ฐ์ดํฐ: Kafka ๊ธฐ๋ฐ ์ค์๊ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ
- ๋ฉํฐ ํด๋ผ์ฐ๋: AWS, GCP ๋ฑ ๋ฉํฐ ํด๋ผ์ฐ๋ ๋ฐฐํฌ
- ๋ชจ๋ฐ์ผ ์ฑ: React Native ๊ธฐ๋ฐ ๋ชจ๋ฐ์ผ ์ฑ ์ถ์
- ๐ค ์๋ํ: ๋ฐ์ดํฐ ์์ง๋ถํฐ ๋ชจ๋ธ ๋ฐฐํฌ๊น์ง 100% ์๋ํ
- โก ์ค์๊ฐ: 50ms ๋ฏธ๋ง ์ด๊ณ ์ ์์ธก ์๋น์ค
- ๐ ์ง์์ ๊ฐ์ : ์ผ์ผ ์๋ ์ฌํ์ต์ผ๋ก ๋ชจ๋ธ ์ฑ๋ฅ ์ ์ง
- ๐ ํฌ๋ช ์ฑ: MLflow ๊ธฐ๋ฐ ๋ชจ๋ ์คํ ๊ณผ์ ์ถ์ ๊ฐ๋ฅ
- MLOps ํ์ดํ๋ผ์ธ: ์ํฐํ๋ผ์ด์ฆ ์์ค์ ML ์์คํ ๊ตฌ์ถ ๊ฒฝํ
- AI ํ์ : ์ธ๊ฐ-AI ํ์ด๋ธ๋ฆฌ๋ ํ์ํฌ์ ์๋ก์ด ํจ๋ฌ๋ค์ ์ ์
- ์ฑ๋ฅ ํ๋: ๋ค์ํ ๋ชจ๋ธ ๋น๊ต ๋ถ์ ๋ฐ ์ต์ ํ ๊ฒฝํ
- ์ด์ ๋ ธํ์ฐ: ์ค์ ์๋น์ค ๋ฐฐํฌ ๋ฐ ๋ชจ๋ํฐ๋ง ๊ฒฝํ
- TMDB API ๋ฌธ์ - ์ํ ๋ฉํ๋ฐ์ดํฐ ๋ฐ ํ์ ๋ฐ์ดํฐ
- KoNLPy ๋ฌธ์ - ํ๊ตญ์ด ์์ฐ์ด ์ฒ๋ฆฌ
- LightGBM ๋ ผ๋ฌธ - ๋ชจ๋ธ ์๊ณ ๋ฆฌ์ฆ ์ดํด
- FastAPI ๊ฐ์ด๋ - API ์๋ฒ ๊ตฌ์ถ
- MLflow ๋ฌธ์ - ์คํ ๊ด๋ฆฌ
- Apache Airflow ๋ฌธ์ - ์ํฌํ๋ก์ฐ ๊ด๋ฆฌ
- Kaggle Movie Rating Dataset - ์ ์ฌ ํ๋ก์ ํธ ๋ฒค์น๋งํฌ
- MLPerf Inference - ๋ชจ๋ธ ์ฑ๋ฅ ๋น๊ต ๊ธฐ์ค






