[변수 선택 및 생성]중요 변수 선택 및 파생 변수 만들기-2
2020. 1. 9. 22:52ㆍ분석 Python/Data Preprocessing
이전 글 | https://data-newbie.tistory.com/382 |
저번 글에서 피드백을 받은 PolynomialFeatures와 추가적인 2가지 변수가 아닌 중요 변수 조합을 시각화하는 그림을 만들어봤다.
대신 polynomial은 곱하기 연산으로만 이루어져서, 나누기라던지, 빼기는 표현이 되지 않지만, 쉽게 쓸 수 있다는 장점이 있어서 좋은 것 같다.
import matplotlib.pyplot as plt
import numpy as np
import pandasa as pd
import saeborn as sns
from scipy.stats import wasserstein_distance as wd , ks_2samp as ks , energy_distance as ed
일단 중요 변수는 저번 글에서 뽑았으니 그대로 사용하자.
중요 변수 : ['V2', 'V5', 'V7', 'V9', 'V10', 'V15', 'V16', 'V28']
일단은 저 중요 변수의 조합인 8C2 = 28개 x (곱하기(4)) = 112개를 만들어보자.
import itertools
important = ['V2', 'V5', 'V7', 'V9', 'V10', 'V15', 'V16', 'V28']
newcol = ["+" , "-" , "x", "/"]
# combinations
a = list(itertools.combinations(important , 2))
이제는 시각화를 해보자 그러면 112 x 4로 시각화를 해보자.
추가로 ks , energy distance , wasserstein distance 총 3가지를 같이 보여주는 것으로 바꿨다.
fig , axes = plt.subplots(nrows=len(a) ,ncols=len(newcol),
figsize=(20,80) )
plt.subplots_adjust(left=0.05, bottom=0.01, right=0.99,
top=0.99, wspace=None, hspace=0.7)
ax = axes.flatten()
combinations = list(map(list,itertools.product(a, newcol))) ## 112
for idx , col in enumerate(combinations) :
one , two = col[0]
cal = col[1]
name = "{} {} {}".format(one , cal , two)
if cal == "+" :
data[name] = (data.loc[: , one] + data.loc[: , two])
elif cal == "/" :
data[name] = (data.loc[: , one] / data.loc[: , two])
elif cal == "-" :
data[name] = (data.loc[: , one] - data.loc[: , two])
elif cal == "x" :
data[name] = (data.loc[: , one] * data.loc[: , two])
target1 = data.loc[idx1 , [name]].dropna()
target0 = data.loc[idx0 , [name]].dropna()
m = MinMaxScaler(feature_range=(-1,1))
target1 = m.fit_transform(target1)
target0 = m.fit_transform(target0)
sns.distplot(target1 , ax = ax[idx])
sns.distplot(target0 , ax = ax[idx])
kdist , b = ks(np.squeeze(target1) , np.squeeze(target0))
wdist = wd(np.squeeze(target1) , np.squeeze(target0))
edist = ed(np.squeeze(target1) , np.squeeze(target0))
msg = "[{}] | ed : {} | ks : {} | wd : {}".format(name ,
np.round(edist,3),
np.round(kdist,3),
np.round(wdist,3),
)
ax[idx].set_title(msg , fontsize= 10)
plt.savefig("./New.png")
plt.show()
이런 식의 그림을 얻을 수 있다!
이제는 polynomialfeature를 통해서 만들어보자.
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(4 , interaction_only=True ,include_bias=False)
important = ['V2', 'V5', 'V7', 'V9', 'V10', 'V15', 'V16', 'V28']
#poly.fit_trans
poly_result = poly.fit(data[important])
poly_result = poly.transform(data[important])
cols = ["poly_{}".format(i) for i in range(poly_result.shape[1])]
output = pd.DataFrame(poly_result , columns= cols)
poly_result.shape ## (85347, 162)
이제 162개의 새로운 변수가 만들어졌는데, 이러면 너무 많으니 분포 간 거리를 재서 1보다 클 경우에만 쓰는 식으로 정하였다.
store = []
for idx , col in enumerate(cols) :
target1 = output.loc[idx1 , [col]].dropna()
target0 = output.loc[idx0 , [col]].dropna()
m = MinMaxScaler(feature_range=(-1,1))
target1 = m.fit_transform(target1)
target0 = m.fit_transform(target0)
wdist = wd(np.squeeze(target1) , np.squeeze(target0))
if wdist > 1 :
store.append(col)
len(store) ## 39
그러면 남은 개수는 162 -> 39개의 유용한 변수들로만 압축했다.
이제 다시 애들을 위의 그림과 동일하게 시각화해보자.
fig , axes = plt.subplots(nrows=10 ,ncols=4,
figsize=(20,20) )
plt.subplots_adjust(left=0.05, bottom=0.01, right=0.99,
top=0.99, wspace=None, hspace=0.7)
ax = axes.flatten()
for idx , col in enumerate(store) :
target1 = output.loc[idx1 , [col]].dropna()
target0 = output.loc[idx0 , [col]].dropna()
m = MinMaxScaler(feature_range=(-1,1))
target1 = m.fit_transform(target1)
target0 = m.fit_transform(target0)
kdist , b = ks(np.squeeze(target1) , np.squeeze(target0))
wdist = wd(np.squeeze(target1) , np.squeeze(target0))
edist = ed(np.squeeze(target1) , np.squeeze(target0))
sns.distplot(target1 , ax = ax[idx])
sns.distplot(target0 , ax = ax[idx])
msg = "[{}] | ed : {} | ks : {} | wd : {}".format(col ,
np.round(edist,3),
np.round(kdist,3),
np.round(wdist,3),
)
ax[idx].set_title(msg , fontsize= 10)
plt.savefig("./New2.png")
plt.show()
polynomial feature를 쓰면 n차 interaction까지 반영할 수 있다.
대신에 아쉽게도 나누기 빼기 더하기 같은 것은 할 수가 없다.
이런 식으로 유용한 변수를 얻어서 변수에 추가하면 모델링하는데 도움이 될 것이라고 생각한다.
- 끝 -
728x90
'분석 Python > Data Preprocessing' 카테고리의 다른 글
[실험] 정형데이터에서 연속형 변수 전처리에 따른 Network 성능 차이는 얼마나 날까? (0) | 2020.03.21 |
---|---|
[변수 선택] sklearn에 있는 mutual_info_classif , mutual_info_regression를 활용하여 변수 선택하기 (feature selection) (0) | 2020.03.09 |
[변수 선택 및 생성]중요 변수 선택 및 파생 변수 만들기 (2) | 2020.01.08 |
[ Python ] Scikit-Learn, 변수 전처리 Pipeline Transformer 만들어보기 (0) | 2019.12.28 |
[ 변수 처리] 결측치 대체 알고리즘 MissForest Imputation 연습 (0) | 2019.12.11 |