(洞见趋势)数据探索--找出规律揭示奥秘

文章目录

1.数据集获取

1.1 数据集介绍
1.2 导入必要的工具包
1.3 数据读取

2.数据探索

2.1 查看标签的分布情况
2.2 查看缺失值
2.3 查看特征数据类型
2.4 异常点检测
2.5 相关性检验
2.6 年龄对还款的影响(探索)
2.7 外部数据源

文章正文

1. 数据集获取

1.1 数据集介绍

本次使用的数据集来源于Kaggle平台,由home credict提供,该公司的服务致力于向无银行账户的人群提供信贷。
**该数据集共8个文件**
我们只用到以下数据集:

  • application_train/application_test:
    – 关于Home credit贷款申请信息的训练和测试数据集,客户由SK-ID-CURR标识。
    – TARGET为0表示贷款已还清,TARGET为1表示贷款未还清。

1.2导入必要的工具包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
pd.set_option('display.max_columns',None)
plt.style.use('fivethirtyeight')

1.3数据读取

1.3.1 读取训练集
df_train=pd.read_csv('./application_train.csv')
df_train.head()
SK_ID_CURR	TARGET	NAME_CONTRACT_TYPE	CODE_GENDER	FLAG_OWN_CAR	FLAG_OWN_REALTY	CNT_CHILDREN	AMT_INCOME_TOTAL	AMT_CREDIT	AMT_ANNUITY	...	FLAG_DOCUMENT_18	FLAG_DOCUMENT_19	FLAG_DOCUMENT_20	FLAG_DOCUMENT_21	AMT_REQ_CREDIT_BUREAU_HOUR	AMT_REQ_CREDIT_BUREAU_DAY	AMT_REQ_CREDIT_BUREAU_WEEK	AMT_REQ_CREDIT_BUREAU_MON	AMT_REQ_CREDIT_BUREAU_QRT	AMT_REQ_CREDIT_BUREAU_YEAR
0	100002	1	Cash loans	M	N	Y	0	202500.0	406597.5	24700.5	...	0	0	0	0	0.0	0.0	0.0	0.0	0.0	1.0
1	100003	0	Cash loans	F	N	N	0	270000.0	1293502.5	35698.5	...	0	0	0	0	0.0	0.0	0.0	0.0	0.0	0.0
2	100004	0	Revolving loans	M	Y	Y	0	67500.0	135000.0	6750.0	...	0	0	0	0	0.0	0.0	0.0	0.0	0.0	0.0
3	100006	0	Cash loans	F	N	Y	0	135000.0	312682.5	29686.5	...	0	0	0	0	NaN	NaN	NaN	NaN	NaN	NaN
4	100007	0	Cash loans	M	N	Y	0	121500.0	513000.0	21865.5	...	0	0	0	0	0.0	0.0	0.0	0.0	0.0	0.0
5 rows × 122 columns
1.3.2 训练集数据整体概览
df_train.info()
# 输出信息
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 307511 entries, 0 to 307510
Columns: 122 entries, SK_ID_CURR to AMT_REQ_CREDIT_BUREAU_YEAR
dtypes: float64(65), int64(41), object(16)
memory usage: 286.2+ MB
1.3.3 读取测试集
df_test=pd.read_csv('./application_test.CSV')
df_test.info()
# 输出信息
SK_ID_CURR	NAME_CONTRACT_TYPE	CODE_GENDER	FLAG_OWN_CAR	FLAG_OWN_REALTY	CNT_CHILDREN	AMT_INCOME_TOTAL	AMT_CREDIT	AMT_ANNUITY	AMT_GOODS_PRICE	...	FLAG_DOCUMENT_18	FLAG_DOCUMENT_19	FLAG_DOCUMENT_20	FLAG_DOCUMENT_21	AMT_REQ_CREDIT_BUREAU_HOUR	AMT_REQ_CREDIT_BUREAU_DAY	AMT_REQ_CREDIT_BUREAU_WEEK	AMT_REQ_CREDIT_BUREAU_MON	AMT_REQ_CREDIT_BUREAU_QRT	AMT_REQ_CREDIT_BUREAU_YEAR
0	100001	Cash loans	F	N	Y	0	135000.0	568800.0	20560.5	450000.0	...	0	0	0	0	0.0	0.0	0.0	0.0	0.0	0.0
1	100005	Cash loans	M	N	Y	0	99000.0	222768.0	17370.0	180000.0	...	0	0	0	0	0.0	0.0	0.0	0.0	0.0	3.0
2	100013	Cash loans	M	Y	Y	0	202500.0	663264.0	69777.0	630000.0	...	0	0	0	0	0.0	0.0	0.0	0.0	1.0	4.0
3	100028	Cash loans	F	N	Y	2	315000.0	1575000.0	49018.5	1575000.0	...	0	0	0	0	0.0	0.0	0.0	0.0	0.0	3.0
4	100038	Cash loans	M	Y	N	1	180000.0	625500.0	32067.0	625500.0	...	0	0	0	0	NaN	NaN	NaN	NaN	NaN	NaN
5 rows × 121 columns
1.3.4 测试集数据整体概览
df_test.info()
# 输出信息
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 48744 entries, 0 to 48743
Columns: 121 entries, SK_ID_CURR to AMT_REQ_CREDIT_BUREAU_YEAR
dtypes: float64(65), int64(40), object(16)
memory usage: 45.0+ MB

2. 数据探索

  • 数据探索(EDA)通过统计和图表发现数据趋势、规律、模式、关系和异常的开放式过程,目的是从数据中发现有用的信息。

2.1 查看标签的分布情况

  • 标签就是我们要预测的目标,0表示及时还款,1表示违约,首先来看两者数量的对比。
  • 通过value_counts方法可以统计每一类的计数。
df_train['TARGET'].value_counts()
# 输出信息
0    282686
1     24825
Name: TARGET, dtype: int64
  • 画图查看标签分布情况。
df_train['TARGET'].plot.hist()

标签分布情况

  • 结论:不管是通过value_counts方法还是绘图方式可以看出数据存在类别不平衡问题即多数类样本是少数类样本数量的10倍以上。

2.2 查看缺失值

  • 机器学习和数据挖掘所使用的数据永远不可能是完美的,因为实际收集的数据常常会缺失重要的字段,因此我们要经常用到缺失值处理。
  • 我们要查看每列特征的缺失值数量和占比,构建一个缺失值统计函数。
def missing_values(df):
	missing_val=df.isnull().sum()
	missing_val_percent=100*df.isnull().sum()/len(df)
	missing_val_data=pd.concat([missing_val,missing_val_percent],axis=1)
	missing_val_data=missing_val_data.rename(columns={
    
    0:'Missing Values',1:'% of Total Values'})
	missing_val_data=missing_val_data[missing_val_data.iloc[:,1]!=0].sort_values('% of Total Values',ascending=False).round(1)
print('数据集有:'+str(df.shape[1])+'列,''其中'+str(missing_value_data.shape[0])+'列存在缺失值')
return missing_val_data
# 也可以实时编写一段:
missing_val=df_train.isnull().sum()
missing_val_percent=100*missing_val/len(df_train)
missing_val_data=pd.concat([missing_val,missing_val_percent],axis=1)
missing_val_data=missing_val_data.rename(columns={
    
    0:'Missing Values',1:'% of Total Values'})
missing_val_data=missing_val_data[missing_val_data.iloc[:,1]!=0].sort_values('% of Total Values',ascending=False).round(2)
# 输出结果:
	Missing Values	% of Total Values
COMMONAREA_MEDI	214865	69.87
COMMONAREA_AVG	214865	69.87
COMMONAREA_MODE	214865	69.87
NONLIVINGAPARTMENTS_MEDI	213514	69.43
NONLIVINGAPARTMENTS_MODE	213514	69.43
...	...	...
OBS_60_CNT_SOCIAL_CIRCLE	1021	0.33
DEF_60_CNT_SOCIAL_CIRCLE	1021	0.33
OBS_30_CNT_SOCIAL_CIRCLE	1021	0.33
EXT_SOURCE_2	660	0.21
AMT_GOODS_PRICE	278	0.09
64 rows × 2 columns
# 缺失值有多少列
missing_val_data.shape[0]
64
  • 查看缺失值占比大于20%的特征有哪些
missing_val_data[missing_val_data['% of Total Values']>20]
# 输出结果
Missing Values	% of Total Values
COMMONAREA_MEDI	214865	69.87
COMMONAREA_AVG	214865	69.87
COMMONAREA_MODE	214865	69.87
NONLIVINGAPARTMENTS_MEDI	213514	69.43
NONLIVINGAPARTMENTS_MODE	213514	69.43
NONLIVINGAPARTMENTS_AVG	213514	69.43
FONDKAPREMONT_MODE	210295	68.39
LIVINGAPARTMENTS_MODE	210199	68.35
LIVINGAPARTMENTS_MEDI	210199	68.35
LIVINGAPARTMENTS_AVG	210199	68.35
FLOORSMIN_MODE	208642	67.85
FLOORSMIN_MEDI	208642	67.85
FLOORSMIN_AVG	208642	67.85
YEARS_BUILD_MODE	204488	66.50
YEARS_BUILD_MEDI	204488	66.50
YEARS_BUILD_AVG	204488	66.50
OWN_CAR_AGE	202929	65.99
LANDAREA_AVG	182590	59.38
LANDAREA_MEDI	182590	59.38
LANDAREA_MODE	182590	59.38
BASEMENTAREA_MEDI	179943	58.52
BASEMENTAREA_AVG	179943	58.52
BASEMENTAREA_MODE	179943	58.52
EXT_SOURCE_1	173378	56.38
NONLIVINGAREA_MEDI	169682	55.18
NONLIVINGAREA_MODE	169682	55.18
NONLIVINGAREA_AVG	169682	55.18
ELEVATORS_MEDI	163891	53.30
ELEVATORS_MODE	163891	53.30
ELEVATORS_AVG	163891	53.30
WALLSMATERIAL_MODE	156341	50.84
APARTMENTS_MODE	156061	50.75
APARTMENTS_MEDI	156061	50.75
APARTMENTS_AVG	156061	50.75
ENTRANCES_MODE	154828	50.35
ENTRANCES_AVG	154828	50.35
ENTRANCES_MEDI	154828	50.35
LIVINGAREA_MEDI	154350	50.19
LIVINGAREA_MODE	154350	50.19
LIVINGAREA_AVG	154350	50.19
HOUSETYPE_MODE	154297	50.18
FLOORSMAX_MEDI	153020	49.76
FLOORSMAX_AVG	153020	49.76
FLOORSMAX_MODE	153020	49.76
YEARS_BEGINEXPLUATATION_AVG	150007	48.78
YEARS_BEGINEXPLUATATION_MEDI	150007	48.78
YEARS_BEGINEXPLUATATION_MODE	150007	48.78
TOTALAREA_MODE	148431	48.27
EMERGENCYSTATE_MODE	145755	47.40
OCCUPATION_TYPE	96391	31.35
  • 统计缺失值大于20%的特征数量
  • missing_val_data[missing_val_data['% of Total Values']>20].count()
  • Missing Values 50 % of Total Values 50 dtype: int64

2.3 查看特征数据类型

  • 统计特征数据类型数量,int64和float64都是数值型特征,objects是类别型特征。
  • df_train.dtypes
df_train.dtypes
# 输出结果:
SK_ID_CURR                      int64
TARGET                          int64
NAME_CONTRACT_TYPE             object
CODE_GENDER                    object
FLAG_OWN_CAR                   object
                               ...   
AMT_REQ_CREDIT_BUREAU_DAY     float64
AMT_REQ_CREDIT_BUREAU_WEEK    float64
AMT_REQ_CREDIT_BUREAU_MON     float64
AMT_REQ_CREDIT_BUREAU_QRT     float64
AMT_REQ_CREDIT_BUREAU_YEAR    float64
Length: 122, dtype: object
  • df_train.dtypes.value_counts()
df_train.dtypes.values()
# 输出结果:
float64    65
int64      41
object     16
dtype: int64
  • 查看object(类别型)特征有多少种取值。
  • df_train.select_dtypes('object')
df_train.select_dtypes('object')
# 输出结果:
	NAME_CONTRACT_TYPE	CODE_GENDER	FLAG_OWN_CAR	FLAG_OWN_REALTY	NAME_TYPE_SUITE	NAME_INCOME_TYPE	NAME_EDUCATION_TYPE	NAME_FAMILY_STATUS	NAME_HOUSING_TYPE	OCCUPATION_TYPE	WEEKDAY_APPR_PROCESS_START	ORGANIZATION_TYPE	FONDKAPREMONT_MODE	HOUSETYPE_MODE	WALLSMATERIAL_MODE	EMERGENCYSTATE_MODE
0	Cash loans	M	N	Y	Unaccompanied	Working	Secondary / secondary special	Single / not married	House / apartment	Laborers	WEDNESDAY	Business Entity Type 3	reg oper account	block of flats	Stone, brick	No
1	Cash loans	F	N	N	Family	State servant	Higher education	Married	House / apartment	Core staff	MONDAY	School	reg oper account	block of flats	Block	No
2	Revolving loans	M	Y	Y	Unaccompanied	Working	Secondary / secondary special	Single / not married	House / apartment	Laborers	MONDAY	Government	NaN	NaN	NaN	NaN
3	Cash loans	F	N	Y	Unaccompanied	Working	Secondary / secondary special	Civil marriage	House / apartment	Laborers	WEDNESDAY	Business Entity Type 3	NaN	NaN	NaN	NaN
4	Cash loans	M	N	Y	Unaccompanied	Working	Secondary / secondary special
  • 每一种object的特征都多少类型的取值。
  • df_train.select_dtypes('object').apply(pd.Series.nunique,axis=0)
df_train.select_dtypes('object').apply(pd.Series.nunique,axis=0)
# 输出结果:
NAME_CONTRACT_TYPE             2
CODE_GENDER                    3
FLAG_OWN_CAR                   2
FLAG_OWN_REALTY                2
NAME_TYPE_SUITE                7
NAME_INCOME_TYPE               8
NAME_EDUCATION_TYPE            5
NAME_FAMILY_STATUS             6
NAME_HOUSING_TYPE              6
OCCUPATION_TYPE               18
WEEKDAY_APPR_PROCESS_START     7
ORGANIZATION_TYPE             58
FONDKAPREMONT_MODE             4
HOUSETYPE_MODE                 3
WALLSMATERIAL_MODE             7
EMERGENCYSTATE_MODE            2
dtype: int64
  • 结论:大部分类别型(object)特征只有少量的取值,后续要对它们做编码操作,即字符特征转换为数值特征。

2.4 异常点检测

  • 数据探索一般会对特征做异常点检测,异常点又称为离群点,它的定义是‘样本中的一个或几个观测值离其他观测值较远,暗示它们可能来自不同的总体’。
  • 异常点的产生有可能来源于误输入,设备测量错误,数据极端情况,所以在实际业务中,需要跟数据采集人员确认产生原因。
  • 由于数据集的特征较多,这里只对DAYS_BIRTH和DAYS_EMPLOYED的异常点检测。
    • DAYS_BIRTH:出生天数,是负数,表示当前时间之前的DAYS_BIRTH天出生;
    • DAYS_EMPLOYED:工作天数,是个负数,表示当前时间之前的DAYS_EMPLOYED天开始工作。
  • 2.4.1 查看出生天数的统计信息

-df_train['DAYS_BIRTH'].describe()

df_train['DAYS_BIRTH'].describe()
# 输出结果:
count    307511.000000
mean     -16036.995067
std        4363.988632
min      -25229.000000
25%      -19682.000000
50%      -15750.000000
75%      -12413.000000
max       -7489.000000
Name: DAYS_BIRTH, dtype: float64

-DAYS_BIRTH/-365就可以得知用户年龄

(df_train['DAYS_BIRTH']/-365).describe()
# 输出结果:
count    307511.000000
mean         43.936973
std          11.956133
min          20.517808
25%          34.008219
50%          43.150685
75%          53.923288
max          69.120548
Name: DAYS_BIRTH, dtype: float64
  • 结论:年龄信息看起来很合理,最大最小值都没有超出常识范围。
  • 2.4.2 查看工作天数统计信息
  • df_train['DAYS_EMPLOYED'].describe()
df_train['DAYS_EMPLOYED'].describe()
#输出结果:
count    307511.000000
mean      63815.045904
std      141275.766519
min      -17912.000000
25%       -2760.000000
50%       -1213.000000
75%        -289.000000
max      365243.000000
Name: DAYS_EMPLOYED, dtype: float64
  • 初步结论:从输出结果来看存在异常值,最大值居然有365243(差不多1000年),而且还是个正数。
  • 2.4.3 画图查看DAYS_EMPLOYED整体分布情况。
df_train['DAYS_EMPLOYED'].plot.hist(title='Days Employed Histogram')
plt.xlabel('Days Employment')

在这里插入图片描述

  • 从图看出大部分数据分布在0附近,少部分数据分布在350000附近。
  • 假设:想要知道异常样本是否有更高或更低的违约率(如果是,或许是一个有效判断贷款违约的特征)。
  • 2.4.4 样本分离:分离出异常样本和非异常样本
  • anomly=df_train[df_train['DAYS_EMPLOYED']>300000]
  • non-anomly=df_train[df_train['DAYS_EMPLOYED']<=300000]
anomaly=df_train[df_train['DAYS_EMPLOYED']>300000]
non-anomaly=df_train[df_train['DAYS_EMPLOYED']<=300000]
# 查看异常样本取值情况:
anomaly['DAYS_EMPLOYED'].unipue()
array([365243], dtype=int64)
  • 异常样本的取值只有一种,即365243这一种。
  • 2.4.5 分别计算出异常样本和非异常样本的标签均值(违约率)
  • anomaly['TARGET'].mean()
  • no_anomaly['TARGET'].mean()
print('The anomalies default on %0.2%% of loans'%(100*anomaly['TARGET'].mean()))
print('The no_anomalies default on %0.2%% of loans'%(100*no_anomaly['TARGET'].mean()))
# 输出结果:
The anomalies default on 5.40% of loans
The no_anomalies default on 8.66% of loans
  • 结论:可以看到异常样本具有更低的违约率
  • 2.4.6 关于异常值处理
    • 关于异常值处理没有既定的规则,一般的做法是把异常样本值作为缺失值处理,并且创建一个指示哑变量来表示样本是否为异常点。
      • 创建指示哑变量DAYS_EMPLOYED_ANOM用于标记样本是否为异常点:
        -df_train['DAYS_EMPLOYED_ANOM']=df_train['DAYS_EMPLOYED'].apply(lamda x: 1 if x==365243 else 0)
      • 用中位数来替换异常值:
        -df_train['DAYS_EMPLOYED'].replace({365243:df_train['DAYS_EMPLOYED'].median()},inplace=True)
      • 画图查看非异常样本分布
        -df_train['DAYS_EMPLOYED'].plot.hist(title='Days Employment Histogram') plt.xlabel('Days Employment')
        异常值处理过的数据分布
  • 结论:现在工作天数的数据分布就正常多了
2.4.7测试集也做同样的操作
df_test['DAYS_EMPLOYED_ANOM']=df_test['DAYS_EMPLOYED'].apply(lambda x:1 if x==365243 else 0)
df_test['DAYS_EMPLOYED'].replace({
    
    365243:df_test['DAYS_EMPLOYED'].median()},inplace=True)
#输出结果:
df_test['DAYS_EMPLOYED_ANOM'].sum()
9274
len(df_test)
48744

2.5 相关性检验

  • 相关检验就是计算所有特征与标签的皮尔森(Pearson)相关系数
  • 皮尔森相关系数用于衡量两个变量(假设是X和Y)之间的线性关系,取值范围是[-1,1]。
    • Pearson相关系数越接近1,越正相关,X和Y越趋向于同向变化;
    • Pearson相关系数越接近-1,越负相关,X和Y越趋向于反向变化;
    • Pearson相关系数越接近0,相关性越弱,X和Y之间的线性关系越小。
    • 相关系数强弱的划分区间:
      • 0-0.2:“非常弱”
      • 0.2-0.4:“弱”
      • 0.4-0.6:“中等”
      • 0.6-0.8:“强”
      • 0.8-1:“非常强”
  • 计算Pearson相关系数使用pandas.DataFrame的corr()函数即可。
correlations=df_train.corr()['TAEGET'].sort_values(ascending=False)
#输出所有结果:
TARGET                         1.000000
DAYS_BIRTH                     0.078239
REGION_RATING_CLIENT_W_CITY    0.060893
DAYS_EMPLOYED                  0.058983
REGION_RATING_CLIENT           0.058899
                                 ...   
FLOORSMAX_MEDI                -0.043768
FLOORSMAX_AVG                 -0.044003
EXT_SOURCE_1                  -0.155317
EXT_SOURCE_2                  -0.160472
EXT_SOURCE_3                  -0.178919
Name: TARGET, Length: 106, dtype: float64
  • 结论:DAYS_BIRTH是最正相关的特征,EXT_SOURCE_1、EXT_SOURCE_2、EXT_SOURCE_3是最负相关的特征。
  • 不过,DAYS_BIRTH本身是负数,比较容易混淆与标签的关系,将DAYS_BIRTH取绝对值,再计算跟标签的相关关系。
df_train['DAYS_BIRTH']=abs(df_train['DAYS_BIRTH'])
df_train['DAYS_BIRTH'].corr(df_train['TARGET'])
# 输出结果:
-0.07823930830982691
  • 结论:年龄跟违约是负相关,年龄越大越不可能违约

2.6 年龄对还款的影响

2.6.1 单独看DAYS_BIRTH特征
  • 对DAYS_BIRTH画直方图查看其分布情况
plt.hist(df_train['DAYS_BIRTH']/365,bins=25)
plt.title('Age of Client')
plt.xlabel('Age(years)')
plt.ylabel('Count')
plt.show()

年龄分布情况

  • 年龄分布比较正常,没有什么特别的信息
  • 2.6.2 展示年龄对TARGET的影响
  • 根据TARGET把DAYS_BIRTH分为还款和违约样本,分别画出它们各自的概率密度分布
plt.figure(figsize=(10,8))
plt.plot(df_train.iloc[df_train['TARGET']==0,'DAYS_BIRTH']/365,label='target==0')
plt.plot(df_train.iloc[df_train['TARGET']==1,'DAYS_BIRTH']/365,label='target==1')
plt.xlabel('Age(years)')
plt.ylabel('Density')
plt.title('Distribution of Ages')

在这里插入图片描述

  • 2.6.3 查看不同年龄段对违约的影响
  • 首先用pandas的cut函数将年龄从20-70岁,按照5年做分段划分(得到10个分段),然后对每一段的数据统计其标签的平均值(违约率)。
age_target_data=df_train[['TARGET','DAYS_BRITH']]
age_target_data['YEARS_BIRTH']=df_train['DAYS_BRITH']/365
gae_target_data['YEARS_BINNED']=pd.cut(age_target_data['YAERS_BIRTH'],bins=np.linspace(20,70,num=11))
age_target_data.head()
# 输出结果:
TARGET	DAYS_BIRTH	YEARS_BIRTH	YEARS_BINNED
0	1	9461	25.920548	(25.0, 30.0]
1	0	16765	45.931507	(45.0, 50.0]
2	0	19046	52.180822	(50.0, 55.0]
3	0	19005	52.068493	(50.0, 55.0]
4	0	19932	54.608219	(50.0, 55.0]

-对YEARS_BINNED做分组,再计算其他列的均值

age_groups_mean=age_target_data.groupby('YEARS_BINNED').mean()
age_groups_mean
# 输出结果:
TARGET	DAYS_BIRTH	YEARS_BIRTH
YEARS_BINNED			
(20.0, 25.0]	0.123036	8532.795625	23.377522
(25.0, 30.0]	0.111436	10155.219250	27.822518
(30.0, 35.0]	0.102814	11854.848377	32.479037
(35.0, 40.0]	0.089414	13707.908253	37.555913
(40.0, 45.0]	0.078491	15497.661233	42.459346
(45.0, 50.0]	0.074171	17323.900441	47.462741
(50.0, 55.0]	0.066968	19196.494791	52.593136
(55.0, 60.0]	0.055314	20984.262742	57.491131
(60.0, 65.0]	0.052737	22780.547460	62.412459
(65.0, 70.0]	0.037270	24292.614340	66.555108
  • 画出标签平均值随年龄段变化的条形图
plt.figure(figsize=(8,8))
plt.bar(age_groups_mean.index.astype(str),100*age_groups_mean['TARGET'])
plt.xticks(rotation=75)
plt.xlabel('Age Group (Years)')
plt.ylabel('Failure to Repay(%)')
plt.title('Failure to Repay by Age Group')
plt.show()

年龄段划分

  • 结论:数据整体的趋势是,越年轻的用户越可能违约;
  • 最年轻的3组用户的违约率都在10%以上,年龄最大的用户违约率在4%以下。
  • 2.7 外部数据源

  • 之前算出来的最负相关的3个特征分别是EXT_SOURCE_1、EXT_SOURCE_2、EXT_SOURCE_3,这3个特征来自外部数据源的归一化处理,但不确定实际含义
  • 分析这3个特征
    • 首先,查看EXT_SOURCE特征与标签之间的相关信息,以及它们互相之间的相关系数。
      -提取标签、EXT_SOURCE、DAYS_BIRTH特征
ext_data=df_train['TARGET','EXT_SOURCE_1','EXT_SOURCE_2','EXT_SOURCE_3','DAYS_BIRTH']
# 计算相关系数矩阵
ext_data_corrs=ext_data.corr()
ext_data_corrs
# 输出结果:
TARGET	EXT_SOURCE_1	EXT_SOURCE_2	EXT_SOURCE_3	DAYS_BIRTH
TARGET	1.000000	-0.155317	-0.160472	-0.178919	-0.078239
EXT_SOURCE_1	-0.155317	1.000000	0.213982	0.186846	0.600610
EXT_SOURCE_2	-0.160472	0.213982	1.000000	0.109167	0.091996
EXT_SOURCE_3	-0.178919	0.186846	0.109167	1.000000	0.205478
DAYS_BIRTH	-0.078239	0.600610	0.091996	0.205478	1.000000
  • 根据相关系数矩阵画热力图
plt.figure(figsize=(8,6))
plt.imshow(ext_data_corrs,cmap=plt.cm.RdYlBu_r,vmin=-0.25,vmax=0.6)
plt.colorbar()
plt.title('Correlation Heatmap')
plt.show()

在这里插入图片描述

  • 持续思考:上述热力图存在两个问题:
    • 数据标签如何显示
    • 特征如何显示在坐标轴上
    • 工具层面:plt画热力图有点费劲,还是需要seaborn绘制
    • bug层面:目前seaborn一直导入不了,暂时没找到解决办法。

seaborn的安装问题解决了,用seaborn画出来的图很直观也很漂亮。

猜你喜欢

转载自blog.csdn.net/weixin_42961082/article/details/113825176