ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ Iris data를 이용한 SVM kernel 실습 ]
    About_Datascience/ML 2023. 3. 17. 21:15

    1. 필요한 Library Import 

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    from sklearn.model_selection import train_test_split
    from sklearn.svm import SVC
    
    np.random.seed(2021)

     

    2. Load data

    from sklearn.datasets import load_iris
    
    iris = load_iris()
    data = iris.data
    target = iris.target

     

    두 개의 그룹을 분류하는 SVM 모델 사용을 위해 데이터를 조금 줄여서 진행하도록 하자. 

     

    data = data[target != 0, :2]
    target = target[target != 0]

     

    3. Scatter Plot 을 이용한 시각화 

    scatter plot

     

     

    4. Data Split ( Train / Test )

    train_data , test_data , train_target , test_target = train_test_split(
                        data , target , train_size=0.9, random_state=2021)

     


    Kernel 

     

    1. Linear Kernel 

    linear_svc = SVC(kernel='linear')
    
    linear_svc.fit(train_data, train_target)

     

    <시각화 함수 정의 >

    def plot_support_vector_machine(svm):
        #전체 데이터
        plt.scatter(data[:,0], data[:,1], c=target, zorder=10,
                   cmap = plt.cm.Paired,edgecolors='k',s=20)
        
        # test data
        plt.scatter(test_data[:,0],test_data[:,1], s=80, facecolors='none',
                   zorder=10, edgecolors='k')
        
        plt.axis('tight')
        x_min = data[:,0].min()
        x_max = data[:,0].max()
        y_min = data[:,1].min()
        y_max = data[:,1].max()
        
        # 영역 칠하기 
        XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j]
        Z = svm.decision_function(np.c_[XX.ravel(), YY.ravel()])
        
        Z = Z.reshape(XX.shape)
        plt.pcolormesh(XX,YY,Z >0 , cmap=plt.cm.Paired, shading='auto')
        plt.contour(XX,YY,Z , colors =['k','k','k'],
                   linestyles =['--','-','--'], levels=[-.5,0,.5])

     

     

    1-1 . Linear Kernel 시각화 

    --> 위의 plot처럼 직선으로 그었을 때는 해당 클래스 영역에 다른 데이터가 있는 경우 구분할 수가 없다.

     

     

    2. Poly Kernel

    --> Poly kernel 은 직선을 곡선으로 mapping 시켜주는 커널이다.

     

     

    * Poly kernel 에 영향을 미치는 argument 

    • gamma : 결정 경계를 스케일링 해주는 값
    • degree : 몇 차원의 곡선으로 mapping 해줄 지 정해주는 값

     

     

    2-1 . gamma 

    # gamma (x) 
    poly_svc = SVC(kernel='poly')
    poly_svc.fit(train_data , train_target)
    
    # 시각화
    plt.figure(figsize=(7,7))
    plot_support_vector_machine(poly_svc)

    poly kernel 을 사용하니 직선이 곡선으로 변하긴 했지만 여전히 분류를 잘하고 있는 것 같지 않다. 

     

    이처럼 gamma 값을 설정해주지 않거나 , 0.1 과 같이 매우 작은 값을 주면 직선과 크게 다르지 않게 결과가 나온다. 

     

     

     

    <gamma 값을 크게 준 경우 (gamma = 10)>

    poly_svc = SVC(kernel='poly',gamma=10)
    poly_svc.fit(train_data , train_target)
    
    plt.figure(figsize=(7,7))
    plot_support_vector_machine(poly_svc)

     

     

    2-1 . degree

     

    <degree = 2인 경우>

    poly_svc = SVC(kernel='poly',gamma=10, degree=2)
    poly_svc.fit(train_data , train_target)
    
    plt.figure(figsize=(7,7))
    plot_support_vector_machine(poly_svc)

    2차원 곡선으로 분류

     

     

     

    <degree = 4인 경우>

    poly_svc = SVC(kernel='poly',gamma=10, degree=4)
    poly_svc.fit(train_data , train_target)
    
    plt.figure(figsize=(7,7))
    plot_support_vector_machine(poly_svc)

    4차원 곡선으로 분류

     

     

     

     

    3. RBF Kernel

    --> RBF Kernel 은 데이터를 고차원의 공간으로 mappping 시켜준다. RBF역시 gamma값으로 scaling을 한다.

     

     <argument 를 주지 않은 기본 rbf kernel>

    rbf_svc = SVC(kernel='rbf')
    rbf_svc.fit(train_data, train_target)
    
    plt.figure(figsize=(7,7))
    plot_support_vector_machine(rbf_svc)

     

     

    <gamma = 5 인 경우>

    rbf_svc = SVC(kernel='rbf', gamma=5)
    rbf_svc.fit(train_data, train_target)
    
    plt.figure(figsize=(7,7))
    plot_support_vector_machine(rbf_svc)

     

     

    <gamma = 10 인 경우>

    rbf_svc = SVC(kernel='rbf',gamma=10)
    rbf_svc.fit(train_data, train_target)
    
    plt.figure(figsize=(7,7))
    plot_support_vector_machine(rbf_svc)


     

    Penalty

    --> penaly 는 c argument 를 이용하여 줄 수 있다. 

     

     

    1. poly kernel 에 대한 No Penalty / Hard Penalty

    poly_svc = SVC(kernel='poly', gamma=10)
    poly_svc.fit(train_data, train_target)
    
    hard_penalty_poly_svc = SVC(kernel='poly', gamma=10, C=100)
    hard_penalty_poly_svc.fit(train_data, train_target)
    
    # 시각화
    plt.figure(figsize=(14,7))
    plt.subplot(1,2,1)
    plot_support_vector_machine(poly_svc)
    plt.title("No penalty")
    
    plt.subplot(1,2,2)
    plot_support_vector_machine(hard_penalty_poly_svc)
    plt.title("Hard penalty")

     

    왼 : No penalty / 오 : Hard penalty

    Poly kernel 에서는 No 와 Hard penalty가 큰 차이가 없어 보인다. 왜일까 ?

     

    그 이유는 Poly 에서는 이미 최대로 적합을 시켰기 때문에 더이상의 패널티를 반영해서 모델을 생성할 수 없기 때문에 

    Support Vector 가 머냐 가깝냐의 차이밖에 없는 것이다. 

     

     

     

    2. RBF kernel 에 대한 No Penalty / Hard Penalty

    rbf_svc = SVC(kernel='rbf', gamma=10)
    rbf_svc.fit(train_data, train_target)
    
    hard_penalty_rbf_svc = SVC(kernel='rbf', gamma=10, C=100)
    hard_penalty_rbf_svc.fit(train_data, train_target)
    
    plt.figure(figsize=(14,7))
    plt.subplot(1,2,1)
    plot_support_vector_machine(rbf_svc)
    plt.title("No penalty")
    
    plt.subplot(1,2,2)
    plot_support_vector_machine(hard_penalty_rbf_svc)
    plt.title("Hard penalty")

     

    확실히 RBF 에서는 패널티를 줬을 때 분류를 훨씬 더 정교하게 수행했음을 알 수 있다. 

Designed by Tistory.