신용평가
python으로 구현한 간이 단변량분석 fineclassing
jaehwi0823
2019. 10. 18. 20:45
신용평가 등의 데이터 분석 시, fineclassing 단변량 분석을 진행한다. fineclassing을 통해 개별 항목의 분포를 확인하고, target과의 관계를 빠르게 살펴볼 수 있기 때문이다.
최근 분석에서 활용한 간이 fineclassing 코드는 다음과 같다. 급하게 만들어서 깔끔하지는 않지만 충분히 실무에서도 쓸 수 있을 것이다.
Args:
- df: <pandas.DataFrame> 분석데이터
- col: <String> 컬럼명
- tgt: <String> target 컬럼명, 해당 컬럼은 0/1 binary 형식이어야 함
- nbins: <Int> 숫자형 변수의 구간수, 숫자만큼 percentile을 계산해서 컬럼 분포를 확인
Return:
- <pandas.DataFrame> 요약 결과 DataFrame을 반환
사용 코드:
from pandas.api.types import is_string_dtype
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
def FC(df, col, tgt, nbins):
mydf = df[[col, tgt]].copy()
if col == tgt:
return
elif is_string_dtype(df[col]):
mydf = mydf.fillna("_Null")
df_left = mydf[col].value_counts().to_frame()
df_right = mydf.groupby(col)[tgt].sum()
df_rslt = pd.concat([df_left, df_right], axis=1, sort=False)
df_rslt['PCT'] = df_rslt[col]/len(df)*100
df_rslt['BR'] = df_rslt[tgt]/df_rslt[col]*100
return df_rslt
else:
fc_num = mydf[col].quantile([round(x/nbins, 2) for x in range(nbins)] + [1], interpolation='nearest').drop_duplicates().astype('float')
sorted_values = sorted(set(fc_num.values))
bins = np.insert(sorted_values, 0, -np.inf)
labels = fc_num.values
cuts = pd.cut(mydf[col], bins=bins, labels=labels)
df_left = cuts.value_counts()
df_left_N = pd.Series({np.NaN: mydf[col].isnull().sum()}, name=col).to_frame()
df_left_F = pd.concat([df_left_N, df_left.to_frame()], axis=0).sort_index()
df_right = mydf.groupby(cuts)[tgt].sum()
df_right_N = pd.Series({np.NaN: mydf.loc[mydf[col].isnull(), tgt].sum()}, name=tgt).to_frame()
df_right_F = pd.concat([df_right_N, df_right.to_frame()], axis=0).sort_index()
df_rslt = pd.concat([df_left_F, df_right_F], axis=1, sort=False)
df_rslt['PCT'] = df_rslt[col]/len(mydf)*100
df_rslt['BR'] = df_rslt[tgt]/df_rslt[col]*100
df_rslt.index = df_rslt.index.astype(str)
# graph
fig, ax1 = plt.subplots()
ax1.bar(df_rslt.index, df_rslt['PCT'])
ax2 = ax1.twinx()
ax2.plot(df_rslt.index, df_rslt['BR'], 'ro-')
fig.tight_layout()
plt.show()
return df_rslt
사용예시:
- FC(train_df, 'FEATURE1', 'TARGET', 20)
팁:
- 이렇게 사용하면 한 눈에 전체 컬럼의 target rate를 한 눈에 볼 수 있다.
for column in mydf.columns:
print(column)
FC(mydf, column, 'TARGET', 20)