2022.04.02 토
# 모델 만들기
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import make_circles
X,y = make_circles(noise=0.25, factor=0.5, random_state=1)
# 클래스 이름 바꾸기
y_named = np.array(["blue", "red"])[y]
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)
train_test_split 여러 개의 배열 한꺼번에 넣을 수 있음
결정 함수
양성 클래스(클래스 1)에 속한다고 믿는 정도 ⇒ 양수 : 양성 클래스(클래스1)
⇒ 음수 : 음성(다른) 클래스(클래스2)
print("X_test.shape:", X_test.shape)
print("결정 함수 결과 shape:", gbrt.decision_function(X_test).shape)
X_test.shape: (25, 2) 결정 함수 결과 shape: (25,)
→ decision_function 반환값 : (n_samples,)
# 결정 함수 결과 중 앞 6개 확인
print("결정함수:\\n", gbrt.decision_function(X_test)[:6])
print("predict():\\n", gbrt.predict(X_test)[:6])
결정함수: [ 4.13592603 -1.70169917 -3.95106099 -3.62609552 4.28986642 3.66166081] predict(): ['red' 'blue' 'blue' 'blue' 'red' 'red']
→ decision_function의 값은 확신도를 측정하는 것이기 때문에 predict와 값이 다름을 알 수 있음
print("임계치와 결정 함수 결과 비교:\\n", gbrt.decision_function(X_test) > 0)
print("예측값:\\n", 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']
→ 부호로 예측 확인 가능 양수 = red
음수 = blue
# boolean값을 0과 1로 변환
greater_zero = (gbrt.decision_function(X_test) > 0).astype(int)
# gbrt.decision_function(X_test)와 predict() 값 비교
print("decision_function는 예측 결과와 같다:", np.all(greater_zero == gbrt.predict(X_test)))
# classes_ class label값으로 사용
pred = gbrt.classes_[greater_zero]
# pred predict()의 값 비교
print("pred는 예측 결과와 같다:", np.all(pred == gbrt.predict(X_test)))
decision_function는 예측 결과와 같다: False pred는 예측 결과와 같다: True
decision_function Boolean(T/F > 0) → int → classes_ class label로 사용
decision_function = gbrt.decision_function(X_test)
print("결정 함수 최솟값: {:.2f} 최댓값: {:.2f}".format(np.min(decision_function), np.max(decision_function)))
결정 함수 최솟값: -7.69 최댓값: 4.29
→ 값 범위 : 데이터와 모델 파라미터에 따라 달라짐
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_train[:,0], X_train[:,1], y_train, markers='o', ax=ax)
mglearn.discrete_scatter(X_test[:,0], X_test[:,1], y_test, markers='^', ax=ax)
ax.set_xlabel("특성0")
ax.set_ylabel("특성1")
# 컬러바
cbar = plt.colorbar(scores_image, ax=axes.tolist())
cbar.set_alpha(1)
cbar.draw_all()
axes[0].legend(["테스트 클래스 0", "테스트 클래스 1", "훈련 클래스 0", "훈련 클래스 1"], ncol=4, loc=(.1, 1.1))
예측 확률
각 클래스에 대한 확률
각 행의 첫번째 원소 = 첫번째 클래스 예측 확률
각 행의 두번째 원소 = 두번째 클래스 예측 확률
범위 : 0~1
확률의 합 = 1
print("예측 확률 결과 shape:", gbrt.predict_proba(X_test).shape)
예측 확률 결과 shape: (25, 2)
→ predict_proba 반환값 : (n_samples,)
print("예측 확률:\\n", gbrt.predict_proba(X_test)[:6])
예측 확률: [[0.01573626 0.98426374] [0.84575653 0.15424347] [0.98112869 0.01887131] [0.97407033 0.02592967] [0.01352142 0.98647858] [0.02504637 0.97495363]]
→ 두 클래스의 합 = 1
→ 한 클래스는 50% 이상 = 해당 클래스 = 예측값
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_train[:,0], X_train[:,1], y_train, markers='o', ax=ax)
mglearn.discrete_scatter(X_test[:,0], X_test[:,1], y_test, markers='^', ax=ax)
ax.set_xlabel("특성0")
ax.set_ylabel("특성1")
# 컬러바
cbar = plt.colorbar(scores_image, ax=axes.tolist())
cbar.set_alpha(1)
cbar.draw_all()
axes[0].legend(["테스트 클래스 0", "테스트 클래스 1", "훈련 클래스 0", "훈련 클래스 1"], ncol=4, loc=(.1, 1.1))
→ 결정 함수 경계가 훨씬 또렷해짐
다중 분류에서의 불확실성 decision_function & predict_proba 다중 분류에서 사용가능 type : (n_samples, n_classes) 결과 값 : 각 클래스에 대한 확신 점수 담음
이진 분류와 다름
결정 함수 decision_function
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("결정 함수의 결과 shape:", gbrt.decision_function(X_test).shape)
print("결정 함수 결과:\\n", gbrt.decision_function(X_test)[:6,:])
결정 함수의 결과 shape: (38, 3) 결정 함수 결과: [[-1.995715 0.04758267 -1.92720695] [ 0.06146394 -1.90755736 -1.92793758] [-1.99058203 -1.87637861 0.09686725] [-1.995715 0.04758267 -1.92720695] [-1.99730159 -0.13469108 -1.20341483] [ 0.06146394 -1.90755736 -1.92793758]]
→ 1행 : 클래스1이 될 가능성이 높음
print("가장 큰 결정 함수의 인덱스:\\n", np.argmax(gbrt.decision_function(X_test),axis=1))
print("예측:\\n", 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]
예측 확률 predict_proba
print("예측확률:\\n", gbrt.predict_proba(X_test)[:6])
print("합:", gbrt.predict_proba(X_test)[:6].sum(axis=1))
예측확률: [[0.10217718 0.78840034 0.10942248] [0.78347147 0.10936745 0.10716108] [0.09818072 0.11005864 0.79176065] [0.10217718 0.78840034 0.10942248] [0.10360005 0.66723901 0.22916094] [0.78347147 0.10936745 0.10716108]] 합: [1. 1. 1. 1. 1. 1.]
print("가장 큰 예측 확률의 인덱스:\\n", np.argmax(gbrt.predict_proba(X_test),axis=1))
print("예측:\\n", 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]
→ argmax()를 사용하여 predict 재현 가능
but, 클래스 = 문자열 or 연속적x, 0부터 시작x 하는 정수형 일 경우,
classed_ 속성 이용하여 클래스의 이름 얻어내야 버그 방지 ⭕️
ex)
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
named_target = iris.target_names[y_train]
logreg.fit(X_train, named_target)
print("훈련 데이터에 있는 클래스 종류:", logreg.classes_)
print("예측:", logreg.predict(X_test)[:10])
argmax_dec_func = np.argmax(logreg.decision_function(X_test), axis=1)
print("가장 큰 결정 함수의 인덱스:", argmax_dec_func[:10])
print("인덱스를 classes_에 연결:", 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']
argmax_dec_func = np.argmax(logreg.decision_function(X_test), axis=1)
→ argmax(decision_function) 값을 사용하여 classes_ 의 class label 값으로 사용해주기