#!/usr/bin/env python # coding: utf-8 # # Chapter 4. 모델 훈련 # In[1]: get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib import matplotlib.pyplot as plt plt.rcParams['axes.labelsize'] = 14 plt.rcParams['xtick.labelsize'] = 12 plt.rcParams['ytick.labelsize'] = 12 matplotlib.rc('font', family='NanumBarunGothic') plt.rcParams['axes.unicode_minus'] = False import os import numpy as np np.random.seed(42) m = 100 X = 6 * np.random.rand(m, 1) - 3 y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1) # --- # ## 4.4 학습곡선 # ![Figure4-14](./images/Figure4-14.png) # **
그림 4-14 고차(300차) 다항 회귀
** # In[2]: from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression def plot_learning_curves(model, X, y): X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=10) train_errors, val_errors = [], [] print(X_train.shape, X_val.shape, y_train.shape, y_val.shape) for m in range(1, len(X_train)): model.fit(X_train[:m], y_train[:m]) y_train_predict = model.predict(X_train[:m]) y_val_predict = model.predict(X_val) train_errors.append(mean_squared_error(y_train[:m], y_train_predict)) val_errors.append(mean_squared_error(y_val, y_val_predict)) plt.plot(np.sqrt(train_errors), "r-+", linewidth=2, label="훈련") plt.plot(np.sqrt(val_errors), "b-", linewidth=3, label="검증") plt.legend(loc="upper right", fontsize=14) plt.xlabel("훈련 세트 크기", fontsize=14) plt.ylabel("RMSE", fontsize=14) lin_reg = LinearRegression() plot_learning_curves(lin_reg, X, y) plt.axis([0, 80, 0, 3]) plt.show() # #### ▣ 단순 선형 회귀 모델(직선)의 학습 곡선 # + 훈련 세트 # + 샘플이 하나 혹은 두 개일 때는 모델이 완벽하게 작동 # + 샘플이 추가됨에 따라 노이즈도 있고 데이터가 비선형이기 때문에 모델이 완벽히 학습하는 것이 불가능 # + 오차가 계속 상승하다가 어느 정도를 유지 # + 검증 세트 # + 샘플의 수가 적으면 제대로 일반화될 수 없어서 검증 오차가 초기에 매우 큼 # + 샘플이 추가됨에 따라 학습이 되고 검증 오차가 천천히 감소 # + 선형 회귀의 직선은 데이터를 잘 모델링할 수 없으므로 오차의 감소가 완만해져서 훈련 세트의 그래프와 가까워짐 # + 과소적합 모델의 전형적인 모습 # → 훈련 샘플을 더 추가해도 효과가 없음, 더 복잡한 모델을 사용하거나 더 나은 특성을 선택해야 함 # --- # #### ▣ 10차 다항 회귀 모델의 학습 곡선 # In[3]: from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import Pipeline polynomial_regression = Pipeline([ ("poly_features", PolynomialFeatures(degree=10, include_bias=False)), ("lin_reg", LinearRegression()), ]) plot_learning_curves(polynomial_regression, X, y) plt.axis([0, 80, 0, 3]) plt.show() # + 훈련 데이터의 오차가 선형 회귀 모델보다 훨씬 낮음 # + 두 곡선 사이에 공간이 있음. 훈련 데이터에서의 모델 성능이 검증 데이터에서보다 훨씬 낫다는 뜻으로 과대적합 모델의 특징임. 그러나 더 큰 훈련 세트를 사용하면 두 곡선이 점점 가까워짐 # + 과대적합 모델을 개선하는 한 가지 방법은 검증 오차가 훈련 오차에 근접할 때까지 더 많은 훈련 데이터를 추가하는 것 # --- # #### ▣ 편향/분산 트레이드오프 # # ※ 모델의 일반화 오차는 세 가지 다른 종류의 오차의 합으로 표현할 수 있음 # + **편향** # 일반화 오차 중에서 편향은 잘못된 가정으로 인한 것임. (예를 들어 데이터가 실제로는 2차인데 선형으로 가정하는 경우) 편향이 큰 모델은 훈련 데이터에 과소적합되기 쉬움 # + **분산** # 분산variance은 훈련 데이터에 있는 작은 변동에 모델이 과도하게 민감하기 때문에 나타남. 자유도가 높은 모델(예를 들면 고차 다항 회귀 모델)이 높은 분산을 가지기 쉬워 훈련 데이터에 과대적합되는 경향이 있음 # + **줄일 수 없는 오차** # 줄일 수 없는 오차irreducible error는 데이터 자체에 있는 노이즈 때문에 발생함. 이 오차를 줄일 수 있는 유일한 방법은 데이터에서 노이즈를 제거하는 것(예를 들어 고장 난 센서 같은 데이터 소스를 고치거나 이상치를 감지해 제거함) # # ※ 모델의 복잡도가 커지면 통상적으로 분산이 늘어나고 편향은 줄어듬. 반대로 모델의 복잡도가 줄어들면 편향이 커지고 분산이 작아짐. # --- # ## 4.5 규제가 있는 선형 모델 # ### 4.5.1 릿지 회귀 # ▣ **릿지 회귀**(또는 **티호노프**Tikhonov 규제) : 규제가 추가된 선형 회귀 # + 규제항 : 가중치 벡터의 $l_2$ 노름의 제곱을 2로 나눈 것을 사용 # + $\alpha$로 모델을 얼마나 많이 규제할지 조절 # + 규제항은 훈련하는 동안에만 비용 함수에 추가됨 # + 모델의 훈련이 끝나면 모델의 성능을 규제가 없는 성능 지표로 평가 # # ![Equation4-8](./images/Equation4-8.png) # **
식 4-8 릿지 회귀의 비용 함수
** # --- # ![Figure4-17](./images/Figure4-17.png) # **
그림 4-17 릿지 회귀
** # + 왼쪽 그래프는 평범한 릿지 모델 # + 오른쪽 그래프는 PolynomialFeatures(degree=10)을 사용해 데이터를 확장하고 StandardScaler를 사용해 스케일을 조정한 릿지 모델 # + $\alpha$가 커질수록 모든 가중치가 거의 0에 가까워지고 결국 데이터의 평균을 지나는 수평선이 됨 # → 모델의 분산은 줄지만 편향은 커짐 # --- # ![Equation4-9](./images/Equation4-9.png) # **
식 4-9 릿지 회귀의 정규방정식
** # + A는 편향에 해당하는 맨 왼쪽 위의 원소가 0인 $(n+1)\times(n+1)$의 단위행렬identity matrix # In[4]: from sklearn.linear_model import Ridge from sklearn.linear_model import SGDRegressor np.random.seed(42) m = 20 X = 3 * np.random.rand(m, 1) y = 1 + 0.5 * X + np.random.randn(m, 1) / 1.5 # In[5]: # 정규방정식을 사용한 릿지 회귀 ridge_reg = Ridge(alpha=1, solver="cholesky", random_state=42) ridge_reg.fit(X, y) ridge_reg.predict([[1.5]]) # + solver 매개변수의 기본값은 'auto'며 희소 행렬이나 특이 행렬(singular matrix)이 아닐 경우 'cholesky'가 됨 # In[6]: # 확률적 경사 하강법을 사용한 릿지 회귀 sgd_reg = SGDRegressor(max_iter=5, penalty="l2", random_state=42) sgd_reg.fit(X, y.ravel()) sgd_reg.predict([[1.5]]) # In[7]: ridge_reg = Ridge(alpha=1, solver="sag", random_state=42) ridge_reg.fit(X, y) ridge_reg.predict([[1.5]]) # + 확률적 평균 경사 하강법(Stochastic Average Gradient Descent, SAG) - SGD의 변종 # : 현재 그래디언트와 이전 스텝에서 구한 모든 그래디언트를 합해서 평균한 값으로 모델 파라미터를 갱신 # --- # ### 4.5.2 라쏘 회귀 # ▣ **라쏘**Least Absolute and Selection Operator(Lasso) **회귀** : 선형 회귀의 또 다른 규제된 버전 # + 규제항 : 가중치 벡터의 $l_1$ 노름을 사용 # ![Equation4-10](./images/Equation4-10.png) # **
식 4-10 라쏘 회귀의 비용함수
** # --- # ![Figure4-18](./images/Figure4-18.png) # **
그림 4-18 라쏘 회귀
** # + 덜 중요한 특성의 가중치를 완전히 제거하려고 함(즉, 가중치가 0이 됨) # + 자동으로 특성 선택을 하고 **희소 모델**sparse model을 만듬(즉, 0이 아닌 특성의 가중치가 적음) # --- # ![Figure4-19](./images/Figure4-19.png) # **
그림 4-19 라쏘 및 릿지 규제
** # + 파란 배경의 등고선(타원형) : 규제가 없는($\alpha$=0) MSE 비용 함수 # + 하얀색 원 : 비용 함수에 대한 배치 경사 하강법의 경로 # + 무지개색 등고선 : $l_1$(다이아몬드형, 왼쪽 위), $l_2$(타원형, 왼쪽 아래) 페널티에 대한($\alpha$→**∞**) 배치 경사 하강법의 경로 # + 오른쪽 위 그래프 : $\alpha$=0.5의 $l_1$ 페널티가 더해진 비용 함수 → 라쏘 회귀의 비용함수 # + 오른쪽 아래 그래프 : $\alpha$=0.5의 $l_2$ 페널티가 더해진 비용 함수 → 릿지 회귀의 비용함수 # ※ 규제가 있는 경우의 최젓값이 규제가 없는 경우보다 $\theta$값이 0에 더 가까움(가중치가 완전히 제거되지는 않음) # --- # + 라쏘의 비용 함수는 $\theta_i$=0($i$=1~n)에서 미분 불가능 # → **서브그래디언트 벡터**subgradient vector **g**를 사용하여 해결 # ![Equation4-11](./images/Equation4-11.png) # **
식 4-11 라쏘 회귀의 서브그래디언트 벡터
** # In[8]: from sklearn.linear_model import Lasso # 정규방정식을 사용한 라쏘 회귀 lasso_reg = Lasso(alpha=0.1) lasso_reg.fit(X, y) lasso_reg.predict([[1.5]]) # In[9]: # 확률적 경사 하강법을 사용한 라쏘 회귀 sgd_reg = SGDRegressor(max_iter=5, penalty="l1", random_state=42) sgd_reg.fit(X, y.ravel()) sgd_reg.predict([[1.5]]) # --- # ### 4.5.3 엘라스틱넷 # ▣ **엘라스틱넷**Elastic Net : 릿지 회귀와 라쏘 회귀를 절충한 모델 # + 규제항은 릿지 회귀와 라쏘 회귀의 규제항을 단순히 더해서 사용 # + 혼합 정도는 혼합 비율 r을 사용해 조절 # + r=0 → 릿지 회귀 # + r=1 → 라쏘 회귀 # ![Equation4-12](./images/Equation4-12.png) # **
식 4-12 엘라스틱넷 비용 함수
** # In[10]: from sklearn.linear_model import ElasticNet elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5, random_state=42) elastic_net.fit(X, y) elastic_net.predict([[1.5]]) # --- # ▣ **보통의 선형 회귀, 릿지, 라쏘, 엘라스틱넷** # + 적어도 규제가 약간 있는 것이 대부분의 경우에 좋으므로 일반적으로 평범한 선형 회귀는 피해야 함 # + 릿지가 기본, 실제로 쓰이는 특성이 몇 개뿐이라고 의심되면 라쏘나 엘라스틱넷이 좋음(불필요한 특성의 가중치를 0으로 만듦) # + 특성 수가 훈련 샘플 수보다 많거나 특성 몇 개가 강하게 연관되어 있을 때는 보통 라쏘보다 엘라스틱넷이 선호됨(라쏘는 특성 수가 샘플 수(n)보다 많으면 최대 n개의 특성을 선택함. 또, 여러 특성이 강하게 연관되어 있으면 이들 중 임의의 특성 하나를 선택함) # --- # ### 4.5.4 조기 종료 # ▣ **조기 종료**early stopping : 검증 에러가 최솟값에 도달하면 바로 훈련을 중지시키는 방식 # ![Figure4-20](./images/Figure4-20.png) # **
그림 4-20 조기 종료 규제
** # In[11]: from sklearn.preprocessing import StandardScaler from sklearn.base import clone X_train, X_val, y_train, y_val = train_test_split(X[:50], y[:50].ravel(), test_size=0.5, random_state=10) poly_scaler = Pipeline([ ("poly_features", PolynomialFeatures(degree=90, include_bias=False)), ("std_scaler", StandardScaler()), ]) X_train_poly_scaled = poly_scaler.fit_transform(X_train) X_val_poly_scaled = poly_scaler.transform(X_val) sgd_reg = SGDRegressor(max_iter=1, warm_start=True, penalty=None, learning_rate="constant", eta0=0.0005, random_state=42) minimum_val_error = float("inf") best_epoch = None best_model = None for epoch in range(1000): sgd_reg.fit(X_train_poly_scaled, y_train) # 이어서 학습합니다 y_val_predict = sgd_reg.predict(X_val_poly_scaled) val_error = mean_squared_error(y_val, y_val_predict) if val_error < minimum_val_error: minimum_val_error = val_error best_epoch = epoch best_model = clone(sgd_reg) best_epoch, best_model # **※** warm_start=True로 지정하면 fit() 메서드가 호출될 때 처음부터 다시 시작하지 않고 이전 모델 파라미터에서 훈련을 이어감 # ◈ SGDRegressor : https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDRegressor.html # --- # ### 4.6 로지스틱 회귀 # ▣ **로지스틱 회귀**Logistic Regression(또는 **로짓 회귀**Logit Regression) : 샘플이 특정 클래스에 속할 확률을 추정 # e.g.) 이메일이 스팸일 확률(이진 분류기) # --- # ### 4.6.1 확률 추정 # ![Equation4-13](./images/Equation4-13.png) # **
식 4-13 로지스틱 회귀 모델의 확률 추정(벡터 표현식)
** # **※** $\sigma(·)$ → logistic 또는 logit이라고 부름 # : 0과 1사이의 값을 출력하는 **시그모이드 함수**sigmoid function (S자 형태) # ![Equation4-14](./images/Equation4-14.png) # **
식 4-14 로지스틱 함수
** # ![Figure4-21](./images/Figure4-21.png) # **
그림 4-21 로지스틱 함수
** # ![Equation4-15](./images/Equation4-15.png) # **
식 4-15 로지스틱 회귀 모델 예측
** # --- # ### 4.6.2 훈련과 비용 함수 # ![Equation4-16](./images/Equation4-16.png) # **
식 4-16 하나의 훈련 샘플에 대한 비용 함수
** # # # ![Equation4-17](./images/Equation4-17.png) # **
식 4-17 로지스틱 회귀의 비용 함수(로그 손실log loss)
** # # # ![Equation4-18](./images/Equation4-18.png) # **
식 4-18 로지스틱 비용 함수의 편도함수
** # --- # ### 4.6.3 결정 경계 # In[12]: from sklearn import datasets iris = datasets.load_iris() list(iris.keys()) # In[13]: iris.data.shape, iris.target.shape # In[14]: print(iris.DESCR) # In[15]: X = iris["data"][:, 3:] # 꽃잎 넓이 y = (iris["target"] == 2).astype(np.int) # Iris-Virginica이면 1 아니면 0 X.shape, y.shape # In[16]: from sklearn.linear_model import LogisticRegression log_reg = LogisticRegression(solver='liblinear', random_state=42) log_reg.fit(X, y) # + 다른 선형 모델처럼 로지스틱 회귀 모델도 $l_1, l_2$ 페널티를 사용하여 규제할 수 있음 # + 사이킷런은 $l_2$ 페널티를 기본으로 함 # + LogisticRegression 모델의 규제 강도를 조절하는 하이퍼파라미터는 # alpha가 아니고 그 역수에 해당하는 C(높을수록 규제가 줄어듦) # # **※** https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html # In[17]: X_new = np.linspace(0, 3, 1000).reshape(-1, 1) y_proba = log_reg.predict_proba(X_new) decision_boundary = X_new[y_proba[:, 1] >= 0.5][0] plt.figure(figsize=(8, 3)) plt.plot(X[y==0], y[y==0], "bs") plt.plot(X[y==1], y[y==1], "g^") plt.plot([decision_boundary, decision_boundary], [-1, 2], "k:", linewidth=2) plt.plot(X_new, y_proba[:, 1], "g-", linewidth=2, label="Iris-Virginica") plt.plot(X_new, y_proba[:, 0], "b--", linewidth=2, label="Not Iris-Virginica") plt.text(decision_boundary+0.02, 0.15, "결정 경계", fontsize=14, color="k", ha="center") plt.arrow(decision_boundary, 0.08, -0.3, 0, head_width=0.05, head_length=0.1, fc='b', ec='b') plt.arrow(decision_boundary, 0.92, 0.3, 0, head_width=0.05, head_length=0.1, fc='g', ec='g') plt.xlabel("꽃잎의 폭 (cm)", fontsize=14) plt.ylabel("확률", fontsize=14) plt.legend(loc="center left", fontsize=14) plt.axis([0, 3, -0.02, 1.02]) plt.show() # In[18]: decision_boundary # In[19]: log_reg.predict([[1.7], [1.5]]) # ![Figure4-24](./images/Figure4-24.png) # **
그림 4-24 선형 결정 경계
** # --- # ### 4.6.4 소프트맥스 회귀 # ▣ **소프트맥스 회귀**softmax Regression 또는 **다항 로지스틱 회귀**Multinomial Logistic Regression # # ![Equation4-19](./images/Equation4-19.png) # **
식 4-19 클래스 $k$에 대한 소프트맥스 점수
** # + 각 클래스는 자신만의 파라미터 벡터 $\theta^{(k)}$가 있음 # + 이 벡터들은 **파라미터 행렬parameter matrix** $\Theta$에 행으로 저장됨 # # ![Equation4-20](./images/Equation4-20.png) # **
식 4-20 소프트맥스 함수
** # + K는 클래스 수 # + $s(x)$는 샘플 x에 대한 각 클래스의 점수를 담고 있는 벡터 # + $\sigma(s(x))_k$는 샘플 x에 대한 각 클래스의 점수가 주어졌을 때 이 샘플이 클래스 k에 속할 추정 확률 # # ![Equation4-21](./images/Equation4-21.png) # **
식 4-21 소프트맥스 회귀 분류기의 예측
** # + 추정 확률이 가장 높은 클래스 → 가장 높은 점수를 가진 클래스 # # **※** 소프트맥스 회귀 분류기는 다중 출력multioutput이 아니라 한 번에 하나의 클래스만 예측하는 **다중 클래스**multiclass이기 때문에 상호 배타적인 클래스에서만 사용해야 함 # --- # ![Equation4-22](./images/Equation4-22.png) # **
식 4-22 크로스 엔트로피 비용 함수
** # + $i$번째 샘플에 대한 타깃 클래스가 $k$일 때 $y_k^{(i)}$가 1이고, 그 외에는 0 # + 딱 두 개의 클래스가 있을 때(K=2) 이 비용 함수는 로지스틱 회귀의 비용 함수와 같음(식 4-17의 로그 손실) # # ![Equation4-23](./images/Equation4-23.png) # **
식 4-23 클래스 $k$에 대한 크로스 엔트로피의 그래디언트 벡터
** # In[20]: X = iris["data"][:, (2, 3)] # 꽃잎 길이, 꽃잎 넓이 y = iris["target"] softmax_reg = LogisticRegression(multi_class="multinomial",solver="lbfgs", C=10, random_state=42) softmax_reg.fit(X, y) # + LogisticRegression은 클래스가 둘 이상일 때 기본적으로 일대다(OvA) 전략을 사용 # + multi_class 매개변수를 "multinomial"로 바꾸면 소프트맥스 회귀를 사용할 수 있음 # + 소프트맥스 회귀를 사용하려면 solver 매개변수에 "lbfgs"와 같이 소프트맥스 회귀를 지원하는 알고리즘을 지정해야 함 # In[21]: softmax_reg.predict([[5, 2]]) # In[22]: softmax_reg.predict_proba([[5, 2]]) # ![Figure4-25](./images/Figure4-25.png) # **
그림 4-25 소프트맥스 회귀 결정 경계
** # --- # ### 4.7 연습문제 # #### 1. 수백만 개의 특성을 가진 훈련 세트에서는 어떤 선형 회귀 알고리즘을 사용할 수 있을까요? # ☞ 수백만 개의 특성이 있는 훈련 세트를 가지고 있다면 **확률적 경사 하강법(SGD)**이나 **미니배치 경사하강법**을 사용할 수 있습니다. 훈련 세트가 메모리 크기에 맞으면 배치 경사 하강법도 가능합니다. 하지만 정규방정식은 계산 복잡도가 특성 개수에 따라 매우 빠르게 증가하기 때문에 사용할 수 없습니다. # #### 2. 훈련 세트에 있는 특성들이 각기 아주 다른 스케일을 가지고 있습니다. 이런 데이터에 잘 작동하지 않는 알고리즘은 무엇일까요? 그 이유는 무엇일까요? 이 문제를 어떻게 해결할 수 있을까요? # ☞ 훈련 세트에 있는 특성의 스케일이 매우 다르면 비용 함수는 길쭉한 타원 모양의 그릇 형태가 됩니다. 그래서 **경사 하강법(GD) 알고리즘이 수렴하는 데 오랜 시간이 걸릴 것입니다.** 이를 해결하기 위해서는 **모델을 훈련하기 전에 데이터의 스케일을 조절**해야 합니다. 정규방정식은 스케일 조정 없이도 잘 작동합니다. 또한 규제가 있는 모델은 특성의 스케일이 다르면 지역 최적점에 수렴할 가능성이 있습니다. 실제로 규제는 가중치가 커지지 못하게 제약을 가하므로 특성값이 작으면 큰 값을 가진 특성에 비해 무시되는 경향이 있습니다. # #### 3. 경사 하강법으로 로지스틱 회귀 모델을 훈련시킬 때 지역 최솟값에 갇힐 가능성이 있을까요? # ☞ 로지스틱 회귀 모델의 비용 함수는 **볼록 함수**이므로 경사 하강법이 훈련될 때 지역 최솟값에 갇힐 가능성이 없습니다. # #### 4. 충분히 오랫동안 실행하면 모든 경사 하강법 알고리즘이 같은 모델을 만들어낼까요? # ☞ 최적화할 함수가 (선형 회귀나 로지스틱 회귀처럼) **볼록 함수이고 학습률이 너무 크지 않다고 가정하면 모든 경사 하강법 알고리즘이 전역 최적값에 도달**하고 결국 비슷한 모델을 만들 것입니다. 하지만 학습률을 점진적으로 감소시키지 않으면 SGD와 미니배치 GD는 진정한 최적점에 수렴하지 못할 것입니다. 대신 전역 최적점 주변을 이리저리 맴돌게 됩니다. 이 말은 매우 오랫동안 훈련을 해도 경사 하강법 알고리즘들은 조금씩 다른 모델을 만들게 된다는 뜻입니다. # #### 5. 배치 경사 하강법을 사용하고 에포크마다 검증 오차를 그래프로 나타내봤습니다. 검증 오차가 일정하게 상승되고 있다면 어떤 일이 일어나고 있는 걸까요? 이 문제를 어떻게 해결할 수 있나요? # + 훈련 에러도 같이 올라간다면 학습률이 너무 높아 알고리즘이 **발산**하는 것이기 때문에 학습률을 낮추어야 함 # + 훈련 에러는 올라가지 않는다면 모델이 훈련 세트에 **과대적합**된 것이므로 훈련을 멈추어야 함 # #### 6. 검증 오차가 상승하면 미니배치 경사 하강법을 즉시 중단하는 것이 좋은 방법인가요? # ☞ 무작위성 때문에 확률적 경사 하강법이나 미니배치 경사 하강법 모두 매 훈련 반복마다 학습의 진전을 보장하지 못합니다. 검증 에러가 상승될 때 훈련을 즉시 멈춘다면 최적점에 도달하기 전에 너무 일찍 멈추게 될지 모릅니다. 더 나은 방법은 **정기적으로 모델을 저장하고 오랫동안 진전이 없을 때(즉, 최상의 점수를 넘어서지 못하면), 저장된 것 중 가장 좋은 모델로 복원하는 것**입니다. # #### 7. (우리가 언급한 것 중에서) 어떤 경사 하강법 알고리즘이 가장 빠르게 최적 솔루션의 주변에 도달할까요? 실제로 수렴하는 것은 어떤 것인가요? 다른 방법들도 수렴하게 만들 수 있나요? # ☞ **확률적 경사 하강법은 한 번에 하나의 훈련 샘플만 사용하기 때문에 훈련 반복이 가장 빠릅니다.** 그래서 가장 먼저 전역 최적점 근처에 도달합니다(그다음이 작은 미니배치 크기를 가진 미니배치 GD입니다). 그러나 **훈련 시간이 충분하면 배치 경사 하강법만 실제로 수렴할 것입니다.** 앞서 언급한 대로 **학습률을 점진적으로 감소**시키지 않으면 SGD와 미니배치 GD는 최적점 주변을 맴돌 것입니다. # #### 8. 다항 회귀를 사용했을 때 학습 곡선을 보니 훈련 오차와 검증 오차 사이에 간격이 큽니다. 무슨 일이 생긴 걸까요? 이 문제를 해결하는 세 가지 방법은 무엇인가요? # ☞ 검증 오차가 훈련 오차보다 훨씬 더 높으면 모델이 훈련 세트에 과대적합되었기 때문일 가능성이 높습니다. # 1. **다항 차수 낮추기** : 자유도를 줄이면 과대적합이 훨씬 줄어들 것임 # 2. **모델을 규제** : 예를 들어 비용 함수에 $l_2$ 페널티(릿지)나 $l_1$ 페널티(라쏘)를 추가(이 방법도 모델의 자유도를 감소시킴) # 3. **훈련 세트의 크기 증가시키기** # #### 9. 릿지 회귀를 사용했을 때 훈련 오차와 검증 오차가 거의 비슷하고 둘 다 높았습니다. 이 모델에는 높은 편향이 문제인가요, 아니면 높은 분산이 문제인가요? 규제 하이퍼파라미터 $\alpha$를 증가시켜야 할까요, 아니면 줄여야 할까요? # ☞ 훈련 에러와 검증 에러가 거의 비슷하고 매우 높다면 모델이 훈련 세트에 **과소적합**되었을 가능성이 높습니다. 즉, **높은 편향**을 가진 모델입니다. 따라서 규제 하이퍼파라미터 **$\alpha$를 감소**시켜야 합니다. # #### 10. 다음과 같이 사용해야 하는 이유는? # 1. **평범한 선형 회귀(즉, 아무런 규제가 없는 모델) 대신 릿지 회귀** # 2. **릿지 회귀 대신 라쏘 회귀** # 3. **라쏘 회귀 대신 엘라스틱넷** # 1. **규제가 있는 모델이 일반적으로 규제가 없는 모델보다 성능이 좋습니다.** 그래서 평범한 선형 회귀보다 릿지 회귀가 선호됩니다. # 2. 라쏘 회귀는 $l_1$ 페널티를 사용하여 가중치를 완전히 0으로 만드는 경향이 있습니다. 이는 가장 중요한 가중치를 제외하고는 모두 0이 되는 희소한 모델을 만듭니다. 또한 자동으로 특성 선택의 효과를 가지므로 **단지 몇 개의 특성만 실제 유용할 것이라고 의심될 때 사용하면 좋습니다.** 만약 확신이 없다면 릿지 회귀를 사용해야 합니다. # 3. **라쏘가 어떤 경우(몇 개의 특성이 강하게 연관되어 있거나 훈련 샘플보다 특성이 더 많을 때)에는 불규칙하게 행동**하므로 엘라스틱넷이 라쏘보다 일반적으로 선호됩니다. 그러나 추가적인 하이퍼파라미터가 생깁니다. 불규칙한 행동이 없는 라쏘를 원하면 엘라스틱넷에 l1_ratio를 1에 가깝게 설정하면 됩니다. # #### 11. 사진을 낮과 밤, 실내와 실외로 분류하려 합니다. 두 개의 로지스틱 회귀 분류기를 만들어야 할까요, 아니면 하나의 소프트맥스 회귀 분류기를 만들어야 할까요? # ☞ 실외와 실내, 낮과 밤에 따라 사진을 구분하고 싶다면 **이 둘은 배타적인 클래스가 아니기 때문에(즉, 네 가지 조합이 모두 가능하므로) 두 개의 로지스틱 회귀 분류기를 훈련시켜야 합니다.** # #### 12. 조기 종료를 사용한 배치 경사 하강법으로 소프트맥스 회귀를 구현해보세요(사이킷런은 사용하지 마세요). # **※** https://github.com/rickiepark/handson-ml/blob/master/04_training_linear_models.ipynb