인공지능

[빅데이터 직무연구회] 4회차 모임 정리

Chipmunks 2018. 5. 18.
728x90

[빅데이터 직무연구회] 4회차 모임 정리

모임 요일 : 5월 10일 목요일 저녁 6시


2.3.7 커널 서포트 벡터 머신 (SVM)

"분류용 선형 모델"에서 선형 서포트 벡터 머신을 사용해 봤다.

커널 서포트 벡터 머신은 입력 데이터에서 단순한 초평면(hyperplane)으로 정의되지 않느 더 복잡한 모델을 만들 수 있도록 확장한 것이다.

분류와 회귀 모두 사용할 수 있다. 분류 문제만을 다뤄보겠다.


선형 모델과 비선형 특성

직선과 초평면은 유연하지 못하다. 따라서 저차원 데이터셋에서 선형 모델이 매우 제한적이다.

선형 모델을 유연하게 만드는 방법은 다음과 같다.

  • 특성끼리 곱함
  • 특성을 거듭제곱함

위 같은 방법으로 새로운 특성을 추가하는 것이다.

커널 기법

비선형 특성을 추가해 선형 모델을 강력하게 만듦. 특성이 많은 경우 어떤 특성을 추가해야 할까?
무턱대고 많이 추가한다면, 연산 비용이 커질 것이다. 따라서 커널 기법이 탄생했다. 이는 수학적 방법으로 새로운 특성을 많이 만들지 않아도 고차원에서 분류기를 학습시킬 수 있다.

커널 기법(kernel trick) : 확장된 특성에 대한 데이터 포인트들의 거리(스칼라 곱)를 계산한다. 데이터는 확장하지 않는다.

서포트 벡터 머신에서 데이터를 고차원 공간에 매핑하는 데 많이 사용하는 방법은 다음 두 가지다.
  • 다항식 커널 : 원래 특성의 가능한 조합을 지정된 차수까지 모두 계산 (예, 특성1 ** 2 * 특성2 ** 5)
  • 가우시안(Gausiaan) 커널, RBF(radial basis function) 커널 : 차원이 무한한 특성 공간에 매핑. 모든 차수의 모든 다항식을 고려한다. 그러나 특성의 중요도는 고차항이 될수록 줄어든다.
    • 이는 테일러 급수 전개를 이용한 것이다.

SVM 이해하기

서포트 벡터(support vector) : 두 클래스 사이의 경계에 위치한 데이터 포인트들 

일반적으로 SVM은 학습이 진행되는 동안 각 훈련 데이터 포인트가 두 클래스 사이의 결정 경계를 구분하는 데 얼마나 중요한지를 배움. 일반적으로 훈련 데이터의 일부만 결정 경계를 만드는 데 영향을 줌.


새로운 데이터 포인트를 예측 : 각 서포트 벡터와의 거리를 측정.

분류 결정은 서포트 벡터까지의 거리에 기반한다. 서포트 벡터의 중요도는 훈련 과정에서 학습한다. (SVC 객체의 dual_coef_ 속성에 저장됨 )


가우시안 커널 : 데이터 포인트 사이의 거리 측정 방법

  • x1, x2 : 데이터 포인트
  • || x1 - x2 || : 유클리디안 거리
  •  𝜸 : 가우시안 커널의 폭을 제어

SVM 매개변수 튜닝

  • gamma 매개변수 : 위 공식에 나와 있는 𝜸 로 가우시안 커널 폭의 역수에 해당
    • 하나의 훈련 샘플이 미치는 영향의 범위를 결정
    • 작은 값 : 넓은 영역
    • 큰 값 : 제한적인 영역
      • 𝜸 > 0이므로 가우시한 커널 함수 값의 범위는 e^0 ~ e^∞, 즉 1~0 사이이다. 적을 수록 데이터 포인트의 영향 범위가 커진다.
  • C 매개변수 : 선형 모델에서 사용한 것과 비슷한 규제 매개변수
    • 각 포인트의 중요도(dual_coef_ 값)를 제한한다.
    • 작은 값 : 매우 제약이 큰 모델을 만듦. 각 데이터 포인트의 영향력이 작음. 잘못 분류된 데이터 포인트가 경계에 거의 영향을 주지 않음
    • 큰 값 : 잘못 분류된 데이터 포인트들이 모델에 큰 영향을 줌. 결정 경계를 휘어서 정확하게 분류하려고 함

SVM을 위한 데이터 전처리

특성 값의 범위가 다르면 SVM 성능에 큰 영향을 준다. 따라서 특성 값의 범위가 비슷해지도록 조정해야 한다.

모든 특성 값을 0과 1 사이로 맞추는 방법은, MinMaxScaler 라는 것이 있다. 이 식은 다음과 같다.

장단점과 매개변수

< 매개변수 >
  • 규제 매개변수 C
  • 어떤 커널을 사용할지와 각 커널에 따른 매개변수
    • rbf
      • gamma : 가우시ㅏㄴ 커널 폭으 ㅣ역수
    • linear(x1·x2)
    • poly(𝜸(x1·x2)+c)^d
    • sigmoid(tanh(𝜸(x1·x2)+c))
    • precomputed : 미리 계산된 거리 값을 입력 특성
      • c : coef0 매개변수
      • d : degree 매개변수

< 장점 >

  • 강력한 모델
  • 다양한 데이터셋에서 잘 작동
  • 데이터의 특성이 몇 개 안되더라도 복잡한 결정 경계를 만듦

< 단점 >

  • 샘플이 많을 때 잘 맞지 않음. 메모리 관점에서 힘듦
  • 데이터 전처리와 매개변수 설정에 신경을 많이 써야 함
  • 모델을 분석하기 어려움


2.3.8 신경망(딥러닝)

다층 퍼셉트론(multilayer perceptrons, MLP, 피드포워드(feed-forward) 신경망, 신경망) : 분류와 회귀 모두 쓸 수 있음

신경망 모델

선형 모델의 일반화된 모습. MLP에서는 가중치 합을 만드는 과정이 여러 번 반복됨.
은닛 유닛(hidden unit) : 중간 단계를 구성. 이를 이용해 가중치 합을 계산하여 최종 결과를 산출

선형 모델과 다른 점은 각 은닉 유닛의 가중치 합을 계산한 후, 그 결과에 비선형 함수를 적용한다.
그 예는 대표적으로 다음과 같다.
  • 렐루(rectified linear unit, ReLU) : 0 이하를 잘라버림
  • 하이퍼볼릭 탄젠트(hyperbolic tangent, tanh)
    • 낮은 입력값 : -1로 수렴
    • 큰 입력값 : +1로 수렴
  • 시그모이드(sigmoid), 로지스틱 함수
    • 1 / (1+e^(-z)), z는 유닛의 출력 값
위 함수 결과의 가중치 합을 계산해 출력 y을 만듦.

장단점과 매개변수

< 매개변수 >

  • 은닉층의 개수
  • 각 은닉층의 유닛 수
  • solver 매개변수 : 모델을 학습시키는 방법 또는 매개변수 학습에 사용하는 알고리즘을 지정할 수 있음
    • 기본값 : 'adam'
      • 대부분 잘 작동
      • 데이터의 스케일에 조금 민감함
      • 데이터를 평균 0, 분산 1로 조정하는게 중요
    • 'lbfgs' : (Limited-memory BFGS) BFGS 알고리즘을 제한된 메모리 공간에서 구현한 것
      • 안정적임
      • 규모가 큰 모델이나 대량의 데이터셋에서는 시간이 오래 걸림
    • 'sgd' : 여러 매개변수와 함께 튜닝하여 최선의 결과를 만들 수 있음
      • momentum 매개변수
        • 이전의 그래디언트를 momentum 매개변수 비율만큼 현재 계산된 그래디언트에 반영하여 갱신할 그래디언트를 구함.
        • 이전의 그래디언트 : 속도
        • 일정 비율의 과거 그래디언트를 모두 포함해 관성 같은 효과를 줌
      • nesterovs_momentum 매개변수
        • 모멘텀에서 구한 그래디언트를 이전 그래디언트로 가정하고 한 번 더 모멘텀 방식을 적용해 갱신할 그래디언트를 계산함

처음엔 한 개 또는 두 개의 은닉층으로 시작해 늘려가야 한다.

각 은닉층의 유닛 수는 보통 입력 특성의 수와 비슷하게 설정한다.


< 장점 >

  • 대량의 데이터에 내재된 정보를 잡아냄
  • 매우 복잡한 모델을 만들 수 있음

< 단점 >

  • 종종 학습이 오래 걸림
  • 데이터 전처리에 주의해야 함 ( SVM과 비슷하게 모든 특성이 같은 의미를 가진 동질의 데이터에서 잘 작동 )
  • 다른 조류의 특성을 가진 데이터라면 트리 기반 모델이 더 잘 작동할 수 있음
  • 신경망 매개변수 튜닝이 매우 어려움

신경망의 복잡도 추정

학습된 가중치 또는 계수의 수가 모델의 복잡도를 측정하는데 도움이 된다.

특성 100개와 은닉 유닛 100개를 가진 이진 분류라면, 입력층과 첫 번째 은닉층 사이에
100 * 100 = 10,000개의 가중치가 있다. 은닉층과 출력층 사이에 100 * 1 = 100개의 가중치가 있다.
따라서 10,000 + 100 = 10,100개다.

신경망의 매개변수를 조정하는 일반적인 방법
  • 먼저 충분히 과대적합된 큰 모델을 만듦
  • 신경만 구조를 줄이거나 규제 강화를 위해 alpha 값을 증가시켜 일반화 성능을 향상시킴

2.4 분류 예측의 불확실성 추정

2.4.1 결정 함수

이진 분류에서 decision_function 반환값의 크기 : (n_samples, ) 으로 각 샘플이 하나의 실수 값을 반환
값의 범위는 데이터와 모델 파라미터에 따라 달라짐

음성 클래스 : classes_ 속성의 첫 번째 원소
양성 클래스 : classes_ 속성의 두 번째 원소


2.4.2 예측 확률

predict_prorba : 각 클래스에 대한 확률. 이진 분류에서의 반환값 크기는 (n_samples, 2) 이다.

첫 번째 클래스의 예측 확률 : 첫 번째 원소
두 번째 클래스의 예측 확률 : 두 번째 원소
항상 0과 1 사이의 실수값이며, 두 클래스에 대한 확률의 합은 항상 1이다.

2.4.3 다중 분류에서의 불확실성

decision_function과 predict_proba 모두 다중 분류에도 사용할 수 있음.

decision_function 의 크기 : (n_samples, n_classes)

각 열은 각 클래스에 대한 확신 점수를 담고 있다. 수치가 크면 그 클래스일 가능성이 크고 수치가 작으면 그 클래스일 가능성이 낮다. 데이터 포인트마다 점수들에서 가장 큰 값을 찾아 예측 결과를 재현할 수 있다.


predict_proba 의 크기 : (n_samples, n_classes) 마찬가지로 각 데이터 포인트에서 클래스 확률의 합은 1이다.

argmax() 함수를 적용해 예측을 재현할 수 있다.


2.5 요약 및 정리

각 모델에 대한 간단한 요약
  • 최근접 이웃
    • 작은 데이터셋일 경우,기본 모델로서 좋음
    • 설명하기 쉬움
  • 선형 모델
    • 대용량 데이터셋 가능
    • 고차원 데이터에 가능
  • 나이브 베이즈
    • 분류만 가능
    • 선형 모델보다 훨씬 빠름
    • 대용량 데이터셋과 고차원 데이터에 가능
    • 선형 모델보다 덜 정확함
  • 결정 트리
    • 매우 빠름
    • 데이터 스케일 조정이 필요 없음
    • 시각화하기 좋음
    • 설명하기 쉬움
  • 랜덤 포레스트
    • 결정 트리 하나보다 거의 항상 좋은 성능을 냄
    • 매우 안정적이고 강력함
    • 데이터 스케일이 필요 없음
    • 고차원 희소 데이터에는 잘 안 맞음
  • 그래디언트 부스팅 결정 트리
    • 랜덤 포레스트보다 성능이 조금 더 좋음
    • 랜덤 포레스트보다 학습은 느리나 예측은 빠르고 메모리를 조금 사용
    • 랜덤 포레스트보다 매개변수 튜닝이 많이 필요함
  • 서포트 벡터 머신
    • 중간 규모 데이터셋에 잘 맞음
    • 데이터 스케일 조정이 필요
    • 매개변수에 민감
  • 신경망
    • 대용량 데이터셋에서 매우 복잡한 모델을 만들 수 있음
    • 매개변수 선택과 데이터 스케일에 민감
    • 큰 모델은 학습이 오래 걸림


# 커널 서포트 벡터 머신
X, y = make_blobs(centers=4, random_state=8)
y = y % 2

mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[69]:
Text(0,0.5,'특성 1')
In [70]:
from sklearn.svm import LinearSVC
linear_svm = LinearSVC().fit(X, y)

mglearn.plots.plot_2d_separator(linear_svm, X)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[70]:
Text(0,0.5,'특성 1')
In [71]:
# 두 번째 특성을 제곱하여 추가합니다.
X_new = np.hstack([X, X[:, 1:] ** 2])

from mpl_toolkits.mplot3d import Axes3D, axes3d
figure = plt.figure()
# 3차원 그래프
ax = Axes3D(figure, elev=-152, azim=-26)
# y == 0인 포인트를 먼저 그리고 그다음 y == 1인 포인트를 그립니다.
mask = y == 0
ax.scatter(X_new[mask, 0], X_new[mask, 1], X_new[mask, 2], c='b', cmap=mglearn.cm2, s=60, edgecolor='k')
ax.scatter(X_new[~mask, 0], X_new[~mask, 1], X_new[~mask, 2], c='r', marker='^', cmap=mglearn.cm2, s=60, edgecolor='k')
ax.set_xlabel("특성0")
ax.set_ylabel("특성1")
ax.set_zlabel("특성1 ** 2")
Out[71]:
Text(0.5,0,'특성1 ** 2')
In [72]:
linear_svm_3d = LinearSVC().fit(X_new, y)
coef, intercept = linear_svm_3d.coef_.ravel(), linear_svm_3d.intercept_

# 선형 결정 경계 그리기
figure = plt.figure()
ax = Axes3D(figure, elev=-152, azim=-26)
xx = np.linspace(X_new[:, 0].min() - 2, X_new[:, 0].max() + 2, 50)
yy = np.linspace(X_new[:, 1].min() - 2, X_new[:, 1].max() + 2, 50)

XX, YY = np.meshgrid(xx, yy)
ZZ = (coef[0] * XX + coef[1] * YY + intercept) / -coef[2]
ax.plot_surface(XX, YY, ZZ, rstride=8, cstride=8, alpha=0.3)
ax.scatter(X_new[mask, 0], X_new[mask, 1], X_new[mask, 2], c='b', cmap=mglearn.cm2, s=60, edgecolor='k')
ax.scatter(X_new[~mask, 0], X_new[~mask, 1], X_new[~mask, 2], c='r', marker='^', cmap=mglearn.cm2, s=60, edgecolor='k')
ax.set_xlabel("특성0")
ax.set_ylabel("특성1")
ax.set_zlabel("특성1 ** 2")
Out[72]:
Text(0.5,0,'특성1 ** 2')
In [73]:
ZZ = YY ** 2
dec = linear_svm_3d.decision_function(np.c_[XX.ravel(), YY.ravel(), ZZ.ravel()])
plt.contourf(XX, YY, dec.reshape(XX.shape), levels=[dec.min(), 0, dec.max()], cmap=mglearn.cm2, alpha=0.5)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[73]:
Text(0,0.5,'특성 1')
In [74]:
from sklearn.svm import SVC
X, y = mglearn.tools.make_handcrafted_dataset()
svm = SVC(kernel='rbf', C=10, gamma=0.1).fit(X, y)

mglearn.plots.plot_2d_separator(svm, X, eps=.5)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
# 서포트 벡터
sv = svm.support_vectors_
# dual_coef_의 부호에 의해 서포트 벡터의 클래스 레이블이 결정됩니다.
sv_labels = svm.dual_coef_.ravel() > 0
mglearn.discrete_scatter(sv[:, 0], sv[:, 1], sv_labels, s=15, markeredgewidth=3)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[74]:
Text(0,0.5,'특성 1')
In [75]:
fig, axes = plt.subplots(3, 3, figsize=(15, 10))

for ax, C in zip(axes, [-1, 0, 3]):
    for a, gamma in zip(ax, range(-1, 2)):
        mglearn.plots.plot_svm(log_C=C, log_gamma=gamma, ax=a)

axes[0,0].legend(["클래스 0", "클래스 1", "클래스 0 서포트 벡터", "클래스 1 서포트 벡터"], ncol=4, loc=(.9, 1.2))
Out[75]:
<matplotlib.legend.Legend at 0x1181d0da0>
In [76]:
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)

svc = SVC()
svc.fit(X_train, y_train)

print("훈련 세트 정확도: {:.2f}".format(svc.score(X_train, y_train)))
print("테스트 세트 정확도: {:.2f}".format(svc.score(X_test, y_test)))
훈련 세트 정확도: 1.00
테스트 세트 정확도: 0.63
In [77]:
plt.boxplot(X_train, manage_xticks=False)
plt.yscale("symlog")
plt.xlabel("특성 목록")
plt.ylabel("특성 크기")
Out[77]:
Text(0,0.5,'특성 크기')
In [78]:
# 훈련 세트에서 특성별 최솟값 계산
min_on_training = X_train.min(axis=0)
# 훈련 세트에서 특성별 (최댓값 - 최솟값) 범위 계산)
range_on_training = (X_train - min_on_training).max(axis=0)

# 훈련 데이터에 최솟값을 빼고 범위로 나누면
# 각 특성에 대해 최솟값은 0, 최댓값은 1입니다.
X_train_scaled = (X_train - min_on_training) / range_on_training
print("특성별 최소 값\n{}".format(X_train_scaled.min(axis=0)))
print("특성별 최대 값\n{}".format(X_train_scaled.max(axis=0)))
특성별 최소 값
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0.]
특성별 최대 값
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
 1. 1. 1. 1. 1. 1.]
In [79]:
# 테스트 세트에도 같은 작업을 적용하지만
# 훈련 세트에서 계산한 최솟값과 범위를 사용합니다. ( 자세한 내용은 3장에 있습니다. )
X_test_scaled = (X_test - min_on_training) / range_on_training
In [80]:
svc = SVC()
svc.fit(X_train_scaled, y_train)

print("훈련 세트 정확도: {:.3f}".format(svc.score(X_train_scaled, y_train)))
print("테스트 세트 정확도: {:.3f}".format(svc.score(X_test_scaled, y_test)))
훈련 세트 정확도: 0.948
테스트 세트 정확도: 0.951
In [81]:
# C값을 증가함
svc = SVC(C=1000)
svc.fit(X_train_scaled, y_train)

print("훈련 세트 정확도: {:.3f}".format(svc.score(X_train_scaled, y_train)))
print("테스트 세트 정확도: {:.3f}".format(svc.score(X_test_scaled, y_test)))
훈련 세트 정확도: 0.988
테스트 세트 정확도: 0.972
In [82]:
# 신경망 모델 ( 딥러닝 )
display(mglearn.plots.plot_logistic_regression_graph())
inputsoutputx[0]yw[0]x[1]w[1]x[2]w[2]x[3]w[3]
In [83]:
display(mglearn.plots.plot_single_hidden_layer_graph())
inputshidden layeroutputx[0]h[0]h[1]h[2]x[1]x[2]x[3]y
In [84]:
line = np.linspace(-3, 3, 100)
plt.plot(line, np.tanh(line), label="tanh")
plt.plot(line, np.maximum(line, 0), label="relu")
plt.legend(loc="best")
plt.xlabel("x")
plt.ylabel("relu(x), tanh(x)")
Out[84]:
Text(0,0.5,'relu(x), tanh(x)')
In [85]:
mglearn.plots.plot_two_hidden_layer_graph()
Out[85]:
inputshidden layer 1hidden layer 2outputx[0]h1[0]h1[1]h1[2]x[1]x[2]x[3]h2[0]h2[1]h2[2]y
In [86]:
from sklearn.neural_network import MLPClassifier
from sklearn.datasets import make_moons

X, y = make_moons(n_samples=100, noise=0.25, random_state=3)

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)
mlp = MLPClassifier(solver='lbfgs', random_state=0).fit(X_train, y_train)
mglearn.plots.plot_2d_separator(mlp, X_train, fill=True, alpha=.3)
mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[86]:
Text(0,0.5,'특성 1')
In [87]:
mlp = MLPClassifier(solver='lbfgs', random_state=0, hidden_layer_sizes=[10]).fit(X_train, y_train)
mglearn.plots.plot_2d_separator(mlp, X_train, fill=True, alpha=.3)
mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[87]:
Text(0,0.5,'특성 1')
In [88]:
# 10개의 유닛으로 된 두 개의 은닉층
mlp = MLPClassifier(solver='lbfgs', random_state=0, hidden_layer_sizes=[10, 10]).fit(X_train, y_train)
mglearn.plots.plot_2d_separator(mlp, X_train, fill=True, alpha=.3)
mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[88]:
Text(0,0.5,'특성 1')
In [89]:
# tanh 활성화 함수가 적용된 10개의 유닛으로 된 두 개의 은닉층
mlp = MLPClassifier(solver='lbfgs', activation='tanh', random_state=0, hidden_layer_sizes=[10, 10]).fit(X_train, y_train)
mglearn.plots.plot_2d_separator(mlp, X_train, fill=True, alpha=.3)
mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train)
plt.xlabel("특성 0")
plt.ylabel("특성 1")
Out[89]:
Text(0,0.5,'특성 1')
In [90]:
fig, axes = plt.subplots(2, 4, figsize=(20, 8))
for axx, n_hidden_nodes in zip(axes, [10, 100]):
    for ax, alpha in zip(axx, [0.0001, 0.01, 0.1, 1]):
        mlp = MLPClassifier(solver='lbfgs', random_state=0, hidden_layer_sizes=[n_hidden_nodes, n_hidden_nodes], alpha=alpha)
        mlp.fit(X_train, y_train)
        mglearn.plots.plot_2d_separator(mlp, X_train, fill=True, alpha=.3, ax=ax)
        mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train, ax=ax)
        ax.set_title("n_hidden=[{}, {}]\nalpha={:.4f}".format(n_hidden_nodes, n_hidden_nodes, alpha))
In [91]:
fig, axes = plt.subplots(2, 4, figsize=(20, 8))
for i, ax in enumerate(axes.ravel()):
    mlp = MLPClassifier(solver='lbfgs', random_state=i, hidden_layer_sizes=[100, 100])
    mlp.fit(X_train, y_train)
    mglearn.plots.plot_2d_separator(mlp, X_train, fill=True, alpha=.3, ax=ax)
    mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train, ax=ax)
In [92]:
print("유방암 데이터의 특성별 최댓값:\n{}".format(cancer.data.max(axis=0)))
유방암 데이터의 특성별 최댓값:
[2.811e+01 3.928e+01 1.885e+02 2.501e+03 1.634e-01 3.454e-01 4.268e-01
 2.012e-01 3.040e-01 9.744e-02 2.873e+00 4.885e+00 2.198e+01 5.422e+02
 3.113e-02 1.354e-01 3.960e-01 5.279e-02 7.895e-02 2.984e-02 3.604e+01
 4.954e+01 2.512e+02 4.254e+03 2.226e-01 1.058e+00 1.252e+00 2.910e-01
 6.638e-01 2.075e-01]
In [93]:
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=0)

mlp = MLPClassifier(random_state=42)
mlp.fit(X_train, y_train)

print("훈련 세트 정확도: {:.2f}".format(mlp.score(X_train, y_train)))
print("테스트 세트 정확도: {:.2f}".format(mlp.score(X_test, y_test)))
훈련 세트 정확도: 0.91
테스트 세트 정확도: 0.88
In [94]:
# 훈련 세트 각 특성의 평균을 계산합니다.
mean_on_train = X_train.mean(axis=0)
# 훈련 세트 각 특성의 표준 편차를 계산합니다.
std_on_train = X_train.std(axis=0)

# 데이터에서 평균을 빼고 표준 편차로 나누면
# 평균 0, 표준 편차 1인 데이터로 변환됩니다.
X_train_scaled = (X_train - mean_on_train) / std_on_train
# (훈련 데이터의 평균과 표준 펀차를 이용해) 같은 변환을 테스트 세트에도 합니다.
X_test_scaled = (X_test - mean_on_train) / std_on_train

mlp = MLPClassifier(random_state = 0)
mlp.fit(X_train_scaled, y_train)

print("훈련 세트 정확도: {:.3f}".format(mlp.score(X_train_scaled, y_train)))
print("테스트 세트 정확도: {:.3f}".format(mlp.score(X_test_scaled, y_test)))
훈련 세트 정확도: 0.991
테스트 세트 정확도: 0.965
/usr/local/lib/python3.6/site-packages/sklearn/neural_network/multilayer_perceptron.py:564: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (200) reached and the optimization hasn't converged yet.
  % self.max_iter, ConvergenceWarning)
In [95]:
mlp = MLPClassifier(max_iter=1000, random_state=0)
mlp.fit(X_train_scaled, y_train)

print("훈련 세트 정확도: {:.3f}".format(mlp.score(X_train_scaled, y_train)))
print("테스트 세트 정확도: {:.3f}".format(mlp.score(X_test_scaled, y_test)))
훈련 세트 정확도: 0.993
테스트 세트 정확도: 0.972
In [96]:
mlp = MLPClassifier(max_iter=1000, alpha=1, random_state=0)
mlp.fit(X_train_scaled, y_train)

print("훈련 세트 정확도: {:.3f}".format(mlp.score(X_train_scaled, y_train)))
print("테스트 세트 정확도: {:.3f}".format(mlp.score(X_test_scaled, y_test)))
훈련 세트 정확도: 0.988
테스트 세트 정확도: 0.972
In [97]:
plt.figure(figsize=(20, 5))
plt.imshow(mlp.coefs_[0], interpolation='none', cmap='viridis')
plt.yticks(range(30), cancer.feature_names)
plt.xlabel("은닉 유닛")
plt.ylabel("입력 특성")
plt.colorbar()
Out[97]:
<matplotlib.colorbar.Colorbar at 0x11430c7b8>
In [98]:
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import make_circles
X, y = make_circles(noise=0.25, factor=0.5, random_state=1)

# 예제를 위해 클래스의 이름을 "blue"와 "red로 바꿉니다.
y_named = np.array(["blue", "red"])[y]

# 여러 배열을 한꺼번에 train_test_split에 넣을 수 있습니다.
# 훈련 세트와 테스트 세트로 나뉘는 방식은 모두 같습니다.
X_train, X_test, y_train_named, y_test_named, y_train, y_test = \
    train_test_split(X, y_named, y, random_state=0)
    
# 그래디언트 부스팅 모델을 만듭니다.
gbrt = GradientBoostingClassifier(random_state=0)
gbrt.fit(X_train, y_train_named)
Out[98]:
GradientBoostingClassifier(criterion='friedman_mse', init=None,
              learning_rate=0.1, loss='deviance', max_depth=3,
              max_features=None, max_leaf_nodes=None,
              min_impurity_decrease=0.0, min_impurity_split=None,
              min_samples_leaf=1, min_samples_split=2,
              min_weight_fraction_leaf=0.0, n_estimators=100,
              presort='auto', random_state=0, subsample=1.0, verbose=0,
              warm_start=False)
In [99]:
print("X_test.shape: {}".format(X_test.shape))
print("결정 함수 결과 형태: {}".format(gbrt.decision_function(X_test).shape))
X_test.shape: (25, 2)
결정 함수 결과 형태: (25,)
In [100]:
# 결정 함수 결과 중 앞부분 일부를 확인합니다.
print("결정 함수:\n{}".format(gbrt.decision_function(X_test)[:6]))
결정 함수:
[ 4.13592629 -1.7016989  -3.95106099 -3.62599351  4.28986668  3.66166106]
In [101]:
print("임계치와 결정 함수 결과 비교:\n{}".format(gbrt.decision_function(X_test) > 0))
print("예측:\n{}".format(gbrt.predict(X_test)))
임계치와 결정 함수 결과 비교:
[ True False False False  True  True False  True  True  True False  True
  True False  True False False False  True  True  True  True  True False
 False]
예측:
['red' 'blue' 'blue' 'blue' 'red' 'red' 'blue' 'red' 'red' 'red' 'blue'
 'red' 'red' 'blue' 'red' 'blue' 'blue' 'blue' 'red' 'red' 'red' 'red'
 'red' 'blue' 'blue']
In [102]:
# 불리언 값을 0과 1로 변화합니다.
greater_zero = (gbrt.decision_function(X_test) > 0).astype(int)
# classes_에 인덱스로 사용합니다.
pred = gbrt.classes_[greater_zero]
# pred와 gbrt.predict의 결과를 비교합니다.
print("pred는 예측 결과와 같다: {}".format(np.all(pred == gbrt.predict(X_test))))
pred는 예측 결과와 같다: True
In [103]:
decision_function = gbrt.decision_function(X_test)
print("결정 함수 최솟값: {:.2f} 최댓값: {:.2f}".format(np.min(decision_function), np.max(decision_function)))
결정 함수 최솟값: -7.69 최댓값: 4.29
In [104]:
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
mglearn.tools.plot_2d_separator(gbrt, X, ax=axes[0], alpha=.4, fill=True, cm=mglearn.cm2)
scores_image = mglearn.tools.plot_2d_scores(gbrt, X, ax=axes[1], alpha=.4, cm=mglearn.ReBl)

for ax in axes:
    # 훈련 포인트와 테스트 포인트를 그리기
    mglearn.discrete_scatter(X_test[:, 0], X_test[:, 1], y_test, markers='^', ax=ax)
    mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train, markers='o', ax=ax)
    ax.set_xlabel("특성 0")
    ax.set_ylabel("특성 1")
cbar = plt.colorbar(scores_image, ax=axes.tolist())
axes[0].legend(["테스트 클래스 0", "테스트 클래스 1", "훈련 클래스 0", "훈련 클래스 1"], ncol=4, loc=(.1, 1.1))
Out[104]:
<matplotlib.legend.Legend at 0x112ecddd8>
In [105]:
print("확률 값의 형태: {}".format(gbrt.predict_proba(X_test).shape))
확률 값의 형태: (25, 2)
In [106]:
# predict_proba 결과 중 앞부분 일부를 확인합니다.
print("예측 확률:\n{}".format(gbrt.predict_proba(X_test[:6])))
예측 확률:
[[0.01573626 0.98426374]
 [0.84575649 0.15424351]
 [0.98112869 0.01887131]
 [0.97406775 0.02593225]
 [0.01352142 0.98647858]
 [0.02504637 0.97495363]]
In [107]:
fig, axes = plt.subplots(1, 2, figsize=(13, 5))

mglearn.tools.plot_2d_separator(gbrt, X, ax=axes[0], alpha=.4, fill=True, cm=mglearn.cm2)
scores_image = mglearn.tools.plot_2d_scores(gbrt, X, ax=axes[1], alpha=.5, cm=mglearn.ReBl, function='predict_proba')

for ax in axes:
    # 훈련 포인트와 테스트 포인트를 그리기
    mglearn.discrete_scatter(X_test[:, 0], X_test[:, 1], y_test, markers='^', ax=ax)
    mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train, markers='o', ax=ax)
    ax.set_xlabel("특성 0")
    ax.set_ylabel("특성 1")
cbar = plt.colorbar(scores_image, ax=axes.tolist())
axes[0].legend(["테스트 클래스 0", "테스트 클래스 1", "훈련 클래스 0", "훈련 클래스 1"], ncol=4, loc=(.1, 1.1))
Out[107]:
<matplotlib.legend.Legend at 0x1136f3898>
In [108]:
from sklearn.datasets import load_iris

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=42)

gbrt = GradientBoostingClassifier(learning_rate=0.01, random_state=0)
gbrt.fit(X_train, y_train)

print("결정 함수의 결과 형태: {}".format(gbrt.decision_function(X_test).shape))
# decision function 결과 중 앞부분 일부를 확인합니다.
print("결정 함수 결과:\n{}".format(gbrt.decision_function(X_test)[:6, :]))
결정 함수의 결과 형태: (38, 3)
결정 함수 결과:
[[-0.52931069  1.46560359 -0.50448467]
 [ 1.51154215 -0.49561142 -0.50310736]
 [-0.52379401 -0.4676268   1.51953786]
 [-0.52931069  1.46560359 -0.50448467]
 [-0.53107259  1.28190451  0.21510024]
 [ 1.51154215 -0.49561142 -0.50310736]]
In [109]:
print("가장 큰 결정 함수의 인덱스:\n{}".format(np.argmax(gbrt.decision_function(X_test), axis=1)))
print("예측:\n{}".format(gbrt.predict(X_test)))
가장 큰 결정 함수의 인덱스:
[1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0 0 0 1 0 0 2 1
 0]
예측:
[1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0 0 0 1 0 0 2 1
 0]
In [110]:
# predict_proba 결과 중 앞부분 일부를 확인합니다.
print("예측 확률:\n{}".format(gbrt.predict_proba(X_test)[:6]))
# 행 방향으로 확률을 더하면 1이 됩니다.
print("합: {}".format(gbrt.predict_proba(X_test)[:6].sum(axis=1)))
예측 확률:
[[0.10664722 0.7840248  0.10932798]
 [0.78880668 0.10599243 0.10520089]
 [0.10231173 0.10822274 0.78946553]
 [0.10664722 0.7840248  0.10932798]
 [0.10825347 0.66344934 0.22829719]
 [0.78880668 0.10599243 0.10520089]]
합: [1. 1. 1. 1. 1. 1.]
In [111]:
print("가장 큰 예측 확률의 인덱스: \n{}".format(np.argmax(gbrt.predict_proba(X_test), axis=1)))
print("예측:\n{}".format(gbrt.predict(X_test)))
가장 큰 예측 확률의 인덱스: 
[1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0 0 0 1 0 0 2 1
 0]
예측:
[1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0 0 0 1 0 0 2 1
 0]
In [112]:
logreg = LogisticRegression()

# iris 데이터셋의 타깃을 클래스 이름으로 나타내기
named_target = iris.target_names[y_train]
logreg.fit(X_train, named_target)
print("훈련 데이터에 있는 클래스 종류: {}".format(logreg.classes_))
print("예측: {}".format(logreg.predict(X_test)[:10]))
argmax_dec_func = np.argmax(logreg.decision_function(X_test), axis=1)
print("가장 큰 결정 함수의 인덱스: {}".format(argmax_dec_func[:10]))
print("인덱스를 classes_에 연결: {}".format(logreg.classes_[argmax_dec_func][:10]))
훈련 데이터에 있는 클래스 종류: ['setosa' 'versicolor' 'virginica']
예측: ['versicolor' 'setosa' 'virginica' 'versicolor' 'versicolor' 'setosa'
 'versicolor' 'virginica' 'versicolor' 'versicolor']
가장 큰 결정 함수의 인덱스: [1 0 2 1 1 0 1 2 1 1]
인덱스를 classes_에 연결: ['versicolor' 'setosa' 'virginica' 'versicolor' 'versicolor' 'setosa' 

'versicolor' 'virginica' 'versicolor' 'versicolor']

댓글