이번 주제는 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()
- 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]))
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)))
- 만약 우리가 분산에 근거하여 선택한다면 우리는 오히려 많은 변수를 잃을 수 있다.
- 하지만 우리는 변수가 많지 않기 때문에 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]]))
- 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()])
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]:
'Competition > Kaggle' 카테고리의 다른 글
[kaggle][필사] Porto serqruo safe prediction(Gabriel Preda) (1) (0) | 2020.09.07 |
---|---|
[kaggle] Porto serqruo safe prediction(Bert Carremans) (1) (0) | 2020.09.05 |
[kaggle] Titanic: Machine Learning from Disaster (4) (0) | 2020.09.04 |