
@ai.seoeunjin.com/mlservice/app/titanic/train.csv ์ DF๋ก ์ ํํ๋ ค๊ณ ํด @ai.seoeunjin.com/mlservice/app/titanic/titanic_method.py ์ด ์ฝ๋๋ฅผ ์ฌ๊ธฐ์ pd.read_csv๋ฅผ ๋ฆฌํดํ๋ ๋ฉ์๋๋ก ์์ฑํด์ค
@titanic_method.py (31-43) ์ฌ๊ธฐ์ @titanic_method.py (16-30) ์ด DF์์ Survived ๊ฐ์ ์ ๊ฑฐํ๋ ๊ฐ์ ๋ฆฌํดํ๋ ์ฝ๋๋ฅผ ์์ฑํด์ค
@titanic_method.py (47-59) ์ฌ๊ธฐ์ @titanic_method.py (16-29) ์ด DF์์ Survived์ ๋ผ๋ฒจ๋ง ๋ถ๋ฆฌ์ํจ DF๋ฅผ ๋ง๋ค์ด์ค
@titanic_method.py (46-61) ์ด ๋ฉ์๋ ๋ฐ์ ํผ์ณ๋ฅผ ์ญ์ ํ๋ ๋ฉ์๋์ ๋์ ์ฒดํฌํ๋ ๋ฉ์๋๋ฅผ ์ด๋ฆ๋ง ๋๊ฐ ์์ฑํ์ฌ ๋ด๋ถ๋ pass๋ก ๋ง๋ค์ด์ค
@titanic_method.py (67-69) df์์ ๋์ ๊ฐฏ์๋ฅผ ๋ฆฌํดํ๋ ๋ฉ์๋๋ฅผ ์ฝ๋ฉํด์ค

์ด๋ถ๋ถ ๋ฃ๊ธฐ
๋ฉ์๋ ํ์ผ ์ด๊ฑธ๋ก ๋ฐ๊ฟ
ํ๋ฒ๋ ๋ด์ฉ ๋ฐ๊ฟ
@titanic_method.py (19-23) ์ด๊ฒ์ ๋ฆฌ์คํธ ์ปดํ๋ฆฌํจ์ ์ผ๋ก ๋ณ๊ฒฝํด์ค.
๋ณ๊ฒฝ ์ฌํญ:
์ด์ :
๋ณ๊ฒฝ ํ:
๋ฆฌ์คํธ ์ปดํ๋ฆฌํจ์ ์ผ๋ก ๋ณ๊ฒฝํ์ต๋๋ค. ๋์์ ๋์ผํ๋ฉฐ, *feature ํํ์ ๊ฐ ์์๋ฅผ ๋ฆฌ์คํธ๋ก ๋ณํํฉ๋๋ค.

@docker-compose.yaml @api.seoeunjin.com @ai.seoeunjin.com ์ด ๋๊ฐ์ ์ปจํ ์ด๋๋ง ์์ฑ๋๋๋ก ์ฝ๋๋ฅผ ๋ณ๊ฒฝํด์ค

@ai.seoeunjin.com/mlservice/app/titanic/router.py ์ฌ๊ธฐ์ @ai.seoeunjin.com/mlservice/app/main.py ์ฌ๊ธฐ๋ฅผ ๊ฑฐ์ณ @titanic_service.py (103-114) ์ด ๋ก๊ทธ๊ฐ ๋ณด์ฌ์ฃผ๋ ๋ผ์ฐํฐ๋ฅผ ์์ฑํด์ค ์ด๋ฆ์ /titanic ์ผ๋ก ํด์ค
ํฌ์คํธ๋งจ์์ ๋งํฌ๋ฅผ ๋๋ฅด๋ฉด ํฐ๋ฏธ๋์์ ์์ ๋ด์ฉ์ด ๋จ๊ฒ ํ๊ธฐ!
์๋ฌ ๊ณ์ ์ก์ผ๋ฉด์ ๊ตฌํํ์์
@titanic_method.py (8-26) ์ด๊ฑฐ๋ฅผ Titanic ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ์ฉ ํด๋์ค๋ฅผ ๊ตฌํํ๋ ค๊ณ ํฉ๋๋ค.
์๋ ๋ฉ์๋ ์๊ทธ๋์ฒ์ ์ฃผ์์ ๊ธฐ์ค์ผ๋ก, ๊ฐ ํผ์ฒ์ ์ฒ๋(nominal, ordinal, ratio/interval)์ ๋ง๊ฒ ์ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํด ์ฃผ์ธ์.
์ ์ ์กฐ๊ฑด
- ์ ๋ ฅ df๋ Titanic ๋ฐ์ดํฐ์ ์ pandas DataFrame์ ๋๋ค.
- ์ฃผ์ ์ปฌ๋ผ: ["Pclass", "Fare", "Embarked", "Sex", "Age", "Name"] ๊ฐ ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
- ๋ชจ๋ ๋ฉ์๋๋ df๋ฅผ ์์ ํ ๋ค, ์์ ๋ df ์์ฒด๋ฅผ ๋ฐํํ๋๋ก ๊ตฌํํฉ๋๋ค.
- ๊ฐ๋ฅํ ํ in-place ์ฐ์ฐ์ ์ฌ์ฉํ๋, ์ฒด์ด๋ ๊ฐ๋ฅ์ฑ์ ์ํด df๋ฅผ ๋ช ์์ ์ผ๋ก ๋ฐํํฉ๋๋ค.
- ๊ฒฐ์ธก์น ์ฒ๋ฆฌ ์ ๋ต๋ ๊ฐ๋จํ ํฌํจํด ์ฃผ์ธ์.
์๋๋ ํด๋์ค์ ๊ณจ๊ฒฉ์ ๋๋ค.
```python
import numpy as np
import pandas as pd
from pandas import DataFrame
class TitanicPreprocessor:
def pclass_ordinal(self, df: DataFrame) -> pd.DataFrame:
"""
Pclass: ๊ฐ์ค ๋ฑ๊ธ (1, 2, 3)
- ์์ดํ ์ฒ๋(ordinal)๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- 1๋ฑ์ > 2๋ฑ์ > 3๋ฑ์์ด๋ฏ๋ก, ์์กด๋ฅ ๊ด์ ์์ 1์ด ๊ฐ์ฅ ์ข๊ณ 3์ด ๊ฐ์ฅ ์ ์ข์ต๋๋ค.
๊ตฌํ ์๊ตฌ์ฌํญ:
- df["Pclass"]๊ฐ int ๋๋ category๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค.
- ๋ณ๋์ ์ธ์ฝ๋ฉ ์ปฌ๋ผ๋ช ์ ์ฌ์ฉํ ์ง, ๊ธฐ์กด Pclass๋ฅผ ๋ฎ์ด์ธ์ง๋ ํฉ๋ฆฌ์ ์ผ๋ก ์ ํํ์ธ์.
(์: "Pclass_ordinal" ์ปฌ๋ผ์ ์๋ก ๋ง๋ค๊ณ , ๊ธฐ์กด Pclass๋ ์ ์งํด๋ ์ข์ต๋๋ค.)
"""
pass
def fare_ordinal(self, df: DataFrame) -> pd.DataFrame:
"""
Fare: ์๊ธ (์ฐ์ํ ratio ์ฒ๋์ด์ง๋ง, ์ฌ๊ธฐ์๋ ๊ตฌ๊ฐํํ์ฌ ์์ดํ์ผ๋ก ์ฌ์ฉํ๋ ค๊ณ ํฉ๋๋ค.)
๊ตฌํ ์๊ตฌ์ฌํญ:
- ๊ฒฐ์ธก์น๊ฐ ์์ผ๋ฉด ์ค์๊ฐ์ผ๋ก ์ฑ์๋๋ค.
- Fare๋ฅผ ์ฌ๋ถ์์ ๋๋ ์ ์ ํ ๊ตฌ๊ฐ์ผ๋ก binning ํ์ฌ ordinal ํผ์ฒ๋ฅผ ๋ง๋ญ๋๋ค.
์: pd.qcut(df["Fare"], q=4, labels=[0,1,2,3]) ์ ๊ฐ์ ๋ฐฉ์.
- ์๋ก์ด ์ปฌ๋ผ๋ช ์: "Fare_band" ๋๋ "Fare_ordinal".
- ์๋ Fare ์ปฌ๋ผ์ ๊ทธ๋๋ก ์ ์งํ๊ณ , band ์ปฌ๋ผ๋ง ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํฉ๋๋ค.
"""
pass
def embarked_ordinal(self, df: DataFrame) -> pd.DataFrame:
"""
Embarked: ํ์น ํญ๊ตฌ (C, Q, S)
- ๋ณธ์ง์ ์ผ๋ก๋ nominal(๋ช ๋ชฉ) ์ฒ๋์ ๋๋ค. ๋ค๋ง ๋ฉ์๋ ์ด๋ฆ์ embarked_ordinal๋ก ๋จ๊ธฐ๋,
์ค์ ์ ์ฒ๋ฆฌ๋ ๋ช ๋ชฉํ์ ๋ง๊ฒ one-hot encoding์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ํ๋นํฉ๋๋ค.
๊ตฌํ ์๊ตฌ์ฌํญ:
- ๊ฒฐ์ธก์น๋ ๊ฐ์ฅ ๋ง์ด ๋ฑ์ฅํ๋ ๊ฐ์ผ๋ก ์ฑ์๋๋ค (mode).
- df["Embarked"]๋ฅผ ์ด์ฉํด one-hot ์ปฌ๋ผ์ ์์ฑํฉ๋๋ค.
์: "Embarked_C", "Embarked_Q", "Embarked_S"
- ์๋ "Embarked" ์ปฌ๋ผ์ ๋จ๊ฒจ๋ฌ๋ ๋๊ณ , ์ญ์ ํด๋ ๋ฉ๋๋ค. ๋ ์ค ํฉ๋ฆฌ์ ์ธ ์ชฝ์ผ๋ก ๊ตฌํํ์ธ์.
- pandas.get_dummies๋ฅผ ์ฌ์ฉํด๋ ๋ฉ๋๋ค.
"""
pass
def gender_nominal(self, df: DataFrame) -> pd.DataFrame:
"""
Sex: ์ฑ๋ณ (male, female)
- nominal ์ฒ๋์ ๋๋ค.
๊ตฌํ ์๊ตฌ์ฌํญ:
- df["Sex"]๋ฅผ ์ด์ง ์ธ์ฝ๋ฉ ๋๋ one-hot encoding์ผ๋ก ๋ณํํฉ๋๋ค.
- ์1) "Sex_male" = 1, "Sex_female" = 0
- ์2) get_dummies(df["Sex"], prefix="Sex") ์ฌ์ฉ
- ๊ธฐ์กด "Sex" ์ปฌ๋ผ์ ์ ์งํ ์ง ์ฌ๋ถ๋ ๊ตฌํ์์ ํฉ๋ฆฌ์ ์ผ๋ก ๊ฒฐ์ ํฉ๋๋ค.
- ๋ฐํ ์ df์๋ ํ์ต์ ์ฌ์ฉ ๊ฐ๋ฅํ ์์นํ ์ปฌ๋ผ์ด ํฌํจ๋๋๋ก ํฉ๋๋ค.
"""
pass
def age_ratio(self, df: DataFrame) -> pd.DataFrame:
"""
Age: ๋์ด
- ์๋๋ ratio ์ฒ๋์ง๋ง, ์ฌ๊ธฐ์๋ ๋์ด๋ฅผ ๊ตฌ๊ฐ์ผ๋ก ๋๋ ordinal ํผ์ฒ๋ฅผ ๋ง๋ค๊ณ ์ ํฉ๋๋ค.
- ์ด๋ฏธ bins ๋ฆฌ์คํธ๊ฐ ์๋์ ๊ฐ์ด ์ ๊ณต๋์ด ์์ต๋๋ค.
"""
bins = [-1, 0, 5, 12, 18, 24, 35, 60, np.inf]
"""
๊ตฌํ ์๊ตฌ์ฌํญ:
- Age ๊ฒฐ์ธก์น๋ ์ค์๊ฐ ๋๋ ํ๊ท ์ผ๋ก ์ฑ์๋๋ค (์ค์๊ฐ ์ถ์ฒ).
- ์ bins๋ฅผ ์ฌ์ฉํด์ ๋์ด๋ฅผ ๊ตฌ๊ฐํํฉ๋๋ค.
์: pd.cut(df["Age"], bins=bins, labels=False) ๋ฑ
- ์๋ก์ด ์ปฌ๋ผ๋ช ์: "Age_band" ๋๋ "Age_ordinal".
- ํ์ํ๋ค๋ฉด ๋ฒ์ฃผ(label)์ ์๋ฏธ(์ ์/์ด๋ฆฐ์ด/์ฒญ์๋ /์ฑ์ธ ๋ฑ)๋ฅผ ์ฃผ์์ผ๋ก ๋จ๊ฒจ์ฃผ์ธ์.
- ์๋ณธ Age ์ปฌ๋ผ์ ์ ์งํ๊ณ , band ์ปฌ๋ผ์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํฉ๋๋ค.
"""
pass
def title_nominal(self, df: DataFrame) -> pd.DataFrame:
"""
Title: ๋ช ์นญ (Mr, Mrs, Miss, Master, Dr, etc.)
- Name ์ปฌ๋ผ์์ ์ถ์ถํ ํ์ดํ์ ๋๋ค.
- nominal ์ฒ๋์ ๋๋ค.
๊ตฌํ ์๊ตฌ์ฌํญ:
- df["Name"] ์ปฌ๋ผ์์ ์ ๊ทํํ์ ๋ฑ์ ์จ์ Title์ ์ถ์ถํฉ๋๋ค.
์: df["Name"].str.extract(r',\s*([^\.]+)\.', expand=False)
- ํฌ์ํ ํ์ดํ์ "Rare" ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ต๋๋ค.
์: ["Lady", "Countess", "Capt", "Col", "Don", ...] → "Rare"
- ์ต์ข ์ ์ผ๋ก df["Title"] ์ปฌ๋ผ์ ๋ง๋ค๊ฑฐ๋ ์ ๋ฆฌํ๊ณ ,
์ด๋ฅผ one-hot encoding ๋๋ LabelEncoding ๋ฑ ์์นํ์ผ๋ก ๋ณํํฉ๋๋ค.
- ์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ ๋ชจ๋ธ์ ๋ฐ๋ก ๋ฃ์ ์ ์๋ ํํ๊ฐ ๋๋๋ก ํฉ๋๋ค.
"""
pass
--์ด ์ ๋ต์ ์น์ธํ๋ฏ๋ก ์ปค์๋ ์ด๋๋ก ์์ ํด์ค
@titanic_method.py (88-99) ์ฃผ์๋๋ก ํผ์ฒ ์ด๋ฆ์ Gender ๋ก ๋ณ๊ฒฝํด์ค


docker compose up gateway
docker compose up mlservice
๋ค์ ์์ ํ๊ณ ํ ๋
docker compose build mlservice
docker compose up -d mlservice


์ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฑฐ์ผ? mlservice ์ปจํ ์ด๋์ ๋ก๊ทธ๋ฅผ ๋ณด์ฌ์ค
Error" -Context 5
INFO: 172.18.0.1:43250 - "GET /docs HTTP/1.1" 200 OK
INFO: 172.18.0.1:43250 - "GET /openapi.json HTTP/1.1" 200 OK
> INFO: 172.18.0.1:52272 - "GET /titanic/preprocess HTTP/1.1" 500 Internal
Server Error
INFO: 172.18.0.1:52388 - "GET /docs HTTP/1.1" 200 OK
INFO: 172.18.0.1:52388 - "GET /openapi.json HTTP/1.1" 200 OK
> INFO: 172.18.0.1:52392 - "GET /titanic/preprocess HTTP/1.1" 500 Internal
Server Error
INFO: 172.18.0.1:40128 - "GET /docs HTTP/1.1" 200 OK
INFO: 172.18.0.1:40128 - "GET /openapi.json HTTP/1.1" 200 OK
> INFO: 172.18.0.1:40128 - "GET /titanic/preprocess HTTP/1.1" 500 Internal
Server Error
> INFO: 172.18.0.1:40128 - "GET /titanic/preprocess HTTP/1.1" 500 Internal
Server Error
INFO: 172.18.0.1:51412 - "GET /docs HTTP/1.1" 200 OK
INFO: 172.18.0.1:51412 - "GET /openapi.json HTTP/1.1" 200 OK
INFO: 172.18.0.1:51412 - "GET /docs HTTP/1.1" 200 OK
INFO: 172.18.0.1:51412 - "GET /openapi.json HTTP/1.1" 200 OK
> INFO: 172.18.0.1:48824 - "GET /titanic/preprocess HTTP/1.1" 500 Internal -์ด ๋ก๊ทธ๋ฅผ ๋ณด๊ณ ์๋ฌ๋ฅผ ์์ ํด์ค

@titanic_method.py (91-102) male์ 0, female ์ 1๋ก ๋์ค๋๋ก ๋งคํํด์ค. ํ์ฌ๋ male, female๋ก ๋์ค๊ณ ์์ด.

'Project ESG+AI > [์ผ์ KPMG]ESG ๋ฐ์ดํฐ ํ์ฉ ํ์คํ ๊ฐ๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| 42์ผ์ฐจ. (0) | 2025.12.10 |
|---|---|
| 41์ผ์ฐจ. (1) | 2025.12.09 |
| 39์ผ์ฐจ. (0) | 2025.12.05 |
| 38์ผ์ฐจ. (0) | 2025.12.04 |
| 37์ผ์ฐจ. (0) | 2025.11.28 |