文章目录
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提供,该公司的服务致力于向无银行账户的人群提供信贷。
我们只用到以下数据集:
- 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
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
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')
- 创建指示哑变量DAYS_EMPLOYED_ANOM用于标记样本是否为异常点:
- 关于异常值处理没有既定的规则,一般的做法是把异常样本值作为缺失值处理,并且创建一个指示哑变量来表示样本是否为异常点。
- 结论:现在工作天数的数据分布就正常多了
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()
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')
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_SOURCE特征与标签之间的相关信息,以及它们互相之间的相关系数。
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画出来的图很直观也很漂亮。