【数据分析】信用卡用户画像及违约预测逻辑回归模型

1、数据源说明

kaggle上比较经典的数据集,来源某银行个人信贷业务,包含客户数据、信用卡数据、交易订单等基本数据,通过这些数据可以了解银行信贷业务及风险防控相关内容。

2、数据库导入及宽表建立

为便于理解及跨软件处理,已将六张表数据表导入mysql,并将账户、卡、客户信息聚合形成宽表(办卡时长和年龄字段为虚构,交易表最后交易日期为1998.12.31,故以1999.1.1为基准日期分别减去发卡日期和生日得到两个字段),E-R图如下:
在这里插入图片描述

--宽表形成逻辑
CREATE table card_client_totle as
SELECT c.card_id,c.issued,TIMESTAMPDIFF(year,c.issued,'1999-01-01') as 'used_duration',c.type,cl.sex,cl.birth_date,TIMESTAMPDIFF(year,cl.birth_date,'1999-01-01') as 'age', a.account_id,dt.A1 as district_id
FROM  card c LEFT JOIN disp d on c.disp_id = d.disp_id
left join clients cl on d.client_id = cl.client_id
LEFT JOIN accounts a on d.account_id = a.account_id
LEFT join district dt on cl.district_id = dt.A1
where d.type = '所有者'

3、tableau可视化

(1)发卡情况总体描述

在这里插入图片描述
由以上仪表盘可知:
1)金卡与普通卡用户的年龄分布比青年卡更均匀,且年龄更大,年龄分布基本符合不同类型卡的目标用户群体;
2)各类卡发卡量均呈逐年增加的趋势,增加率金卡>普通卡>青年卡,增加量普通卡>金卡>青年卡;
3)各类卡持有量普通卡>金卡>青年卡,普通卡持有量总占比达到总量的四分之三;
4)普通卡、青年卡的持卡量性别差异不明显,金卡用户男性>女性。

4、python违约预测模型建立

(1)数据提取

前期建立宽表过程中,发现card表和accounts表数据量并不匹配,即开通账户的可能并没有开通任何一种类型的卡,所以可视化中信用卡分析用到的card表不能再作为建模的基表。且其他表的外键基本上都是account_id,因此重写了宽表,以accounts表为左表,命名为card_client_totle_1。数据提取代码:

import pandas as pd
import sqlalchemy
import cryptography
import numpy as np

engine = sqlalchemy.create_engine("mysql+pymysql://root:数据库密码@localhost:3306/库名",echo=True)
model_sql = '''SELECT
	t.age,
	t.sex,
	d.GDP,
	d.A11 as 'average_salary',
	d.A10 as 'city_rate',
	d.A15 'crime_rate_1995',
	d.a16 'crime_rate_1996',
	d.A12 'unemployment_rate_1995',
	d.A13 'unemployment_rate_1996',
	d.A14 'entrepreneur_counts',
	d.A4 'resident_population',
	od.amount as od_amount,
	l.amount as loan_amount,
	l.duration,
	l.date,
	l.`status`,
	l.account_id	
FROM
	loans l LEFT JOIN `card_client_totle_1` t ON l.account_id = t.account_id
	left JOIN district d ON t.district_id = d.A1
	LEFT JOIN (select ord.account_id,sum(ord.amount) as amount from `order` ord GROUP BY ord.account_id) od on t.account_id = od.account_id;'''

df_main_info = pd.read_sql(model_sql,engine)
df_main_info.head()

获得结果:
在这里插入图片描述
将宽表与trans表连接,并增加一个索引列。

df_trans = pd.read_sql("select t.account_id,t.date,t.type,t.amount,t.balance from trans t",engine)
df_trans.head()

df_all = df_main_info.merge(df_trans,how='left',on='account_id')
df_all =  df_all.reset_index()
df_all.columns.values[0] = 'New_id'
df_all.info()

查看表信息:
在这里插入图片描述

(2)数据清洗

由上一步可知1995年的失业率和犯罪率有空值,使用中位数进行填充:

#data cleaning
#fill rate_1995 null with median
df_main_info['unemployment_rate_1995'].fillna(df_all['unemployment_rate_1995'].median(),inplace=True)
df_main_info['crime_rate_1995'].fillna(df_all['crime_rate_1995'].median(),inplace=True)

df_all
  • 2
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值