
from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone
skfolds = StratifiedKFold(n_splits=3, shuffle=True)
for train_index, test_index in skfolds.split(X_train, y_train_5):
clone_clf = clone(sgd_clf)
X_train_folds = X_train[train_index]
y_train_folds = y_train_5[train_index]
X_test_fold = X_train[test_index]
y_test_fold = y_train_5[test_index]
clone_clf.fit(X_train_folds, y_train_folds)
y_pred = clone_clf.predict(X_test_fold)
n_correct = sum(y_pred == y_test_fold)
print(n_correct / len(y_pred))
from sklearn.dummny import DummyClassifier
dummy_clf = DummyClassifier()
dummy_clf.fit(X_train, y_train_5)
print(any(dummy_clf.predict(X_train))) # False
cross_val_score() : 모든 교차 검증 fold에 대해 평가지표(일반적으로 accuracy)의 점수를 반환cross_val_score(dummy_clf, X_train, y_train_5, cv=3, scoring="accuracy")
## array([0.9065, 0.90965, 0.90965])
cross_val_predict() : 모든 교차 검증 fold에서 얻은 예측을 반환y_train_pred= cross_val_predict(sgd_clf, X_train, y_train_5, cv=3)
결과 해석
accuracy(정확도) : 불균형한 데이터를 다룰 때 (ex.어떤 클래스가 다른 것보다 월등히 많을 때) 좋은 성능지표가 될 수 없음
기본 아이디어 : 클래스 A의 sample이 클래스 B로 분류된 횟수를 셈
from sklearn met ics import confusion_mat
cm = confusion mat (y_t ain ain p ed)
cm
## array([[53892, 687], [1891, 3530]])
첫번째 행은 음성 클래스(5가 아님)를 의미
두번째 행은 양성 클래스(5임)를 의미


TP : 진짜 양성의 수
FP : 거짓 양성의 수
TN : 진짜 음성의 수
FN : 거짓 음성의 수
제일 확신이 높은 샘플을 양성 예측하고 나머지를 모두 음성 예측했을 때, 양성 예측이 맞다면 precision(정밀도)는 100%임
→ 그래서 재현율(recall) 을 같이 사용하는 것이 일반적임
- 높은 Precision이 중요한 경우
: 스팸 메일 필터링- 높은 Recall이 중요한 경우
: 암 진단 모델
y_scores = sgd_clf .decision_function ([some_digit]) 
→ 임계값이 높아질수록 재현율(recall)은 낮아지고, 정밀도(precision)은 높아짐
→ recall과 precision은 trade-off 관계
precision_recall_curve() : 가능한 모든 threshold 값에 대해 precision과 recall을 계산
from sklearn.metrics import precision_recall_curve
precisions, recalls, thresholds = precision_recall_curve(y_train_5, y_scores)
plt.plot(thresholds, precisions[:-1], "b--", label="정밀도", linewidth=2)
plt.plot(thresholds, recalls[:-1], "g-", label="재현율", linewidth=2)
plt.vlines(threshold, 0, 1.0, "k", "dotted", label="임곗값")
plt.legend()
plt.show()

plt.plot(recalls, precisions, linewidth=2, label ”정밀도/재현율 곡선” )
[ ... ]
plt.show()

→ recall 80% 근처에서 precision이 급격하게 줄어들기 때문에 하강점 직전을 trade-off로 선택하는 것이 좋음
→ 선택은 프로젝트의 목표에 따라 다름 (어떤 재현율에서 precision % 달성하는지를 보는 것이 중요)
TPR : 진짜 양성 비율
FPR : 거짓 양성 비율
TNR(특이도) : 진짜 음성 비율
recall(민감도) == 1-특이도
threshold_for_90_precision = thresholds[np.argmax(precisions >= 0.90)]
fpr, tpr, roc_thresholds = roc_curve(y_true, y_scores)
idx_for_threshold_at_90 = (roc_thresholds <= threshold_for_90_precision).argmax()
tpr_90 = tpr[id_x_for_threshold_at_90]
fpr_90 = fpr[id_x_for_threshold_at_90]
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, linewidth=2, label="ROC 곡선")
plt.plot([0, 1], [0, 1], 'k--', label="랜덤 분류기의 ROC 곡선")
plt.plot(fpr_90, tpr_90, "ko", label="90% 정밀도 지점")

→ 좋은 분류기는 이 점선에서 최대한 멀리 떨어져 있어야 함
- LogisticRegression, RandomForestClassifier, GaussianNB
: 여러개의 클래스를 처리- SGDClassifier, SVC
: 이진 분류기를 여러개 사용해 다중 클래스를 분류
Example
숫자가 7 이상인지 (large)
숫자가 홀수인지 (odd)
→ 이 두 가지 레이블을 동시에 예측1. y_multilabel 배열 생성
y_train_large = (y_train >= 7) y_train_odd = (y_train % 2 == 1) y_multilabel = np.c_[y_train_large, y_train_odd]2. model 학습
knn_clf = KNeighborsClassifier() knn_clf.fit(X_train, y_multilabel) knn_clf.predict([some_digit]) # → array([[False, True]])y_train_knn_pred = cross_val_predict(knn_clf, X_train, y_multilabel, cv=3) f1_score(y_multilabel, y_train_knn_pred, average='macro') # → 0.9764102655606053. 성능 평가
- 각 레이블에 대한 F1-Score를 계산한 후, 이들을 평균하여 성능을 나타냄
- average parameter
- macro : 클래스별 중요도 동일 (→ 단순평균)
- weighted : 각 레이블의 지지도(Support)에 따라 중요도를 다르게 부여
다중 레이블 분류에서 한 레이블이 다중 class가 될 수 있도록 일반화한 것
ex) 이미지에 노이즈를 추가하고 복원 작업 진행
# 노이즈 생성
np.random.seed(42)
noise = np.random.randint(0, 100, (len(X_train), 784))
X_train_mod = X_train + noise
noise = np.random.randint(0, 100, (len(X_test), 784))
X_test_mod = X_test + noise
y_train_mod = X_train
y_test_mod = X_test
left: input / right: target
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_mod, y_train_mod)
clean_digit = knn_clf.predict([X_test_mod[0]])
plot_digit(clean_digit)
plt .show()
output
→ 오차 행렬 분석
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
from sklearn.model_selection import cross_val_predict
y_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3)
ConfusionMatrixDisplay.from_predictions(y_train, y_train_pred)
plt.show()

→ 정규화된 오차 행렬 분석
ConfusionMatrixDisplay.from_predictions(
y_train, y_train_pred,
normalize='true', # 각 행을 기준으로 정규화 (실제 클래스 기준)
values_format=".0%" # 퍼센트 표시
)
plt.show()
