1. 분류와 회귀
머신러닝(Machine Learning) 은 크게 두 종류로 나타낼 수 있습니다.
- 분류(Classification)
- 회귀(Regression)
분류 (Classification) 는 미리 정의된 가능성 있는 여러 클래스 레이블 중 하나를 예측하는 것입니다. 분류는 딱 두 개의 클래스로 분류하는 이진 분류와 셋 이상의 클래스로 분류하는 다중 분류로 나뉩니다.
이메일에서 스팸을 분류하는 것이 이진 분류 문제의 한 예입니다.
회귀 (Regression) 는 연속적인 숫자 또는 프로그래밍 용어로 말하면 부동소수점 (Floating Point) 수를 예측하는 것입니다.
어떤 사람의 교육 수준, 나이, 주거지를 바탕으로 연간 소득을 예측하는 것이 회귀 문제의 한 예입니다.
출력값이 연속성이 있는지를 질문해보면 회귀와 분류 문제를 쉽게 구분할 수 있습니다.
2. 일반화 (Normalization), 과대 적합 (Overfitting), 과소 적합 (Underfitting)
모델이 처음 보는 데이터에 대해 정확하게 예측할 수 있으면, 이를 훈련 세트 (Training Set) 에서 테스트 세트 (Test Set) 로 일반화 (Normalization) 되었다고 합니다. 그래서 모델을 만들 때는 가능한 한 정확하게 일반화되도록 해야 합니다.
보통 훈련 세트에 대해 정확히 예측하도록 모델을 구축합니다. (* 훈련 세트로 모델을 훈련 시키기 때문에 훈련 세트에 대해 정확할 수 있다) 훈련 세트와 테스트 세트가 매우 비슷하다면 그 모델이 테스트 세트에서도 정확히 예측하리라 기대할 수 있습니다. 그러나 항상 그런 것만은 아닙니다. 예를 들어 아주 복잡한 모델을 만든다면 훈련 세트에만 정확한 모델이 될 수 있습니다.(* Overfitting)
훈련 세트에 100%의 정확도를 달성하는 것은 목표가 아닙니다. 초보 데이터 과학자가 했던 것처럼 가진 정보를 모두 사용해서 너무 복잡한 모델을 만드는 것을 과대 적합 (Overfitting) 이라고 합니다. 과대 적합은 모델이 훈련 세트의 각 샘플에 너무 가깝게 맞춰져서 새로운 데이터에 일반화되기 어려울 때 일어납니다.
반대로 모델이 너무 간단하면, 즉 "집이 있는 사람은 모두 요트를 사려고 한다" 와 같은 경우에는 데이터의 면면과 다양성을 잡아내지 못할 것이고 훈련 세트에도 잘 맞지 않을 것입니다. 너무 간단한 모델이 선택되는 것을 과소 적합 (Underfitting) 이라고 합니다.
모델을 복잡하게 할수록 훈련 데이터에 대해서는 더 정확히 예측할 수 있습니다. 그러나 너무 복잡해지면 훈련 세트의 각 데이터 포인트에 너무 민감해져 새로운 데이터에 잘 일반화되지 못합니다. 우리가 찾으려는 모델은 일반화 성능이 최대가 되는 최적점에 있는 모델입니다.
3. 모델 복잡도와 데이터셋의 크기의 관계
데이터셋에 다양한 데이터 포인트가 많을수록 과대적합 없이 더 복잡한 모델을 만들 수 있습니다. 보통 데이터 포인트를 더많이 모으는 것이 다양성을 키워주므로 큰 데이터셋은 더 복잡한 모델을 만들 수 있게 해줍니다. 그러나 같은 데이터 포인트를 중복하거나 매우 비슷한 데이터를 모으는것은 도움이 되지 않습니다.(* Overfitting) 데이터를 많이 수집하고 적절하게 더 복잡한 모델을 만들면 지도 학습 문제에서 종종 놀라운 결과를 얻을 수 있습니다. 모델을 변경하거나 조정하는 것보다 더 이득일 수 있으므로 실제 환경에서는 데이터를 얼마나 많이 모을지 정해야 합니다. 데이터양의 힘을 과소평가하지 마세요.
4. 지도 학습 알고리즘
4.1 KNN 알고리즘 (k-최근접 이웃)
k-NN 알고리즘은 가장 간단한 머신러닝 알고리즘입니다. 훈련 데이터셋을 그냥 저장하는 것이 모델을만드는 과정의 전부입니다. 새로운 데이터 포인트에 대해 예측할 땐 알고리즘이 훈련 데이터셋에서 가장 가까운 데이터 포인트, 즉 '최근접 이웃' 을 찾습니다.
가장 간단한 k-NN 알고리즘은 가장 가까운 훈련 데이터 포인트 하나를 최근접 이웃으로 찾아 예측에 사용합니다. 단순히 훈련 데이터 포인트의 출력이 예측됩니다. 가장 가까운 이웃 하나가 아니라 임의의 k개를 선택할 수도 있습니다. 그래서 k-최근접 이웃 알고리즘이라 불립니다. 둘 이상의 이웃을 선택할 때는 레이블을 정하기 위해 투표를 합니다. 투표 결과 이웃이 더 많은 클래스를 레이블로 지정합니다. scikit-learn 을 사용하여 적용해보겠습니다.
from sklearn.model_selection import train_test_split
X, y = mglearn.datasets.make_forge()
X_train, y_train, X_test, y_test = train_test_split(X, y, random_state=0)
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors = 3)
clf.fit(X_train, y_train)
print("테스트 세트 예측 : ", clf.predict(X_test))
print("테스트 세트 정확도 : {:.2f}", .format(clf.score(X_test, y_test)))
모델의 정확도는 86% 로 나왔습니다.
4.2 KNeighborsClassifier 분석
2차원 데이터셋이므로 가능한 모든 테스트 포인트의 예측을 xy 평면에 그려볼 수 있습니다. 그리고 각 데이터 포인트가 속한 클래스에 따라 평면에 색을 칠합니다. 이렇게 하면 알고리즘이 클래스 0과 클래스 1로 지정한 영역으로 나뉘는 결정 경계를 볼 수 있습니다.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 3, figsize=(10,3))
for n_neighbors, ax in zip([1,3,9], axes):
# fit 메소드는 self 오브젝트를 리턴합니다
clf = KNeighborsClassifier(n_neighbors = n_neighbors).fit(X, y)
mglearn.plots.plot_2d_separator(clf, X, fill=True, eps=0.5, ax=ax, alpha=.4)
mglearn.discrete_scatter(X[:,0], X[:,1], y, ax=ax)
ax.set_title("{} neighbors".format(n_neighbors))
ax.set_xlabel("feature 0")
ax.set_ylabel("feature 1")
axes[0].legend(loc=3)
그림을 보면 이웃을 하나 선택했을 때는 결정 경계가 훈련 데이터에 가깝게 따라가고 있습니다(* Overfitting). 이웃의 수를 늘릴수록 결정 경계는 더 부드러워집니다. 부드러운 경계는 더 단순한 모델을 의미합니다. 다시 말해 이웃을 적게 사용하면 모델의 복잡도가 높아지고, 많이 사용하면 복잡도는 낮아집니다. 앞서 이야기한 모델의 복잡도와 일반화 사이의 관계를 입증하기 위해 유방암 데이터셋을 사용하겠습니다.
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
X_train, y_train, X_test, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=66)
training_accuracy = []
test_accuracy = []
# 1 에서 10 까지 n_neighbors 를 적용
neighbors_settings = range(1,11)
for n_neighbors in neighbors_settings:
# 모델 생성
clf = KNeighborsClassifier(n_neighbors = n_neighbors)
clf.fit(X_train, y_train)
# 훈련 세트 정확도 저장
training_accuracy.append(clf.score(X_test, y_test))
#일반화 정확도 저장
test_accuracy.append(clf.score(X_test, y_test))
plt.plot(neigbors_setting, training_accuracy, label="훈련 정확도")
plt.plot(neigbors_setting, test_accuracy, label="테스트 정확도")
plt.ylabel("정확도")
plt.xlabel("n_neighbors")
plt.legend()
여기서 과대 적합과 과소 적합의 특징을 볼 수 있습니다. 최근접 이웃의 수가 하나일 때는 훈련 데이터에 대한 예측이 완벽합니다(* Overfitting). 하지만 이웃의 수가 늘어나면 모델은 단순해지고 훈련 데이터의 정확도는 줄어듭니다. 이웃을 하나 사용한 테스트 세트의 정확도는 이웃을 많이 사용했을 때보다 낮습니다. 이것은 1-최근접 이웃이 모델을 너무 복잡하게 만든다는 것을 설명해줍니다. 반대로 이웃을 10개 사용했을 때는 모델이 너무 단순해서 정확도는 더 나빠집니다. 정확도가 가장 좋을 때는 중간 정도인 7, 8 개를 사용한 경우입니다.
FeedBack
: mglearn 의 각 메소드를 이해하면 좋을 듯
'[Deep daiv.] > 머신러닝' 카테고리의 다른 글
머신러닝 공부 4.1 - 규제 Regularization (0) | 2024.03.30 |
---|---|
머신러닝 공부 - 4 Lasso (.contd) and LinearClassifier (0) | 2024.03.25 |
머신러닝 공부 - 3 Ridge Regression and Lasso (0) | 2024.03.23 |
머신러닝 공부 - 2 KNN Regression and Linear Model (0) | 2024.03.22 |