SVM(svc)

김혜인·2023년 5월 25일

머신러닝

목록 보기
7/11

Support Vector Machine(SVM)

  • from sklearn.svm import SVC

선형(Linear)SVM

  • SVM모델: 두 클래스 간의 거리를 가장 넓게 분리할 수있는 경계선을 찾는 것이 목표
    = support vector간의 가장 넓은 margin을 가지는결정경계를 찾는다
    (support vector: 경계찾는 기준/ margin: 두 support vector간 너비)

규제 - Hard/Soft margin

  • Hard Margin -이상치 무시X >> overfitting
  • Soft Margin -이상치 무시 >> underfitting

하이퍼파라미터C

  • 이상치 무시하는 비율 :: 제약조건이라 생각
  • C값 ↑ > 제약조건 ↑ >> Hard Margin >> overfitting
  • C값 ↓ > 제약조건 ↓ >> Soft Margin >> underfitting

overfitting: hard margin(제약 ↑) > C 값을 낮춤
underfitting: soft margin(제약 ↓) > C 값을 높임

#데이터 로딩/ train,test set 나누기
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=0)

#전처리 -Scaling
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

#모델 생성 및 학습
#작으면 : soft - under fitting, 너무크면: hard - over fitting

#from sklearn.svm import SVC, linearSVC < 이거로 사용 가능

C_list = [0.0001, 0.001, 0.01, 0.1, 1, 10, 100]

train_acc_list = []
test_acc_list = []

for C in C_list:
    svc = SVC(kernel='linear', C=C, random_state=0) #linearSVC()
    svc.fit(X_train_scaled, y_train)
    
    pred_train = svc.predict(X_train_scaled)
    pred_test = svc.predict(X_test_scaled)
    
    train_acc_list.append(accuracy_score(y_train, pred_train))
    test_acc_list.append(accuracy_score(y_test, pred_test))
    

svc kernel : linear(선형)/rbf, poly, sigmoid (비선형)

x, y 값 차이 클때, 지수적으로 증가: log사용

# y, x의 값의 차이가 크다 -> 변화 흐름을 제대로 확인하기가 어렵다
#0.6 -> 0.9x ===> (0.9,1.0)
# X: 지수적으로 증가 => log
print(C_list)
print(np.log10(np.array(C_list)))

Kernel SVM(비선형(Non Linear)SVM)

  • 차원을 늘려 선형 분리가 되도록 변환
    - 1차원 > 2차원/ 2차원> 3차원 으로 늘려서 선형 분리가 되도록함

Kernel trick(커널 트릭)

  • 차원을 변경하기 위해 사용하는 함수(:Kernel)로 차원을 변경하는 것
  • 종류
    - Radial kernel
    - Polynomial kernel
    - Sigmoid kernel

비선형 SVM 모델 하이퍼파라미터

  • C : 오차허용기준관련 규제(default:1, 크면 규제 ↑, 작은면 규제 ↓)
  • gamma: 커널함수 규제(default:1, 크면 규제 ↑, 작은면 규제 ↓)
    :: 둘다 overfitting이면 감소, underfitting이면 증가

C를 고정하고 gamma값을 변경해서 모델의 복잡도를 확인
C, gamma: 큰값 - 복잡한 모델(강한 규제), overfitting이 발생할 수 있다.
: 작은 값 - 단순한 모델(약한 규제), underfitting이 발생할 수 있다.
overfitting: C, gamma 를 감소
underfitting: C, gamma를 증가

gamma_list = [0.0001, 0.001, 0.01, 0.1, 1, 10, 100] #default:1
train_acc_list =[]
test_acc_list =[]
for gamma in gamma_list:
    svc = SVC(kernel='rbf',  #rbf: 기본, 'poly', 'sigmoid', 'linear'(선형)
              C=1, #C는 고정
              gamma = gamma,
              random_state=0
             )
    svc.fit(X_train_scaled, y_train)
    
    pred_train = svc.predict(X_train_scaled)
    pred_test = svc.predict(X_test_scaled)
    
    train_acc_list.append(accuracy_score(y_train, pred_train))
    test_acc_list.append(accuracy_score(y_test, pred_test))

SVC -> probability=True(default:False)로 설정해야 predict_proba()-클래스별 확률-을 조회할 수 있다.

ROC AUC score/ AP score 볼때

-gridsearch
- kernel: 'linear', 'rbf'
- C, gamma: 0.001, 0.01, 0.1, 1, 10
- 평가지표: accuracy(refit), roc_auc, average_precision

#pipeline
from sklearn.pipeline import Pipeline

pipeline = Pipeline([('scaler',StandardScaler()),('svm',SVC(random_state=0, probability=True))], verbose=True)

#grid search
params = {
    "svm__kernel":['linear','rbf','poly','sigmoid'],  #linear만 선형, 나머지는 비선형
    "svm__C":[0.001, 0.01, 0.1, 1, 10], 
    "svm__gamma":[0.001, 0.01, 0.1, 1, 10]
    #<-underfitting--------------------일반화--------------------overfitting->
}
gs = GridSearchCV(pipeline,params,scoring=["accuracy", "roc_auc", "average_precision"], refit="accuracy",cv=4, n_jobs=-1)


#train
gs.fit(X_train,y_train)

gs.best_score_

gs.best_params_

result_df = pd.DataFrame(gs.cv_results_)
result_df.sort_values('rank_test_accuracy').head()

0개의 댓글