close_btn
조회 수 760 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files
서술형 및 전체 코드는 첨부파일을 참조하시기 바랍니다.
ToBigs_11th Session_Week02 :

EDA and Classification using Logistic Regression, Naive Bayes, SVM, KNN

원안 작성자 10기 박규리, 황이은

과제 수행자 11기 김대웅



0. Importing package


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pandas as pd
import numpy as np
import os
#from tqdm import tnrange,tqdm_notebook
import seaborn as sns; sns.set()
import matplotlib.pyplot as plt
import datetime
import re
from sklearn.cluster import KMeans
from pandas.plotting import scatter_matrix
 
from sklearn.linear_model import LinearRegression
from sklearn import cross_validation as CV
 
#디렉토리 경로 적어주세요
os.getcwd()
os.chdir("C:/Users/wungi/Desktop/tobigs session/1주차/1주차 Linear Regression/과제 부동산 경매/Auction_master")
AM_train = pd.read_csv("Auction_master_train.csv")
cs


1. Preprosessing

1.1. 데이터 탐색

 지난번 과제와 달라진 부분만 작성하였습니다. 전체 과정은 첨부파일에 있습니다. 

상관행렬 살펴보기

  • 변수들이 너무 많아 보기어렵다.
  • 상관계수가 너무 낮은 변수를 제거한 후 다시 살펴보자.


1
2
3
4
5
6
7
8
9
heatmap_data = AM_train[AM_train.columns[1:]]
 
colormap = plt.cm.RdBu
plt.figure(figsize=(1412))
plt.title('Pearson Correlation of Features', y=1.05, size=15)
sns.heatmap(heatmap_data.astype(float).corr(), linewidths=0.1, vmax=1.0,
           square=True, cmap=colormap, linecolor='white', annot=False, annot_kws={"size"16})
 
del heatmap_data
cs

cormtx.png


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#예측변수와의 상관계수 본다음 정렬하기(ascending=False는 내림차순)
abs(corr_matrix["Hammer_price"]).sort_values(ascending=False)
 
# 상관계수 0.1보다 낮은 경우 버림
cor_a = abs(corr_matrix["Hammer_price"]).sort_values(ascending=False)
low_cor_index = cor_a[cor_a <= 0.1].index
 
new_AM_train = AM_train.drop(list(low_cor_index),axis=1)
 
#21개로 줄은 피쳐
new_AM_train.shape
# (1933, 21)
 
new_AM_train.columns
'''
Index(['Auction_key', 'Bid_class', 'Claim_price', 'Total_land_real_area',
       'Total_land_auction_area', 'Total_building_area',
       'Total_building_auction_area', 'Total_appraisal_price',
       'Minimum_sales_price', 'addr_do', 'Total_floor', 'Current_floor',
       'point.y', 'point.x', 'Hammer_price', 'Floor', 'Diff_price',
       'addr_si_강남구', 'addr_si_사하구', 'addr_si_서초구', 'addr_si_송파구'],
      dtype='object')
'''
 
 
cs


연속형 변수 정리 2 : 이상치 제거 및 정규화

  • 각각의 히스토그램을 살펴보고 정규분포를 따르지 않는 경우 정규화, 이상치가 존재할 경우 제거
1
2
3
4
5
6
7
8
9
10
11
# 연속형 변수의 histogram
fig, axs = plt.subplots(ncols=2, nrows=4, figsize=(1224))
 
sns.distplot(new_AM_train.Claim_price, kde=True, hist=False, ax=axs[0,0])
sns.distplot(new_AM_train.Total_land_real_area, kde=True, hist=False, ax=axs[0,1])
sns.distplot(new_AM_train.Total_land_auction_area, kde=True, hist=False, ax=axs[1,0])
sns.distplot(new_AM_train.Total_building_area, kde=True, hist=False, ax=axs[1,1])
sns.distplot(new_AM_train.Total_building_auction_area, kde=True, hist=False, ax=axs[2,0])
sns.distplot(new_AM_train.Total_appraisal_price, kde=True, hist=False, ax=axs[2,1])
sns.distplot(new_AM_train.Minimum_sales_price, kde=True, hist=False, ax=axs[3,0])
sns.distplot(new_AM_train.Diff_price, kde=True, hist=False, ax=axs[3,1])
cs


del outlier.png


연속형 변수를 살펴본 결과 극단치가 존재하여 분포를 정확히 확인할 수 없다.

MAD(Median Absolute Deviation)을 이용해 이상치를 제거해보자.

1
2
3
4
5
6
7
8
9
def mad_based_outlier(points, thresh=3.5):
    if len(points.shape) == 1:
        points = points[:,None]
    median = np.median(points, axis=0)
    diff = np.sum((points - median)**2, axis=-1)
    diff = np.sqrt(diff)
    med_abs_deviation = np.median(diff)
    modified_z_score = 0.6745 * diff / med_abs_deviation
    return modified_z_score > thresh 
cs




1
2
3
# Claim_price의 이상치를 제거한 분포는 아래와 같다.
Test = new_AM_train[~mad_based_outlier(new_AM_train.Claim_price)]
sns.distplot(Test.Claim_price, kde=True, hist=True)
cs

다운로드.png

1
2
3
# 정적편포의 형태를 띄고 있으므로 정규화를 위해 제곱근변환 한다.
Test.Claim_price = np.sqrt(Test.Claim_price)
sns.distplot(Test.Claim_price, kde=True, hist=True)
cs


다운로드 (1).png

 위와 같은 방식으로 그래프를 확인하며 정적편포를 보일 경우 제곱근 변환합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 이어서 Total_land_real_area의 이상치 제거하면
Test = Test[~mad_based_outlier(Test.Total_land_real_area)]
sns.distplot(Test.Total_land_real_area, kde=True, hist=True)
 
# 이어서 Total_land_auction_area의 이상치를 제거
Test = Test[~mad_based_outlier(Test.Total_land_auction_area)]
sns.distplot(Test.Total_land_auction_area, kde=True, hist=True)
 
# Total_appraisal_price의 이상치도 제거
Test = Test[~mad_based_outlier(Test.Total_appraisal_price)]
sns.distplot(Test.Total_appraisal_price, kde=True, hist=True)
# 정적편포를 보이므로 제곱근 변환
Test.Total_appraisal_price = np.sqrt(Test.Total_appraisal_price)
sns.distplot(Test.Total_appraisal_price, kde=True, hist=True)
cs



1
2
3
4
# Diff_price의 경우 감정가와 낙찰가 간의 차이가 얼마 나지 않는 경우가 매우 많다.
# 감정가와 낙찰가의 차이가 작은 경우와 그렇지 않은 경우로 변수를 변환하자.
Test = Test[~mad_based_outlier(Test.Diff_price)]
sns.distplot(Test.Diff_price, kde=True, hist=True)
cs


다운로드 (2).png

1
2
3
# 위 histogram에서 bin을 확인하기 위해 동일한 급간 개수만큼 hist함수를 통해 그리고 bins에 저장된 값을 확인
n, bins, patches = plt.hist(Test.Diff_price, bins=16)
plt.show()
cs

다운로드 (3).png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bins
'''
array([0.00000e+00, 1.37250e+07, 2.74500e+07, 4.11750e+07, 5.49000e+07,
       6.86250e+07, 8.23500e+07, 9.60750e+07, 1.09800e+08, 1.23525e+08,
       1.37250e+08, 1.50975e+08, 1.64700e+08, 1.78425e+08, 1.92150e+08,
       2.05875e+08, 2.19600e+08])
'''
 
# 0을 포함한 정적편포에서는 보통 log(X + C) 변환을 사용함. (where C > 1)
# 이 경우 두 분포로 나눠지게 된다.
sns.distplot(np.log(Test.Diff_price + 1), kde=True, hist=True)
 
# 두 그룹으로 나눠지는 경계값을 확인하기 위해 bins=3으로 그리고 두 집단간의 사이값을 경계값으로 삼아 집단을 2분류하자
n, bins, patches = plt.hist(np.log(Test.Diff_price+1), bins=3)
plt.show()
cs


다운로드 (4).png다운로드 (5).png


1
2
3
4
5
6
bins
# array([ 0.        ,  6.40243942, 12.80487885, 19.20731827])
bins[1:3].mean()
# 9.603659136076692
# 파생변수 추가 : Diff_price_Bi : 경매가-낙찰가 차이의 집단 2분류
Test["Diff_price_Bi"= Test.Diff_price.apply(lambda x : 1 if np.log(x + 1> bins[1:3].mean() else 0)
cs


상관성이 높은 변수 제거


 토지면적을 나타내는 변수들끼리의 상관성이 매우 높아 하나의 변수만 남기고 삭제한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
# Total_land_real_area : 양의 상관관계가 보임
# 값이 0인 경우도 많이 보임
fig, axs = plt.subplots(ncols=4, nrows=2,  figsize=(2010))
# 서울
sns.scatterplot(x='Total_land_real_area',y = 'Hammer_price',data=Test[Test.addr_do == 1], linewidth=0.5, s=5, ax=axs[0,0])
sns.scatterplot(x='Total_land_auction_area',y = 'Hammer_price',data=Test[Test.addr_do == 1], linewidth=0.5, s=5, ax=axs[0,1])
sns.scatterplot(x='Total_building_area',y = 'Hammer_price',data=Test[Test.addr_do == 1], linewidth=0.5, s=5, ax=axs[0,2])
sns.scatterplot(x='Total_building_auction_area',y = 'Hammer_price',data=Test[Test.addr_do == 1], linewidth=0.5, s=5, ax=axs[0,3])
# 부산
sns.scatterplot(x='Total_land_real_area',y = 'Hammer_price',data=Test[Test.addr_do == 0], linewidth=0.5, s=5, ax=axs[1,0])
sns.scatterplot(x='Total_land_auction_area',y = 'Hammer_price',data=Test[Test.addr_do == 0], linewidth=0.5, s=5, ax=axs[1,1])
sns.scatterplot(x='Total_building_area',y = 'Hammer_price',data=Test[Test.addr_do == 0], linewidth=0.5, s=5, ax=axs[1,2])
sns.scatterplot(x='Total_building_auction_area',y = 'Hammer_price',data=Test[Test.addr_do == 0], linewidth=0.5, s=5, ax=axs[1,3])
cs



다운로드 (6).png


서울, 부산 모두 면적과 낙찰가는 강한 양의 상관을 보인다. 면적을 나타내는 변수들은 모두 서로 강한 양의 상관을 보이고 있는데, 이들 중 Total_land_auction_area, Total_land_real_area는 값이 0인 자료가 보이므로 해당 변수를 사용하는 대신 상관이 큰 다른 변수를 사용하는 것이 적절할 것이다. Total_building_area, Total_building_auction_area 두 변수는 예측대상 변수에 대한 상관정도가 비슷하므로, 이 두 변수 중 의미상으로 더 적절한 것을 고르면 된다. 후자의 경우 경매에 부쳐진 건물의 면적을 의미하므로, 전자인 전체 빌딩 면적보다 낙찰가에 더 관련이 있다고 볼 수 있다. 따라서 Total_building_auction_area 변수만을 사용한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 해당 변수 삭제
Test.drop(["Total_land_real_area""Total_land_auction_area""Total_building_area"], axis=1, inplace=True)
 
 
# 상관행력 재확인
heatmap_data = Test[Test.columns[1:]]
 
colormap = plt.cm.RdBu
plt.figure(figsize=(1412))
plt.title('Pearson Correlation of Features', y=1.05, size=15)
sns.heatmap(heatmap_data.astype(float).corr(), linewidths=0.1, vmax=1.0,
           square=True, cmap=colormap, linecolor='white', annot=False, annot_kws={"size"16})
 
del heatmap_data
cs



다운로드 (7).png

히트맵을 다시 확인했을 때 서로 상관이 큰 변수들과 예측 대상 변수와의 상관 정도에 따른 선택할 변수는 다음과 같다.

  • [Floor, Current_floor, Total_floor] : Total_floor

  • [Claim_price, Total_building_auction_area, Total_appraisal_price, Mininum_sales_price] : Minimum_sales_price

  • [Diff_price, Diff_price_Bi] : Diff_price


1
2
3
4
5
6
7
8
9
10
11
12
13
# 상관이 높은 변수들 중 예측할 변수와 가장 상관이 큰 변수만 남기고 나머지 변수는 삭제
Test.drop(["Floor""Current_floor""Claim_price""Total_building_auction_area""Total_appraisal_price","Diff_price_Bi"], axis=1, inplace=True)
 
# 최종 상관행렬
heatmap_data = Test[Test.columns[1:]]
 
colormap = plt.cm.RdBu
plt.figure(figsize=(1412))
plt.title('Pearson Correlation of Features', y=1.05, size=15)
sns.heatmap(heatmap_data.astype(float).corr(), linewidths=0.1, vmax=1.0,
           square=True, cmap=colormap, linecolor='white', annot=False, annot_kws={"size"16})
 
del heatmap_data
cs

다운로드 (8).png


이진분류 모델 적합 및 비교 : Logistic Regression, KNN, SVM, Naive Bayes


이진분류를 위한 class 설정


1
binary_y = y.apply(lambda x : 1 if x > y.median() else 0)
cs


모델 비교

0) Robust Scaling

  • Robust scaling은 이상치의 영향을 줄여주는 방법으로 중앙값과 IQR을 사용하여 스케일링합니다.

cf. 어떤 모델이 Scaling이 필요한가?

  • SVM, KNN, NN : 거리(혹은 유사도)기반이므로 scale에 민감한 모델이며 따라서 feature scaling이 필요합니다.
  • 반면 Graphical-model 기반 분류기인 LDA, Naive Bayes, Decision Trees, Tree-based ensemble 기법(RF, XGB)는 feature scale에 영향을 받지 않습니다.
  • Linear Regression과 Logistic Regression의 경우 입력변수가 정규성을 만족한다면 Scaling이 필요하지 않습니다.

cf. 스케일링의 종류

  1. 패키지 : sklearn.preprocessing
  2. 함수
    • scale(X) : 기본 스케일
    • robust_scale(X) : 중앙값과 IQR 사용, outlier 최소화
    • minmax_scale(X) : 최대/최소값 각각 1, 0이 되도록 스케일링
    • maxabs_scale(X) : 최대절대값과 최소절대값이 각각 1, 0이 되도록 스케일링
  3. 클래스 : 파이프라인을 사용할 때 사용
    • StandardScaler() : scale() 함수에 대응
    • RobustScaler() : robust_scale() 함수에 대응
    • 클래스 사용방법 :
      1. 클래스 객체 생성
      2. fit() 메서드와 트레이닝 데이터를 사용해 변환계수 추정
      3. transform() 메서드 사용해 실제로 자료 변환
      4. 또는 fit_transform() 메서드 사용해 계수추정과 자료 변환을 동시에 실행
  4. 위 두 방법 다 np.array 형태로 리턴된다.

참고


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# (1) robust_scale을 사용해 데이터셋을 직접 변환하는 방법
from sklearn.preprocessing import robust_scale
rb_x = pd.DataFrame(robust_scale(x), columns=x.columns)
 
# (2) RobustScaler() Class 사용
# pipeline 형태로 사용할 때 쓰임
from sklearn.preprocessing import RobustScaler
 
rbscaler = RobustScaler()
# 이 방법
rbscaler.fit(x)
rb_x2 = rbscaler.transform(x)
# 또는 이 방법
rbscaler.fit_transform(x)
cs


1) train set과 test set 분리

  • train set : 모델의 훈련 및 hyperparameter 결정을 위한 K-fold cv test에 사용하는 data set
  • test set : 모델 간 비교를 위한 data set.
1
2
3
from sklearn.model_selection import train_test_split
dfX_train, dfX_test, dfy_train, dfy_test = train_test_split(x, binary_y, test_size = 0.2, random_state=0)
dfX_train.shape, dfX_test.shape, dfy_train.shape, dfy_test.shape
cs


2) K-fold Cross Validation : StratifiedKFold

  • 예측변수의 분포가 불균형할 때 사용하는 방법 여기선 정확하게 50%로 잘랐으므로 불균형하진 않지만 보다 일반적인 상황에서 사용할 수 있으므로 소개함
  • sklearn v0.20을 기점으로 cross_validation 모듈의 함수, 클래스 등이 model_selection 모듈로 이동함
  • 이 중 KFold 계열 클래스가 용법이 바뀜.
  • https://www.haya-programming.com/entry/2018/12/04/052713
  • 새 버전에서도 이전 버전처럼 쓰려면 아래처럼 사용
1
2
3
4
5
6
7
8
9
10
# 구형 : GridSearchCV()내부에서 cv에 바로 넣을 수 있음
from sklearn.cross_validation import StratifiedKFold 
list(StratifiedKFold(y=dfy_train, n_folds=5))
 
# 신형(v0.20 이후)
# 구형처럼 바로 generate 되지 않고, class attribute로 fold 수 지정 후
# .split 메서드를 이용해 X와 Y를 넣어줘야함.
# GridSearchCV()의 cv= 에 list() 안씌우고 넣으면 작동하지 않음
from sklearn.model_selection import StratifiedKFold
list(StratifiedKFold(n_splits=5).split(dfX_train, dfy_train))
cs



3) Hyperparameter tuning

  • 모델별로 Hyper-parameter optimization에 다음 방법을 사용함.
  • [sklearn.model_selection]

    1. validation_curve : 단일 하이퍼 파라미터 최적화
    2. GridSearchCV : 그리드를 사용한 복수 하이퍼 파라미터 최적화
      • 클래스로서 fit 메서드로 사용
      • 다음 속성들을 가진다.
        • cvresults : param_grid의 모든 prameter 조합에 대한 성능 결과 (구 : gridscores)
        • bestscore : 최고점수
        • bestestimator : 최고 점수를 낸 parameter를 가진 model
    3. ParameterGrid : 복수 파라미터 최적화용 그리드
  • 참고 : https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html

3.1) Logistic Regression Hyper-parameter tuning

3.3.1) validation_curve를 이용하는 방법

  • train_scores, test_scores를 쉽게 얻을 수 있음
  • best parameter를 찾으려면 반환되는 array의 max값의 index를 가지고 param_range에서 해당 parameter를 찾아야함.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import validation_curve
 
param_range_LR = np.logspace(-3,610)
 
train_scores, test_scores = \
    validation_curve(LogisticRegression(), robust_scale(dfX_train), dfy_train,
                     param_name="C", param_range = param_range_LR,
                     cv = list(StratifiedKFold(n_splits=5).split(dfX_train, dfy_train)),
                     scoring="accuracy", n_jobs=4)
 
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
 
plt.figure(figsize=(12,12))
plt.semilogx(param_range_LR, train_scores_mean, label="Training score", color="r")
plt.fill_between(param_range_LR, train_scores_mean - train_scores_std,
                train_scores_mean + train_scores_std, alpha = 0.2, color="r")
plt.semilogx(param_range_LR, test_scores_mean,
            label = "Cross-validation score", color="g")
plt.fill_between(param_range_LR, test_scores_mean - test_scores_std, 
                test_scores_mean + test_scores_std, alpha = 0.2, color = "g")
plt.legend(loc="best")
plt.title("Validation Curve with SVM")
plt.xlabel("$\gamma$")
plt.ylabel("Score")
plt.ylim(0.01.1)
plt.show()
cs

다운로드 (9).png

3.3.2) GridSearchCV 를 이용하는 방법

  • 설정이 복잡하지만 GridSeachCV 과정에 대한 상세한 정보를 얻을 수 있음
  • 메서드를 통해 최적 parameter가 적용된 모델과 그 점수를 바로 확인 가능
  • 아래 코드의 실행결과 나오는 그래프는 위의 것과 같아 생략


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
 
param_range_LR = np.logspace(-3,610)
param_grid_LR = dict(C=param_range_LR)
 
grid = GridSearchCV(LogisticRegression(), param_grid = param_grid_LR,
                    cv = list(StratifiedKFold(n_splits=5).split(dfX_train, dfy_train)))
grid.fit(robust_scale(dfX_train), dfy_train) # robust scaling
 
print("The best classifier is : ", grid.best_estimator_,
      "\nThe best Score is : ", grid.best_score_)
 
# 별도의 변수에 저장 (뒤에서 비교 위함)
clf_LR = copy.deepcopy(grid.best_estimator_)
clf_LR_Best = copy.deepcopy(grid.best_score_)
 
'''
The best classifier is :  LogisticRegression(C=1000.0, class_weight=None, dual=False,
          fit_intercept=True, intercept_scaling=1, max_iter=100,
          multi_class='ovr', n_jobs=1, penalty='l2', random_state=None,
          solver='liblinear', tol=0.0001, verbose=0, warm_start=False) 
The best Score is :  0.996996996996997
'''
 
train_scores_mean = grid.cv_results_["mean_train_score"]
train_scores_std = grid.cv_results_["std_train_score"]
test_scores_mean = grid.cv_results_['mean_test_score']
test_scores_std = grid.cv_results_["std_test_score"]
 
plt.figure(figsize=(12,12))
plt.semilogx(param_range_LR, train_scores_mean, label="Training score", color="r")
plt.fill_between(param_range_LR, train_scores_mean - train_scores_std,
                train_scores_mean + train_scores_std, alpha = 0.2, color="r")
plt.semilogx(param_range_LR, test_scores_mean,
            label = "Cross-validation score", color="g")
plt.fill_between(param_range_LR, test_scores_mean - test_scores_std, 
                test_scores_mean + test_scores_std, alpha = 0.2, color = "g")
plt.legend(loc="best")
plt.title("Validation Curve with LR")
plt.xlabel("C")
plt.ylabel("Score(ACC)")
plt.ylim(0.01.1)
plt.show()
cs



3.2) KNN Hyper-parameter tuning

  • hyper-parameter k(n_neighbors), distance measuring method(p)를 튜닝합니다.
  • n_neigbors 는 최근접 이웃의 개수로 홀수로 선정하며(동률 방지) 너무 작으면 Overfitting, 너무 크면 Underfitting의 가능성이 커집니다.
  • p는 1일 경우 Manhattan 2일 경우 Uclidain


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
 
param_range_KNN = np.arange(1,30,2)
param_grid_KNN = dict(p=np.array([1,2], dtype=np.int8),n_neighbors=param_range_KNN)
 
grid = GridSearchCV(KNeighborsClassifier(), param_grid = param_grid_KNN,
                    cv = list(StratifiedKFold(n_splits=5).split(dfX_train, dfy_train)))
grid.fit(robust_scale(dfX_train), dfy_train) # robust scaling
 
print("The best classifier is : ", grid.best_estimator_,
      "\nThe best Score is : ", grid.best_score_)
 
# 별도의 변수에 저장 (뒤에서 비교 위함)
clf_KNN = copy.deepcopy(grid.best_estimator_)
clf_KNN_Best = copy.deepcopy(grid.best_score_)
 
'''
The best classifier is :  KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=1, n_neighbors=3, p=1,
           weights='uniform') 
The best Score is :  0.9782282282282282
'''
cs


hyper-parameter가 2개인 경우 격자모양으로 살펴보면 편하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pylab as pl
# plot the scores of the grid
# grid_scores_ contains parameter settings and scores
 
# We extract just the scores
scores = grid.cv_results_["mean_test_score"]
scores = np.array(scores).reshape(len(param_range_KNN), 2)
 
scores = scores.T
 
# Make a nice figure
pl.figure(figsize=(10,10))
pl.subplots_adjust(left=0.15, right=0.95, bottom=0.15, top=0.95)
pl.imshow(scores, interpolation="nearest", cmap=pl.cm.Spectral)
pl.ylabel("")
pl.xlabel("k(n_neighbors)")
pl.colorbar()
pl.xticks(np.arange(len(param_range_KNN)), param_range_KNN, rotation=45)
pl.yticks(np.arange(2), np.array(["Manhattan","Uclidian"]))
pl.show()
cs



다운로드 (10).png

3.3) SVM Hyper-parameter tuning

  • hyper-parameter : C, gamma(RBF kernel의 경우)
  • C는 decision boundary에서의 error 허용 정도를 의미하며 C값이 작을수록 높은 일반화 성능
  • gamma는 하나의 데이터 샘플이 영향력을 행사하는 거리, guasian function의 std와 관련됨, gamma값이 클수록 작은 std를 가져 decision boundary의 curvature가 커짐
  • 두 parameter 모두 너무 낮으면 underfitting 너무 높으면 overfitting 가능성 커짐



linaer와 RBF kernel SVM을 한 번에 비교할 경우

  • 보통 SVM은 10의 배수 간격으로 그리드 서치를 수행합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from sklearn.svm import SVC
# sklearn v0.20 기준
from sklearn.model_selection import StratifiedKFold
C_range = np.logspace(-285)
gamma_range = np.logspace(-8-45)
 
param_grid = np.array([dict(C=C_range, kernel=["linear"]), dict(C=C_range, gamma = gamma_range, kernel = ["rbf"])])
                           # cf. 구형 (v0.20 이전) : cv = StratifiedKFold(y=dfy_train, n_folds=5)
grid = GridSearchCV(SVC(), param_grid = param_grid,
                    cv = list(StratifiedKFold(n_splits=5).split(dfX_train, dfy_train)),n_jobs=2)
%time grid.fit(robust_scale(dfX_train), dfy_train)
print("The best classifier is : ", grid.best_estimator_)
print("The best score is : ", grid.best_score_)
 
# 별도의 변수에 저장 (뒤에서 비교 위함)
clf_SVM = copy.deepcopy(grid.best_estimator_)
clf_SVM_Best = copy.deepcopy(grid.best_score_)
 
# Linaer SVM과 RBF SVM 중 grid내에서 성능이 제일 좋은 모델
'''
Wall time: 8.79 s
The best classifier is :  SVC(C=316227.7660168379, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
The best score is :  0.9977477477477478
'''
 
cs


  • Linear SVM의 경우 Validation Curve


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Linear SVM의 점수만 가져오기
train_scores_mean = grid.cv_results_["mean_train_score"][:len(C_range)]
train_scores_std = grid.cv_results_["std_train_score"][:len(C_range)]
test_scores_mean = grid.cv_results_['mean_test_score'][:len(C_range)]
test_scores_std = grid.cv_results_["std_test_score"][:len(C_range)]
 
plt.figure(figsize=(12,12))
plt.semilogx(C_range, train_scores_mean, label="Training score", color="r")
plt.fill_between(C_range, train_scores_mean - train_scores_std,
                train_scores_mean + train_scores_std, alpha = 0.2, color="r")
plt.semilogx(C_range, test_scores_mean,
            label = "Cross-validation score", color="g")
plt.fill_between(C_range, test_scores_mean - test_scores_std, 
                test_scores_mean + test_scores_std, alpha = 0.2, color = "g")
plt.legend(loc="best")
plt.title("Validation Curve with Linear SVM")
plt.xlabel("C")
plt.ylabel("Score(ACC)")
plt.ylim(0.91.01)
plt.show()
cs

다운로드 (11).png


  • RBF SVM의 경우 Grid Heatmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# plot the scores of the grid
scores = grid.cv_results_["mean_test_score"][len(C_range):]
scores = np.array(scores).reshape(len(C_range), len(gamma_range))
 
# Make a nice figure
pl.figure(figsize=(12,8))
pl.subplots_adjust(left=0.15, right=0.95, bottom=0.15, top=0.95)
pl.imshow(scores, interpolation="nearest", cmap=pl.cm.Spectral)
pl.xlabel("$\gamma$")
pl.ylabel("C")
pl.colorbar()
pl.xticks(np.arange(len(gamma_range)), gamma_range, rotation=45)
pl.yticks(np.arange(len(C_range)), C_range)
pl.show()
cs



다운로드 (12).png

RBF에 대해서만 GridSearchCV하고 싶다면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
C_range = np.logspace(6810)
gamma_range = np.logspace(-5-210)
 
param_grid = dict(gamma = gamma_range, C=C_range )
 
grid = GridSearchCV(SVC(), param_grid = param_grid, cv = list(StratifiedKFold(n_splits=5).split(dfX_train, dfy_train)))
grid.fit(dfX_train, dfy_train)
print("The best classifier is : ", grid.best_estimator_)
 
# plot the scores of the grid
# grid_scores_ contains parameter settings and scores
score_dict = grid.grid_scores_
 
# We extract just the scores
scores = [x[1for x in score_dict]
scores = np.array(scores).reshape(len(C_range), len(gamma_range))
 
# Make a nice figure
pl.figure(figsize=(12,8))
pl.subplots_adjust(left=0.15, right=0.95, bottom=0.15, top=0.95)
pl.imshow(scores, interpolation="nearest", cmap=pl.cm.Spectral)
pl.xlabel("$\gamma$")
pl.ylabel("C")
pl.colorbar()
pl.xticks(np.arange(len(gamma_range)), gamma_range, rotation=45)
pl.yticks(np.arange(len(C_range)), C_range)
pl.show()
'''
The best classifier is :  SVC(C=1668100.537200059, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma=0.00021544346900318823,
  kernel='rbf', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
'''
cs

다운로드 (13).png

3.4) Naive Bayes Hyper-parameter tuning

  • hyper-parameter : 모수에 대한 사전정보(전체 자료에서의 label별 비율), 설정하지 않으면 입력 데이터셋에서 추출해 사용함.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import StratifiedKFold
 
# 0 부터 1 까지 0.01간격으로 parameter range 설정
param_range = []
NBarangeSet = np.arange(0,1,0.001)
for i in range(len(NBarangeSet)):
    param_range.append([NBarangeSet[i],1-NBarangeSet[i]])
 
 
param_grid = dict(priors=param_range)
grid = GridSearchCV(GaussianNB(), param_grid = param_grid,
                    cv = list(StratifiedKFold(n_splits=5).split(dfX_train, dfy_train)),n_jobs=2)
 
%time grid.fit(robust_scale(dfX_train), dfy_train)
print("The best classifier is : ", grid.best_estimator_)
print("The best score is : ", grid.best_score_)
 
# 별도의 변수에 저장 (뒤에서 비교 위함)
clf_NB = copy.deepcopy(grid.best_estimator_)
clf_NB_Best = copy.deepcopy(grid.best_score_)
 
'''
Wall time: 11.7 s
The best classifier is :  GaussianNB(priors=[0.609, 0.391])
The best score is :  0.9159159159159159
'''
cs



4. 모델간 성능비교

-test set을 이용해 모델 간의 성능을 비교합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn.metrics import roc_auc_score, roc_curve, confusion_matrix, accuracy_score, mean_squared_error, r2_score, f1_score
 
names = ["LR""KNN""SVM""NB"]
classifiers = [clf_LR, clf_KNN, clf_SVM, clf_NB]
clf_LR.predict
 
result= []
results=[]
confusion_mtx = {}
preds ={}
 
for Name, model in zip(names, classifiers):
    pred = model.predict(robust_scale(dfX_test))
    preds[Name] = pred
    cf_mtx = confusion_matrix(dfy_test, pred)
    AUC = roc_auc_score(dfy_test, pred)
    result = [Name, accuracy_score(dfy_test, pred), f1_score(dfy_test, pred), AUC]
    results.append(result)
    confusion_mtx[Name] = cf_mtx
 
results = pd.DataFrame(results, columns=["Model""ACC""F1""AUC"])
results
 
cs


SmartSelectImage_2019-01-30-11-25-27.png

ACC 및 AUC 값을 기준으로 볼 때 모델의 성능은 LR 및 SVM(Linear) > KNN > NB(Gaussian) 순으로 좋다.





List of Articles
번호 제목 글쓴이 날짜 조회 수
공지 우수 코드 게시판 이용 관련 공지사항 DataMarket 2014.05.21 39740
153 투빅스 10기&11기 8주차 CNN 심화 [VGG 구현]- 11기 홍지은 file 오디빛 2019.03.27 688
152 투빅스 10기&11기 8주차 CNN 심화 - 11기 정혜인 file 정혜인 2019.03.27 496
151 투빅스 10기&11기 7주차 NLP - 11기 김유민 file 2019.03.21 543
150 투빅스 10기&11기 7주차 Algorithm - 11기 한재연 file 한재연 2019.03.20 423
149 투빅스 10기&11기 7주차 CNN (Alexnet) - 11기 심은선 file 심은선 2019.03.15 444
148 투빅스 10기&11기 7주차 - NLP - 11기 유기윤 file 유기윤 2019.03.14 458
147 투빅스 10기&11기 6주차 Advanced Neural Network - 11기 김대웅 file 김대웅 2019.03.12 447
146 투빅스 10기&11기 5주차 Neural Network - 11기 김대웅 file 김대웅 2019.03.07 453
145 투빅스 10기&11기 4주차 Algorithm - 10기 정윤호 UNOVATE 2019.03.04 426
144 투빅스 10기&11기 4주차 ML Performance Tuning - 11기 김대웅 김대웅 2019.02.22 462
143 투빅스 10기&11기 4주차 PCA - 11기 임채빈 임채빈 2019.02.22 528
142 투빅스 10기&11기 3주차 Clustering - 11기 한재연 file 한재연 2019.02.16 485
141 투빅스 10기&11기 3주차 Decision Tree - 11기 김유민 file 2019.02.15 494
140 투빅스 10기&11기 3주차 Clustering - 11기 김대웅 file 김대웅 2019.02.15 496
139 투빅스 10기&11기 3주차 Algorithm - 11기 한재연 file 한재연 2019.02.15 444
138 투빅스 10기&11기3주차 앙상블(Kaggle HousePrice) - 11기 이소라 file 소라찌 2019.02.15 489
137 투빅스 10기&11기 2주차 SVM, Naive Bayes, KNN - 11기 유기윤 file 유기윤 2019.02.02 599
» 투빅스 10기&11기 2주차 SVM, Naive Bayes, KNN - 11기 김대웅 file 김대웅 2019.01.31 760
135 투빅스 10기&11기 1주차 Algorithm - 11기 한재연 1 file 한재연 2019.01.31 1044
134 투빅스 10기&11기 1주차 Algorithm - 11기 권혜민 file 권혜민 2019.01.31 879
Board Pagination ‹ Prev 1 2 3 4 5 6 7 ... 8 Next ›
/ 8

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5