XGBoost & PCA & K-Means & t-SNE 실습 정리

syeom·2026년 5월 18일

멀티캠퍼스 데이터분석 5월 18일 수업 내용 — XGBoost 분류/회귀, PCA 차원축소, GridSearchCV+Pipeline, K-Means 군집화, t-SNE 시각화


📌 목차

XGBoost
1. XGBoost 이론 & 매개변수
2. XGBoost 실습 — 분류 (bodyPerformance)
3. XGBoost 실습 — 회귀 (boston)

PCA

  1. PCA 이론 & 매개변수
  2. PCA 실습 — iris 데이터 & GridSearchCV + Pipeline

K-Means

  1. K-Means 이론 & 매개변수
  2. K-Means 실습 — iris 군집화 & 시각화
  3. K-Means 실습 — bodyPerformance & 최적 K 탐색

t-SNE

  1. t-SNE 이론 & 매개변수
  2. t-SNE 실습 — digits 데이터 2차원 시각화 & PCA 비교

XGBoost

1. XGBoost 이론 & 매개변수

  • Gradient Boosting 알고리즘을 고도화한 트리 기반 앙상블 모델
  • 빠른 속도, 높은 성능, 과적합 제어 기능 제공
  • sklearn에 포함되어 있지 않아 별도 설치 필요
  • 부스팅의 단점인 병렬화 어려움을 어느 정도 해결 (피처별 조건식 생성 시 CPU 병렬 사용)
# !pip install xgboost

매개변수 — 학습 제어

매개변수기본값설명
n_estimators100생성할 트리 수
learning_rate0.3각 단계별 기여도 (권장: 0.01~0.3)
early_stopping_roundsNone검증 지표가 n라운드 연속 개선되지 않으면 학습 중단
objective-손실 함수 지정 (아래 표 참고)
eval_metricNone검증 평가 지표 (조기 종료와 함께 사용)

objective 옵션

유형값출력
이진 분류'binary:logistic'확률 (시그모이드)
이진 분류'binary:logitraw'log-odds 값
다중 분류'multi:softmax'클래스 인덱스(정수)
다중 분류'multi:softprob'클래스별 확률
회귀'reg:squarederror'MSE 기반
회귀'reg:absoluteerror'MAE 기반 (이상치에 유리)
회귀'reg:squaredlogerror'MSLE 기반 (값 범위가 넓은 경우 유리)

매개변수 — 트리 구조 제어

매개변수기본값설명
max_depth6트리 최대 깊이 (권장: 3~10)
min_child_weight1.0leaf 분할을 위한 최소 가중치 (클수록 보수적)
gamma0.0분할에 필요한 최소 손실 감소 (클수록 불필요 분할 억제)
max_leavesNoneleaf 노드 수 제한

매개변수 — 샘플링 / 정규화

매개변수기본값설명
subsample1.0각 트리에서 사용할 샘플 비율 (권장: 0.6~0.9)
colsample_bytree1.0각 트리에서 사용할 피처 비율 (권장: 0.5~0.9)
reg_lambda1.0L2 정규화
reg_alpha0.0L1 정규화 (고차원 데이터에서 유용)
scale_pos_weight1데이터 불균형 처리 (음성/양성 비율 설정)

하이퍼파라미터 튜닝 순서

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=5050라운드마다 성능 출력

주요 속성

속성설명
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']

# Train / Validation / Test 3분할
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_componentsNone주성분 수 또는 분산 비율 설정
whitenFalse주성분 벡터를 단위 분산으로 정규화
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
)

# K-Fold 교차 검증
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# Pipeline: Scaler → PCA → SVC
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_clusters8군집 개수
init'k-means++'초기 중심점 설정 방법
n_init'auto'초기화 시도 횟수
max_iter300최대 반복 횟수
tol1e-4중심점 이동 변화량 수렴 기준
algorithm'lloyd'알고리즘 ('elkan': 밀집 데이터에서 속도 향상)

검증 지표

지표함수기준
inertiamodel.inertia_작을수록 응집
silhouettesilhouette_score()1에 가까울수록 좋음
calinski_harabaszcalinski_harabasz_score()높을수록 좋음
davies_bouldindavies_bouldin_score()낮을수록 좋음
ARIadjusted_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']

# 스케일링 (K-Means는 거리 기반이므로 필수)
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)

# 중심점도 2차원으로 변환
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')

# object 타입 컬럼 전체 LabelEncoding
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)

# 최적 K=2 시각화
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()

# 실제 class 분포와 비교
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_components2축소할 차원
perplexity30이웃 수 제어 (권장: 5~50, 샘플 수/3 정도)
learning_rate'auto'학습 속도 (권장: 100~1000)
max_iter1000전체 학습 반복 횟수
metric'euclidean'거리 계산 방식
n_jobsNone병렬 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()   # 8×8 픽셀 이미지 = 64차원

# 숫자 이미지 시각화
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)   # (1797, 64)

tsne = TSNE(n_components=2, perplexity=40, random_state=42, n_jobs=-1)
x_tsne = tsne.fit_transform(x)

print(x_tsne.shape)   # (1797, 2)

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-SNEPCA
방식비선형선형
목적시각화 (군집 구조)분산 최대화 방향 축소
속도느림빠름
군집 구분명확겹침이 많을 수 있음
역변환불가가능
주요 용도탐색적 분석 (EDA)전처리, 노이즈 제거

📎 핵심 개념 요약

개념설명
XGBoostGradient 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')축 숨기기 (이미지 시각화 시)
profile
공부 기록

0개의 댓글