diff --git a/.gitignore b/.gitignore index c8a273e..b86406d 100644 Binary files a/.gitignore and b/.gitignore differ diff --git a/ANALYSIS_REPORT.md b/ANALYSIS_REPORT.md index ddb9001..51b9c74 100644 --- a/ANALYSIS_REPORT.md +++ b/ANALYSIS_REPORT.md @@ -1,49 +1,76 @@ -# ๐ Project Master Sabermetrics ๋ถ์ ์์ง ๋ฆฌํฌํธ +# ๐ ์์คํ ์ด์ ์์ฐ ๊ฐ์น ๋ถ์ ๋ณด๊ณ ์ (Sabermetrics Edition) -## 1. ๊ฐ์ (Vision) -๋ณธ ์์คํ ์ ๋ฐฉ๋ํ ํ๋ก์ ํธ ์ด์ ๋ฐ์ดํฐ(ํ์ผ ์, ํ๋ ๋ก๊ทธ, ์กฐ์ง ์ ๋ณด)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก **AI ๊ธฐ๋ฐ ํ๋ก์ ํธ ๊ฑด๊ฐ๋(P-SOI)**๋ฅผ ์ฐ์ถํฉ๋๋ค. ๋จ์ํ "์ด์์๋๊ฐ"๋ฅผ ๋์ด, "์ค๋ฌด์ ์ผ๋ก ๊ฐ์น ์๊ฒ ๊ด๋ฆฌ๋๊ณ ์๋๊ฐ"๋ฅผ ์ ๋ฐ ์ง๋จํ๋ ๊ฒ์ด ๋ชฉ์ ์ ๋๋ค. +๋ณธ ๋ณด๊ณ ์๋ ์ผ๊ตฌ์ ํต๊ณ ๋ถ์ ๊ธฐ๋ฒ์ธ **์ธ์ด๋ฒ๋ฉํธ๋ฆญ์ค(Sabermetrics)**๋ฅผ ํ๋ก์ ํธ ๊ด๋ฆฌ ์์คํ ์ ์ด์ํ์ฌ, ๋จ์ ํ๋๋ ์ธก์ ์ ๋์ด **'์ค์ง์ ์์ฐ ๊ฐ์น'**์ **'๋ฏธ๋ ์ด์ ์ํ'**์ ์ ๋ฐ ๋ถ์ํ ๊ฒฐ๊ณผ์ ๋๋ค. --- -## 2. P-SOI ์ฐ์ถ ๋ก์ง (The Formula) +## 1. ํต์ฌ ๋ถ์ ์งํ ์ ์ (Core Metrics) -### 2.1 ๊ธฐ์ด ๋ชจ๋ธ: ์ง์ ๊ฐ์ (Exponential Decay) -ํ๋ก์ ํธ ์ ๋ณด์ ๊ฐ์น๋ ๊ด๋ฆฌ ํ๋์ด ๋ฉ์ถ ์์ ๋ถํฐ ์๊ฐ์ด ํ๋ฅผ์๋ก ๊ธ๊ฒฉํ ํ๋ฝํฉ๋๋ค. -- **์์**: $SOI = 100 \times e^{-\lambda t}$ -- **์๋ฏธ**: 14์ผ ๋ฐฉ์น ์ ๊ฐ์น๊ฐ ์ฝ 50% ์์ค๋๋ ํ์ฅ ํ์ค์ ๋ฐ์ํฉ๋๋ค. +### 1.1 ์ด์ ํ๋ ฅ ์ง์ (AVI, Activity Vitality Index) +ํ๋ก์ ํธ๊ฐ ํ์ฌ ์ผ๋ง๋ '์ด์์ ์จ ์ฌ๊ณ ์๋๊ฐ'๋ฅผ ๋ํ๋ด๋ ์์กด ์ง์์ ๋๋ค. -### 2.2 ๊ณ ๋ํ 1: AAS (AI-Hazard Adaptive SOI) -ํ๋ก์ ํธ์ ์ค์๋์ ์ฃผ๋ณ ํ๊ฒฝ์ ๋ฐ๋ผ ํ๋ฝ ๊ณก์ ์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๋์ ์ผ๋ก ์กฐ์ ํฉ๋๋ค. -- **์์ฐ ๊ท๋ชจ ์ํฅ**: ํ์ผ ์๊ฐ ๋ง์์๋ก ๊ด๋ฆฌ ๋ถ์ฌ ๋ฆฌ์คํฌ๊ฐ ํฌ๋ฏ๋ก AI๊ฐ ํ๋ฝ ์๋๋ฅผ ๊ฐ์์ํต๋๋ค. -- **์กฐ์ง ์ํ ์ ์ผ**: ์์ ๋ถ์๋ ๋ด๋น์์ ์ ์ฒด SOI๊ฐ ๋ฎ์ ๊ฒฝ์ฐ, ์์คํ ์ ๋ถ๊ดด ๋ฆฌ์คํฌ ๊ฐ์ค์น๋ฅผ ๋ถ์ฌํฉ๋๋ค. +* **์ฐ์ถ ๊ณต์**: $AVI = exp(-\lambda \times days) \times Quality \times 100$ +* **ํต์ฌ ๋ฐ์ดํฐ**: + * **์ ์ฒด ์ผ์(days)**: ๋ง์ง๋ง ์ ์๋ฏธํ ํ์ผ ์ ๋ฐ์ดํธ ์ดํ ๊ฒฝ๊ณผ ์๊ฐ. + * **๊ฐ์ ๊ณ์($\lambda$)**: ์์ฐ ๊ท๋ชจ(ํ์ผ ์)๊ฐ ํด์๋ก, ์์ ๋ถ์์ ๋ฐฉ์น์จ์ด ๋์์๋ก ์ปค์ง๋ฉฐ ์ ์๋ฅผ ๋ ๋น ๋ฅด๊ฒ ํ๋ฝ์ํต๋๋ค. + * **ํ๋ ํ์ง(Quality)**: ๋จ์ ์์คํ ๋ก๊ทธ(๋จ์ ์ ์, ์ค์ ๋ณ๊ฒฝ)๋ ๋ฎ๊ฒ ํ๊ฐํ๊ณ , ์ค์ง์ ์ธ ํ์ผ ์ฆ๋ถ ํ๋์ ๊ฐ์ ์ ๋ถ์ฌํฉ๋๋ค. +* **์๋ฏธ**: 100%์ ๊ฐ๊น์ธ์๋ก ์ค์๊ฐ ๊ฐ๋ ์ํ์ด๋ฉฐ, 0%์ ๊ฐ๊น์ธ์๋ก ๋ฐ์ดํฐ ๋ ธํํ๊ฐ ์๋ฃ๋ '์ฌ๋ง' ์ํ๋ฅผ ๋ปํฉ๋๋ค. -### 2.3 ๊ณ ๋ํ 2: ECV (Existence-Conditioned Vitality) -'๋น ๊ป๋ฐ๊ธฐ' ํ๋์ ๊ฑธ๋ฌ๋ด๋ ์กด์ฌ๋ก ์ ํจ๋ํฐ์ ๋๋ค. -- **์ ๋ น ํ๋ก์ ํธ**: ํ์ผ ์๊ฐ 0๊ฐ์ธ ๊ฒฝ์ฐ, ์ต๊ทผ ๋ก๊ทธ์ ๊ด๊ณ์์ด SOI ์ ์๋ฅผ **5% ๋ฏธ๋ง**์ผ๋ก ๊ฐ์ ๊ณ ์ ํฉ๋๋ค. -- **์ ๋ขฐ ๋ณด์ **: ํ์ผ 10๊ฐ ๋ฏธ๋ง์ ์๊ท๋ชจ ํ๋ก์ ํธ๋ ํ๋ ์ ๋ขฐ๋๋ฅผ 40% ์์ค์ผ๋ก ์ ํํฉ๋๋ค. +### 1.2 ์์ฐ ๊ฐ์น ๊ธฐ์ฌ๋ (VCI, Value Contribution Index) +์์คํ ์ ์ฒด์ ์ด์ ํ์ค ๋๋น, ํด๋น ํ๋ก์ ํธ๊ฐ ๊ธฐ์ฌํ๊ณ ์๋ ๊ฐ์น์ ์๋์ ํ์ค์ ์ธก์ ํฉ๋๋ค. -### 2.4 ๊ณ ๋ํ 3: ๋ก๊ทธ ํ์ง ๋ฐ ์ค๋ฌด ํฌ์ ๋ถ์ -- **Log Quality**: ๋ก๊ทธ ํ ์คํธ๋ฅผ ๋ถ์ํ์ฌ [์ค๋ฌด ํ๋(1.0), ๊ด๋ฆฌ ํ๋(0.7), ํ์ ํ๋(0.4)] ๊ฐ์ค์น๋ฅผ ๋ถ์ฌํฉ๋๋ค. -- **Work Effort**: ์ต๊ทผ 30๊ฐ ํ์คํ ๋ฆฌ ์ค ์ค์ **ํ์ผ ์ฆ๊ฐ**์ด ๋ฐ์ํ ๋ ์ ๋น์จ์ ๊ณ์ฐํ์ฌ ์ค์ง ๊ณต์ ํฌ์ ๋ฅ ์ ์ฐ์ถํฉ๋๋ค. +* **์ฐ์ถ ๊ณต์**: $VCI = (AVI - 70.0) \times (\frac{Files}{200} + 0.5)$ +* **ํต์ฌ ๋ก์ง**: + * **๊ฑด๊ฐ ๊ธฐ์ค์ (70.0%)**: ์์คํ ์์ฐ ๊ฐ์น๋ฅผ ์ ์งํ๊ธฐ ์ํ ์ต์ ๋ง์ง๋ ธ์ (Replacement Level)์ ๋๋ค. + * **๊ท๋ชจ ๊ฐ์ค์น**: ํ์ผ ์๊ฐ ๋ง์ ๋ํ ํ๋ก์ ํธ์ผ์๋ก ๋์ผํ ๋ฐฉ์น ์ํฉ์์ ์์คํ ์ ์ฃผ๋ ์ถฉ๊ฒฉ(์์๊ฐ)์ด ๊ธฐํ๊ธ์์ ์ผ๋ก ์ปค์ง๋๋ค. +* **์๋ฏธ**: ์์(+)๋ ๊ฐ์น ์ฐฝ์ถ, ์์(-)๋ ์์คํ ๊ธฐํ๋น์ฉ์ ๊ฐ์๋จน๋ '๊ฐ์น ํ๊ดด' ์ํ์์ ๋ํ๋ ๋๋ค. + +### 1.3 ์ ๋ฌด ์ง์ค๋ (Job Focus) +๋จ์ ๊ด๋ฆฌ ํ์๋ฅผ ์ ์ธํ๊ณ , ์ค์ ์ฑ๊ณผ๋ฌผ(ํ์ผ)์ ์์ฐํ๋ ๋ฐ ์ผ๋ง๋ ๋ชฐ์ ํ๋์ง๋ฅผ ํ๋ณํฉ๋๋ค. + +* **์ฐ์ถ ๊ณต์**: $Job Focus = \frac{\text{์ต๊ทผ 30ํ ์ค ์ค์ง ํ์ผ ๋ณ๋ ๋ฐ์ ํ์}}{\text{์ ์ฒด ๋ฐ์ดํฐ ์์ง ํ์}} \times 100$ +* **์๋ฏธ**: ๋ก๊ทธ๋ง ๋จ๊ธฐ๋ '๋ณด์ฌ์ฃผ๊ธฐ์ ํ๋'์ ํํฐ๋งํ์ฌ ์ด์์ ์ง์ ์ฑ์ ํ์ธํฉ๋๋ค. --- -## 3. ์ ๋ต์ ๋ถ์ ๋๊ตฌ (Visualization) +## 2. ๋ฑ๊ธ ์ฒด๊ณ ๋ฐ ๊ด๋ฆฌ ๊ฐ์ด๋ (Grade System) -### 3.1 ํ๋ก์ ํธ SWOT ๋งคํธ๋ฆญ์ค -X์ถ(์์ฐ ๊ท๋ชจ)๊ณผ Y์ถ(ํ๋์ฑ)์ ๊ฒฐํฉํ์ฌ 4๊ฐ์ง ๊ตญ๋ฉด์ผ๋ก ํ๋ก์ ํธ๋ฅผ ์ง๋จํฉ๋๋ค. -1. **ํต์ฌ ์ฐ๋ (Strategic)**: ๋๊ท๋ชจ ํต์ฌ ์์ฐ์ด๋ฉฐ ํ๋ฐํ ๊ด๋ฆฌ ์ค. -2. **ํ๋ ์ํธ (Agile)**: ๊ท๋ชจ๋ ์์ผ๋ ๋งค์ฐ ํ๋ ฅ์ ์ผ๋ก ์ ๋ฐ์ดํธ ์ค. -3. **๋ฐฉ์น/์๊ท๋ชจ**: ์ค์๋๊ฐ ๋ฎ๊ณ ๋ฐฉ์น๋ ์ํ. -4. **๊ด๋ฆฌ ์ฌ๊ฐ์ง๋ (Critical Risk)**: **์์ฐ ๊ท๋ชจ๋ ํฌ๋ ์ฅ๊ธฐ ๋ฐฉ์น๋จ (์ต์ฐ์ ๊ด๋ฆฌ ๋์)** +### 2.1 VCI ๋ฑ๊ธ (ํ๋ก์ ํธ ์์) +| ๋ฑ๊ธ (Grade) | ์ ์ ๊ธฐ์ค | ์ด์ ์๋ฏธ ๋ฐ ๊ด๋ฆฌ ์ ๋ต | +| :--- | :--- | :--- | +| **Masterpiece** | +10.0 ์ด์ | **ํต์ฌ ์์ฐ (MVP)**: ์์คํ ๊ฐ์น๋ฅผ ๊ฒฌ์ธํ๋ ์ต์ฐ๋ ํ๋ก์ ํธ | +| **Blue Chip** | +2.0 ~ +10.0 | **์ฐ๋ ์์ฐ (์ฃผ์ )**: ๊พธ์คํ ํ๋ ฅ์ผ๋ก ๊ฐ์น๋ฅผ ์ฐฝ์ถํ๋ ํต์ฌ๊ตฐ | +| **Steady** | -2.0 ~ +2.0 | **ํ์ ์ ์ง (๋ณด๊ฒฐ)**: ํ์ค ์์ค์ ์ด์์ ์ ์ง ์ค์ธ ์์ ๊ตฐ | +| **Underperform** | -10.0 ~ -2.0 | **์ ์ฑ๊ณผ (๋ง์ด๋)**: ๊ท๋ชจ ๋๋น ํ๋ ฅ์ด ๋ถ์กฑํ์ฌ ๋ฆฌ์์ค ํฌ์ ํ์ | +| **Liability** | -10.0 ์ดํ | **๊ฐ์น ํ๊ดด (๋ฐฉ์ถ)**: ์์คํ ๊ฐ์น๋ฅผ ํผ์ ์ค์ธ ์ข๋น ํ๋ก์ ํธ. ํ์ ๊ฒํ ์๊ธ | -### 3.2 AI ์ง๋จ ์์ฝ๋์ธ ๋ฆฌํฌํธ -์ฌ์ฉ์๊ฐ ์ง์ ์ฐ์ถ ๊ฒฐ๊ณผ์ ๋ฉ๋ํ ์ ์๋๋ก, ๊ฐ๋ณ ํ๋ก์ ํธ ํ ํด๋ฆญ ์ **4๋จ๊ณ AI ์ถ๋ก ๊ณผ์ **์ ์ค์๊ฐ ๋ฆฌํฌํธ๋ก ์ ๊ณตํฉ๋๋ค. +### 2.2 ์ํ ์๋ณด (AI Forecast) +์ต๊ทผ ํ๋์ **๊ฐ์๋(Acceleration)**์ **๊ด์ฑ(Momentum)**์ AI๊ฐ ๋ถ์ํ 14์ผ ๋ค ์ ๋ง์ ๋๋ค. + +* **์ฑ์ฅ ๊ฐ์ (Bullish)**: ํ๋ ์๋์ง๊ฐ ์ฆ๊ฐ ์ถ์ธ์ด๋ฉฐ ๊ฐ์น๊ฐ ์ค๋ฅผ ์ ๋ง. +* **์์ ์ ์ง (Neutral)**: ํ์ฌ์ ์์ ์ ์ธ ์ด์ ๋ฆฌ๋ฌ์ ์ง์ํ ์ ๋ง. +* **ํ๋ ฅ ์ ํ (Bearish)**: ์ ์ฒด ์งํ ํฌ์ฐฉ. ๋จ๊ธฐ ๋ด ๊ฐ๋๋ฅ ํ๋ฝ ์์. +* **์ค๋จ ์๊ธฐ (Warning)**: ๊ธ๊ฒฉํ ํ๋ ์ ํ๋ก ์ธํ ์์ฐ ์๋ฉธ ์ํ ๋ ธ์ถ. --- -## 4. ํฅํ ๋ฅ๋ฌ๋ ๋ก๋๋งต (Evolution) -๋ฐ์ดํฐ๊ฐ ๋์ ๋จ์ ๋ฐ๋ผ ๋ค์๊ณผ ๊ฐ์ ์๊ฐ ํ์ตํ ์์ง์ผ๋ก ์งํํฉ๋๋ค. -- **LSTM ๊ธฐ๋ฐ ๋ฆฌ๋ฌ ํ์ต**: ๊ฐ ํ๋ก์ ํธ์ ๊ณ ์ ํ ์ ๋ฐ์ดํธ ์ฃผ๊ธฐ์ ํจํด(Life Rhythm)์ ์ธ์ฝ๋ฉํ์ฌ ๋ง์ถคํ ์๋ณด ์ํ. -- **NLP ์๋ฒ ๋ฉ**: ๋จ์ ํค์๋๋ฅผ ๋์ด ๋ก๊ทธ ํ ์คํธ์ ๋งฅ๋ฝ์ ์๋ฏธ๋ฅผ ๋ฅ๋ฌ๋์ด ์ค์ค๋ก ํ์ตํ์ฌ ๊ฐ์ค์น ์๋ ์ฐ์ . -- **๋ณ๋ชฉ ์์ธก AI**: ํน์ ๋ด๋น์๋ ๋ถ์์ ์ ๋ฌด ๊ณผ๋ถํ ํจํด์ ํ์ตํ์ฌ ์ง๋จ ๋ฐฉ์น ์ํ์ ์ ์ ์ ์ผ๋ก ์๋ณด. +## 3. ๋ฐ์ดํฐ ๋ถ์ ํ๋ก์ธ์ค (Analysis Process) + +1. **๋ฐ์ดํฐ ์์ง**: `projects_history` ํ ์ด๋ธ๋ก๋ถํฐ ์ผ๋ณ ํ์ผ ์ ๋ฐ ๋ก๊ทธ ํ ์คํธ๋ฅผ ์ถ์ถํฉ๋๋ค. +2. **ํผ์ฒ ์ถ์ถ**: + * **Velocity**: ํ์ผ ์์ ๋ณํ ์๋ ๊ณ์ฐ. + * **Acceleration**: ํ๋์ ๊ฐ์/๊ฐ์ ์ฌ๋ถ ํ๋ณ. + * **Stagnation**: ๋ง์ง๋ง ํ๋ ์ดํ์ ๊ณต๋ฐฑ ๊ธฐ๊ฐ ์ธก์ . +3. **AI ์๋ฎฌ๋ ์ด์ **: ์ถ์ถ๋ ํผ์ฒ๋ฅผ AAS(AI ์ํ ์ ์ํ ๋ชจ๋ธ)์ ์ ๋ ฅํ์ฌ ๊ฐ๋ณ ํ๋ก์ ํธ๋ง์ **'์ํ ๊ณก์ '**์ ์์ฑํฉ๋๋ค. +4. **์ต์ข ํ์ **: AVI์ VCI๋ฅผ ๊ฒฐํฉํ์ฌ ๋ฆฌ๋๋ณด๋์ ๋ฑ๊ธ๊ณผ ๊ด๋ฆฌ ๊ฐ์ด๋๋ผ์ธ์ ์ก์ถํฉ๋๋ค. + +--- + +## 4. ๊ด๋ฆฌ์ ์ ์ธ (Action Plan) + +* **VCI ์์ ํ๋ก์ ํธ ์ง์ค ๊ด๋ฆฌ**: ๋จ์ ํ๋๋์ด ์๋ VCI๊ฐ ๋ฎ์ ๋ํ ํ๋ก์ ํธ๋ถํฐ ์ฐ์ ์ ์ผ๋ก ์ธ๋ ฅ์ ๋ฐฐ์นํ๊ฑฐ๋ ์ด์ ์ ์ฑ ์ ์ฌ์ ๊ฒํด์ผ ํฉ๋๋ค. +* **AI Forecast ํ์ฉ**: 'ํ๋ ฅ ์ ํ' ์๋ณด๊ฐ ๋ฌ ํ๋ก์ ํธ๋ ์ค์ AVI๊ฐ ๊ธ๋ฝํ๊ธฐ ์ ์ ์ ์ ์ธ ์กฐ์น(์ ๋ฌด ๋ ๋ ค, ํ์ผ ํํํ)๋ฅผ ์ทจํ ์ ์์ต๋๋ค. +* **ํ์ผ ์์ ํ๋ ฅ์ ๊ท ํ**: ํ์ผ ์๊ฐ ๋ง์๋ฐ ํ๋ ฅ(AVI)์ด ๋ฎ์ ๊ฒฝ์ฐ, ์์คํ ์ ์ฒด์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ํด์น ์ ์์ผ๋ฏ๋ก ๋ฐ์ดํฐ ํด๋ ์ง์ด๋ ์์นด์ด๋น์ ๊ถ๊ณ ํฉ๋๋ค. + +--- +*๋ณธ ๋ถ์ ์์ง์ Project Master Sabermetrics ์๊ณ ๋ฆฌ์ฆ์ ์ํด ์๋ ์์ฑ๋์์ต๋๋ค.* diff --git a/__pycache__/analysis_service.cpython-312.pyc b/__pycache__/analysis_service.cpython-312.pyc index 1a1a5ba..df75f8a 100644 Binary files a/__pycache__/analysis_service.cpython-312.pyc and b/__pycache__/analysis_service.cpython-312.pyc differ diff --git a/__pycache__/prediction_service.cpython-312.pyc b/__pycache__/prediction_service.cpython-312.pyc index b100aa7..d80a302 100644 Binary files a/__pycache__/prediction_service.cpython-312.pyc and b/__pycache__/prediction_service.cpython-312.pyc differ diff --git a/__pycache__/sql_queries.cpython-312.pyc b/__pycache__/sql_queries.cpython-312.pyc index 75c1741..b7d27ec 100644 Binary files a/__pycache__/sql_queries.cpython-312.pyc and b/__pycache__/sql_queries.cpython-312.pyc differ diff --git a/analysis_service.py b/analysis_service.py index 4c57d26..30ba1ef 100644 --- a/analysis_service.py +++ b/analysis_service.py @@ -170,11 +170,17 @@ class AnalysisService: total_soi += soi_score + # [์ต์ข ์ธ์ด๋ฒ๋ฉํธ๋ฆญ์ค ๋ณด์ : P-WAR+ (Adjusted Score)] + # ์ ๋ ๊ธฐ์ค์ (Replacement Level): 70.0% (์ด ์ดํ๋ ์์ฐ ๊ฐ์น ํ๊ดด๋ก ๊ฐ์ฃผ) + REPLACEMENT_LEVEL = 70.0 + asset_weight = (file_count / 200.0) + 0.5 # ํ์ผ 100๊ฐ๋น 0.5๋ฐฐ ๊ฐ์ค (์ต์ 0.5๋ฐฐ) + p_war_score = (soi_score - REPLACEMENT_LEVEL) * asset_weight + results.append({ "project_nm": p['short_nm'] or p['project_nm'], "file_count": file_count, "days_stagnant": days_stagnant, - "risk_count": 0, + "risk_count": round(p_war_score, 2), # P-WAR+ ์ ๋ ๊ธฐ์ฌ๋ ์ ์ (ํ๊ท ์ ํจ์ ๊ทน๋ณต์ฉ) "p_war": round(soi_score, 1), "predicted_soi": predicted_soi, "is_auto_delete": is_auto_delete, diff --git a/js/analysis.js b/js/analysis.js index f076781..f5ad012 100644 --- a/js/analysis.js +++ b/js/analysis.js @@ -1,6 +1,6 @@ /** * Project Master Analysis JS - * P-WAR (Project Performance Above Replacement) ๋ถ์ ์์ง + * AVI (Activity Vitality Index) & VCI (Value Contribution Index) ๋ถ์ ์์ง */ // Chart.js ํ๋ฌ๊ทธ์ธ ์ ์ญ ๋ฑ๋ก @@ -9,40 +9,49 @@ if (typeof ChartDataLabels !== 'undefined') { } document.addEventListener('DOMContentLoaded', () => { - console.log("Analysis engine initialized..."); - loadPWarData(); + console.log("Business Analysis Engine initialized..."); + loadProjectAnalysisData(); }); -async function loadPWarData() { +async function loadProjectAnalysisData() { try { const response = await fetch('/api/analysis/p-war'); const data = await response.json(); if (data.error) throw new Error(data.error); - renderPWarLeaderboard(data); - renderSOICharts(data); + renderVitalityLeaderboard(data); + renderValueCharts(data); if (data.length > 0 && data[0].avg_info) { const avg = data[0].avg_info; const infoEl = document.getElementById('avg-system-info'); - if (infoEl) infoEl.textContent = `* ์์คํ ์ข ํฉ ๊ฑด๊ฐ๋: ${avg.avg_risk}% (0.0%์ ๊ฐ๊น์ธ์๋ก ๋ฐฉ์น ์ฌ๊ฐ)`; + if (infoEl) infoEl.textContent = `* ์์คํ ์ข ํฉ ์์ฐ ๊ฑด์ ๋: ${avg.avg_risk}% (์ด์ ํ์ค 70.0% ๋๋น)`; } } catch (e) { console.error("๋ถ์ ๋ฐ์ดํฐ ๋ก๋ฉ ์คํจ:", e); } } -function getStatusInfo(soi, isAutoDelete) { - if (isAutoDelete || soi < 10) return { label: '์ฌ๋ง', class: 'badge-system', key: 'dead' }; - if (soi < 30) return { label: '์ํ', class: 'badge-danger', key: 'danger' }; - if (soi < 70) return { label: '์ฃผ์', class: 'badge-warning', key: 'warning' }; - return { label: '์ ์', class: 'badge-active', key: 'active' }; +function getStatusInfo(avi, isAutoDelete) { + if (isAutoDelete || avi < 10) return { label: '์ค๋จ/๋ฐฉ์น', class: 'badge-system', key: 'dead' }; + if (avi < 30) return { label: '์ํ ๋ ธ์ถ', class: 'badge-danger', key: 'danger' }; + if (avi < 70) return { label: '๊ด๋ฆฌ ์ฃผ์', class: 'badge-warning', key: 'warning' }; + return { label: '์ ์ ์ด์', class: 'badge-active', key: 'active' }; } -function renderSOICharts(data) { +// VCI ๋ฑ๊ธ ํ์ ๋ก์ง (Sabermetrics WAR ๋ฑ๊ธ ๊ธฐ์ค ์์ฉ) +function getVciGrade(vci) { + if (vci >= 10) return { label: 'Masterpiece', class: 'grade-mvp', desc: '์์คํ ๊ฐ์น๋ฅผ ๊ฒฌ์ธํ๋ ํต์ฌ ์์ฐ (MVP๊ธ)' }; + if (vci >= 2) return { label: 'Blue Chip', class: 'grade-allstar', desc: '๊พธ์คํ ํ๋ ฅ์ ์ฐ๋ ์์ฐ (์ฃผ์ ๊ธ)' }; + if (vci >= -2) return { label: 'Steady', class: 'grade-starter', desc: 'ํ์ค ์์ค์ ํ์ ์ ์ง (๋ณด๊ฒฐ๊ธ)' }; + if (vci >= -10) return { label: 'Underperform', class: 'grade-bench', desc: '์ด์ ๋ฏธ๋น๋ก ์ธํ ๊ฐ์น ํ๋ฝ (๋ง์ด๋๊ธ)' }; + return { label: 'Liability', class: 'grade-out', desc: '๊ฐ์น๋ฅผ ํผ์ ์ค์ธ ๋ฐฉ์น ์์ฐ (๋ฐฉ์ถ๊ธ)' }; +} + +function renderValueCharts(data) { if (!data || data.length === 0) return; - // 1. ์ํ ๋ถํฌ (Doughnut) + // 1. ์ด์ ํ๋ ฅ ๋ถํฌ (Doughnut) try { const stats = { active: [], warning: [], danger: [], dead: [] }; data.forEach(p => { @@ -56,7 +65,7 @@ function renderSOICharts(data) { window.myStatusChart = new Chart(statusCtx, { type: 'doughnut', data: { - labels: ['์ ์', '์ฃผ์', '์ํ', '์ฌ๋ง'], + labels: ['์ ์ ์ด์', '๊ด๋ฆฌ ์ฃผ์', '์ํ ๋ ธ์ถ', '์ค๋จ/๋ฐฉ์น'], datasets: [{ data: [stats.active.length, stats.warning.length, stats.danger.length, stats.dead.length], backgroundColor: ['#1E5149', '#22c55e', '#f59e0b', '#ef4444'], @@ -75,53 +84,40 @@ function renderSOICharts(data) { onClick: (e, elements) => { if (elements.length > 0) { const idx = elements[0].index; - openProjectListModal(['์ ์', '์ฃผ์', '์ํ', '์ฌ๋ง'][idx], stats[['active', 'warning', 'danger', 'dead'][idx]]); + openProjectListModal(['์ ์ ์ด์', '๊ด๋ฆฌ ์ฃผ์', '์ํ ๋ ธ์ถ', '์ค๋จ/๋ฐฉ์น'][idx], stats[['active', 'warning', 'danger', 'dead'][idx]]); } } } }); } catch (err) { console.error("๋๋ ์ฐจํธ ์๋ฌ:", err); } - // 2. ํ๋ก์ ํธ SWOT ๋งคํธ๋ฆญ์ค (Scatter) + // 2. ์ ๋ต์ ์์ฐ ๋งคํธ๋ฆญ์ค (Scatter) try { - const scatterData = data.map(p => ({ - x: Math.min(500, p.file_count), - y: p.p_war, - label: p.project_nm - })); + const sortedByAVI = [...data].sort((a, b) => b.p_war - a.p_war); + const top5Ids = sortedByAVI.slice(0, 5).map(p => p.project_nm); + const bottom5Ids = sortedByAVI.slice(-5).map(p => p.project_nm); + const largeProjects = data.filter(p => p.file_count > 450).map(p => p.project_nm); + + const vipProjectNames = new Set([...top5Ids, ...bottom5Ids, ...largeProjects]); + + const scatterData = data.map(p => { + const vci = p.risk_count || 0; + const absVci = Math.abs(vci); + return { + x: Math.min(500, p.file_count), + y: p.p_war, + label: p.project_nm, + isVip: vipProjectNames.has(p.project_nm), + vci: vci, + radius: Math.max(5, Math.min(25, 5 + (absVci / 10))) + }; + }); const vitalityCtx = document.getElementById('forecastChart').getContext('2d'); if (window.myVitalityChart) window.myVitalityChart.destroy(); - // ํ๋ฌ๊ทธ์ธ ํตํฉ (Duplicate Key ๋ฐฉ์ง) - const chartPlugins = []; - if (typeof ChartDataLabels !== 'undefined') chartPlugins.push(ChartDataLabels); - - chartPlugins.push({ - id: 'quadrants', - beforeDraw: (chart) => { - const { ctx, chartArea: { left, top, right, bottom }, scales: { x, y } } = chart; - const midX = x.getPixelForValue(250); - const midY = y.getPixelForValue(50); - ctx.save(); - ctx.fillStyle = 'rgba(34, 197, 94, 0.03)'; ctx.fillRect(left, top, midX - left, midY - top); - ctx.fillStyle = 'rgba(30, 81, 73, 0.03)'; ctx.fillRect(midX, top, right - midX, midY - top); - ctx.fillStyle = 'rgba(148, 163, 184, 0.03)'; ctx.fillRect(left, midY, midX - left, bottom - midY); - ctx.fillStyle = 'rgba(239, 68, 68, 0.05)'; ctx.fillRect(midX, midY, right - midX, bottom - midY); - ctx.lineWidth = 2; ctx.strokeStyle = 'rgba(0,0,0,0.1)'; ctx.beginPath(); - ctx.moveTo(midX, top); ctx.lineTo(midX, bottom); ctx.moveTo(left, midY); ctx.lineTo(right, midY); ctx.stroke(); - ctx.font = 'bold 12px Pretendard'; ctx.textAlign = 'center'; ctx.fillStyle = 'rgba(0,0,0,0.2)'; - ctx.fillText('ํ๋ ์ํธ', (left + midX) / 2, (top + midY) / 2); - ctx.fillText('ํต์ฌ ์ฐ๋', (midX + right) / 2, (top + midY) / 2); - ctx.fillText('๋ฐฉ์น/์๊ท๋ชจ', (left + midX) / 2, (midY + bottom) / 2); - ctx.fillStyle = 'rgba(239, 68, 68, 0.4)'; ctx.fillText('๊ด๋ฆฌ ์ฌ๊ฐ์ง๋', (midX + right) / 2, (midY + bottom) / 2); - ctx.restore(); - } - }); - window.myVitalityChart = new Chart(vitalityCtx, { type: 'scatter', - plugins: chartPlugins, data: { datasets: [{ data: scatterData, @@ -133,45 +129,73 @@ function renderSOICharts(data) { if (p.x < 250 && p.y < 50) return '#94a3b8'; return '#ef4444'; }, - pointRadius: 6, - hoverRadius: 10 + pointRadius: (ctx) => ctx.raw ? ctx.raw.radius : 5, + hoverRadius: (ctx) => (ctx.raw ? ctx.raw.radius : 5) + 3 }] }, options: { responsive: true, maintainAspectRatio: false, - layout: { padding: { top: 30, right: 40, left: 10, bottom: 10 } }, + layout: { padding: { top: 30, right: 45, left: 10, bottom: 10 } }, scales: { x: { type: 'linear', min: 0, max: 500, - title: { display: true, text: '์์ฐ ๊ท๋ชจ (ํ์ผ ์)', font: { size: 11, weight: '700' } }, + title: { display: true, text: 'ํ์ผ ์ (Files)', font: { size: 11, weight: '700' } }, grid: { display: false }, ticks: { stepSize: 125, callback: (v) => v >= 500 ? '500+' : v } }, y: { min: 0, max: 100, - title: { display: true, text: 'ํ๋์ฑ (SOI %)', font: { size: 11, weight: '700' } }, + title: { display: true, text: '์ด์ ํ๋ ฅ (AVI %)', font: { size: 11, weight: '700' } }, grid: { display: false } } }, plugins: { legend: { display: false }, datalabels: { - align: 'top', offset: 5, font: { size: 10, weight: '700' }, color: '#475569', - formatter: (v) => v.label, - display: (ctx) => ctx.raw.x > 100 || ctx.raw.y < 30, + backgroundColor: 'rgba(255, 255, 255, 0.8)', + borderRadius: 4, padding: 4, + align: (ctx) => (ctx.raw && ctx.raw.y > 80 ? 'bottom' : 'top'), + offset: (ctx) => (ctx.raw ? ctx.raw.radius : 5) + 2, + font: { size: 10, weight: '800' }, + color: '#1e293b', + formatter: (v) => v ? v.label : '', + display: (ctx) => ctx.raw && ctx.raw.isVip, clip: false }, tooltip: { - callbacks: { label: (ctx) => ` [${ctx.raw.label}] SOI: ${ctx.raw.y.toFixed(1)}% | ํ์ผ: ${ctx.raw.x >= 500 ? '500+' : ctx.raw.x}๊ฐ` } + callbacks: { + label: (ctx) => ` [${ctx.raw.label}] ํ๋ ฅ(AVI): ${ctx.raw.y.toFixed(1)}% | ๊ฐ์น ๊ธฐ์ฌ(VCI): ${ctx.raw.vci.toFixed(1)}` + } } } - } + }, + plugins: [{ + id: 'quadrants', + beforeDraw: (chart) => { + const { ctx, chartArea: { left, top, right, bottom }, scales: { x, y } } = chart; + const midX = x.getPixelForValue(250); + const midY = y.getPixelForValue(50); + ctx.save(); + ctx.fillStyle = 'rgba(34, 197, 94, 0.03)'; ctx.fillRect(left, top, midX - left, midY - top); + ctx.fillStyle = 'rgba(30, 81, 73, 0.03)'; ctx.fillRect(midX, top, right - midX, midY - top); + ctx.fillStyle = 'rgba(148, 163, 184, 0.03)'; ctx.fillRect(left, midY, midX - left, bottom - midY); + ctx.fillStyle = 'rgba(239, 68, 68, 0.05)'; ctx.fillRect(midX, midY, right - midX, bottom - midY); + ctx.lineWidth = 2; ctx.strokeStyle = 'rgba(0,0,0,0.1)'; ctx.beginPath(); + ctx.moveTo(midX, top); ctx.lineTo(midX, bottom); ctx.moveTo(left, midY); ctx.lineTo(right, midY); ctx.stroke(); + ctx.font = 'bold 12px Pretendard'; ctx.textAlign = 'center'; ctx.fillStyle = 'rgba(0,0,0,0.2)'; + ctx.fillText('ํ๋ ฅ ์ํธ', (left + midX) / 2, (top + midY) / 2); + ctx.fillText('ํต์ฌ ๊ฐ์น', (midX + right) / 2, (top + midY) / 2); + ctx.fillText('์ ์ฒด/์๊ท๋ชจ', (left + midX) / 2, (midY + bottom) / 2); + ctx.fillStyle = 'rgba(239, 68, 68, 0.4)'; ctx.fillText('์์ฐ ์์ค ์ํ', (midX + right) / 2, (midY + bottom) / 2); + ctx.restore(); + } + }] }); - } catch (err) { console.error("SWOT ์ฐจํธ ์๋ฌ:", err); } + } catch (err) { console.error("์ ๋ต ๋งคํธ๋ฆญ์ค ์๋ฌ:", err); } } -function renderPWarLeaderboard(data) { +function renderVitalityLeaderboard(data) { const container = document.getElementById('p-war-table-container'); if (!container) return; const sortedData = [...data].sort((a, b) => a.p_war - b.p_war); @@ -181,29 +205,34 @@ function renderPWarLeaderboard(data) {
| ํ๋ก์ ํธ๋ช | +ํ๋ก์ ํธ๋ช | ํ์ผ ์ | -๋ฐฉ์น์ผ | +์ ์ฒด ์ผ์ | ์ํ ํ์ | -ํ์ฌ SOI | -์ค๋ฌด ํฌ์ | -AI ์๋ณด (14d) | +๊ฐ์น ๊ธฐ์ฌ (VCI) | +ํ๋ ฅ ์ง์ (AVI) | +์ ๋ฌด ์ง์ค๋ | +์ํ ์๋ณด (14d) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ${p.project_nm} | ${p.file_count.toLocaleString()}๊ฐ | ${p.days_stagnant}์ผ | -${status.label} | -${p.p_war.toFixed(1)}% | +${status.label === '์ฌ๋ง' ? '์ค๋จ' : status.label} | ++ ${vci > 0 ? '+' : ''}${vci.toFixed(1)} + | +${avi.toFixed(1)}% |
${p.work_effort}%
@@ -215,52 +244,60 @@ function renderPWarLeaderboard(data) {
${p.predicted_soi !== null ? p.predicted_soi.toFixed(1) + '%' : '-'} |
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + |
- โ๏ธ AI ์ํ ์ ์ํ ๋ชจ๋ธ(AAS) ์ฐ์ถ ์๋ฎฌ๋ ์ด์
-
-
- ๐ ์ค์ง ์
๋ฌด ํ์ฑํ ๋ถ์ (Work Vitality)
- ํฌ์
๋ฅ ${p.work_effort}%
+
โ๏ธ AI ์์ฐ ๊ฑด์ ์ฑ ๋ถ์ ์๋ฎฌ๋ ์ด์
(AAS Metrics)
+
+
+
+
+
+
+ ๐ ์ค์ง ์
๋ฌด ์ง์ค๋ Analysis
+ ${p.work_effort}%
+
+
+ ์ต๊ทผ ์์ง ๋ก๊ทธ ์ค ์ค์ง์ ์์ฐ ์ฆ๋ถ์ด ํฌ์ฐฉ๋ ๋ฐ๋์
๋๋ค.
+
+
-
-
+
+ VCI GRADE
+ ${grade.label}
+ ${grade.desc}
์ต๊ทผ 30ํ ์ค ์ค์ ํ์ผ ๋ณ๋์ด ํฌ์ฐฉ๋ ๋ ์ ๋น์จ์
๋๋ค. ํ์ฌ ${p.work_effort >= 70 ? '๋งค์ฐ ํ๋ฐ' : p.work_effort <= 30 ? '์ ์ฒด' : '๊ฐํ์ '} ์ํ์
๋๋ค.
1
-
๋์ ์ํ ๊ณ์(ฮป)
+ ๋์ ๊ฐ์ ๊ณ์(ฮป) ์ฐ์ถ
+ ์์ฐ ๊ท๋ชจ ๋ฐ ์กฐ์ง ์ํ์ ํฉ์ฐํ์ฌ ๊ฐ๋ณ ํ๋ ฅ ๊ณก์ ์ ์์ฑํฉ๋๋ค.
ฮป = ${p.ai_lambda.toFixed(4)}
2
-
ํ๋ ํ์ง (Quality)
- Factor = ${(p.log_quality * 100).toFixed(0)}%
+ ํ๋ ์ง์ ์ฑ ๊ฒ์ฆ
+ Factor = ${(p.log_quality * 100).toFixed(0)}%
3
-
๋ฐฉ์น ์๊ฐ ๊ฐ์
- Result = ${((p.p_war / (p.file_count === 0 ? 0.05 : p.file_count < 10 ? 0.4 : 1) / p.log_quality) || 0).toFixed(1)}%
+ ๊ฐ๋ ๋ณด์กด์จ (AVI)
+ Result = ${avi.toFixed(1)}%
4
-
์กด์ฌ ์ง์ ์ฑ (ECV)
- Factor = ${ecvText}
+ ๊ฐ์น ๊ธฐ์ฌ ์ํฅ๋ ฅ (VCI)
+ VCI = ${vci.toFixed(1)}
-
* ๊ณต์: AAS_Score ร Quality_Factor ร ECV_Factor
- ์ต์ข
P-SOI: ${p.p_war.toFixed(1)}%
- |
@@ -275,12 +312,19 @@ function toggleProjectDetail(rowId) {
const container = document.querySelector('.table-scroll-wrapper');
const mainRow = document.querySelector(`tr[onclick*="toggleProjectDetail('${rowId}')"]`);
const detailRow = document.getElementById(`detail-${rowId}`);
+
if (detailRow && container) {
if (!detailRow.classList.contains('active')) {
document.querySelectorAll('.detail-row').forEach(row => row.classList.remove('active'));
detailRow.classList.add('active');
- setTimeout(() => { container.scrollTo({ top: mainRow.offsetTop - (container.querySelector('thead').offsetHeight || 40), behavior: 'smooth' }); }, 50);
- } else detailRow.classList.remove('active');
+ setTimeout(() => {
+ const headerH = container.querySelector('thead').offsetHeight || 45;
+ const targetScrollTop = mainRow.offsetTop - headerH;
+ container.scrollTo({ top: targetScrollTop, behavior: 'smooth' });
+ }, 100);
+ } else {
+ detailRow.classList.remove('active');
+ }
}
}
@@ -288,14 +332,15 @@ function openProjectListModal(label, projects) {
const modal = document.getElementById('analysisModal');
const title = document.getElementById('modalTitle');
const body = document.getElementById('modalBody');
- title.innerText = `[${label}] ํ๋ก์ ํธ ๋ชฉ๋ก (${projects.length}๊ฑด)`;
- body.innerHTML = projects.length === 0 ? '|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ํ๋ก์ ํธ๋ช | ๊ด๋ฆฌ์ | ๋ฐฉ์น์ผ | ํ์ฌ SOI | |
|---|---|---|---|---|
| ${p.project_nm} | ${p.master || '-'} | ${p.days_stagnant}์ผ | ${p.p_war.toFixed(1)}% | |
| ํ๋ก์ ํธ๋ช | ๋ถ์ | ๊ด๋ฆฌ์ | ์ ์ฒด์ผ | ํ๋ ฅ(AVI) |
| ${p.project_nm} | ${p.dept || '-'} | ${p.master || '-'} | ${p.days_stagnant}์ผ | ${p.p_war.toFixed(1)}% |
๋ฐฉ์น์ผ์์ ๋ฐ๋ฅธ ๊ฐ์น ํ๋ฝ ๋ชจ๋ธ์ ๋๋ค.
'; + + if (type === 'avi') { + title.innerText = '์ด์ ํ๋ ฅ ์ง์ (AVI) ๋ฑ๊ธ ๊ฐ์ด๋'; + body.innerHTML = ` +์์ฐ์ ๊ฐ๋ ์ํ์ ์์กด์จ์ ๋ํ๋ด๋ ์งํ์ ๋๋ค.
+| ์ง์ (AVI) | ๋ฑ๊ธ | ์ด์ ์ํ |
|---|---|---|
| 90%โ | Live | ์ค์๊ฐ ์ฑ๊ณผ๋ฌผ์ด ๋์ถ๋๋ ์ต์๊ธ ๊ฐ๋ |
| 70~90% | Stable | ์ฃผ๊ธฐ์ ์ ๋ฐ์ดํธ๊ฐ ์ด๋ค์ง๋ ํ์ค ์์ |
| 30~70% | Idle | ๊ด๋ฆฌ๊ฐ ํ์ํ ์ ํด/์ ์ฒด ์ํ |
| 10~30% | Risk | ์์ฐ ๊ฐ์น ์๋ฉธ ์ง์ ์ ์ํ ์ํ |
| 10%โ | Frozen | ์ด์์ด ์ค๋จ๋ ๋๊ฒฐ/๋ฐฉ์น ์ํ |
์ด์ ํ์ค(AVI 70%) ๋๋น ์์ฐ ๊ฐ์น ๊ธฐ์ฌ๋์ ๋ฐ๋ฅธ ํ๋ก์ ํธ ์์ ๋ถ๋ฅ์ ๋๋ค.
+| ์ ์ (VCI) | ๋ฑ๊ธ | ์ด์ ์๋ฏธ |
|---|---|---|
| +10.0โ | Masterpiece | ์์คํ ๊ฐ์น๋ฅผ ๊ฒฌ์ธํ๋ ํต์ฌ ์์ฐ (MVP๊ธ) |
| +2.0 ~ +10.0 | Blue Chip | ๊พธ์คํ ํ๋ ฅ์ ์ฐ๋ ์์ฐ (์ฃผ์ ๊ธ) |
| -2.0 ~ +2.0 | Steady | ํ์ค ์์ค์ ํ์ ์ ์ง (๋ณด๊ฒฐ๊ธ) |
| -10.0 ~ -2.0 | Underperform | ์ด์ ๋ฏธ๋น๋ก ์ธํ ๊ฐ์น ํ๋ฝ (๋ง์ด๋๊ธ) |
| -10.0โ | Liability | ๊ฐ์น๋ฅผ ํผ์ ์ค์ธ ๋ฐฉ์น ์์ฐ (๋ฐฉ์ถ๊ธ) |
๋จ์ ๊ด๋ฆฌ ๋ก๊ทธ๋ฅผ ์ ์ธํ ์ค์ง์ ์ธ ์ฐ์ถ๋ฌผ ๋ณํ์ ๋ฐ๋์ ๋๋ค.
+| ๋น์จ (%) | ๋ฑ๊ธ | ํ๋ ์ฑ๊ฒฉ |
|---|---|---|
| 80%โ | Intensive | ์ฑ๊ณผ๋ฌผ ์์ฃผ์ ๊ณ ๋ฐ๋ ์ง์ค ์์ |
| 50~80% | Active | ์ฑ๊ณผ์ ๊ด๋ฆฌ๊ฐ ๊ท ํ ์กํ ์ํํ ์คํ |
| 20~50% | Maintenance | ์ค์ /ํ์ ๋ฑ ๋จ์ ๊ด๋ฆฌ ์ค์ฌ์ ์์ |
| 20%โ | Surface | ์ค์ฒด์ ๋ณํ๊ฐ ์ ์ ํ์์ ๋ก๊ทธ ์ค์ฌ |
ํ๋ ๊ฐ์๋ ๋ฐ ๋ฐ๋๋ฅผ ๋ถ์ํ์ฌ 14์ผ ๋ค์ ์ํ๋ฅผ ์๋ณดํฉ๋๋ค.
'; + title.innerText = '์ํ ์๋ณด (AI Forecast) ๋ถ์ ๊ฐ์ด๋'; + body.innerHTML = ` +๋จ์ํ ํ์ฌ ์ ์ ๋์ด์ด ์๋, ์ต๊ทผ ํ๋์ ๊ฐ์๋(Acceleration)์ ๋ณํ ํจํด์ AI๊ฐ ๋ถ์ํ์ฌ ๋ฏธ๋์ ํ๋ ฅ ์ง์(AVI)๋ฅผ ์๋ณดํฉ๋๋ค.
+| ๋ถ์ ๊ฒฐ๊ณผ | ์ํ ๋ฑ๊ธ | ๊ด๋ฆฌ ๊ฐ์ด๋๋ผ์ธ |
|---|---|---|
| AVI ์์นโ | ์ฑ์ฅ ๊ฐ์ | ํ๋ ๋ชจ๋ฉํ ์ด ์์น ์ค์ธ ์ฐ์ ์์ฐ |
| AVI ์ ์ง | ์์ ์ ์ง | ํ์ฌ์ ๋ฆฌ๋ฌ์ ์ ์งํ๋ ํ์ค ์ด์ ์ํ |
| AVI ํ๋ฝโ | ํ๋ ฅ ์ ํ | ์ ์ฒด ์งํ ํฌ์ฐฉ, ๊ด๋ฆฌ ๋ฆฌ์์ค ํฌ์ ๊ฒํ |
| AVI 10%โ | ์ค๋จ ์๊ธฐ | ๋จ๊ธฐ ๋ด ์์ ๋ฐฉ์น ๋ฐ ๊ฐ์น ์๋ฉธ ์ํ |
์์ง๋ ํ๋ ๋ก๊ทธ ๋ฐ ์์ฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ํต๊ณ์ ์ฑ๋ฅ ์งํ (Beta)
+์์ง๋ ํ๋ ๋ก๊ทธ ๋ฐ ์์ฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ํต๊ณ์ ํ๋ ฅ ์งํ (Beta)
์ต๊ทผ 9ํ์ฐจ ์๊ณ์ด์ Velocity ๋ฐ ๊ฐ์๋ ๋ถ์
+ ๋ถ์ ๋ชจ๋ธ +์ต๊ทผ 9ํ์ฐจ ์๊ณ์ด์ Velocity ๋ฐ ๋ณํ์จ ๋ถ์
ํ๋ ์ '์ ํ ์ถ์ธ', ์ ์ฒด ์ '์ง์ ๊ฐ์' ๊ฐ์ค์น ์ ์ฉ
+ ๊ฐ์ค์น ๋ก์ง +ํ๋ ์ '์ ํ ์ ์ง', ์ ์ฒด ์ '์ง์ ๊ฐ์' ๋์ ์ ์ฉ
์์ฐ ๊ท๋ชจ๋ฅผ ๊ฐ์งํ์ฌ, ๋ํ ํ๋ก์ ํธ ๋ฐฉ์น ์ ๋ฐ์ดํฐ ๊ฐ์น ํ๋ฝ ์๋๋ฅผ ๊ฐ์(Acceleration)์ํต๋๋ค.
+๊ท๋ชจ๋ฅผ ๊ฐ์งํ์ฌ, ๋ํ ํ๋ก์ ํธ ์ ์ฒด ์ ๋ฐ์ดํฐ ๊ฐ์น ํ๋ฝ ์๋๋ฅผ ๊ฐ์(Acceleration)์ํต๋๋ค.
์์ ๋ถ์์ ์ ๋ฐ์ ์ธ ํ๋์ฑ์ด ๋ฎ์ ๊ฒฝ์ฐ, ๊ฐ๋ณ ์ํ ์ง์๋ฅผ ์ํฅ ์กฐ์ ํ์ฌ ์์คํ ์ ๋ถ๊ดด๋ฅผ ์๋ณดํฉ๋๋ค.
+์์ ๋ถ์์ ์ ๋ฐ์ ์ธ ํ๋ ฅ์ด ๋ฎ์ ๊ฒฝ์ฐ, ๊ฐ๋ณ ์ํ ์ง์๋ฅผ ์ํฅ ์กฐ์ ํ์ฌ ์์คํ ์ ๋ถ๊ดด๋ฅผ ์๋ณดํฉ๋๋ค.
ํ๋ก์ ํธ๋ง๋ค ๊ฐ๋ณํ๋ ์ํ ๊ณก์ ์ ์์ฑํ์ฌ ํ์ฅ์ ๊ฐ์ฅ ๋ฐ์ฐฉ๋ ๊ฐ์น ๋ณด์กด์จ์ ์ ๊ณตํฉ๋๋ค.
+ํ๋ก์ ํธ๋ง๋ค ๊ฐ๋ณํ๋ ๊ฐ์ ๊ณก์ ์ ์์ฑํ์ฌ ํ์ฅ์ ๊ฐ์ฅ ๋ฐ์ฐฉ๋ ๋ณด์กด์จ์ ์ ๊ณตํฉ๋๋ค.
์ด์์ ๊ด๋ฆฌ ์ํ(100%) ๋๋น ํ๋ ๋ณด์กด์จ ๋ฐ ๋ฏธ๋ ์์ธก ๋ฆฌ๋๋ณด๋
+์ด์ ํ์ค(AVI 70%) ๋๋น ํ์ผ ๋ณด์กด์จ ๋ฐ ๋ฏธ๋ ๊ฐ์น ๊ธฐ์ฌ ๋ฆฌ๋๋ณด๋