선 (1)과 (2)중 어떤 선이 최적의 분류 선일까?

(2) 가 최적의 분류를 위한 경계선이다. 이유는 각 클래스의 별로 가장 가까이 있는 데이터간의 거리가 가장 넓기 때문이다. 넓다는 것은 그만큼 겹치는 부분이 적다는 것이므로 새로운 데이터를 예측할 때 모호성이 적어져서 맞을 확률이 더 높아지게 된다. SVM 모델은 두 클래스 간의 거리를 가장 넓게 분리할 수있는 경계선을 찾는 것을 목표로 한다.
결정경계(Decision boundary)란
- 분류 문제에서 클래스들을 구분/분리하는 기준이다.
- 분류 모델들은 학습시 train dataset을 이용해 결정경계를 찾는다.

C로 정한다. 무시비율이 너무 커지면 underfitting 문제가 발생할 수 있다.


[2차원으로 변환 항 추가]

[원래 공간으로 변환]

from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split X, y = load_breast_cancer(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=1)##### SVM 전처리 ### 연속형(수치형) - Feature scaling ### 범주형 - One Hot Encoding from sklearn.preprocessing import StandardScaler #, OneHotEncoder scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # Linear SVM - hyper parameter: C C_list = [0.001, 0.01, 0.1, 1, 10, 100] train_acc_list = [] test_acc_list = []from sklearn.svm import SVC # SVR: 회귀, SVC: 분류 from sklearn.metrics import accuracy_score for C in C_list: svm = SVC( kernel="linear", # 커널 함수 지정. 선형SVM: linear, 비선형SVM: rbf(기본), poly, sigmoid C=C, # soft - hard margin 설정. (작을수록 강한 규제) # gamma=100, # 비선형 svm의 hyperparameter random_state=0 ) svm.fit(X_train_scaled, y_train) pred_train = svm.predict(X_train_scaled) pred_test = svm.predict(X_test_scaled) train_acc_list.append(accuracy_score(y_train, pred_train)) test_acc_list.append(accuracy_score(y_test, pred_test))import pandas as pd import numpy as np df = pd.DataFrame({ "C":np.log10(C_list), "Train": train_acc_list, "Test": test_acc_list }) df.set_index("C")
df.set_index("C").plot();
### 비선형 SVM. Hyper Parameter - C: soft/hard margin 규제, gamma (기본: 1) # gamma 변경에 따른 성능 변화. gamma_list = [0.001, 0.01, 0.1, 1, 5, 10, 100] train_acc_list = [] test_acc_list = [] for gamma in gamma_list: svm = SVC(kernel="rbf", C=1, gamma=gamma) # kernel기본값: rbf svm.fit(X_train_scaled, y_train) train_acc_list.append(accuracy_score(y_train, svm.predict(X_train_scaled))) test_acc_list.append(accuracy_score(y_test, svm.predict(X_test_scaled)))df = pd.DataFrame({ "gamma":np.log10(gamma_list), "Train":train_acc_list, "Test":test_acc_list }) df
df.set_index("gamma").plot(grid=True);
ROC AUC score, AP score
from sklearn.metrics import roc_auc_score, average_precision_score # roc_auc_score(정답, 추정한 양성의 확률) -> model.predict_proba(X)[:, 1] svm = SVC(probability=True) # probability=True 설정해야 predict_proba() 사용가능. svm.fit(X_train_scaled, y_train) pos_proba = svm.predict_proba(X_train_scaled)[:, 1] print(roc_auc_score(y_train, pos_proba)) print(average_precision_score(y_train, pos_proba))0.997880008479966
0.9985299004450608
from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split X, y = load_breast_cancer(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=1)### Pipeline -> 1) scaler 2) svm from sklearn.pipeline import Pipeline from sklearn.model_selection import GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC pipeline = Pipeline([ ("scaler", StandardScaler()), ("svm", SVC(random_state=0, probability=True)) ]) params = { "svm__kernel":["linear", "rbf", "poly", "sigmoid"], "svm__C": [0.001, 0.01, 0.1, 1, 10, 100], "svm__gamma": [0.001, 0.01, 0.1, 1, 10, 100] } gs = GridSearchCV(pipeline, params, scoring=["accuracy", "average_precision", "roc_auc"], refit="accuracy", cv=4, n_jobs=-1) gs.fit(X_train, y_train)
### 결과 확인 gs.best_params_{'svmC': 10, 'svmgamma': 0.01, 'svm__kernel': 'rbf'}
gs.best_score_0.9836007758772702
pd.options.display.max_colwidth = 100 # 컬럼의 값을 몇글자 까지 다 보여줄지. result = pd.DataFrame(gs.cv_results_) result.sort_values("rank_test_roc_auc")[result.columns[7:]].head()
# 최종평가 best_model = gs.best_estimator_ pred_test = best_model.predict(X_test) accuracy_score(y_test, pred_test)0.972027972027972