[플레이데이터 SK네트웍스 Family AI 캠프 21기] 11월 1주차 회고
이번주에 드디어 머신러닝이 시작했다. 먼저 기존 프로그램 방식과 머신러닝의 프로그램 방식의 차이점에대해서 이해하고 실제 데이터 분석 실습까지 진행했다.
🤖 AI, 머신러닝, 딥러닝의 차이
AI (인공지능) : 딥러닝 & 머신러닝 기술로 사용자들에게 서비스를 제공하는 형태.
Machine Learning (머신러닝) : 대부분 정형 데이터. 학습 데이터를 통해 규칙(함수)를 만들어내 결과를 예측하거나 분류하는 기술 분야.
Deep Larning (딥러닝) : 인공신경망 알고리즘 기반으로 머신러닝의 한 분야. 비정형 데이터에서 뛰어난 성능을 나타냄.
딥러닝 < 머신러닝 < 인공지능의 형태인데 요즘은 딥러닝을 워낙 광범위하게 많이 사용하고 있어 딥러닝 / 머신러닝을 따로 구분하지 않고 말하기도 한다고 한다.
🆚 기존 프로그래밍 방식 vs 머신러닝 방식
기존 프로그래밍 방식 : 데이터 / 프로그램 (함수, 알고리즘) -> 컴퓨터 -> 결과 (Output)
머신러닝 프로그래밍 방식 : 데이터 / 결과 (Output) -> 컴퓨터 -> 프로그램 (알고리즘, 모델, 규칙)
기존에는 개발자들이 함수와 알고리즘을 작성해서 결과를 추출해내게 하는 형태였지만,
머신러닝은 데이터와 결과를 넣어서 컴퓨터가 프로그램을 추출해내게 하는 형태이다.
$y = f(x)$ 에서 입력변수 = 학습데이터, 출력변수 = 결과를 알려주고 $f$ = 함수는 컴퓨터가 알아내는 형태.
🧩 머신러닝 개발 절차
1️⃣ 비즈니스 이해 (Business Understanding)
2️⃣ 데이터 수집 (Data Understanding)
3️⃣ 데이터 전처리 (Data Preparation) : 모델의 성능을 높이기 위해서 제일 중요한 단계!! ✨✨
-> Garbage in, garbage out : 쓰레기 값을 넣으면 결과도 쓸모 없다.
-> 정형데이터의 경우, 머신러닝에서 사람이 데이터 전처리를 했는데
비정형데이터의 경우, 딥러닝에서 모델이 직접 데이터 전처리까지 진행한다.
4️⃣ 모델 선정 및 학습 (Modeling)
-> 모델 학습 : Hyper-Parameter Tuning을 통해서 모델 성능을 높일 수 있다. (한계 있음 -> 전처리가 중요함.)
5️⃣ 모델 평가 (Evaluation) : 평가 결과에 따라 위 프로세스 반복
6️⃣ 서비스 적용 (Deployment)
🎯 머신러닝 | 지도학습(Supervised Learning) 정리
- 머신러닝의 대표적인 학습 방식
- 지도학습의 두 가지 유형 : 분류(Classification), 회귀(Regression)
데이터 타입이 범주형이나 수치형이냐에따라 분류와 회귀로 나눠진다.
분류(Classification) 유형은 yes or no로 대답할 수 있는 뚜렷한 범주형 데이터 예측 방식으로 스팸메일 여부, 질병 진단, 품종 분류 등 맞춘 개수가 명확하다.
-> 예측값에대한 정답률에따라 모델 성능을 평가한다.
회귀 (Regresssion) 유형은 연속적인 수치 데이터를 예측 방식으로 집값 예측, 온도 예측, 매출 예측 등 수치형 데이터로 명확한 정답값을 맞추기에는 한계가 있다.
-> 예측값과 정답값의 오차 범위를 가지고 모델 성능을 평가한다.
📚 데이터셋 Hold out 분류 - Train Dataset / Validation Dataset / Test Dataset
하나의 모델을 만들기 위해서 3가지 입력과 출력을 가지고 있는 Dataset이 필요하다.
Train Dataset (학습 데이터셋)은 모델을 학습시키는 데이터로 70~80% 비율로 가져가야하고,
Validation Dataset (검증 데이터셋)은 학습 중 모델의 하이퍼파라미터를 조정할 때 성능 검증용으로 사용하는 데이터로 10~20% 비율로 가져가야한다. 데이터가 충분히 많을때 사용해야하고 데이터가 없을때는 K-Fold 교차검증으로 대체한다.
Test Dataset (평가 데이터셋)은 최종 성능 평가때 사용하는 데이터로 한번도 사용하지 않은 데이터로 해야하기때문에 딱 한번만 사용한다. 비율은 10~20%로 진행한다.
from sklearn.model_selection import train_test_split
## train_test_split(): 2개 dataset 으로 분리
X_train, X_test, y_train, y_test = train_test_split(
X, # input
y, # output
test_size=0.2, # testset의 비율. default: 0.25
stratify=y,
random_state=10
)
train_dataset = (X_train.shape, y_train.shape) # (input, output)
test_dataset = (X_test.shape, y_test.shape) # 20% 비율을 가진 test dataset
# 150개의 데이터 -> 120개 + 30개
# train_dataset = ((120, 4), (120,))
# test_dataset = ((30, 4), (30,))
train / validate / test 데이터 3개의 dataset으로 분리한다고 하면 train_test_split을 2번 호출하면 된다.
# train dataset -> train / validate 분리
X_train, X_val, y_train, y_val = train_test_split(
X_train_val, y_train_val,
test_size=0.25, # train_val의 25% → 전체의 0.25 * 0.8 = 20% (val)
stratify=y_train_val,
random_state=10
)
train_dataset = (X_train, y_train)
val_dataset = (X_val, y_val)
# 결과 Train : 60%, Validation : 20%, Test : 20%
여기서 stratify와 random_state은 어떤 파라미터❓
stratify는 분류 유형에서만 사용되는 파라미터로,
강아지 vs 고양이를 나누는 데이터라고 하면 y의 강아지/고양이 비율이 6:4라고 하자. 그럼 훈련데이터와 평가데이터에서도 강아지/고양이 비율이 6:4로 동일하게 분할시키기위한 파라미터이다.
즉, stratify = y 는 y의 클래스 비율이 유지된 채로 데이터를 나누기 위한 파라미터이다.
random_state는 데이터셋을 나누기 전에 shuffle을 수행할지 말지에대한 파라미터이다.
정렬되어있는 데이터의 경우, 위에서부터 20개 평가데이터, 밑에 80개 훈련데이터로 나눠버리면 정렬된 값 하나에 치중된 모델을 만들게 된다. 그걸 방지하기 위한 파라미터. 데이터를 섞은 후 2:8로 나누겠다는 파라미터이다. 숫자는 특별한 의미 없지만 숫자가 같으면 섞인 데이터의 결과가 똑같이 나오게 된다. random seed랑 비슷한 개념으로 생각하면 됨.
max_depth 같은 하이퍼파라미터를 가지고 비교해야할 때 random_state를 같은 값으로 고정해서 max_depth만 달라졌을때 성능 평가를 비교하도록 한다.
Hold out 분류 방식의 단점은 데이터가 충분하지 않을때는 이상치에대한 영향을 많이 받게 되고, 다양한 패턴이 없기때문에 훈련데이터의 과적합이 이루어져 새로운 데이터에대한 예측 성능이 떨어지게 된다. Hold out 분류 방식은 다양한 패턴이 존재하고 많은 데이터가 존재할 때 사용하기 적합하다.
데이터가 충분하지 않을때 사용하는 데이터셋 분류 방식은 K-Fold Cross Validation이 있다.
📚 데이터셋 K-Fold Cross Validation 분류 - K개의 데이터셋
K-겹 교차검증은 데이터셋을 K개로 분류한다. K개 중 하나를 검증 데이터셋이라고 두고 K-1개는 훈련 데이터셋으로 사용한다. K개가 모두 한번씩 검증 데이터셋으로 설정해 K번 반복하여 모델을 학습시키고 K개의 평가지표들의 평균값을 가지고 모델 성능을 평가한다.
KFold는 회귀 유형의 Dataset 분리할 때 사용하고, StratifiedKFold는 y 클래스 비율을 유지하기때문에 분류 유형의 Dataset 분리할 때 사용한다.
from sklearn.model_selection import KFold
from sklearn.tree import DecisionTreeRegressor # XXXXXRegressor (회귀)
from sklearn.metrics import mean_squared_error # 오차제곱 평균.(회귀 평가지표중 하나.)
import numpy as np
mse_list = []
# 객체 생성 - k개 지정
kfold = KFold(n_splits=5) # K=5 - 8:2 , K=4 - 7.5:2.5
# K개 fold로 나눴을 때 train 데이터와 test 데이터의 index를 반환하는 generator를 생성
gen = kfold.split(X)
# gen = tuple(trainset index: ndarray, testset index: ndarray)
for train_idx, test_idx in gen:
X_train, y_train = X[train_idx], y[train_idx]
X_test, y_test = X[test_idx], y[test_idx]
# 모델 생성
model = DecisionTreeRegressor(max_depth=2, random_state=0)
# 학습
model.fit(X_train, y_train)
# 검증
pred = model.predict(X_test)
# mean_squared_error: 회귀 유형의 대표적인 평가지표 = np.mean((정답 - 예측값)**2)
mse = mean_squared_error(y_test, pred)
mse_list.append(mse)
# K개의 평가지표들의 평균값
np.mean(mse_list)
s_kfold = StratifiedKFold(n_splits=4)
s_gen = s_kfold.split(X, y)
# fold별 검증 결과를 저장할 리스트
val_result = []
for train_idx, test_idx in s_gen:
X_train, y_train = X[train_idx], y[train_idx]
X_test, y_test = X[test_idx], y[test_idx]
# 모델 생성
model = DecisionTreeClassifier(max_depth=2, random_state=0)
# 학습
model.fit(X_train, y_train)
# 검증
pred = model.predict(X_test)
# accuracy_score : 분류 유형의 대표적인 평가지표
score = accuracy_score(y_test, pred)
val_result.append(score)
np.mean(val_result)
Cross Validation을 해주는 cross_val_score
from sklearn.model_selection import cross_val_score
from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor(max_depth=2, random_state=0)
val_results = cross_val_score(
estimator=model, # 교차검증할 모델
X=X_train, # X-input, features
y=y_train, # y-output, target, label
scoring="neg_mean_squared_error", # 평가지표함수-문자열, 함수객체
cv=4, # fold 수
)
cross_val_score 함수는 K-Fold 교차검증을 자동으로 수행해주는 템플릿 함수이다.
estimator 파라미터에 모델이 분류용인지 회귀용인지에따라서 KFold, StratifiedKFold로 판단한다. 모델 클래스가 Classifier로 끝나면 분류 유형, Regressor로 끝나면 회귀 유형이다.
cross_val_score는 함수 객체나 함수 string를 넣을 수 있다. 함수 종류와 string은 아래 링크에서 확인 가능하다.
cross_validate 함수도 존재하는데,,
해당 함수에는 scoring 파라미터에 list도 넣어 여러 평가지표의 결과를 확인할 수 있다.
3.4. Metrics and scoring: quantifying the quality of predictions
Which scoring function should I use?: Before we take a closer look into the details of the many scores and evaluation metrics, we want to give some guidance, inspired by statistical decision theory...
scikit-learn.org
✨ 데이터 전처리
데이터 전처리는 매우 중요하고 설명해야할 양이 많아서 따로 정리했다.
모델 성능을 높이기 위한 데이터 전처리 ✨
데이터 전처리는 데이터들을 분석하고 머신러닝 모델에 적합한 형태로 데이터셋을 변환하거나 조정하는 과정을 말한다. 데이터도 다양하고 좋아야하지만 동일한 데이터로 데이터 전처리를 어
itstudentstudy.tistory.com
📝 모델 선정 및 학습 (Modeling)
분류(Classification) : 범주형 데이터 모델
대표적인 분류 모델들,,
- 결정트리 : sklearn.tree.DecisionTreeClassifier
- 랜덤포레스트 : sklearn.ensemble.RandomForestClassifier
- K-최근접 이웃(KNN) : sklearn.neighbors.KNeighborsClassifier
max_depth : 하이퍼파라미터
max_depth 값에따라서 성능평가 결과가 달라진다. 현재 max_depth = 10일때가 가장 성능 좋음.
from sklearn.tree import DecisionTreeClassifier
max_depth_list = [3, 4, 5, 6, 7, 8, 9, 10]
result_train = list() # []
result_val = list()
for max_depth in max_depth_list:
# 1. 모델 생성
model = DecisionTreeClassifier(max_depth=max_depth, random_state=0)
# 2. trainset으로 학습
model.fit(X_train, y_train)
# 3. 검증
## 추론
pred_train = model.predict(X_train)
pred_val = model.predict(X_val)
## 검증
result_train.append(accuracy_score(y_train, pred_train))
result_val.append(accuracy_score(y_val, pred_val))
for i in range(len(max_depth_list)):
max_depth = max_depth_list[i]
print("max_depth ", max_depth, " => ", result_train[i], " ", result_val[i])

회귀 (Regression) : 수치형 데이터 모델
- 선형회귀 : sklearn.linear_model.LinearRegression
- K-최근접 이웃(KNN) : sklearn.neighbors.KNeighborsRegressor
📊 모델 평가
모델 성능 평가는 검증 단계와 최종 성능 평가에서 진행한다.
🧩 혼동행렬(Confusion Matrix) -> 분류 유형
| 실제값 ↓ / 예측값 → | Positive (참이라고 예측) | Negative (거짓이라고 예측) |
| Positive (참) | ✅ TP (True Positive) 실제 참을 참이라고 맞춘 경우 |
❌ FN (False Negative) 실제 참을 거짓으로 틀린 경우 |
| Negative (거짓) | ❌ FP (False Positive) 실제 거짓을 참으로 틀린 경우 |
✅ TN (True Negative) 실제 거짓을 거짓이라고 맞춘 경우 |
얼마나 많이 맞췄는가? (Accuracy)를 떠나서 어떤 종류의 오류를 얼마나 냈는지를 알려주는 행렬이 혼동행렬이다.
| 상황 | 중앙지표 | |
| 전체 정확도를 보고 싶을 때 | Accuracy | $\frac {TP+TN} {TP+TN+FP+FN}$ |
| “Positive로 예측한 게 실제로 맞는가?” | Precision | $\frac {TP} {TP+FP}$ |
| “실제 Positive를 얼마나 잘 찾았는가?” | Recall (Sensitivity) | $\frac {TP} {TP+FN}$ |
| “실제 Negative를 얼마나 잘 구별했는가?” | Specificity | $\frac {TN} {TN+FP}$ |
| “Precision과 Recall 균형을 보고 싶을 때” | F1 Score | $2 * \frac {Recall * Precision} {Recall + Precision}$ |
모델의 목적에 따라 중요한 지표가 다르다..
- Recall (재현율/Sensitivity) 중심
- 질병 진단 모델
- FN(False Negative)를 낮추는데 중점을 둔다.
- Precision (정밀도) 중심
- 스팸 메일 필터
- FP(False Positive)를 낮추는데 중점을 둔다.
- Accuracy (정확도) 중심
- F1 Score
- 균형 잡힌 판단
from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score, classification_report
pred_train = model.predict(X_train)
pred_test = model.predict(X_test)
pred_train, pred_test
# 정확도
print(accuracy_score(y_train, pred_train), accuracy_score(y_test, pred_test))
# 재현율
print(recall_score(y_train, pred_train), recall_score(y_test, pred_test))
# 정밀도
print(precision_score(y_train, pred_train), precision_score(y_test, pred_test))
# f1 score
print(f1_score(y_train, pred_train), f1_score(y_test, pred_test))
print("===")
print(classification_report(y_test, pred_test))

🧩 회귀 유형 평가지표
정답과 예측값이 얼마나 차이나는가로 모델을 평가한다.
- MAE (Mean Absolute Error) : 예측 오차의 평균 절댓값
- MSE (Mean Squared Error) : 예측 오차의 제곱 평균
- RMSE (Root Mean Squared Error) : 제곱근 취한 오차
- $R^2$ (결정계수) : 모델 설명력
- $R^2 = 1 - \frac {\sum({y_i - \hat{y_i})^2}} {\sum({y_i - \bar{y})^2}}$
- $y_i$ : 실제값, $\hat{y_i}$ : 모델 예측값, $\bar{y}$ : 실제값들의 평균
💬 PMI 회고
Plus
머신러닝을 배우게 되면서 모르는 내용들이 너무 많아져서 복습할 내용이 많았다. 실제 데이터를 가지고 학습을 시켜보고 결과를 확인할 수 있어서 좋았다.
Minus
모르는 모델 종류들이 너무 많다. 깊게 공부하는 시간이 필요할 듯 하다.
분류와 회귀 데이터에따라 다르게 학습시키는 모델과 평가 함수들이 아직 익숙치 않다.
Impressive
기존 프로그래밍 방식과 머신러닝 프로그래밍 방식의 차이를 먼저 배우고 머신러닝 데이터 - 학습 - 검증 - 평가 하는 루트가 이해하기 쉬웠다.