项目8:信用违约预测-集成学习

目录

背景说明

项目介绍

导入模块

数据加载

分析与处理数据

划分数据集

使用随机森林创建并训练模型

通过参数搜索和过采样,缓解标签不平衡问题

小结


背景说明

风险已经成为了今年金融市场的重要主题之一,银行作为贷方,随时都面临着借贷者违约的风险。传统的专家规则在金融科技时代逐渐过时,机器学习和金融业务的交叉也延伸到信贷领域。违约预测就是其中一重要应用。本实验基于信贷业务场景中一个月内的抽样数据,数据集有34个维度,Target表示客户在接下来一个月是否有违约。模型生成后可使用当前月的数据预测接下来一个月客户是否会违约。

项目介绍

违约预测只有违约和没有预约两种结果,是个二分类问题。针对二分类问题,可使用的算法有逻辑回归、朴素贝叶斯、支持向量机、树模型等。本实验选用集成学习的算法来拟合数据。考虑到样本极度不均衡,模型评价选用综合指标f1_score。

导入模块

# 数据读取、处理、分析、可视化,算法模块等
import pandas as pd
import numpy as np
#导入相关包
%matplotlib inline
# import seaborn as sns
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")

数据加载

读入数据,数据文件是dataset-credit-default.csv,定义为df。查看数据尺寸、打印信息,##查看Target的分布 ,是否违约(1是,0否)等

df = pd.read_csv('./数据集/dataset-credit-default.csv')
df

# 查看数据尺寸
print(df.shape)

# 打印信息
print(df.info())

# 查看Target的分布,是否违约(1是,0否)
print(df['Target'].value_counts(normalize=True))

分析与处理数据

观察数据缺失情况,把缺失比例超过20%的数据列删掉

data = df[df.columns[df.notnull().sum()/len(df)>0.8]].dropna(axis=0) 

划分数据集

提取特征数据X和目标数据y。

X = data.drop('Target', axis=1)
y = data['Target']

划分训练集和测试集,通过观察发现正样本与负样本非常不平衡。将数据集作3:1的划分,按照标签比例做分层抽样,分出训练集和测试集,观察每个数据集中正负样本数量。

from sklearn.model_selection import train_test_split

# 3:1的划分,按照标签比例做分层抽样
X_train, X_test, y_train, y_test = train_test_split(X, y,         test_size=0.25, stratify=y, random_state=42)

# 观察每个数据集中正负样本数量
print(y_train.value_counts())
print(y_test.value_counts())

引入StandardScaler标准化工具库,对训练集和测试集做标准化

from sklearn.preprocessing import StandardScaler

# 对训练集和测试集做标准化
std_scaler = StandardScaler().fit(X_train)
X_train_std = std_scaler.transform(X_train)
X_test_std = std_scaler.transform(X_test)

标准化后的测试集

X_train_std

X_test_std

查看X_train_std

模块化处理:对从分析与处理数据-划分数据集进行函数(模块化)处理

# 通过函数化的编程思想,把上面数据预处理的过程模块化
# 实现 分析与处理数据 -- 划分数据集 -- 对训练集和测试集做标准化
def process_data(df):
    """
    传入读入的df
    """
    # 把缺失比例超过20%的数据列删掉
    data = df[df.columns[df.notnull().sum()/len(df)>0.8]].dropna(axis=0) 

    # 提取特征数据X和目标数据y
    X = data.drop('Target', axis=1)
    y = data['Target']

    # 3:1的划分,按照标签比例做分层抽样
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, 
                                                    stratify=y, random_state=42)
    # 此时得到了return的y_train, y_test,还需标准化X_train, X_test
    # 对训练集和测试集做标准化
    std_scaler = StandardScaler().fit(X_train)
    X_train_std = std_scaler.transform(X_train)
    X_test_std = std_scaler.transform(X_test)

    # 返回标准化后的训练集、测试集和训练标签、测试标签
    return X_train_std,X_test_std,y_train, y_test

测试模块化后的函数是否可用

df2 = pd.read_csv('./数据集/dataset-credit-default.csv')

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
X_train_std,X_test_std,y_train, y_test = process_data(df2)
X_train_std,X_test_std,len(X_train_std),len(X_test_std)

使用随机森林创建并训练模型

引入随机森林的库,构建并训练模型。

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

# 创建随机森林分类器
rf_model = RandomForestClassifier(random_state=42)

# 训练模型
rf_model.fit(X_train_std, y_train)

对模型进行评价:准确率、召回率、精确率和f1分数。

# 对测试集进行预测
y_test_pred1 = rf_model.predict(X_test_std)

# 计算评估指标
accuracy = accuracy_score(y_test, y_test_pred1)
recall = recall_score(y_test, y_test_pred1)
precision = precision_score(y_test, y_test_pred1)
f1 = f1_score(y_test, y_test_pred1)

# 打印评估结果
print(f"准确率: {accuracy:.4f}")
print(f"召回率: {recall:.4f}")
print(f"精确率: {precision:.4f}")
print(f"F1分数: {f1:.4f}")

观察混淆矩阵,深入了解模型性能

from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix

cm = confusion_matrix(y_test, y_test_pred1, labels=rf_model.classes_)
disp_1 = ConfusionMatrixDisplay(confusion_matrix=cm,display_labels=rf_model.classes_)
disp_1.plot()

通过参数搜索和过采样,缓解标签不平衡问题

正反样本分开

X_train_0 = X_train[y_train==0]
y_train_0 = y_train[y_train==0]
X_train_1 = X_train[y_train==1]
y_train_1 = y_train[y_train==1]

对正样本过采样

# 过采样后的正样本数量将接近负样本数量的一半,从而一定程度上减少类别不平衡

from sklearn.utils import resample
X_train_1_res,y_train_1_res = resample(X_train_1,y_train_1,replace=True,n_samples=int(len(X_train_0)*0.5),random_state=42)
X_train_res = np.vstack([X_train_0,X_train_1_res])
y_train_res = np.hstack([y_train_0,y_train_1_res])

# 引入StandardScaler标准化工具库
from sklearn.preprocessing import StandardScaler
#对训练集和测试集做标准化
std_scaler_res = StandardScaler().fit(X_train_res)
X_train_std_res = std_scaler.transform(X_train_res)

from sklearn.model_selection import cross_val_score
cv_scores = cross_val_score(rf_model, X_train_std_res, y_train_res,  cv=5)  
print('cross validation score of model version1 {}'.format(cv_scores))

随机森林调参

参数搜索矩阵如下:

param_test0 = {'class_weight':[{0:0.8,1:0.2},{0:0.7,1:0.3},{0:0.1,1:0.9},'balanced'],
               'max_depth':[2,4,6,8],
               'n_estimators':[50,100,200]}

from sklearn.model_selection import GridSearchCV

# 创建 GridSearchCV 对象
grid_search = GridSearchCV(estimator=rf_model, param_grid=param_test0, scoring='f1', cv=5, n_jobs=-1, verbose=1)

# 执行网格搜索
grid_search.fit(X_train_std_res, y_train_res)

# 输出最佳参数
print("最佳参数:", grid_search.best_params_)
print("最佳分数:", grid_search.best_score_)

# 输出所有结果
results = grid_search.cv_results_
for mean_score, params in zip(results['mean_test_score'], results['params']):
    print(f"参数: {params}, 平均分数: {mean_score:.4f}")

随机森林模型效果评估

# 使用最佳参数构建随机森林模型
rf_model_res = RandomForestClassifier(
    class_weight='balanced',
    max_depth=8,
    n_estimators=200,
    random_state=42
)

# 训练模型(使用过采样后的数据)
rf_model_res.fit(X_train_std_res, y_train_res)

# 对测试集进行预测
y_pred_res = rf_model_res.predict(X_test_std)

# 计算评估指标
accuracy_res = accuracy_score(y_test, y_pred_res)
recall_res = recall_score(y_test, y_pred_res)
precision_res = precision_score(y_test, y_pred_res)
f1_res = f1_score(y_test, y_pred_res)

# 打印评估结果
print("过采样后的模型性能:")
print(f"准确率: {accuracy_res:.4f}")
print(f"召回率: {recall_res:.4f}")
print(f"精确率: {precision_res:.4f}")
print(f"F1分数: {f1_res:.4f}")

观察混淆矩阵

# 计算混淆矩阵
conf_matrix_res = confusion_matrix(y_test, y_pred_res)

# 绘制混淆矩阵
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix_res, annot=True, fmt='d', cmap='Blues', 
            xticklabels=['Predicted 0', 'Predicted 1'], 
            yticklabels=['Actual 0', 'Actual 1'])
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix (After Oversampling)')
plt.show()

过采样前后的结果对比

# 过采样前的模型性能(假设已经训练过并保存了结果)
print("过采样前的模型性能:")
print(f"准确率: {accuracy:.4f}")
print(f"召回率: {recall:.4f}")
print(f"精确率: {precision:.4f}")
print(f"F1分数: {f1:.4f}")

# 过采样后的模型性能
print("\n过采样后的模型性能:")
print(f"准确率: {accuracy_res:.4f}")
print(f"召回率: {recall_res:.4f}")
print(f"精确率: {precision_res:.4f}")
print(f"F1分数: {f1_res:.4f}")

过采样前后的混淆矩阵的结果对比

# 过采样前的混淆矩阵(假设已经计算过并保存为 conf_matrix)
plt.figure(figsize=(12, 5))

# 过采样前的混淆矩阵
plt.subplot(1, 2, 1)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
            xticklabels=['Predicted 0', 'Predicted 1'], 
            yticklabels=['Actual 0', 'Actual 1'])
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix (Before Oversampling)')

# 过采样后的混淆矩阵
plt.subplot(1, 2, 2)
sns.heatmap(conf_matrix_res, annot=True, fmt='d', cmap='Blues', 
            xticklabels=['Predicted 0', 'Predicted 1'], 
            yticklabels=['Actual 0', 'Actual 1'])
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix (After Oversampling)')

plt.tight_layout()
plt.show()

小结

本实验主要使用Python进行数据预处理、数据分析,使用Matplotlib做可视化分析,使用过采样方法平衡正反例数据,使用随机森林建模,使用网格搜索来寻找最优参数组合。违约预测问题面临着所需数据维度多、正负样本严重不均衡等问题,在实际应用上,可以多搜集各类维度的特征,多尝试过采样、欠采样,也可以尝试使用无监督学习、深度神经网络等。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文了解:部署 Deepseek 各版本的硬件要求

很多朋友在咨询关于 DeepSeek 模型部署所需硬件资源的需求,最近自己实践了一部分,部分信息是通过各渠道收集整理,so 仅供参考。 言归正转,大家都知道,DeepSeek 模型的性能在很大程度上取决于它运行的硬件。我们先看一下…

Redis分布式锁故障处理:当Redis不可用时的应对策略

Redis分布式锁故障处理:当Redis不可用时的应对策略 在分布式系统中,Redis因其高性能和丰富的特性常被用于实现分布式锁。但当加锁过程中Redis服务不可用时,系统将面临严重挑战。本文将深入探讨这一问题,并提供多维度解决方案。 目…

GO 进行编译时插桩,实现零码注入

Go 编译时插桩 Go 语言的编译时插桩是一种在编译阶段自动注入监控代码的技术,目的是在不修改业务代码的情况下,实现对应用程序的监控和追踪。 基本原理 Go 编译时插桩的核心思想是通过在编译过程中对源代码进行分析和修改,将监控代码注入到…

vue3中ref和reactive响应式数据、ref模板引用(组合式和选项式区别)、组件ref的使用

目录 Ⅰ.ref 1.基本用法:ref响应式数据 2.ref模板引用 3.ref在v-for中的模板引用 ​4.ref在组件上使用 ​5.TS中ref数据标注类型 Ⅱ.reactive 1.基本用法:reactive响应式数据 2.TS中reactive标注类型 Ⅲ.ref和reactive的使用场景和区别 Ⅳ.小结…

计算机毕业设计SpringBoot+Vue.js视频网站系统(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

LVS+Keepalived 高可用集群搭建

一、高可用集群: 1.什么是高可用集群: 高可用集群(High Availability Cluster)是以减少服务中断时间为目地的服务器集群技术它通过保护用户的业务程序对外不间断提供的服务,把因软件、硬件、人为造成的故障对业务的影响…

macos下myslq图形化工具之Sequel Ace

什么是Sequel Ace 官方github:https://github.com/Sequel-Ace/Sequel-Ace Sequel Ace 是一款快速、易于使用的 Mac 数据库管理应用程序,用于处理 MySQL 和 MariaDB 数据库。 Sequel Ace 是一款开源项目,采用 MIT 许可证。用户可以通过 Ope…

lvgl运行机制分析

lv_timer_handler() 是 LVGL 的“心脏”:这个函数会依次做以下事情: 处理定时器(如动画、延迟回调)。 读取输入设备(如触摸屏、按键的状态)。 刷新脏区域(仅重绘屏幕上发生变化的区域&#xf…

C++ | 高级教程 | 文件和流

👻 概念 文件流输出使用标准库 fstream,定义三个新的数据类型: 数据类型描述ofstream输出文件流,用于创建文件并向文件写入信息。ifstream输入文件流,用于从文件读取信息。fstream文件流,且同时具有 ofst…

Linux:Shell环境变量与命令行参数

目录 Shell的变量功能 什么是变量 变数的可变性与方便性 影响bash环境操作的变量 脚本程序设计(shell script)的好帮手 变量的使用:echo 变量的使用:HOME 环境变量相关命令 获取环境变量 环境变量和本地变量 命令行…

Halcon 学习之路 set_grayval 算子

gen_imag_const 创建灰度图像 gen_image_const(Image,Type,Width,Height) 算子gen_image_const创建指定大小的图像,图像的宽度和高度由Width和Height决定 Type 像素类型 byte :每像素1字节,无符号(0-255&…

基于springboot学生管理系统

目录 项目介绍 图片展示 运行环境 项目介绍 管理员 学生信息管理:查询、添加、删除、修改学生信息 班级信息管理:查询、添加、删除、修改班级信息 教师信息管理:查询、添加、删除、修改教师信息 课程信息管理&…

wav格式的音频压缩,WAV 转 MP3 VBR 体积缩减比为 13.5%、多个 MP3 格式音频合并为一个、文件夹存在则删除重建,不存在则直接建立

🥇 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 🎉 声明: 作为全网 AI 领域 干货最多的博主之一,❤️ 不负光阴不负卿 ❤️ 文章目录 问题一:wav格式的音频压缩为哪些格式,网络传输给用户播放…

JavaWeb-Servlet对象生命周期

文章目录 关于Servlet对象的生命周期创建和销毁Servlet对象的流程测试先后顺序在服务器启动时就创建实例tip: init和无参构造的作用差不多, 为什么定义的规范是init() 关于Servlet对象的生命周期 我们都知道, 我们开发一个Servlet程序的时候, 每一个类都要实现Servlet接口, 然…

在docker容器中运行Ollama部署deepseek-r1大模型

# 启动ollama容器 docker run -itd --gpusall -v /app/ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama:0.5.12# 进入容器 docker exec -it ollama bash ## 拉取大模型(7B为例) ollama pull deepseek-r1:7b## 修改监听地址和端口 expo…

git - study

文章目录 git - study概述可以用 git gui工具来添加快捷命令工具如果要在提交日志中搜索,可以用gitk的view编辑功能实验环境直接用git自带环境进行git操作的好处查看git所有配置配置全局数据配置项目专用的数据查询配置数据的原始值配置git使用的文本编辑器获取某个…

光谱相机的市场发展趋势

市场规模增长 整体市场稳步扩张:据贝哲斯咨询预测,高光谱相机市场在未来几年将保持稳步增长,2022 年市场规模约为 20 亿美元,预计到 2027 年将达到 30 亿美元,年均复合增长率约为 8%,到 2030 年市场规模将…

编写一个程序,输入两个数字并输出它们的和(Python版)

编写一个程序,输入两个数字并输出它们的和 以下是一个简单的 Python 程序,它会从用户输入中读取两个数字,并输出它们的和: # 获取用户输入的两个数字 num1 float(input("请输入第一个数字: ")) num2 float(input(&qu…

STM32——HAL库开发笔记21(定时器2—输出比较)(参考来源:b站铁头山羊)

本文主要讲述输出比较及PWM信号相关知识。 一、概念 所谓输出比较,就是通过单片机的定时器向外输出精确定时的方波信号。 1.1 PWM信号 PWM信号即脉冲宽度调制信号。PWM信号的占空比 (高电压 所占周期 / 整个周期) * 100% 。所以PWM信号…

1.2 Kaggle大白话:Eedi竞赛Transformer框架解决方案02-GPT_4o生成训练集缺失数据

目录 0. 本栏目竞赛汇总表1. 本文主旨2. AI工程架构3. 数据预处理模块3.1 配置数据路径和处理参数3.2 配置API参数3.3 配置输出路径 4. AI并行处理模块4.1 定义LLM客户端类4.2 定义数据处理函数4.3 定义JSON保存函数4.4 定义数据分片函数4.5 定义分片处理函数4.5 定义文件名排序…