diff --git a/README.md b/README.md index 3e20804..0d94a0c 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,119 @@ -# โœจProject Conventionโœจ ---- +# ๐Ÿค– ์ž”๋ฐ˜ํ”Œ๋ŸฌํŒ… AI -
- -## โœ‰๏ธ Commit Convention +FastAPI ๊ธฐ๋ฐ˜์˜ **AI ์ถ”์ฒœ ์„œ๋ฒ„**๋กœ, ์‹์•ฝ์ฒ˜ ์˜์–‘์„ฑ๋ถ„ํ‘œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ +**๋งž์ถคํ˜• ๋ฐ˜์ฐฌ ์ถ”์ฒœ**๊ณผ **์„ญ์ทจ ํŒ ์ œ๊ณต**์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. -์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋Š” **Udacity ์Šคํƒ€์ผ**์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ์ž‘์„ฑ +### ๐Ÿ”น AI ๊ธฐ๋Šฅ -``` -type: Subject (์ œ๋ชฉ) +* **๋ฉ”๋‰ด ์ถ”์ฒœ** -body (๋ณธ๋ฌธ) (๊ธด ์„ค๋ช…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์ž‘์„ฑ) + * 5๊ฐ€์ง€ ์ฝ˜์…‰ํŠธ ๊ธฐ๋ฐ˜: + `diet(๋‹ค์ด์–ดํŠธ)`, `keto(์ €ํƒ„๊ณ ์ง€)`, `low_sodium(์ €์—ผ)`, `glycemic(ํ˜ˆ๋‹น)`, `bulking(๋ฒŒํฌ์—…)` + * ์ž…๋ ฅ ๋ฉ”๋‰ด๋ช… -> ์œ ์‚ฌ๋„ ๋งค์นญ -> ์˜์–‘ ์„ฑ๋ถ„ ํ”ผ์ฒ˜ํ™” -> ์ฝ˜์…‰ํŠธ๋ณ„ ์ ์ˆ˜ํ™”(0\~100) -footer (๊ผฌ๋ฆฌ๋ง) (issue tracker ID๋ฅผ ๋ช…์‹œํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์ž‘์„ฑ) -``` -
+* **Tip ์ƒ์„ฑ** + + * OpenAI API ์—ฐ๋™์„ ํ†ตํ•œ **์‹์Šต๊ด€ ๊ฐ€์ด๋“œ / ๋ ˆ์‹œํ”ผ ์ œ์•ˆ** + +--- +## ๐Ÿš€ Tech Stack +struct-be -### ๐Ÿ›  **type**: ์ปค๋ฐ‹์˜ ์œ ํ˜• +### ๐Ÿ”น Framework & Language +- **Python 3.11** +- **FastAPI : ๊ฒฝ๋Ÿ‰ ์›น ํ”„๋ ˆ์ž„์›Œํฌ** +- **Uvicorn : ASGI ์„œ๋ฒ„** -| ํƒ€์ž… | ์„ค๋ช… | -|------------|------------------------------------------------| -| `feat` | โœจ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€ | -| `fix` | ๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ • | -| `docs` | ๐Ÿ“ ๋ฌธ์„œ ์ˆ˜์ • (README, ์ฃผ์„ ๋“ฑ) | -| `style` | ๐Ÿ’„ ์ฝ”๋“œ ํฌ๋งทํŒ…, ์„ธ๋ฏธ์ฝœ๋ก  ๋ˆ„๋ฝ ๋“ฑ ๊ธฐ๋Šฅ ์˜ํ–ฅ ์—†๋Š” ๋ณ€๊ฒฝ | -| `refactor` | โ™ป๏ธ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง (๊ธฐ๋Šฅ ๋ณ€ํ™” ์—†์Œ) | -| `test` | โœ… ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€ ๋˜๋Š” ์ˆ˜์ • | -| `chore` | ๐Ÿ”ง ๋นŒ๋“œ ์„ค์ •, ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์„ค์ • ๋“ฑ ๊ธฐํƒ€ ์ž‘์—… | -| `perf` | โšก ์„ฑ๋Šฅ ๊ฐœ์„  | -| `ci` | ๐Ÿ”„ CI ๊ด€๋ จ ์„ค์ • ๋ฐ ์Šคํฌ๋ฆฝํŠธ ์ˆ˜์ • | -| `revert` | โš™๏ธ ์ด์ „ ์ปค๋ฐ‹ ๋˜๋Œ๋ฆฌ๊ธฐ | + -
-### ๐Ÿ–Š๏ธ **Subject**: ์ œ๋ชฉ -- 50์ž ์ด๋‚ด๋กœ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ -- ๋งˆ์นจํ‘œ(`.`) ๊ธˆ์ง€ -- ๊ณผ๊ฑฐ ์‹œ์ œ X, ๋ช…๋ น์–ด ์‚ฌ์šฉ +### ๐Ÿ”น Data / ML +- **scikit-learn : ๋ฒกํ„ฐํ™”, ์ฐจ์› ์ถ•์†Œ, ์Šค์ผ€์ผ๋ง, ๊ฒฐ์ธก์น˜ ๋ณด์ •** +- **hnswlib : ๊ทผ์ ‘ ํƒ์ƒ‰ (๋ฉ”๋‰ด๋ช… ์œ ์‚ฌ๋„ ๋งค์นญ)** +- **numpy / joblib : ์ˆ˜์น˜ ์—ฐ์‚ฐ ๋ฐ ๋ชจ๋ธ ์ง๋ ฌํ™”** +-**์‹์•ฝ์ฒ˜ ์˜์–‘์„ฑ๋ถ„ํ‘œ ๋ฐ์ดํ„ฐ (Excel/CSV) : ์˜์–‘ ์ •๋ณด ๊ธฐ๋ฐ˜ ํ•™์Šต/์ถ”์ฒœ** + + -
-### ๐Ÿ“ **Body**: ๋ณธ๋ฌธ +--- -- **์„ ํƒ ์‚ฌํ•ญ** -- ์ œ๋ชฉ์—์„œ ์„ค๋ช…ํ•  ์ˆ˜ ์—†๋Š” ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณต -- "๋ฌด์—‡์„"๊ณผ "์™œ"๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ƒ์„ธํžˆ ๊ธฐ์ˆ  -- ํ•œ ์ค„๋‹น 72์ž ์ด๋‚ด๋กœ ์ž‘์„ฑ -- ํ•„์š”์‹œ Markdown ์‚ฌ์šฉ ๊ฐ€๋Šฅ +## ๐Ÿ“‚ Project Structure +```text +๐Ÿ“ฆ menu-ai +โ”œโ”€โ”€ Dockerfile +โ”œโ”€โ”€ main.py # FastAPI ์‹คํ–‰ ์—”ํŠธ๋ฆฌํฌ์ธํŠธ +โ”œโ”€โ”€ requirements.txt +โ”œโ”€โ”€ leftovers +โ”‚ โ”œโ”€โ”€ core # ์„ค์ •, ์—๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ, ๊ณตํ†ต ์‘๋‹ต, ์™ธ๋ถ€ ํด๋ผ์ด์–ธํŠธ +โ”‚ โ””โ”€โ”€ domain +โ”‚ โ”œโ”€โ”€ recommend # ๋ฉ”๋‰ด ์ถ”์ฒœ ๋„๋ฉ”์ธ +โ”‚ โ”‚ โ”œโ”€โ”€ api/ # ์ถ”์ฒœ API +โ”‚ โ”‚ โ”œโ”€โ”€ data/ # ์›๋ณธ ์˜์–‘ ๋ฐ์ดํ„ฐ (์‹์•ฝ์ฒ˜ ์—‘์…€) +โ”‚ โ”‚ โ”œโ”€โ”€ model_store # ํ•™์Šต๋œ ๋ชจ๋ธ ๋ฐ ์ „์ฒ˜๋ฆฌ ์•„ํ‹ฐํŒฉํŠธ +โ”‚ โ”‚ โ”œโ”€โ”€ schemas/ # ์š”์ฒญ/์‘๋‹ต ์Šคํ‚ค๋งˆ +โ”‚ โ”‚ โ””โ”€โ”€ service/ # ์ถ”์ฒœ ๋กœ์ง (๋งค์นญ, ์Šค์ฝ”์–ด๋ง, ์ „์ฒ˜๋ฆฌ, ํ•™์Šต) +โ”‚ โ””โ”€โ”€ tip # ํŒ/๋ ˆ์‹œํ”ผ ๋„๋ฉ”์ธ +โ”‚ โ”œโ”€โ”€ api/ # Tip API +โ”‚ โ”œโ”€โ”€ schemas/ # ์š”์ฒญ/์‘๋‹ต ์Šคํ‚ค๋งˆ +โ”‚ โ””โ”€โ”€ service/ # ํ”„๋กฌํ”„ํŠธ/LLM ํ˜ธ์ถœ +``` --- -
+## ๐Ÿ”ฌ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ & ์•Œ๊ณ ๋ฆฌ์ฆ˜ -## ๐ŸŒฟ Git Flow ๋ธŒ๋žœ์น˜ ์ „๋žต (with `main`) ๐ŸŒฟ +1. **๋ฐ์ดํ„ฐ ๋กœ๋”ฉ** + * ์‹์•ฝ์ฒ˜ ์˜์–‘ ๋ฐ์ดํ„ฐ(`.xlsx`) ๋กœ๋“œ -> ๊ฒฐ์ธก์น˜ ๋ณด์ •(Imputer) -> ์ •๊ทœํ™”(Scaler) -### ๐ŸŒด ๊ธฐ๋ณธ ๋ธŒ๋žœ์น˜ -| ๋ธŒ๋žœ์น˜ | ์—ญํ•  | -|--------|------| -| `main` | ์ตœ์ข… ๋ฐฐํฌ์šฉ ๋ธŒ๋žœ์น˜ (stable) | -| `develop` | ๋‹ค์Œ ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ํ†ตํ•ฉ ๊ฐœ๋ฐœ ๋ธŒ๋žœ์น˜ | +2. **๋ฉ”๋‰ด๋ช… ๋งค์นญ** -
+ * TF-IDF ๋ฒกํ„ฐํ™” -> TruncatedSVD ์ฐจ์› ์ถ•์†Œ -> hnswlib ๊ทผ์ ‘ ํƒ์ƒ‰์œผ๋กœ ์œ ์‚ฌ ๋ฉ”๋‰ด ๊ฒ€์ƒ‰ -### ๐ŸŒฑ **์ž‘์—… ๋ธŒ๋žœ์น˜ ๋„ค์ด๋ฐ ๊ทœ์น™** +3. **์˜์–‘ ํ”ผ์ฒ˜ํ™”** -``` -type/#issue๋ฒˆํ˜ธ (์ž‘์—… ๋‹จ์œ„๋Š” ๊ธฐ๋Šฅ/์ˆ˜์ •/๋ฆฌํŒฉํ† ๋ง ๋“ฑ์œผ๋กœ ๊ตฌ๋ถ„) -``` + * `kcal, protein, fat, carbs, sugar, sodium` ๋“ฑ ์ฃผ์š” ์˜์–‘์†Œ๋ฅผ ๋ฒกํ„ฐํ™” +4. **์Šค์ฝ”์–ด๋ง (Concept Scoring)** -| prefix | ์„ค๋ช… | ์˜ˆ์‹œ | -|--------------|------------------------------|-----------------------------------| -| `feature/` | โœจ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ | `feature/#15` | -| `fix/` | ๐Ÿ› ๋ฒ„๊ทธ ์ˆ˜์ • | `fix/#42` | -| `refactor/` | โ™ป๏ธ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง | `refactor/#23` | -| `chore/` | ๐Ÿ”ง ์„ค์ • ๋ณ€๊ฒฝ, ์žก์ผ | `chore/#25` | -| `perf/` | โšก ์„ฑ๋Šฅ ๊ฐœ์„  | `perf/#94` | -| `hotfix/` | ๐Ÿš‘ ๊ธ‰ํ•œ ์ˆ˜์ • (main์—์„œ ๋ฐ”๋กœ ๋ถ„๊ธฐ) | `hotfix/#102` | -| `test/` | ๐Ÿงช ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€/์ˆ˜์ • | `test/#55` | + * ๋‹ค์ด์–ดํŠธ: ์—ด๋Ÿ‰ยท๋‹น๋ฅ˜ยทํƒ„์ˆ˜ํ™”๋ฌผ ์ œํ•œ + * ์ €์—ผ: ๋‚˜ํŠธ๋ฅจ ์—„๊ฒฉ ์ œํ•œ + * ํ˜ˆ๋‹น: ๋‹น๋ฅ˜ยทํƒ„์ˆ˜ํ™”๋ฌผ ๋™์‹œ ์ œํ•œ + * ์ €ํƒ„๊ณ ์ง€/๋ฒŒํฌ์—…: ๊ธฐ์กด ๋น„์œจ ์œ ์ง€ -
+5. **์ถ”์ฒœ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜** -### ๐Ÿš€ ๋ธŒ๋žœ์น˜ ํ๋ฆ„ ์š”์•ฝ + * ์ ์ˆ˜(0\~100) ๊ธฐ๋ฐ˜ ๋žญํ‚น -> ์ƒ์œ„ N๊ฐœ ๋ฐ˜ํ™˜ + * ์‘๋‹ต ๊ตฌ์กฐ: `isSuccess`, `httpStatus`, `data`, `timeStamp` -```text -1. main โ† ๋ฐฐํฌ -2. develop โ† ํ†ตํ•ฉ ๊ฐœ๋ฐœ (PR ๋Œ€์ƒ) -3. develop์—์„œ feature/fix/... ๋ธŒ๋žœ์น˜ ๋ถ„๊ธฐ -4. ๊ธฐ๋Šฅ ์™„๋ฃŒ ํ›„ develop์œผ๋กœ PR & ๋จธ์ง€ -5. ๋ฐฐํฌ ์‹œ develop โ†’ main ๋จธ์ง€ -6. ๊ธ‰ํ•œ ์ˆ˜์ •์€ hotfix์—์„œ main โ†’ develop ๋ณ‘ํ•ฉ +--- + +## โš™๏ธ ์‹คํ–‰ ๋ฐฉ๋ฒ• + +### 1. ์˜์กด์„ฑ ์„ค์น˜ + +```bash +python3.11 -m venv .venv +source .venv/bin/activate +pip install --no-cache-dir -r requirements.txt ``` ---- +### 2. ํ•™์Šต (๋ชจ๋ธ ์ƒ์„ฑ) + +์ตœ์ดˆ ์‹คํ–‰ ์‹œ, `model_store/`๊ฐ€ ๋น„์–ด ์žˆ๋‹ค๋ฉด ํ•™์Šต ๊ณผ์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. + +```bash +python -m leftovers.domain.recommend.service.train +``` + +โ†’ `nutrition_imputer.joblib`, `nutrition_scaler.joblib`, `concept_model_*.joblib` ๋“ฑ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + +### 3. ์„œ๋ฒ„ ์‹คํ–‰ + +```bash +uvicorn main:app --host 0.0.0.0 --port 8000 +```