지도 머신러닝에서 모델 파라미터는 최적화 알고리즘(예: 경사 하강법, 정규 방정식)을 통해 학습 데이터로부터 직접 학습되는 내부 변수입니다. 선형 모델의 회귀 가중치와 편향, 또는 의사결정나무의 분기 임계값 등이 대표적인 예입니다. 반면 하이퍼파라미터는 학습 과정, 모델의 용량, 아키텍처를 제어하기 위해 학습 시작 전에 외부에서 지정하는 설정값입니다. 최적화 알고리즘이 손실 함수를 최소화하는 과정에서 자명하게 과적합을 일으킬 수 있기 때문에(예: 트리 깊이를 무한대로 설정하는 등), 일반적인 학습 손실 최소화 방식으로는 직접 학습할 수 없습니다. 대표적인 예로는 학습률(learning rate), 규제 강도(lambda/C), 포레스트 내 트리의 개수, 트리의 최대 깊이 등이 있습니다. 하이퍼파라미터는 검증 데이터나 교차 검증을 사용하여 튜닝합니다.
from sklearn.linear_model import Ridge
import numpy as np
X = np.array([[1.0], [2.0], [3.0]])
y = np.array([2.0, 4.0, 6.0])
# Hyperparameter: alpha (regularization strength set beforehand)
model = Ridge(alpha=1.0)
# Fitting optimizes internal parameters on training data
model.fit(X, y)
# Learned parameters
print(f"Weight (Parameter): {model.coef_[0]:.4f}")
print(f"Intercept (Parameter): {model.intercept_:.4f}")
2최소자승법(OLS, Ordinary Least Squares) 선형 회귀의 기본 가정은 무엇이며, 잔차 진단을 통해 가정 위반을 어떻게 확인할 수 있나요?
최소자승법(OLS) 선형 회귀는 다음과 같은 몇 가지 핵심 가정에 기반합니다: 1. 선형성(Linearity): 독립변수와 종속변수 간의 관계가 모수(parameter)에 대해 선형이어야 합니다. 2. 오차의 독립성(Independence of errors): 관측치와 잔차 오차가 서로 독립적이어야 합니다(자기상관 부재). 3. 등분산성(Homoscedasticity): 모든 독립변수 수준에서 오차항의 분산이 일정해야 합니다. 4. 잔차의 정규성(Normality of residuals): 오차항이 정규분포를 따라야 합니다(유효한 신뢰구간 및 가설 검정을 위해 필요). 5. 다중공선성 부재(No multicollinearity): 독립변수 간에 선형 종속 관계가 없어야 합니다(설계 행렬의 최대 열 계수 충족). 잔차 진단은 다음과 같은 방식으로 가정 위반을 확인합니다: - 잔차 대 적합값 플롯(Residuals vs. Fitted Values plot): 곡선 형태나 비무작위 패턴은 비선형성을 나타내며, 깔때기나 부채꼴 모양은 이분산성(일정하지 않은 분산)을 나타냅니다. - 정규 Q-Q 플롯(Normal Q-Q plot): 직선 대각선에서 체계적으로 벗어나는 형태(예: S자 곡선이나 두터운 꼬리)는 비정규성을 나타냅니다. - 잔차 대 관측 순서/시간 플롯(Residuals vs. Order/Time plot): 체계적인 추세나 주기적 패턴은 오차의 자기상관을 나타냅니다. - 레버리지 / 쿡의 거리 플롯(Leverage / Cook's Distance plot): 적합된 모델을 과도하게 왜곡하는 고레버리지 이상치나 영향점(influential points)을 식별합니다.
import numpy as np
import statsmodels.api as sm
np.random.seed(42)
X = np.linspace(1, 10, 50)
# Quadratic underlying pattern creates a linearity violation
y = 2 * X + 0.5 * (X ** 2) + np.random.normal(0, 2, 50)
X_with_const = sm.add_constant(X)
model = sm.OLS(y, X_with_const).fit()
residuals = model.resid
print(f"Mean Residual: {np.mean(residuals):.4f}")
print(f"Curvature in residuals indicates model misspecification.")
3로지스틱 회귀(logistic regression)는 이진 분류를 어떻게 모델링하며, 시그모이드 함수(sigmoid function)의 역할은 무엇인가요?
로지스틱 회귀는 사후 클래스 확률 $P(Y=1|X)$를 추정하여 이진 분류를 모델링합니다. 예측 확률이 $(0, 1)$ 범위 내로 유지되도록 하기 위해 양성 클래스의 로그 오즈(log-odds, 로짓)를 입력값의 선형 함수로 모델링합니다: $\ln\left(\frac{p}{1-p}\right) = w^T x + b$. 시그모이드(로지스틱) 함수 $\sigma(z) = \frac{1}{1 + e^{-z}}$는 모든 실수 범위의 선형 점수 $z = w^T x + b \in (-\infty, +\infty)$를 유효한 확률 $p \in (0, 1)$로 단조 매핑하는 연결 함수(link function) 역할을 합니다. 이산적인 클래스 결정은 결정 임계값 $\tau$(일반적으로 0.5)를 적용하여 이루어집니다: $P(Y=1|X) \ge \tau$이면 $\hat{y} = 1$, 그렇지 않으면 $0$입니다. $\sigma(z) = 0.5$는 정확히 $z = 0$일 때 발생하므로, 피처 공간에서의 결정 경계는 선형 초평면 $w^T x + b = 0$이 되며, 이에 따라 표준 로지스틱 회귀는 선형 분류기로 동작합니다.
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
w = np.array([1.5, -2.0])
b = 0.5
x = np.array([2.0, 1.0])
z = np.dot(w, x) + b
prob = sigmoid(z)
threshold = 0.5
pred = int(prob >= threshold)
print(f"Log-odds (z): {z:.2f}")
print(f"Probability: {prob:.4f}")
print(f"Class Prediction: {pred}")
4L2 정규화란 무엇이며, 릿지 회귀(Ridge regression)는 목적 함수와 계수 추정치를 어떻게 변화시키나요?
L2 정규화(릿지 회귀)는 최소자승법(OLS, Ordinary Least Squares) 손실 함수에 가중치 제곱합에 비례하는 페널티를 추가합니다: $$\min_w \|y - Xw\|_2^2 + \lambda \|w\|_2^2$$ 해석적으로 릿지 회귀는 역행렬을 계산하기 전 그람 행렬(Gram matrix)에 $\lambda I$를 더하여 정규 방정식을 수정합니다: $$w_{\text{ridge}} = (X^T X + \lambda I)^{-1} X^T y$$ 목적 함수 및 계수 추정치에 미치는 주요 영향은 다음과 같습니다. 1. 축소(Shrinkage): 계수는 특성의 분산과 상관관계에 비례하여 0을 향해 축소되며, 계수를 정확히 0으로 만들지 않으면서 모델의 복잡도를 낮춥니다. 2. 다중공선성과 역행렬 계산 가능성: 특성 간 공선성이 있거나 $p > N$인 경우, $X^T X$는 특이 행렬(singular)이 되거나 조건이 나빠집니다(ill-conditioned). $\lambda I$를 더하면 $(X^T X + \lambda I)$가 엄격히 양의 정부호(strictly positive definite)가 되어 역행렬 계산이 가능해지므로 매개변수 추정이 안정화됩니다. 3. 편향-분산 트레이드오프(Bias-Variance Trade-off): $\lambda$를 증가시키면 계수 추정치에 의도적인 편향이 생기지만 분산이 크게 감소하여, 새로운 데이터에 대한 일반화 오차 기댓값이 낮아집니다. 4. 특성 스케일링(Feature Scaling) 요구사항: 페널티가 모든 가중치를 동등하게 취급하므로, 스케일이 더 큰 특성이 불균형하게 더 큰 정규화 영향을 받게 됩니다. 따라서 모델 학습 전에 특성을 반드시 표준화(평균 0, 분산 1)해야 합니다.
import numpy as np
def ridge_regression(X, y, alpha):
X_std = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
n_features = X_std.shape[1]
I = np.eye(n_features)
beta = np.linalg.inv(X_std.T @ X_std + alpha * I) @ X_std.T @ y
return beta
X = np.array([[1.0, 2.0], [2.0, 4.1], [3.0, 5.9], [4.0, 8.2]])
y = np.array([2.1, 4.0, 6.2, 8.1])
weights = ridge_regression(X, y, alpha=1.0)
print('Ridge Weights:', weights)
5의사결정나무(decision tree)는 특성 공간(feature space)을 어떻게 재귀적으로 분할하며, 분류 기준 분할을 선택할 때 어떤 척도가 사용되나요?
의사결정나무는 **재귀적 이진 분할(recursive binary partitioning)**이라 불리는 하향식(top-down) 탐욕(greedy) 알고리즘을 통해 특성 공간을 분할합니다. 모든 훈련 데이터를 포함하는 루트 노드에서 시작하여, 알고리즘은 모든 특성과 가능한 임곗값을 탐색하며 불순도(impurity) 감소를 극대화하는 단일 축 정렬 분할($X_j \le t$)을 찾습니다. 데이터셋은 두 개의 자식 노드로 분할되며, 정지 조건(예: 최대 깊이, 리프당 최소 샘플 수, 순수 노드 도달 등)을 충족할 때까지 각 자식 노드에 대해 이 과정이 재귀적으로 적용됩니다. 분할 시 한 번에 하나의 특성을 임곗값과 비교하여 평가하므로, 생성되는 결정 경계는 직교 초평면(특성 공간 내 축 정렬 직사각형 영역)이 됩니다. 분류 나무에서 최적의 분할을 평가하고 선택하기 위해 주로 다음 두 가지 불순도 기준이 사용됩니다: 1. **지니 불순도(Gini Impurity, CART에서 사용)**: 노드의 클래스 분포에 따라 임의로 레이블을 지정할 때 무작위로 선택된 샘플이 잘못 분류될 확률을 측정합니다. 비율이 $p_k$인 $K$개 클래스에 대해 다음과 같이 정의됩니다: $$I_G = 1 - \sum_{k=1}^K p_k^2$$ 2. **엔트로피 및 정보 획득량(Entropy and Information Gain, ID3, C4.5에서 사용)**: 엔트로피는 노드의 불확실성을 측정합니다: $H = -\sum_{k=1}^K p_k \log_2(p_k)$. 분할은 부모 노드의 엔트로피에서 자식 노드들의 가중 평균 엔트로피를 뺀 값인 **정보 획득량(Information Gain)**을 극대화하도록 선택됩니다: $$IG = H(\text{parent}) - \sum_{c \in \{\text{left, right}\}} \frac{N_c}{N} H(c)$$ 두 지표 모두 노드가 완전히 순수할 때(모든 샘플이 단일 클래스에 속할 때) 0이 되며, 클래스들이 균등하게 분포되어 있을 때 최댓값에 도달합니다.
6k-최근접 이웃(k-nearest neighbors)이란 무엇이며, 분류와 회귀에서 어떻게 예측을 수행합니까?
k-최근접 이웃(k-Nearest Neighbors, kNN)은 비모수적(non-parametric)이고 인스턴스 기반(지연 학습, lazy learning)인 지도학습 알고리즘입니다. 명시적인 모수 모델을 학습하지 않고, 학습 데이터셋을 저장해 둔 뒤 추론 시점에 모든 계산을 수행합니다. 예측 워크플로: 1. 거리 계산: 쿼리 인스턴스가 주어지면 지정된 거리 지표(유클리드 거리, 맨해튼 거리, 민코프스키 거리 등)를 사용하여 저장된 모든 학습 인스턴스와의 거리를 계산합니다. 2. 이웃 선택: 쿼리 인스턴스와 거리가 가장 가까운 $k$개의 학습 인스턴스를 선택합니다. 3. 집계: - 분류: $k$개 이웃 간의 다수결 투표(최빈값) 또는 거리 가중 투표를 통해 클래스를 할당합니다. - 회귀: $k$개 이웃의 타깃 값에 대한 국소 평균(평균값 또는 중앙값)이나 거리 가중 평균을 계산하여 연속형 타깃 값을 예측합니다. 거리 계산은 특성의 스케일에 직접적인 영향을 받으므로, 스케일이 큰 특성이 거리 계산을 지배하지 않도록 특성 정규화(normalization) 또는 표준화(standardization)가 필수적입니다.
7나이브 베이즈(naive Bayes)의 조건부 독립 가정을 서술하고, 이 가정이 위배되더라도 나이브 베이즈가 여전히 잘 작동할 수 있는 이유를 설명해 주세요.
나이브 베이즈의 조건부 독립 가정은 클래스 레이블 Y = y가 주어졌을 때, 모든 특징 X_1, X_2, ..., X_d가 서로 상호 독립적이라는 가정입니다. 즉, P(X_1, ..., X_d | Y = y) = \prod_{j=1}^d P(X_j | Y = y)입니다. 베이즈 정리를 사용하면 사후 확률은 다음과 같습니다. P(Y = y | X) \propto P(Y = y) \prod_{j=1}^d P(X_j | Y = y), 여기서 P(Y = y)는 클래스 사전 확률이고 P(X_j | Y = y)는 클래스 조건부 우도(예: 연속형 특징의 경우 가우시안, 빈도수의 경우 다항 분포)입니다. 독립성 가정이 위배되더라도 실무에서 나이브 베이즈가 잘 작동하는 경우가 많은 이유는 분류가 정확한 확률 보정(calibration)보다는 argmax 결정 규칙(argmax_y P(Y=y | X))에 의존하기 때문입니다. 특징 간의 상관관계로 인해 예측 확률이 과신되거나 왜곡되더라도 올바른 클래스가 가장 높은 상대적 순위를 유지하는 경우가 많습니다. 상관관계가 클래스 우도의 순위를 뒤집지 않는 한, 0-1 분류 결정은 여전히 정확하게 유지됩니다.
from sklearn.naive_bayes import GaussianNB
import numpy as np
X = np.array([[1.0, 1.1], [1.2, 0.9], [-1.0, -1.2], [-0.8, -1.1]])
y = np.array([1, 1, 0, 0])
model = GaussianNB()
model.fit(X, y)
# Prediction uses argmax over class posterior scores
print("Predicted class:", model.predict([[1.1, 1.0]]))
8OLS(Ordinary Least Squares)의 닫힌 형태 해를 유도하거나 설명하고, 이 해가 유일하게 존재하는 조건을 서술해 주세요.
최소자승법(OLS, Ordinary Least Squares)의 목적 함수는 잔차 제곱합을 최소화하는 것입니다. $S(\beta) = \|y - X\beta\|^2 = (y - X\beta)^T (y - X\beta) = y^T y - 2\beta^T X^T y + \beta^T X^T X \beta$입니다. $\beta$에 대한 기울기(gradient)를 0으로 설정하면 다음과 같습니다: $$\nabla_\beta S(\beta) = -2 X^T y + 2 X^T X \beta = 0 \implies X^T X \beta = X^T y$$ 이를 정규 방정식(normal equations)이라고 합니다. $X^T X$가 비특이 행렬(가역 행렬)일 때, 유일한 닫힌 형태의 해는 다음과 같습니다: $$\hat{\beta} = (X^T X)^{-1} X^T y$$ 기하학적으로 $\hat{y} = X\hat{\beta} = X(X^T X)^{-1} X^T y = H y$는 타깃 벡터 $y$를 계획 행렬(design matrix) $X$의 열공간(column space)으로 정사영한 것을 나타내며, 여기서 $H$는 사영 행렬(hat matrix)입니다. 해가 유일하게 존재하기 위한 필요충분조건은 $X^T X$가 역행렬을 가져야 한다는 것이며, 이는 $N \times P$ 크기의 계획 행렬 $X$가 완전 열계수(full column rank, $Rank(X) = P$)를 가질 것을 요구합니다. 즉, $N \ge P$여야 하고 완전한 다중공선성이 없어야(어떤 피처도 다른 피처들의 선형 결합으로 표현되지 않아야) 합니다. $X$의 계수가 부족(rank-deficient)하면 $X^T X$는 특이 행렬이 되어 해가 무수히 많아지며, 이는 대개 정규화(regularization)나 무어-펜로즈 유사역행렬(Moore-Penrose pseudoinverse) $X^+ y$를 통해 해결합니다.
import numpy as np
# Design matrix X (with intercept column) and target y
X = np.array([[1, 1], [1, 2], [1, 3], [1, 4]])
y = np.array([2.1, 3.9, 6.2, 8.0])
# Normal equations: (X^T X)^(-1) X^T y
beta_hat = np.linalg.inv(X.T @ X) @ X.T @ y
H = X @ np.linalg.inv(X.T @ X) @ X.T
y_hat = H @ y
print(f"Beta: {beta_hat}")
print(f"Predictions: {y_hat}")
9최대 우도 추정법(MLE, Maximum Likelihood Estimation)이란 무엇이며, 이것이 어떻게 로지스틱 회귀의 크로스 엔트로피 목적 함수로 유도되나요?
최대 우도 추정법(MLE, Maximum Likelihood Estimation)은 관측된 데이터셋의 우도(likelihood) $L(\theta) = P(\mathcal{D}|\theta)$를 최대화하는 모델 파라미터 $\theta$의 값을 찾는 추정 기법입니다. 이진 로지스틱 회귀에서 각 라벨 $y_i \in \{0, 1\}$는 $x_i$를 조건부로 하며 성공 확률이 $p_i = \sigma(w^T x_i + b)$인 독립 베르누이 확률 변수로 모델링됩니다. 관측치 $i$에 대한 확률 질량 함수는 $P(y_i|x_i) = p_i^{y_i} (1 - p_i)^{1 - y_i}$입니다. 샘플들이 독립 항등 분포(i.i.d.)를 따른다고 가정하면 결합 우도는 다음과 같습니다.
$$L(w, b) = \prod_{i=1}^N p_i^{y_i} (1 - p_i)^{1 - y_i}$$
자연로그를 취하면 곱셈 형태를 계산하기 쉬운 로그 우도의 합으로 변환할 수 있습니다.
$$\ell(w, b) = \sum_{i=1}^N \left[ y_i \ln(p_i) + (1 - y_i) \ln(1 - p_i) \right]$$
최적화 알고리즘은 관례적으로 최소화 문제로 정의되므로, 로그 우도에 음수를 취하고 표본 크기 $N$으로 정규화하면 음의 로그 우도(NLL, Negative Log-Likelihood)가 얻어지며, 이는 정확히 이진 크로스 엔트로피(로그 손실) 목적 함수와 일치합니다.
$$J(w, b) = -\frac{1}{N} \sum_{i=1}^N \left[ y_i \ln(p_i) + (1 - y_i) \ln(1 - p_i) \right]$$
이 목적 함수는 선형 로짓/가중치에 대해 볼록(convex) 함수이므로 적절한 수치 최적화 알고리즘을 통해 전역 최적해를 찾을 수 있습니다. 엄격한 볼록성(strict convexity)과 유한한 유일 MLE를 보장하기 위해서는 충분한 피처 랭크, 규제(regularization), 완벽한 클래스 분리가 없는 상태 등의 추가 조건이 필요합니다.
10경사 하강법은 고전적 ML(Machine Learning) 목적 함수를 어떻게 최적화하며 학습률, 수렴성, 볼록성은 학습에 어떤 영향을 미치나요?
경사 하강법은 모델 매개변수에 대한 목적 함수의 그래디언트 반대 방향으로 매개변수를 반복 갱신하여 경험적 손실 함수를 최소화합니다: $\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t)$. 학습에 영향을 미치는 핵심 요인은 다음과 같습니다: 1. 학습률($\eta$): 보폭(step size)을 제어합니다. 너무 작게 설정하면 수렴 속도가 지나치게 느려져 학습이 정체될 수 있습니다. 너무 크게 설정하면 최솟값을 지나쳐 진동하거나 수치적으로 발산하게 됩니다. 2. 수렴성: 작은 그래디언트 노름($||\nabla L(\theta)|| \le \epsilon$), 최소 수준의 매개변수 변화량, 또는 연속된 반복 간 손실 감소의 정체(plateauing)와 같은 조기 종료 기준을 모니터링하여 판단합니다. 3. 볼록성(Convexity): 볼록 목적 함수(예: 표준 OLS 선형 회귀 또는 로지스틱 회귀)에서는 모든 국소 최솟값이 전역 최솟값임이 보장되므로, 적절한 보폭을 사용하면 경사 하강법이 안정적으로 수렴합니다. 비볼록 목적 함수(예: 다층 신경망)에서는 손실 지형에 다수의 국소 최솟값, 안장점, 평탄 영역이 존재하여 최종 결과가 초기값 설정에 민감해집니다. 4. 최적화 vs 일반화: 훈련 손실의 수렴은 최적화의 성공을 나타내며, 검증 손실은 일반화 성능을 평가합니다. 검증 오차가 높은 상태에서 낮은 훈련 손실에 도달하는 것은 최적화 실패가 아니라 과적합을 의미합니다.
import numpy as np
def gradient_descent(X, y, lr=0.01, max_iters=1000, tol=1e-6):
n_samples, n_features = X.shape
theta = np.zeros(n_features)
prev_loss = float('inf')
for i in range(max_iters):
predictions = X @ theta
error = predictions - y
loss = (1 / (2 * n_samples)) * np.dot(error, error)
if abs(prev_loss - loss) < tol:
print(f'Converged at iteration {i}')
break
prev_loss = loss
grad = (1 / n_samples) * (X.T @ error)
theta -= lr * grad
return theta
11희소성(sparsity), 상관관계가 있는 특성 처리, 그리고 실제 모델 선택 관점에서 L1, L2, ElasticNet 규제를 비교해 주세요.
L1(Lasso), L2(Ridge), ElasticNet 규제는 페널티 함수 형태, 제약 영역의 기하학적 특성, 희소성 생성 여부, 상관관계가 있는 예측 변수를 다루는 방식에서 차이가 있습니다.
1. 희소성 및 기하학적 특성:
- L1은 절댓값 페널티($\lambda \|w\|_1$)를 사용합니다. 제약 조건 경계는 좌표축 위에 날카로운 꼭짓점을 갖는 다포체(마름모) 형태입니다. 손실 함수의 등고선이 이 모서리와 만날 때 가중치가 정확히 0이 되므로 자동 특성 선택(feature selection) 효과가 나타납니다.
- L2는 유클리드 노름의 제곱 페널티($\lambda \|w\|_2^2$)를 사용합니다. 제약 조건 경계는 모서리가 없는 매끄러운 초구(hypersphere) 형태입니다. 가중치를 점근적으로 0에 가깝게 축소하지만 정확히 0으로 만들지는 않습니다.
2. 상관관계가 있는 특성:
- 다중공선성이 강할 때, L1은 서로 상관관계가 높은 특성 그룹 중 하나를 임의로 선택하고 나머지 계수를 0으로 만드는 경향이 있어 재표본추출(resampling) 간 추정치가 불안정해집니다.
- L2는 상관관계가 높은 특성들을 모두 유지하며 가중치를 분배하고 함께 축소합니다.
3. ElasticNet:
- 두 페널티를 결합한 형태입니다: $\lambda_1 \|w\|_1 + \lambda_2 \|w\|_2^2$ (보통 $\alpha$와 $l_1\_\text{ratio}$로 매개변수화됨).
- Lasso의 희소성 및 특성 선택 이점을 제공하는 동시에 Ridge의 그룹화 효과를 유지하여 상관관계가 있는 예측 변수 군집을 함께 선택합니다. 특성 수가 샘플 수보다 많은 경우($p > N$)나 심각한 다중공선성이 존재할 때 특히 유용합니다.
12릿지 회귀(Ridge regression), 주성분 회귀(PCR, Principal Component Regression), 부분 최소제곱(PLS, Partial Least Squares)의 개념적 차이는 무엇인가요?
릿지 회귀, 주성분 회귀(PCR, Principal Component Regression), 부분 최소제곱(PLS, Partial Least Squares)은 다중공선성과 고차원 문제를 다루는 세 가지 선형 기법이지만, 분산을 줄이는 방식과 차원 축소가 연속적인지 혹은 지도 방식(supervised)인지에 차이가 있습니다:
1. 릿지 회귀(Ridge Regression): 원래의 $p$개 특성을 모두 유지하면서 L2 페널티를 통해 계수의 크기를 연속적으로 축소(shrinkage)합니다. 저차원 잠재 성분을 생성하거나 특성 차원을 버리지 않으며, 대신 $X^T X$의 고유값이 작은 방향을 따라 분산을 축소합니다.
2. 주성분 회귀(PCR): 2단계로 진행되는 비지도(unsupervised) 차원 축소 기법입니다. 먼저 설명 변수 행렬 $X$에만 주성분 분석(PCA, Principal Component Analysis)을 엄격히 적용하여 최대 분산을 갖는 직교 방향을 찾고, 상위 $k$개의 주성분을 선택한 뒤 이 $k$개 성분에 대해 보통 최소제곱(OLS, Ordinary Least Squares) 회귀를 적합합니다. PCA는 타깃 변수 $y$를 고려하지 않으므로, $X$에서의 분산은 작지만 $y$에 대한 예측력이 높은 주성분이 버려질 위험이 있습니다.
3. 부분 최소제곱(PLS): 지도(supervised) 방식의 차원 축소 기법입니다. $X$와 반응 변수 $y$ 간의 공분산을 극대화하는 $X$의 선형 결합을 찾아 $k$개의 직교 잠재 성분을 구성합니다. 타깃 정보를 명시적으로 반영함으로써 PLS는 특성의 분산과 반응 변수의 변동을 모두 설명하는 성분을 도출합니다.
from sklearn.linear_model import Ridge, LinearRegression
from sklearn.decomposition import PCA
from sklearn.cross_decomposition import PLSRegression
from sklearn.pipeline import make_pipeline
# 1. Ridge: Regularized full feature space
ridge = Ridge(alpha=1.0)
# 2. PCR: Unsupervised PCA followed by OLS
pcr = make_pipeline(PCA(n_components=2), LinearRegression())
# 3. PLS: Supervised latent component projection and regression
pls = PLSRegression(n_components=2)
13XGBoost, LightGBM, CatBoost와 같은 최신 그래디언트 부스팅 구현체들은 학습을 최적화하거나 정형 데이터의 피처(feature)를 처리할 때 어떤 차별화된 방식을 사용하나요?
최신 그래디언트 부스팅 결정 트리(GBDT, Gradient Boosted Decision Tree) 프레임워크들은 분할 탐색(split-finding) 알고리즘, 트리 성장 전략, 정형/범주형 피처 처리 방식에서 상당한 차이를 보입니다:
1. XGBoost: 전통적으로 정확한 탐욕적(exact greedy) 방식이나 근사 분위수 스케치(approximate quantile sketch) 분할 탐색(이후 Fast Hist 추가)을 사용하며, 레벨별(depth-wise/level-wise) 트리 성장 방식을 취합니다. 또한 결측치는 분할 탐색 과정에서 최적의 기본 분기 방향을 학습하여 처리합니다.
2. LightGBM: 히스토그램 기반 분할 탐색(연속형 피처를 보통 256개의 이산형 버킷으로 비닝)을 사용하고, 빠른 손실 감소를 위해 리프 중심(leaf-wise/best-first) 트리 성장을 적용합니다. 또한 그래디언트가 큰 인스턴스는 유지하고 작은 인스턴스는 서브샘플링하는 GOSS(Gradient-based One-Side Sampling)와 상호 배타적인 희소 피처를 병합하는 EFB(Exclusive Feature Bundling)를 사용합니다. 범주형 변수의 경우 범주형 히스토그램 빈을 정렬($O(K \log K)$)하여 최적의 분할을 찾습니다.
3. CatBoost: 특정 깊이의 모든 노드가 완전히 동일한 분할을 공유하는 대칭형(oblivious/symmetric) 결정 트리를 사용하여 CPU/GPU에서 빠른 벡터화 예측을 수행합니다. 핵심적인 혁신은 정렬된 타깃 통계량(Ordered Target Statistics)과 순서형 부스팅(ordered boosting)으로, 학습 데이터의 무작위 순열(permutation)을 기반으로 타깃 통계량을 계산하여 타깃 누수(target leakage)와 예측 편향(prediction shift)을 방지합니다.
14비대칭적인 비즈니스 비용이 발생하는 상황에서 그래디언트 부스팅 모델에 사용자 정의 손실 함수(custom loss)를 적용할지 여부를 어떻게 결정하시겠습니까?
비대칭적인 비즈니스 비용이 존재할 때 그래디언트 부스팅 모델에 사용자 정의 손실 함수를 도입할지 결정하려면, 해당 비대칭성을 확률 보정(probability calibration)과 임계값 튜닝을 통해 다운스트림에서 처리할 수 있는지, 아니면 트리 분할 과정에서 최적화 지형(optimization landscape) 자체를 근본적으로 바꿔야 하는지를 평가해야 합니다.
1. 임계값 튜닝 대 사용자 정의 손실 함수: 오류 비용이 비대칭적인 분류 작업(예: 거짓 음성 비용이 거짓 양성 비용의 10배인 경우)에서 표준 크로스 엔트로피는 사후 확률 $P(y=1|x)$를 추정하기에 적합한 적정 점수 규칙(proper scoring rule)이지만, 검증 데이터에서 보정 상태를 확인하고 필요 시 교정해야 합니다. 비즈니스 비용 행렬 $\tau = \frac{C_{FP}}{C_{FP} + C_{FN}}$에 기반해 분류 결정 임계값을 조정하거나 샘플 가중치를 적용하는 방식이 구현상 더 깔끔하며 복잡한 도함수 계산을 피할 수 있습니다. 반면, 비대칭 회귀(예: 재고 수요 예측을 위한 비대칭 핀볼 손실)나 표준 목적 함수로는 최적의 분할을 유도할 수 없는 비선형적 페널티 구조에서는 사용자 정의 손실 함수를 사용하는 것이 적절합니다.
2. GBDT의 수학적 요구사항: 2차 미분을 활용하는 부스터(XGBoost, LightGBM)의 경우, 분할 이득(split gain) 및 리프 노드 가중치($w^* = -\sum g_i / (\sum h_i + \lambda)$)를 계산하기 위해 사용자 정의 손실 $L(y, \hat{y})$에 대해 1차 도함수 그래디언트($g_i = \partial L / \partial \hat{y}_i$)와 2차 곡률인 헤시안($h_i = \partial^2 L / \partial \hat{y}_i^2$)을 계산할 수 있어야 합니다. 수치적 안정성을 위해 헤시안 값은 음수가 아니어야 하며, 안전하게 근사하거나 클리핑해야 합니다. 일부 프레임워크는 1차 미분이나 근사 목적 함수도 지원하므로 구체적인 요구사항은 프레임워크에 따라 다릅니다. 미분 불가능하거나 불연속적인 비즈니스 지표는 매끄러운 대리(surrogate) 근사치(예: 후버(Huber) 변형 또는 log-cosh 변형)로 대체해야 합니다.
import numpy as np
import xgboost as xgb
def asymmetric_mse_objective(preds, dtrain):
labels = dtrain.get_label()
residual = preds - labels
# Penalize underestimation (residual < 0) 5x more heavily than overestimation
penalty = np.where(residual < 0, 5.0, 1.0)
grad = 2.0 * penalty * residual
hess = 2.0 * penalty
return grad, hess
# Usage:
# model = xgb.train(params, dtrain, obj=asymmetric_mse_objective)
15LambdaMART란 무엇이며, 랭킹 학습(Learning-to-Rank) 목적식에 맞게 그래디언트 부스팅을 어떻게 적용하나요?
LambdaMART는 MART(Multiple Additive Regression Trees, 그래디언트 부스팅)와 LambdaRank 프레임워크를 결합한 LTR(Learning-to-Rank) 알고리즘입니다. 랭킹 작업에서 NDCG(Normalized Discounted Cumulative Gain)나 MAP 같은 목표 지표는 이산적인 정렬 순서(순위)에 의존하므로, 대부분의 구간에서 기울기가 0(flat)이며 연속적인 모델 점수에 대해 미분이 불가능합니다. LambdaMART는 동일한 쿼리 내의 아이템 쌍 $(i, j)$에 대해 '람다 그래디언트(lambda gradient)'($\lambda_{ij}$)라 불리는 가상 그래디언트를 구성하여 이 문제를 해결합니다. 기본 쌍별(pairwise) 그래디언트는 점수 차이($s_i - s_j$)에 대한 로지스틱 손실에서 도출됩니다. LambdaMART는 문서 $i$와 문서 $j$의 위치가 바뀌었을 때 발생하는 목표 랭킹 지표의 변화량 절댓값($|\Delta \text{NDCG}_{ij}|$)으로 이 그래디언트를 스케일링합니다: $$\lambda_{ij} = \frac{-\sigma}{1 + e^{\sigma(s_i - s_j)}} |\Delta \text{NDCG}_{ij}|$$ 개별 문서 $i$에 대한 최종 그래디언트는 문서 $i$가 포함된 모든 쌍의 람다 값을 집계하여 계산됩니다: $\lambda_i = \sum_{j: j \succ i} \lambda_{ij} - \sum_{k: i \succ k} \lambda_{ki}$. 그런 다음 부스팅 앙상블의 표준 회귀 트리가 각 부스팅 반복마다 이 문서별 결합 람다 그래디언트를 피팅하여, 리스트 단위(listwise) 랭킹 지표를 직접 최적화합니다.
import lightgbm as lgb
import numpy as np
# Simulated query-grouped data: 2 queries with 3 docs each
X = np.random.randn(6, 10)
y = np.array([3, 1, 0, 2, 0, 1]) # Relevance grades (0-3)
group = [3, 3] # Query group sizes
train_data = lgb.Dataset(X, label=y, group=group)
params = {
'objective': 'lambdarank',
'metric': 'ndcg',
'ndcg_eval_at': [1, 3],
'learning_rate': 0.1,
'n_estimators': 50
}
ranker = lgb.train(params, train_data)