처리해야 할 데이터 종류에 따라서 classification 작업의 복잡성이 증가하게 되어 설정하는 조건에 따라서 민감한 결과들이 얻어지기도 한다.
다음 그림에서 3가지 결과를 검토해보자. 첫 번째는 직선적 hyperplane으로 분리한 결과 현재의 2차원 문제에서 절편 값이 상당히 커 보일 정도로 직선화되어 있는데 다시 말하면 바이아스 값 b 또는 w0 의 값이 지나치게 크게끔 처리 되었다.
두번째는 곡선형 hyperplane으로 분리되었으며 일부 포기하는 데이터가 포함되었다. 세 번째는 포기하는 데이터가 전혀 없는 대신에 상당히 복잡한 형태의 hyperplane을 보여주는데 이러한 경우를 과잉학습에 의해 Overfitting 되었다고 하며 Variance 가 높다고 평가한다. Variance 란 예측 모델을 여러 번 재학습 시킬 경우에 특수한 샘플 데이터들에 대한 모델의 일관성을 측정하는 척도라고 보면 된다. 이러한 사례는 5만개에 달하는 MNIST 데이터를 모조리 학습시키면 Overfitting이 일어나 너무 민감하므로 현실적으로는 100개 단위 묶음으로 임의로 추출하여 여러 번 학습 시키는 사례가 있다.
즉 학습단계에서는 Overfitting 이 일어나도 학습까지는 완료가 되겠지만 decision boundary 의 형상이 너무 복잡하여 트렌드를 상실하게 되므로 그 다음 테스트 데이터를 넣었을 경우 판단이 애매할 수밖에 없다.
실제로 다음의 SVM 기법 사례를 보면 그러한 High Variance인 과잉학습 현상이 classification 작업에서 나타나는 것이 사실인 듯하다. 반면에 오른쪽의 High Bias 두가지 사례를 보면 동일한 랜덤 데이터에 대해서도 시스템적으로 처리하는 방법에 따라서 극단적일 정도로 지나치게 다른 양상을 보여 주기도 한다.
이와 같이 양극단간에서 좋은 결과를 얻어내기 위한 trade off 작업 단계에서 Regularization을 통해 모델의 복잡성을 튜닝해야 해야 할 필요가 있다. Regularization은 높은 상관관계를 갖는 특징(features) 데이타들을 처리하고 데이터에 포함되어 있는 노이즈를 제거함과 동시에 궁극적으로는 Overfitting을 방지하는 기법으로서 그 배경에 깔린 개념은 극단적인 웨이트 값 생성에 페널티를 부과할 수 있도록 바이아스 정보를 추가적으로 도입한다.
L2 로 불리우는 가장 보편적인 형태의 Regularization 은 다음과 같이 파라메터 λ를 사용하여 표현된다.
이 항들은 Margin 최대화 알고리듬에서 이미 최소화가 필요한 항으로 지적되었다. 따라서 cost 함수에 부가하여 사용이 가능하며 사용자가 임의로 λ값을 조절할 수 있는데 실제 코딩에서는 그 역수인 C 값이 사용된다.
다음의 코딩에서처럼 ‘linear’ kernel을 사용하여 특정 C 값에 대한 SVM 사례를 실행해 보자.
#ch03_data_read_1_3.py
from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target
print('Class labels:', np.unique(y))
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=1, stratify=y)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
#Training a perceptron via scikit-learn
#Redefining the plot_decision_region function from chapter 2:
from sklearn.linear_model import Perceptron
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):
# setup marker generator and color map
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
# plot the decision surface
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0],
y=X[y == cl, 1],
alpha=0.8,
c=colors[idx],
marker=markers[idx],
label=cl,
edgecolor='black')
# highlight test samples
if test_idx:
# plot all samples
X_test, y_test = X[test_idx, :], y[test_idx]
plt.scatter(X_test[:, 0],
X_test[:, 1],
c='',
edgecolor='black',
alpha=1.0,
linewidth=1,
marker='o',
s=100,
label='test set')
#Maximum margin classification with support vector machines
#Maximum margin intuition
#Dealing with the nonlinearly separable case using slack variables
from sklearn.svm import SVC
from matplotlib.colors import ListedColormap
svm = SVC(kernel='linear', C=1.0, random_state=1)
svm.fit(X_train_std, y_train)
X_combined_std = np.vstack((X_train_std, X_test_std))
y_combined = np.hstack((y_train, y_test))
plot_decision_regions(X_combined_std,
y_combined,
classifier=svm,
test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
plt.show()