Competition/Kaggle

[kaggle] Porto serqruo safe prediction(Bert Carremans) (2)

bisi 2020. 9. 6. 17:39

이번 주제는 Porto serqruo safe prediction 로,

목표는 운전자가 내년에 자동차 보험 청구를 시작할 확률울 예측하는 모델을 구축 하는 것이다.

 

이번 필사는 Bert Carremans님의 코드를 참고하였다.

 

 

총 2가지 포스트로 내용을 나누었고, 순서는 아래와 같다. 

 

Porto serqruo safe prediction(Bert Carremans) (1)

더보기

1.데이터확인

2. Metadata

3. 기술 통계(Description Statistics)

4. 불균형 클래스 처리

5. 데이터 품질검사

 

Porto serqruo safe prediction(Bert Carremans) (2)

더보기

6. EDA Visualization

7. Feature Engineering

8. Feature 선택

9. Feature 확장

 

 


 

 

 

 

 

Porto-serqruo-safe-prediction

 

6. EDA Visualization

 
  • 범주형 변수
    • 범주형 변수와 target value가 1인 customer의 비율에 대해서 알자보자
In [45]:
v = meta[(meta.level == 'nominal') & (meta.keep)].index

for f in v:
    plt.figure()
    fig, ax = plt.subplots(figsize=(10,5))
    # 범주형 값당 target value가 1인 비율 계산
    cat_perc = train[[f, 'target']].groupby([f], as_index=False).mean()
    cat_perc.sort_values(by='target', ascending=False, inplace=True)
    # Bar plot
    # target 평균값으로 bar 내림차순 정렬
    sns.barplot(ax=ax, x=f, y ='target', data=cat_perc, order=cat_perc[f])
    plt.ylabel('% target', fontsize=18)
    plt.xlabel(f, fontsize=18)
    plt.tick_params(axis='both', which='major', labelsize=18)
    plt.show()
    
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
<Figure size 432x288 with 0 Axes>
 
 
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-45-72d900da3224> in <module>
      5     fig, ax = plt.subplots(figsize=(10,5))
      6     # 범주형 값당 target value가 1인 비율 계산
----> 7     cat_perc = train[[f, 'target']].groupby([f], as_index=False).mean()
      8     cat_perc.sort_values(by='target', ascending=False, inplace=True)
      9     # Bar plot

c:\users\hanbit\appdata\local\programs\python\python37\lib\site-packages\pandas\core\frame.py in __getitem__(self, key)
   2906             if is_iterator(key):
   2907                 key = list(key)
-> 2908             indexer = self.loc._get_listlike_indexer(key, axis=1, raise_missing=True)[1]
   2909 
   2910         # take() does not accept boolean indexers

c:\users\hanbit\appdata\local\programs\python\python37\lib\site-packages\pandas\core\indexing.py in _get_listlike_indexer(self, key, axis, raise_missing)
   1252             keyarr, indexer, new_indexer = ax._reindex_non_unique(keyarr)
   1253 
-> 1254         self._validate_read_indexer(keyarr, indexer, axis, raise_missing=raise_missing)
   1255         return keyarr, indexer
   1256 

c:\users\hanbit\appdata\local\programs\python\python37\lib\site-packages\pandas\core\indexing.py in _validate_read_indexer(self, key, indexer, axis, raise_missing)
   1302             if raise_missing:
   1303                 not_found = list(set(key) - set(ax))
-> 1304                 raise KeyError(f"{not_found} not in index")
   1305 
   1306             # we skip the warning on Categorical

KeyError: "['ps_car_11_cat'] not in index"
 
<Figure size 432x288 with 0 Axes>
 
 
  • Interval variables
    • 수치 변수간의 상관관계를 측정한다. heatmap 은 변수간의 상관관계를 시각화하여 보여주는데 좋은 방법이다.
In [47]:
def corr_heatmap(v):
    correlations = train[v].corr()
    
    # 두가지 색상으로 범위를 나타냄
    cmap = sns.diverging_palette(220, 10, as_cmap=True)
    
    fig, ax = plt.subplots(figsize=(10,10))
    sns.heatmap(correlations, cmap=cmap, vmax=1.0, center=0, fmt='.2f',
               square=True, linewidths=.5, annot=True, cbar_kws={"shrink": .75})
    plt.show()
    
v = meta[(meta.level == 'interval') & (meta.keep)].index
corr_heatmap(v)
 
 
  • 강한 상관관계를 띄는 것

    • ps_reg_03 와 ps_reg_02 : 0.7
    • ps_car_13 와 ps_car_12 : 0.67
    • ps_car_14 와 ps_car_12 : 0.58
    • ps_car_13 와 ps_car_15 : 0.53
  • Seaborn은 변수들 사이의 (선형) 관계를 시각화할 수 있는 몇 가지 유용한 플롯을 가지고 있다. 변수들 사이의 관계를 시각화하기 위해 pairplot을 사용할 수 있다. 하지만 heatmap에서 이미 제한된 수의 상관 변수를 보여 주었기 때문에, 우리는 각각의 높은 상관 관계를 가진 변수들을 개별적으로 살펴보도록 하겠다.

In [50]:
# train data 중 임의로 10%만 추출함.
s = train.sample(frac=0.1)
 
  • ps_reg_02 ans ps_reg_03
    • 회귀선이 보여주듯이 이들 변수 사이에는 선형 관계가 있다.
    • hue parameter 덕분에 target=0과 target=1의 회귀선이 동일함을 알 수 있다
In [55]:
sns.lmplot(x='ps_reg_02', y='ps_reg_03', data=s, hue='target', palette='Set1', scatter_kws={'alpha':0.5})
plt.show()
 
 
  • ps_car_12 와 ps_car_13
In [60]:
sns.lmplot(x='ps_car_12', y='ps_car_13', data=s, hue='target', palette='Set1', scatter_kws={'alpha':0.3})
plt.show()
 
 
  • ps_car_12 와 ps_car_14
In [61]:
sns.lmplot(x='ps_car_12', y='ps_car_14', data=s, hue='target', palette='Set1', scatter_kws={'alpha':0.3})
plt.show()
 
 
  • ps_car_13 와 ps_car_15
In [63]:
sns.lmplot(x='ps_car_15', y='ps_car_13', data=s, hue='target', palette='Set1', scatter_kws={'alpha':0.3})
plt.show()
 
 
  • 어떤 상관 변수를 유지할 것인가 결정해야한다. 변수에 대한 주성분 분석(PCA)를 수행하여 치수를 줄일 수 있다.
  • 상관 변수의 수가 다소 적기 때문에, 모델이 무거운 heavy-lifting을 진행한다.
 
  • 순서형 변수의 상관관계 확인
In [65]:
v = meta[(meta.level == 'ordinal') & (meta.keep)].index
corr_heatmap(v)
 
 
  • 순서형 변수는 변수들 간의 높은 상관관계가 나타나지 않는다.
  • 하지만, 우리는 목표값을 그룹화 할때, 분포가 어떻게 되는지 살펴봐야한다.
 

7. Feature Engineering

 
  • dummy 변수 만들기
    • 범주형 변수의 값은 순서나 크기를 나타내지 않는다. 예를 들어 범주 2는 범주 1의 두 배가 아니다.
    • 그러므로 우리는 그것을 다룰 더미 변수를 만들 수 있다. 이 정보는 원래 변수의 범주에 대해 생성된 다른 더미 변수에서 파생될 수 있으므로 첫 번째 더미 변수를 삭제한다.
In [76]:
v = meta[(meta.level == 'nominal') & (meta.keep)].index
print('Before dummification we have {} variables in train'.format(train.shape[1]))
train = pd.get_dummies(train, columns=v, drop_first=True)
print('After dummification we have {} variables in train'.format(train.shape[1]))
 
Before dummification we have 57 variables in train
After dummification we have 108 variables in train
 

8. Feature 선택

 
  • classifier 알고리즘을 적용하기 위해선 분산이 낮거나 0인 변수는 제거해야한다.(넣어도 의미가 없기때문)
  • Sklearn 을 사용하면 기본적으로 분산이 0인경우 삭제한다.
  • 1% 이하보다 작은 분산을 가진 변수를 삭제하면 31개 변수가 삭제 된다.
In [66]:
selector = VarianceThreshold(threshold=.01) # 1% 이하인것은 삭제
selector.fit(train.drop(['id','target'], axis=1)) # id와 target 변수를 제외하고 fit 시킨다.

f = np.vectorize(lambda x : not x) # 부울 배열 요소를 전환하기 위한 함수

v = train.drop(['id','target'], axis=1).columns[f(selector.get_support())]
print('{} variables have too low vairance.'.format(len(v)))
print('These variables are {}'.format(list(v)))
 
8 variables have too low vairance.
These variables are ['ps_ind_10_bin', 'ps_ind_11_bin', 'ps_ind_12_bin', 'ps_ind_13_bin', 'ps_car_10_cat', 'ps_car_12', 'ps_car_14', 'ps_car_11_cat_te']
 
  • 만약 우리가 분산에 근거하여 선택한다면 우리는 오히려 많은 변수를 잃을 수 있다.
  • 하지만 우리는 변수가 많지 않기 때문에 classifier가 선택하도록 한다.
  • 변수가 더 많은 데이터 세트의 경우 이렇게 하면 처리 시간이 단축될 수 있다.

  • Sklearn은 또한 다른 특징 선택 방법과 함께 제공된다.

  • 이러한 방법 중 하나는 SelectFromModel이며,이것은 다른 classifier가 최적의 feature을 선택하고 계속하도록 한다.
  • 아래 랜덤 포레스트는 어떻게 하는지 알아보자.
 
  • 랜덤포레스트와 SelectFromModel에 의해 Feature 선택
    • 여기서는 랜덤 포레스트의 Feature Importance를 기준으로 Feature를 선택한다.
    • 그런 다음 Sklearn의 SelectFromModel을 사용하여 유지할 변수 수를 지정할 수 있다.
    • Feature Importance 수준에서 threshold(임계값)을 수동으로 설정할 수 있다.
    • 하지만 여기에선 간단하게 상위 50%의 가장 좋은 변수를 선택한다.
In [90]:
X_train = train.drop(['id', 'target'], axis=1)
y_train = train['target']

feat_labels = X_train.columns

rf = RandomForestClassifier(n_estimators=1000, random_state=0, n_jobs=-1)

rf.fit(X_train, y_train)
importance = rf.feature_importances_

indices = np.argsort(rf.feature_importances_)[::-1]
In [89]:
# 컬럼별 중요도 확인
for f in range(X_train.shape[1]):
    print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]], importance[indices[f]]))
 
 1) ps_car_11_cat_te               0.052553
 2) ps_car_13                      0.051837
 3) ps_reg_03                      0.047464
 4) ps_car_14                      0.040319
 5) ps_calc_10                     0.034157
 6) ps_calc_14                     0.033609
 7) ps_calc_11                     0.031921
 8) ps_ind_15                      0.030636
 9) ps_ind_03                      0.030089
10) ps_calc_01                     0.029117
11) ps_calc_03                     0.029027
12) ps_calc_02                     0.028940
13) ps_reg_02                      0.028687
14) ps_calc_13                     0.027166
15) ps_calc_08                     0.025785
16) ps_calc_07                     0.025747
17) ps_car_15                      0.024939
18) ps_calc_06                     0.024158
19) ps_calc_09                     0.023499
20) ps_ind_01                      0.022657
21) ps_reg_01                      0.022633
22) ps_calc_05                     0.022208
23) ps_calc_04                     0.022054
24) ps_calc_12                     0.021679
25) ps_car_12                      0.021192
26) ps_car_11                      0.010905
27) ps_calc_17_bin                 0.008706
28) ps_calc_16_bin                 0.008415
29) ps_calc_19_bin                 0.008271
30) ps_calc_18_bin                 0.007922
31) ps_car_09_cat_2                0.006296
32) ps_ind_04_cat_0                0.006212
33) ps_ind_04_cat_1                0.006188
34) ps_car_01_cat_11               0.006185
35) ps_calc_20_bin                 0.006169
36) ps_ind_02_cat_1                0.005952
37) ps_car_06_cat_1                0.005666
38) ps_calc_15_bin                 0.005655
39) ps_car_09_cat_0                0.005533
40) ps_car_06_cat_11               0.005495
41) ps_ind_16_bin                  0.005282
42) ps_ind_02_cat_2                0.005236
43) ps_car_01_cat_7                0.005107
44) ps_ind_07_bin                  0.004841
45) ps_car_08_cat_1                0.004721
46) ps_ind_05_cat_0                0.004703
47) ps_ind_17_bin                  0.004503
48) ps_ind_08_bin                  0.004499
49) ps_ind_06_bin                  0.004406
50) ps_car_02_cat_1                0.004358
51) ps_car_06_cat_14               0.004294
52) ps_ind_09_bin                  0.004185
53) ps_ind_18_bin                  0.004149
54) ps_car_01_cat_10               0.003844
55) ps_car_09_cat_1                0.003692
56) ps_car_01_cat_6                0.003583
57) ps_car_07_cat_1                0.003254
58) ps_car_01_cat_9                0.003162
59) ps_ind_02_cat_3                0.003125
60) ps_car_06_cat_4                0.003054
61) ps_car_01_cat_4                0.003046
62) ps_car_06_cat_10               0.002880
63) ps_car_04_cat_1                0.002666
64) ps_car_06_cat_6                0.002653
65) ps_car_01_cat_8                0.002613
66) ps_car_01_cat_5                0.002306
67) ps_car_06_cat_7                0.002280
68) ps_ind_05_cat_6                0.002274
69) ps_car_07_cat_0                0.002191
70) ps_car_06_cat_15               0.002121
71) ps_ind_02_cat_4                0.002095
72) ps_ind_05_cat_4                0.002010
73) ps_car_06_cat_9                0.001910
74) ps_car_09_cat_3                0.001900
75) ps_car_04_cat_2                0.001847
76) ps_car_04_cat_8                0.001666
77) ps_car_06_cat_3                0.001636
78) ps_car_01_cat_3                0.001574
79) ps_car_01_cat_0                0.001479
80) ps_ind_05_cat_2                0.001425
81) ps_ind_14                      0.001402
82) ps_car_04_cat_9                0.001346
83) ps_ind_05_cat_1                0.001338
84) ps_car_10_cat_1                0.001286
85) ps_ind_05_cat_3                0.001229
86) ps_ind_12_bin                  0.001179
87) ps_car_06_cat_17               0.001116
88) ps_car_09_cat_4                0.001026
89) ps_car_06_cat_13               0.000993
90) ps_car_06_cat_16               0.000953
91) ps_car_01_cat_2                0.000870
92) ps_car_06_cat_12               0.000688
93) ps_car_01_cat_1                0.000633
94) ps_car_06_cat_5                0.000581
95) ps_ind_05_cat_5                0.000500
96) ps_car_04_cat_6                0.000438
97) ps_car_06_cat_2                0.000422
98) ps_car_06_cat_8                0.000337
99) ps_ind_11_bin                  0.000301
100) ps_car_04_cat_3                0.000263
101) ps_car_04_cat_5                0.000243
102) ps_ind_13_bin                  0.000215
103) ps_car_04_cat_7                0.000134
104) ps_ind_10_bin                  0.000111
105) ps_car_10_cat_2                0.000100
106) ps_car_04_cat_4                0.000075
 
  • SelectFromModel을 사용하여 적절한 classifier을 구체화할지, feature importance를 위한 임계치를 정할 수 있다.
  • get_support 방법을 사용하면 train 데이터의 변수 갯수 제한을 줄 수 있다.
In [1]:
sfm = SelectFromModel(rf, threshold='median', prefit=True)
print('Number of feature before selection: {}'.format(X_train.shape[1]))
n_features = sfm.transform(X_train).shape[1]
print('Number of feature after selection: {}'.format(n_features))
selected_vars = list(feat_labels[sfm.get_support()])
 
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-d548a05ec88f> in <module>
      1 # pydev_debug_cell
----> 2 sfm = SelectFromModel(rf, threshold='median', prefit=True)
      3 print('Number of feature before selection: {}'.format(X_train.shape[1]))
      4 n_features = sfm.transform(X_train).shape[1]
      5 print('Number of feature after selection: {}'.format(n_features))

NameError: name 'SelectFromModel' is not defined
In [92]:
train = train[selected_vars + ['target']]
 

9. Feature 확장

 
  • 전에 언급했던 것 처럼, train data에 standard scaling을 적용해야한다.
  • 몇몇 classifiers는 스케일링을 하는게 더 성능이 좋게 나온다.
In [95]:
scaler = StandardScaler()
scaler.fit_transform(train.drop(['target'], axis=1))
Out[95]:
array([[-0.45941104, -1.26665356,  1.25877984, ...,  0.4530072 ,
        -0.69295208,  0.82684717],
       [ 1.55538958,  0.95034274,  1.25877984, ...,  0.4530072 ,
        -0.69295208,  0.82684717],
       [ 1.05168943, -0.52765479,  1.25877984, ...,  0.4530072 ,
        -0.69295208,  0.82684717],
       ...,
       [-0.9631112 ,  0.58084336, -0.7944201 , ...,  0.4530072 ,
        -0.69295208, -1.20941334],
       [-0.9631112 , -0.89715418,  1.25877984, ..., -2.20747042,
        -0.69295208,  0.82684717],
       [-0.45941104, -1.26665356, -0.7944201 , ...,  0.4530072 ,
        -0.69295208,  0.82684717]])

 


github 소스코드 바로가기