멀티캠퍼스 데이터분석 5월 18일 수업 내용 — XGBoost 분류/회귀, PCA 차원축소, GridSearchCV+Pipeline, K-Means 군집화, t-SNE 시각화
📌 목차
XGBoost
1. XGBoost 이론 & 매개변수
2. XGBoost 실습 — 분류 (bodyPerformance)
3. XGBoost 실습 — 회귀 (boston)
PCA
- PCA 이론 & 매개변수
- PCA 실습 — iris 데이터 & GridSearchCV + Pipeline
K-Means
- K-Means 이론 & 매개변수
- K-Means 실습 — iris 군집화 & 시각화
- K-Means 실습 — bodyPerformance & 최적 K 탐색
t-SNE
- t-SNE 이론 & 매개변수
- t-SNE 실습 — digits 데이터 2차원 시각화 & PCA 비교
XGBoost
1. XGBoost 이론 & 매개변수
- Gradient Boosting 알고리즘을 고도화한 트리 기반 앙상블 모델
- 빠른 속도, 높은 성능, 과적합 제어 기능 제공
- sklearn에 포함되어 있지 않아 별도 설치 필요
- 부스팅의 단점인 병렬화 어려움을 어느 정도 해결 (피처별 조건식 생성 시 CPU 병렬 사용)
매개변수 — 학습 제어
| 매개변수 | 기본값 | 설명 |
|---|
n_estimators | 100 | 생성할 트리 수 |
learning_rate | 0.3 | 각 단계별 기여도 (권장: 0.01~0.3) |
early_stopping_rounds | None | 검증 지표가 n라운드 연속 개선되지 않으면 학습 중단 |
objective | - | 손실 함수 지정 (아래 표 참고) |
eval_metric | None | 검증 평가 지표 (조기 종료와 함께 사용) |
objective 옵션
| 유형 | 값 | 출력 |
|---|
| 이진 분류 | 'binary:logistic' | 확률 (시그모이드) |
| 이진 분류 | 'binary:logitraw' | log-odds 값 |
| 다중 분류 | 'multi:softmax' | 클래스 인덱스(정수) |
| 다중 분류 | 'multi:softprob' | 클래스별 확률 |
| 회귀 | 'reg:squarederror' | MSE 기반 |
| 회귀 | 'reg:absoluteerror' | MAE 기반 (이상치에 유리) |
| 회귀 | 'reg:squaredlogerror' | MSLE 기반 (값 범위가 넓은 경우 유리) |
매개변수 — 트리 구조 제어
| 매개변수 | 기본값 | 설명 |
|---|
max_depth | 6 | 트리 최대 깊이 (권장: 3~10) |
min_child_weight | 1.0 | leaf 분할을 위한 최소 가중치 (클수록 보수적) |
gamma | 0.0 | 분할에 필요한 최소 손실 감소 (클수록 불필요 분할 억제) |
max_leaves | None | leaf 노드 수 제한 |
매개변수 — 샘플링 / 정규화
| 매개변수 | 기본값 | 설명 |
|---|
subsample | 1.0 | 각 트리에서 사용할 샘플 비율 (권장: 0.6~0.9) |
colsample_bytree | 1.0 | 각 트리에서 사용할 피처 비율 (권장: 0.5~0.9) |
reg_lambda | 1.0 | L2 정규화 |
reg_alpha | 0.0 | L1 정규화 (고차원 데이터에서 유용) |
scale_pos_weight | 1 | 데이터 불균형 처리 (음성/양성 비율 설정) |
하이퍼파라미터 튜닝 순서
1순위 (모델 성능) : n_estimators, learning_rate, max_depth, min_child_weight
2순위 (과적합 방지) : gamma, subsample, colsample_bytree
3순위 (세밀한 조정) : reg_lambda, reg_alpha, scale_pos_weight, tree_method
fit() 주요 옵션
| 옵션 | 설명 |
|---|
eval_set=[(X_vali, y_vali)] | 검증 데이터셋 지정 |
verbose=50 | 50라운드마다 성능 출력 |
주요 속성
| 속성 | 설명 |
|---|
feature_importances_ | 피처별 중요도 |
best_iteration | 조기 종료 시 최적 라운드 |
best_score | 조기 종료 시 최적 점수 |
2. XGBoost 실습 — 분류 (bodyPerformance)
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np
from sklearn.metrics import confusion_matrix, classification_report
body = pd.read_csv('../data/bodyPerformance.csv')
body['gender'] = np.where(body['gender'] == 'M', 0, 1)
body['class'] = body['class'].map({'A': 0, 'B': 1, 'C': 2, 'D': 3})
x = body.drop('class', axis=1)
y = body['class']
X_train, X_test, y_train, y_test = train_test_split(
x, y, test_size=0.3, random_state=42, stratify=y
)
X_vali, X_test, y_vali, y_test = train_test_split(
X_test, y_test, test_size=0.5, random_state=42, stratify=y_test
)
clf = XGBClassifier(
n_estimators = 1000,
learning_rate = 0.05,
objective = 'multi:softprob',
eval_metric = 'mlogloss',
max_depth = 5,
min_child_weight = 2,
subsample = 0.8,
colsample_bytree = 0.8,
early_stopping_rounds= 50,
random_state = 42,
tree_method = 'hist'
)
clf.fit(
X_train, y_train,
eval_set = [(X_vali, y_vali)],
verbose = 50
)
print('Best Iteration :', clf.best_iteration)
print('Best Score :', clf.best_score)
clf_pred = clf.predict(X_test)
print(confusion_matrix(y_test, clf_pred))
print(classification_report(y_test, clf_pred))
💡 Train / Validation / Test 3분할
early_stopping_rounds 를 사용할 때는 Test 셋과 별개의 Validation 셋이 필요합니다.
Test 셋으로 조기 종료를 판단하면 Test 데이터가 학습에 영향을 주는 데이터 누수가 발생합니다.
3. XGBoost 실습 — 회귀 (boston)
from xgboost import XGBRegressor
from sklearn.metrics import mean_squared_error, r2_score
boston = pd.read_csv('../csv/boston.csv')
x = boston.drop('Price', axis=1)
y = boston['Price']
X_train, X_test, y_train, y_test = train_test_split(
x, y, test_size=0.2, random_state=42
)
reg = XGBRegressor(
random_state = 42,
n_estimators = 1000,
learning_rate = 0.01,
subsample = 1.0,
colsample_bytree = 1.0,
max_depth = 10,
reg_lambda = 1.0,
early_stopping_rounds= 100,
objective = 'reg:squarederror',
min_child_weight = 3
)
reg.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=50)
reg_pred = reg.predict(X_test)
print('Best Iteration :', reg.best_iteration)
print('MSE :', mean_squared_error(y_test, reg_pred))
print('R2 :', r2_score(y_test, reg_pred))
PCA
4. PCA 이론 & 매개변수
- 고차원 데이터를 상관관계가 없는 새로운 축(주성분) 으로 변환
- 데이터의 분산을 최대한 보존하면서 차원을 줄여 시각화 및 전처리에 활용
주요 매개변수
| 매개변수 | 기본값 | 설명 |
|---|
n_components | None | 주성분 수 또는 분산 비율 설정 |
whiten | False | 주성분 벡터를 단위 분산으로 정규화 |
svd_solver | 'auto' | 분해 방식 ('full': 정확한 SVD / 'randomized': 대규모 데이터) |
n_components 설정 방식
| 값 | 설명 |
|---|
None | 모든 주성분 유지 |
int | 선택할 주성분 개수 |
float (0~1) | 누적 설명 분산 비율 기준으로 자동 선택 |
'mle' | 자동으로 최적 차원 수 결정 (샘플 수 < 피처 수인 경우) |
주요 속성
| 속성 | 설명 |
|---|
explained_variance_ratio_ | 각 주성분이 설명하는 분산 비율 |
components_ | 선택된 주성분 벡터 |
explained_variance_ | 각 주성분이 설명하는 분산 값 |
5. PCA 실습 — iris 데이터 & GridSearchCV + Pipeline
분산 비율 시각화
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
iris = pd.read_csv('../csv/iris.csv')
x = iris.drop('species', axis=1)
y = iris['species']
pca = PCA()
X_pca = pca.fit_transform(x, y)
ex_var_ratio = pca.explained_variance_ratio_
cum_var_ratio = np.cumsum(ex_var_ratio)
plt.figure(figsize=(8, 8))
plt.bar(range(1, len(ex_var_ratio) + 1), ex_var_ratio, alpha=0.5)
plt.step(range(1, len(cum_var_ratio) + 1), cum_var_ratio,
color='red', where='mid')
plt.show()
💡 차원 축소 기준
- 막대: 각 주성분이 설명하는 분산 비율
- 빨간 선: 누적 분산 비율
- 일반적으로 누적 분산이 90~95% 이상이 되는 지점까지의 주성분만 선택
GridSearchCV + Pipeline — 최적 PCA + SVC 조합 탐색
from sklearn.model_selection import train_test_split, GridSearchCV, StratifiedKFold
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import classification_report
X_train, X_test, y_train, y_test = train_test_split(
x, y, test_size=0.2, random_state=42, stratify=y
)
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
pipe = Pipeline([
('scaler', StandardScaler()),
('pca', PCA(random_state=42)),
('svc', SVC(random_state=42, probability=True))
])
params = {
'pca__n_components' : [None, 2, 3],
'svc__C' : [0.1, 1, 10],
'svc__gamma' : ['scale', 'auto'],
'svc__kernel' : ['linear', 'rbf']
}
grid = GridSearchCV(
estimator = pipe,
param_grid = params,
scoring = 'accuracy',
cv = cv,
n_jobs = -1,
verbose = 1,
refit = True
)
grid.fit(X_train, y_train)
print('Best Estimator :', grid.best_estimator_)
print('Best Params :', grid.best_params_)
print(classification_report(y_test, grid.predict(X_test)))
pd.DataFrame(grid.cv_results_).sort_values('mean_test_score', ascending=True)[
['mean_fit_time', 'params', 'mean_test_score']
]
💡 Pipeline 매개변수 접근 방식
Pipeline 안의 각 단계 매개변수는 단계명__매개변수명 형태로 지정합니다.
예) pca__n_components, svc__C
K-Means
6. K-Means 이론 & 매개변수
- k개의 그룹으로 자동 분류하는 비지도 학습 알고리즘
- 종속 변수 없이 유사한 데이터끼리 묶어 그룹화
- 중심점을 반복적으로 이동하며 군집을 형성
작업 순서
1. k개 초기 중심점 선택
2. 각 데이터와 중심점 거리 계산
3. 가장 가까운 중심점으로 군집 할당
4. 각 군집의 평균으로 새로운 중심점 설정
5. 중심점 변화가 없을 때까지 반복
장점 & 단점
| 내용 |
|---|
| 장점 | 빠르고 단순, 대용량 데이터에 적합 |
| 단점 | 군집 수(k)를 미리 지정해야 함, 이상치에 민감 |
주요 매개변수
| 매개변수 | 기본값 | 설명 |
|---|
n_clusters | 8 | 군집 개수 |
init | 'k-means++' | 초기 중심점 설정 방법 |
n_init | 'auto' | 초기화 시도 횟수 |
max_iter | 300 | 최대 반복 횟수 |
tol | 1e-4 | 중심점 이동 변화량 수렴 기준 |
algorithm | 'lloyd' | 알고리즘 ('elkan': 밀집 데이터에서 속도 향상) |
검증 지표
| 지표 | 함수 | 기준 |
|---|
| inertia | model.inertia_ | 작을수록 응집 |
| silhouette | silhouette_score() | 1에 가까울수록 좋음 |
| calinski_harabasz | calinski_harabasz_score() | 높을수록 좋음 |
| davies_bouldin | davies_bouldin_score() | 낮을수록 좋음 |
| ARI | adjusted_rand_score() | 1=일치, 0=불일치 |
7. K-Means 실습 — iris 군집화 & 시각화
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
import pandas as pd
from sklearn.metrics import (silhouette_score, calinski_harabasz_score,
davies_bouldin_score, adjusted_rand_score)
iris = pd.read_csv('../csv/iris.csv')
x = iris.drop('species', axis=1)
y = iris['species']
x_std = StandardScaler().fit_transform(x)
model = KMeans(n_clusters=3, random_state=42, n_init=10)
model.fit(x_std)
labels = model.predict(x_std)
print('inertia :', round(model.inertia_, 3))
print('silhouette :', round(silhouette_score(x_std, labels), 3))
print('calinski :', round(calinski_harabasz_score(x_std, labels), 3))
print('davies :', round(davies_bouldin_score(x_std, labels), 3))
print('ARI :', round(adjusted_rand_score(y, labels), 3))
PCA로 2차원 축소 후 군집 시각화
pca = PCA(n_components=2)
x_pca = pca.fit_transform(x_std)
center_pca = pca.transform(model.cluster_centers_)
plt.figure(figsize=(12, 8))
plt.scatter(x_pca[:, 0], x_pca[:, 1],
c=labels, cmap='viridis', s=40, alpha=0.7)
plt.scatter(center_pca[:, 0], center_pca[:, 1],
c='black', s=100, marker='X', label='center')
plt.legend()
plt.show()
💡 K-Means는 거리 기반 알고리즘이므로 스케일링이 필수입니다.
스케일링 없이 사용하면 범위가 큰 피처에 군집이 편향됩니다.
8. K-Means 실습 — bodyPerformance & 최적 K 탐색
LabelEncoder로 범주형 변환
from sklearn.preprocessing import LabelEncoder
df = pd.read_csv('../data/bodyperformance.csv')
obj_cols = df.select_dtypes('object').columns
for col in obj_cols:
le = LabelEncoder()
df[col] = le.fit_transform(df[col])
x = df.drop(['gender', 'class'], axis=1)
y1 = df['class']
y2 = df['gender']
x_std = StandardScaler().fit_transform(x)
최적 K 탐색 — inertia & silhouette
rows = []
for k in range(2, 11):
km = KMeans(n_clusters=k, n_init=10, random_state=42)
pred = km.fit_predict(x_std)
rows.append({
'K' : k,
'inertia' : km.inertia_,
'silhouette' : silhouette_score(x_std, pred)
})
scores = pd.DataFrame(rows)
scores.sort_values('silhouette', ascending=False)
최적 K 군집 시각화
pca = PCA(n_components=2, random_state=42)
x_pca = pca.fit_transform(x_std)
km_best = KMeans(n_clusters=2, n_init=10, random_state=42).fit(x_std)
labels_best = km_best.labels_
center_pca = pca.transform(km_best.cluster_centers_)
plt.figure(figsize=(12, 8))
sc = plt.scatter(x_pca[:, 0], x_pca[:, 1],
c=labels_best, s=10, cmap='tab10', alpha=0.4)
plt.scatter(center_pca[:, 0], center_pca[:, 1],
c='black', s=100, marker='X', label='center')
plt.legend(*sc.legend_elements(), title='Cluster')
plt.show()
plt.figure(figsize=(14, 20))
sc_class = plt.scatter(x_pca[:, 0], x_pca[:, 1],
c=y1, cmap='tab10', alpha=0.5)
plt.legend(*sc_class.legend_elements(), title='True Class')
plt.show()
t-SNE
9. t-SNE 이론 & 매개변수
- 고차원 데이터를 2D/3D로 시각화하기 위한 비선형 차원축소 기법
- 고차원: 가우시안 분포 기반 유사도 / 저차원: t-분포 기반 재현
거리 계산 방식
| 방식 | 설명 | 주요 사용 |
|---|
euclidean (기본) | 직선 거리 | 일반 수치 데이터 |
manhattan | 직각 축 기반 거리 | 격자 구조 |
chebyshev | 최대 축 차이 기반 | 체스판 거리 |
cosine | 벡터 방향 기반 유사도 | 자연어 데이터 |
mahalanobis | 변수 간 상관 반영 | 상관 있는 변수 |
주요 매개변수
| 매개변수 | 기본값 | 설명 |
|---|
n_components | 2 | 축소할 차원 |
perplexity | 30 | 이웃 수 제어 (권장: 5~50, 샘플 수/3 정도) |
learning_rate | 'auto' | 학습 속도 (권장: 100~1000) |
max_iter | 1000 | 전체 학습 반복 횟수 |
metric | 'euclidean' | 거리 계산 방식 |
n_jobs | None | 병렬 CPU 수 |
10. t-SNE 실습 — digits 데이터 2차원 시각화 & PCA 비교
digits 데이터 — 손글씨 숫자 이미지
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.datasets import load_digits
from sklearn.preprocessing import StandardScaler
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
digits = load_digits()
plt.figure(figsize=(5, 2))
for i in range(10):
plt.subplot(2, 5, i + 1)
plt.imshow(digits.images[i], cmap='gray')
plt.axis('off')
plt.show()
t-SNE로 64차원 → 2차원 변환
x = StandardScaler().fit_transform(digits['data'])
y = digits['target']
print(x.shape)
tsne = TSNE(n_components=2, perplexity=40, random_state=42, n_jobs=-1)
x_tsne = tsne.fit_transform(x)
print(x_tsne.shape)
plt.figure(figsize=(16, 10))
sc = plt.scatter(x_tsne[:, 0], x_tsne[:, 1], c=y, cmap='tab10', s=40)
plt.legend(*sc.legend_elements(), title='Digits')
plt.show()
PCA로 64차원 → 2차원 변환 & 비교
pca = PCA(n_components=2, random_state=42)
x_pca = pca.fit_transform(x)
plt.figure(figsize=(16, 10))
sc = plt.scatter(x_pca[:, 0], x_pca[:, 1], c=y, cmap='tab10', s=40)
plt.legend(*sc.legend_elements(), title='Digits')
plt.show()
t-SNE vs PCA 비교
| t-SNE | PCA |
|---|
| 방식 | 비선형 | 선형 |
| 목적 | 시각화 (군집 구조) | 분산 최대화 방향 축소 |
| 속도 | 느림 | 빠름 |
| 군집 구분 | 명확 | 겹침이 많을 수 있음 |
| 역변환 | 불가 | 가능 |
| 주요 용도 | 탐색적 분석 (EDA) | 전처리, 노이즈 제거 |
📎 핵심 개념 요약
| 개념 | 설명 |
|---|
| XGBoost | Gradient Boosting 고도화, 별도 설치 필요 |
early_stopping_rounds | 검증 지표 개선 없으면 학습 조기 종료 |
eval_set | 조기 종료에 사용할 검증 데이터 지정 |
best_iteration | 조기 종료 최적 라운드 |
| PCA | 선형 차원축소, 분산 최대화 방향으로 변환 |
explained_variance_ratio_ | 각 주성분의 분산 설명 비율 |
np.cumsum() | 누적합 계산 |
| Pipeline | 여러 전처리+모델 단계를 하나로 묶음 |
단계명__매개변수 | Pipeline 내 매개변수 접근 방식 |
| K-Means | 비지도 군집화, k 사전 지정 필요 |
inertia_ | 군집 내 거리 제곱합 (작을수록 응집) |
silhouette_score() | 응집도+분리도 종합 (1에 가까울수록 좋음) |
LabelEncoder | 범주형 → 정수 인코딩 |
| t-SNE | 비선형 차원축소, 시각화 특화 |
perplexity | 이웃 수 제어 (샘플 수/3 권장) |
sc.legend_elements() | scatter 범례 자동 생성 |
plt.axis('off') | 축 숨기기 (이미지 시각화 시) |