KAGGLE竞赛实战2-捷信金融违约预测竞赛-part1-数据探索及baseline建立

竞赛链接:https://www.kaggle.com/competitions/home-credit-default-risk/

认识数据集:application的两张表是申请人信息

通过id关联bureau:过去的借款、previous_application两张表

而bureau_balance则代表对应的还款信息

表之间的关系如下:

第一部分code我们做数据探索:看缺失值、异常值、相关性情况,并做填补及字段筛选,而后用逻辑回归和随机森林分别建立baseline,最终得分0.70,离0.85的第一名得分有较大差距,后几讲会再优化

具体代码如下:
# coding: utf-8

# In[1]:


import numpy as np


# In[2]:


import pandas as pd
import time


# In[3]:


start_time=time.time()


# In[4]:


application_train=pd.read_csv('./application_train.csv',nrows=100000)


# In[5]:


application_test=pd.read_csv('./application_test.csv')


# In[6]:


previous_application=pd.read_csv('./previous_application.csv',nrows=100000)


# In[7]:


bureau_df=pd.read_csv('./bureau.csv',nrows=100000)


# In[8]:


bureau_balance=pd.read_csv('./bureau_balance.csv',nrows=100000)


# In[9]:


POS_CASH_balance=pd.read_csv('./POS_CASH_balance.csv',nrows=100000)


# In[10]:


credit_card_balance=pd.read_csv('./credit_card_balance.csv',nrows=100000)


# In[11]:


installments_payments=pd.read_csv('./installments_payments.csv',nrows=100000)


# In[12]:


application_train.memory_usage()


# In[13]:


print(f'application_train.shape:{application_train.shape}')


# In[14]:


class_counts=application_train['TARGET'].value_counts()#


# In[15]:


import matplotlib.pyplot as plt
plt.pie(class_counts,labels=class_counts.index,autopct='%1.1f%%')#显示一位小数的百分比


# In[16]:


application_train.head()#发现训练集中缺失的id都出现在了测试集中


# In[17]:


application_train.select_dtypes('object')#看哪些是文本类型


# In[18]:


#看缺失情况
def missing(df):
    missing_number=df.isnull().sum().sort_values(ascending=False)#sum看有几个缺失值,count看一共有几个值,如果直接count会踢掉缺失值再看有几个值
    missing_percent=(df.isnull().sum()/df.isnull().count()).sort_values(ascending=False)
    missing_values=pd.concat([missing_number,missing_percent],axis=1,keys=['missing_number','missing_percent'])
    return missing_values


# In[19]:


missing(application_train).sort_values(by='missing_percent',ascending=False)


# In[20]:


missing(application_train)[missing(application_train)['missing_number']>0].index


# In[21]:


#想怎么填补
#类别型变量应该由众数填补
application_train[application_train['NAME_TYPE_SUITE']=='Unaccompanied']['TARGET'].mean()


# In[22]:


application_train[application_train['NAME_TYPE_SUITE'].isna()]['TARGET'].mean()


# In[23]:


#发现二者违约率不一样,不适合这样填补,因此填成一个特殊的群体
application_train['NAME_TYPE_SUITE']=application_train['NAME_TYPE_SUITE'].fillna('Unknow')


# In[24]:


application_test['NAME_TYPE_SUITE']=application_test['NAME_TYPE_SUITE'].fillna('Unknow')


# In[25]:


application_train['OWN_CAR_AGE'].isnull().sum()


# In[26]:


#想一个人为啥没车,可能FLAG_OWN_CAR也是N
application_train.loc[application_train['OWN_CAR_AGE'].isnull()&(application_train['FLAG_OWN_CAR']=='Y')][['OWN_CAR_AGE','FLAG_OWN_CAR']]


# In[27]:


#填充没有车的人车龄为0
application_train.loc[application_train['FLAG_OWN_CAR']=='N','OWN_CAR_AGE']=application_train.loc[application_train['FLAG_OWN_CAR']=='N','OWN_CAR_AGE'].fillna(0)
application_test.loc[application_test['FLAG_OWN_CAR']=='N','OWN_CAR_AGE']=application_test.loc[application_test['FLAG_OWN_CAR']=='N','OWN_CAR_AGE'].fillna(0)


# In[28]:


#看填充结果
application_train['OWN_CAR_AGE'].isna().sum()


# In[29]:


#再看上次换电话号码的时间,发现有大量是申请当天换的电话号码,这些是没有意义的
application_train['DAYS_LAST_PHONE_CHANGE'].value_counts()


# In[30]:


#考虑把这些设为缺失值,后面再用均值或者中位数填补
application_train['DAYS_LAST_PHONE_CHANGE'].replace(0,np.nan,inplace=True)


# In[31]:


#有时没有缺失值,但有XNA,测试集没有,因此可以把它删掉
application_train['CODE_GENDER'].value_counts()


# In[32]:


application_train=application_train[application_train['CODE_GENDER']!='XNA']


# In[33]:


#开始看异常值
#三类异常:看描述性统计,minmax是否远离均值/看箱线图,是否有离群点/3西格玛法则,看25%和75%分位数是否和minmax差别过大
application_train.describe()


# In[34]:


#观察发现DAYS_EMPLOYED最大值特别大

(application_train['DAYS_EMPLOYED']/365).describe()


# In[35]:


application_train.loc[application_train['TARGET']==0,'DAYS_EMPLOYED'].hist()


# In[36]:


#直方图只适合离散值,连续值需要核密度估计图
import seaborn as sns


# In[37]:


sns.kdeplot(application_train.loc[application_train['TARGET']==0,'DAYS_EMPLOYED']/365,label='target'=='0')


# In[38]:


#写一个二分类的核密度直方图函数
def kde_plot(feature_name,df):
    plt.figure(figsize=(8,6))
    sns.kdeplot(df.loc[df['TARGET']==0,feature_name],label='target==0')
    sns.kdeplot(df.loc[df['TARGET']==1,feature_name],label='target==1')
    plt.legend()#显示曲线所代表的含义
    plt.rcParams['font.sans-serif']=['SimHei']
    plt.rcParams['axes.unicode_minus']=False
    plt.show()


# In[39]:


kde_plot('DAYS_EMPLOYED',application_train)
#发现标签为0的异常值较多,因此


# In[40]:


#把异常值置空并留一列说明这些是异常值
application_train['DAYS_EMPLOYED_ANOM']=application_train["DAYS_EMPLOYED"]
application_train['DAYS_EMPLOYED'].replace({365243:np.nan},inplace=True)
application_test['DAYS_EMPLOYED_ANOM']=application_test["DAYS_EMPLOYED"]
application_test['DAYS_EMPLOYED'].replace({365243:np.nan},inplace=True)


# In[41]:


#看特征关联性,可视化;相关系数;特征重要性


# In[42]:


kde_plot('EXT_SOURCE_3',application_train)
   #发现这个字段对标签影响比较大,特征工程时可以多考虑
   


# In[43]:


#再看看小提琴图,它既可以反应数据的分位数情况,也可以反应数据的密度情况
plt.figure(figsize=(10,8))
sns.violinplot(x='TARGET',y='EXT_SOURCE_3',data=application_train)
plt.show()


# In[44]:


#再看几个连续型变量
kde_plot('DAYS_BIRTH',application_train)


# In[45]:


#看相关性
correlations=application_train.corr()['TARGET'].sort_values()
correlations


# In[46]:


correlations.tail(15)
#看正向最重要的15个特征


# In[47]:


#看绝对值
correlations_abs=abs(correlations).sort_values(ascending=False)[:11]
correlations_abs


# In[48]:


#特征间关系,热力图,选10个最强的特征来画
correlations=application_train.corr()


# In[49]:


plt.figure(figsize=(30,40))
sns.heatmap(correlations[correlations_abs.index.tolist()])
plt.show()


# In[50]:


#发现留个变量有较强相关性
ext_data=application_train[['TARGET','DAYS_BIRTH','FLAG_EMP_PHONE','EXT_SOURCE_1','DAYS_EMPLOYED_ANOM']]


# In[51]:


ext_data_corrs=ext_data.corr()


# In[52]:


plt.figure(figsize=(10,8))
sns.heatmap(ext_data_corrs,cmap='RdBu_r',annot=True,fmt=".2f")#颜色,把字写入
plt.show()


# In[53]:


application_train[application_train['DAYS_EMPLOYED_ANOM']==1]['NAME_INCOME_TYPE'].value_counts()


# In[54]:


#发现新创建的这列DAYS_EMPLOYED_ANOM的信息可能已经被其它特征所反映,但如果能从业务角度挖掘出特别何原因,会对建模有很大帮助


# In[55]:


#验证EXT_SOURCE_1和DAYS_BIRTH有相关性,用六边形图
x=application_train['EXT_SOURCE_1']
y=application_train['DAYS_BIRTH']
plt.hexbin(x,y,gridsize=30)
plt.show()


# In[56]:


#海量数据处理的方法
import polars as pl


# In[57]:


df_pl=pl.read_csv('application_train.csv')


# In[58]:


df_pl.head()


# In[59]:


#建立baseline
bureau=pd.read_csv('./bureau.csv',nrows=100000)


# In[60]:


#先把类别型变量作数据编码。用label encoder,这对树模型不会有影响
#具体使用factorize,它对缺失值和异常值都会分配一个新值,防止自己先做填充出问题
#在合并时会遇到训练集和测试集对不齐(测试集多一列)的问题,解决方法是把训练集和测试集合起来再进行one-hot编码
#然后找到target是nan的
apply=application_train.append(application_test)

# In[61]:


object_col=apply.dtypes[apply.dtypes=='object'].index.to_list()


# In[62]:


for col in object_col:
    if len(apply[col].unique())>2:
        apply=pd.concat([apply,pd.get_dummies(apply[col],prefix=col)],axis=1)#生成独热编码,prefix是前缀
        apply.drop(columns=[col],inplace=True)#inplace表示是否删副本
    else:
        apply[col]=pd.factorize(apply[col])[0]#数值型编码
apply.head()
    


# In[63]:


#分割训练集和测试集,target为null的就是测试集
application_test=apply[apply['TARGET'].isnull()]
application_test=application_test.drop('TARGET',axis=1)
application_train=apply[~apply['TARGET'].isnull()]


# In[64]:


#逻辑回归,需要填补缺失值,并进行缩放
from  sklearn.preprocessing import MinMaxScaler
from sklearn.impute import SimpleImputer#用来算minmax


# In[65]:


train=application_train.drop(columns=['TARGET','SK_ID_CURR'])#ID和TARGET作编号时无用


# In[66]:


features=list(train.columns)


# In[67]:


imputer=SimpleImputer(strategy='median')


# In[68]:


scaler=MinMaxScaler(feature_range=(0,1))
scaler


# In[69]:


#在训练集上进行拟合
imputer.fit(train.append(application_test[features]))


# In[70]:


train=imputer.transform(train)
test=imputer.transform(application_test[features])
train


# In[71]:


scaler.fit(train)
train=scaler.transform(train)
test=scaler.transform(test)
test


# In[72]:


#训练模型
from sklearn.linear_model import LogisticRegression
log_reg=LogisticRegression(C=0.0001)
log_reg.fit(train,application_train['TARGET'])


# In[73]:


#进行预测,确保只获取第二列(为1的概率)
log_reg_pred=log_reg.predict_proba(test)[:,1]

test


# In[74]:


#获取特征的系数
coefficients=log_reg.coef_[0]#把数组转为整数
coefficients


# In[75]:


#看特征重要性
feature_importance=np.abs(coefficients)


# In[76]:


#给特征重要性排序,得出每个特征的重要性排名
sorted_indices=np.argsort(feature_importance)[::-1]


# In[77]:


for idx in sorted_indices:
    print(f"{features[idx]},IMPORTANCE:{feature_importance[idx]}")      


# In[78]:


np.argsort(feature_importance)


# In[79]:


coefficients[::-1]


# In[80]:


#保存结果
submit=application_test[['SK_ID_CURR']]


# In[81]:


submit['TARGET']=log_reg_pred


# In[82]:


submit


# In[83]:


#保存结果
submit.to_csv('baseline_model_log_reg.csv',index=False)


# In[84]:


#再尝试下其它类型的模型,随机森林
#区别于逻辑回归,它不需要缩放

train=application_train.drop(columns=['TARGET','SK_ID_CURR'])#ID和TARGET作编号时无用
features=list(train.columns)
imputer=SimpleImputer(strategy='median')
imputer.fit(train.append(application_test[features]))
train=imputer.transform(train)
test=imputer.transform(application_test[features])


# In[85]:


from sklearn.ensemble import RandomForestClassifier
random_forest=RandomForestClassifier(n_estimators=1000,random_state=2024,verbose=1,n_jobs=-1)


# In[86]:


random_forest.fit(train,application_train['TARGET'])
#提取特征重要性
feature_importance_values=random_forest.feature_importances_
feature_importances=pd.DataFrame({'feature':features,'importance':feature_importance_values})


# In[88]:


#在测试数据上预测
predictions=random_forest.predict_proba(test)[:,1]
#并保存为提交文件
submit=application_test[['SK_ID_CURR']]
submit['TARGET']=predictions


# In[89]:


#保存文件
submit.to_csv('baseline_model_random_forest.csv',index=False)
#0.703分,比逻辑回归稍好些

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/502591.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【软考网工笔记】计算机基础理论与安全——网络安全

病毒 Melissa 宏病毒 1. 是一种快速传播的能够感染那些使用MS Word 97 和MS Office 2000 的计算机宏病毒。 2. 前面有**Macro** 表示这是宏病毒; 3. 宏病毒可以感染后缀为.xls的文件;Worm 蠕虫病毒 1. 通常是通过网络或者系统漏洞进行传播。 2. 利用信…

Java虚拟机(Java Virtual Machine,JVM)

一、Java 虚拟机 Java 虚拟机(Java Virtual Machine, JVM)是运行 Java 字节码的虚拟机。它是Java平台的核心组件之一,使得Java程序具有 一次编写,到处运行(Write Once, Run Anywhere) 的特性。 JVM 有针对…

ChatGPT 主流模型GPT-4/GPT-4o mini的参数规模是多大?

微软论文又把 OpenAI 的机密泄露了??在论文中明晃晃写着: o1-preview 约 300B;o1-mini 约 100BGPT-4o 约 200B;GPT-4o-mini 约 8BClaude 3.5 Sonnet 2024-10-22 版本约 175B微软自己的 Phi-3-7B,这个不用约…

GESP202406 二级【计数】题解(AC)

》》》点我查看「视频」详解》》》 [GESP202406 二级] 计数 题目描述 小杨认为自己的幸运数是正整数 k k k(注:保证 1 ≤ k ≤ 9 1 \le k\le 9 1≤k≤9)。小杨想知道,对于从 1 1 1 到 n n n 的所有正整数中, k…

SpringMVC(六)拦截器

目录 1.什么是拦截器 2.拦截器和过滤器有哪些区别 3.拦截器方法 4.单个拦截器的执行流程 5.使用拦截器实现用户登录权限验证(实例) 1.先在html目录下写一个login.html文件 2.在controller包下写一个LoginController文件 3.加拦截器 1.创建一个conf…

基于Arduino的FPV头部追踪相机系统

构建FPV头部追踪相机:让你置身于遥控车辆之中! 在遥控车辆和模型飞行器的世界中,第一人称视角(FPV)体验一直是爱好者们追求的目标。通过FPV头部追踪相机,你可以像坐在车辆或飞行器内部一样,自由…

jQuery get 方法内操控vue变量(异步ajax请求方法中操控双向绑定的响应式变量)实现异步请求函数内完成变量的双向响应式绑定

// 首先,创建一个Vue实例 new Vue({ el: #app, data: { message: Hello, Vue! }, mounted: function() { var self this; // 使用jQuery发起get请求 $.get(your/api/url, function(data) { // 当请求成功完成后,更新Vue实…

Spring boot接入xxl-job

Spring boot接入xxl-job 导入maven包加入配置增加配置类创建执行器类&#xff08;写job的业务逻辑&#xff09;去控制台中配置job 导入maven包 <dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>…

【超详细】React SSR 服务端渲染实战

前言 这篇文章和大家一起来聊一聊 React SSR&#xff0c;本文更偏向于实战。你可以从中学到&#xff1a; 从 0 到 1 搭建 React SSR 服务端渲染需要注意什么 react 18 的流式渲染如何使用 文章如有误&#xff0c;欢迎指出&#xff0c;大家一起学习交流&#xff5e;。 &…

25年对AI产业的25点预测以及展望思考

| 2025 大宝同学对于AI 产业 25点预测&#xff0c;他自嘲道&#xff1a;“做不做 250 不重要&#xff0c;重要的是不违背自己的良知&#xff0c;以及对自身物种的坚信。”&#x1f600;ps&#xff1a;因大宝的这篇文章基文涉猎太过于广泛&#xff0c;考虑到某些原因&#xff0c…

Qt之屏幕录制设计(十六)

Qt开发 系列文章 - screencap&#xff08;十六&#xff09; 目录 前言 一、实现原理 二、实现方式 1.创建录屏窗口 2.录屏窗口类定义 3.自建容器对象定义 4.用户使用 5.效果演示 总结 前言 利用Qt实现屏幕录制设计&#xff0c;可以通过使用Qt自带的类QScreen、QPixma…

实时高保真人脸编辑方法PersonaMagic,可根据肖像无缝生成新角色、风格或场景图像。

今天给大家介绍的是一个高保真实时人脸编辑方法PersonaMagic&#xff0c;通过分阶段的文本条件调节和动态嵌入学习来优化人脸定制。该技术利用时序动态的交叉注意力机制&#xff0c;能够在不同阶段有效捕捉人脸特征&#xff0c;从而在生成个性化图像时最大程度地保留身份信息。…

我的创作纪念日——《惊变128天》

我的创作纪念日——《惊变128天》 机缘收获日常成就憧憬 机缘 时光飞逝&#xff0c;转眼间&#xff0c;我已在这条创作之路上走过了 128 天。回顾起 2024 年 8 月 29 日&#xff0c;我满怀忐忑与期待&#xff0c;撰写了第一篇技术博客《讲解LeetCode第1题&#xff1a;两数之和…

常见的框架漏洞复现

1.Thinkphp Thinkphp5x远程命令执行及getshell 搭建靶场 cd vulhub/thinkphp/5-rce docker-compose up -d 首页 漏洞根本源于 thinkphp/library/think/Request.php 中method方法可以进行变量覆盖&#xff0c;通过覆盖类的核心属性filter导致rce&#xff0c;其攻击点较为多&…

云备份项目--服务端编写

文章目录 7. 数据管理模块7.1 如何设计7.2 完整的类 8. 热点管理8.1 如何设计8.2 完整的类 9. 业务处理模块9.1 如何设计9.2 完整的类9.3 测试9.3.1 测试展示功能 完整的代码–gitee链接 7. 数据管理模块 TODO: 读写锁&#xff1f;普通锁&#xff1f; 7.1 如何设计 需要管理…

flutter在windows平台中运行报错

PS D:\F\luichun> flutter run当运行flutter项目时&#xff0c;【解决如下报错】 /C:/flutter/packages/flutter/lib/src/painting/star_border.dart:530:27: Error: The getter Matrix4 isnt defined for the class _StarGenerator.- _StarGenerator is from package:flut…

Synthesia技术浅析(二):虚拟人物视频生成

Synthesia 的虚拟人物视频生成模块是其核心技术之一&#xff0c;能够将文本输入转换为带有同步语音和口型的虚拟人物视频。该模块如下所示&#xff1a; 1.文本输入处理 2.语音生成&#xff08;TTS, Text-to-Speech&#xff09; 3.口型同步&#xff08;Lip Syncing&#xff0…

[Linux]进程间通信-共享内存与消息队列

目录 一、共享内存 1.共享内存的原理 2.共享内存的接口 命令行 创建共享内存 共享内存的挂接 去掉挂接 共享内存的控制 3.共享内存的使用代码 Comm.hpp--封装了操作接口 客户端--写入端 服务器--读取端 4.管道实现共享内存的同步机制 二、消息队列 1.底层原理 2…

凸包(convex hull)简述

凸包&#xff08;convex hull&#xff09;简述 这里主要介绍二维凸包&#xff0c;二维凸多边形是指所有内角都在 [ 0 , Π ] [0,\Pi ] [0,Π]范围内的简单多边形。 凸包是指在平面上包含所有给定点的最小凸多边形。 数学定义&#xff1a;对于给定集合 X X X&#xff0c;所有…

【ArcGISPro/GeoScenePro】检查多光谱影像的属性并优化其外观

数据 https://arcgis.com/sharing/rest/content/items/535efce0e3a04c8790ed7cc7ea96d02d/data 操作 其他数据 检查影像的属性 熟悉检查您正在使用的栅格属性非常重要。