数据挖掘案列分析---LightGBM实战贷款违约预测

在今天的机器学习时代,各种算法和工具层出不穷,其中LightGBM凭借其出色的性能和速度,在众多机器学习算法中脱颖而出。本次实战项目,将通过一个简单但不简约的案例,展示如何使用LightGBM进行建模,并通过网格搜索进行模型优化。整个流程将包含数据探索性分析(EDA)、建模和模型优化三个主要部分。

一、数据探索性分析(EDA)

首先,我们需要对数据进行探索性分析,以了解数据的分布、特征之间的相关性以及目标变量的趋势。这一步骤对于后续的建模至关重要,因为只有深入了解数据,我们才能选择合适的特征和算法进行建模。

  • 数据加载与预处理

    使用Python的pandas库加载数据,并进行必要的预处理,如缺失值填充、异常值处理等。

  • 数据描述性分析

    通过绘制直方图、箱线图等可视化图表,我们可以直观地了解每个特征的分布情况。同时,计算特征的均值、中位数、标准差等统计量,有助于我们进一步了解数据的整体情况。

  • 特征相关性分析

    利用热力图或相关矩阵,我们可以分析特征之间的相关性。这对于后续的特征选择和模型构建具有重要的指导意义。

二、基于LightGBM的建模

在完成数据探索性分析后,我们将使用LightGBM进行建模。LightGBM是一种基于决策树算法的梯度提升框架,具有高效、快速、准确等优点。

  • 数据划分

    将数据集划分为训练集和测试集,以便在训练模型时评估其性能。

  • 模型训练

    使用LightGBM的API进行模型训练。我们可以调整LightGBM的参数,如学习率、树的数量、叶子节点的最小样本数等,以寻找最佳模型。

  • 模型评估

    通过计算准确率、召回率、F1值等指标,评估模型在测试集上的性能。同时,绘制ROC曲线和AUC值,进一步了解模型的分类性能。

三、基于网格搜索的模型优化

虽然LightGBM具有许多优秀的默认参数,但针对不同的问题和数据集,我们仍然需要调整参数以获得更好的性能。网格搜索是一种常用的参数优化方法,它通过遍历所有可能的参数组合来找到最优参数。

  • 参数空间定义

    根据LightGBM的文档和经验,我们定义一个包含多个参数的参数空间。这些参数可能包括学习率、树的数量、最大深度、叶子节点的最小样本数等。

  • 网格搜索执行

    使用scikit-learn的GridSearchCV函数进行网格搜索。该函数将自动遍历参数空间中的所有组合,并使用交叉验证评估每个组合的性能。最终,它将返回具有最佳性能的参数组合。

  • 最优模型构建与评估

    使用网格搜索找到的最优参数组合构建新的LightGBM模型,并在测试集上进行评估。与之前的模型相比,优化后的模型应该具有更好的性能。

四、基于LIghtGBM的贷款违约预测

实战项目使用的数据集,具体的实现代码如下:

4.1、导入相应的python库
python 复制代码
import pandas as pd 
import numpy as np 
pd.set_option('display.max_columns', 100)
from IPython.display import display_html

import plotly_express as px 
import plotly.graph_objects as go 

import matplotlib
import matplotlib.pyplot as plt 
plt.rcParams["font.sans-serif"] = ["SimHei"]    #设置字体
plt.rcParams["axes.unicode_minus"] = False      #解决"-"负号乱码问题
import seaborn as sns 
%matplotlib inline

import missingno as ms 
import gc 

from datetime import datetime
from sklearn.model_selection import train_test_split, StartifiedKFold, Gr 
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.decomposition import PCA
from imblearn.under_sampling import ClusterCentroids
from imblearn.over_sampling import KMeansSMOTE, SMOTE 
from sklearn.model_selection import KFold 

from sklearn.metrics import accuracy_score, recall_score, precision_sco
from sklearn.metrics import roc_auc_score, precision_recall_curve, confu

# Classifiers
from sklearn.linear_model import LogisticRegression 
from sklearn.svm import SVC 
from sklearn import tree
from pydotplus import graph_from_dot_data
from sklearn.tree import DecisionTreeClassifier 
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier 
from catboost import CatBoostClassifier 
import lightgbm as lgb 
import xgboost as xgb 

from scipy import stats

import warnings
warnings.filterwarnings("ignore")
4.2 导入数据查看数据情况
python 复制代码
df = pd.read_csv("random_data.csv")
df.columns 
# 缺省值情况
df.isnull().sum()
df["History_Default_Times"].value_counts()  # 历史违约次数统计:

df["Sex"].value_counts()                    # 男女人数几乎相同,很均衡。  

df["Default"].value_counts()                # 目标变量是否违约的人数对比

df[df["History_Default_Times"] == 2]        # 需要注意的是:历史违约次数大于0,不代表一定是违约客户。比如历史违约次数为2,最终是否违约的客户两种情况都有。
4.3 数据简单的可视化
python 复制代码
# 是否违约的客户收入存在差异:
fig = px.violin(df, x="Default",y="Income")
fig.show()
# 基于seaborn绘制密度图:

sns.displot(data=df,x="Income",hue="Default",kind="kde")
plt.show()                                  # 可以看到在低收入和高收入人群中容易发生违约。


fig = px.violin(df, x="Default",y="Age")
fig.show()
sns.displot(data=df,x="Age",hue="Default",kind="kde")
plt.show()                                  # 可以看到是是否违约客户的年龄段分布是一致的。
4.4 数据集合切分
python 复制代码
#  提取特征和目标变量
X = df.drop(columns="Default")
Y = df["Default"]

# 划分训练集和测试集数据
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
4.5 模型训练
python 复制代码
from lightgbm import LGBMClassifier

model = LGBMClassifier()
model.fit(X_train, y_train)  # 模型训练 
4.6 模型预测
python 复制代码
y_pred = model.predict(X_test)
y_pred
4.7 模型评估
python 复制代码
### 1、对比测试集中的实际值和预测值:
predict_true = pd.DataFrame()

predict_true["预测值"] = list(y_pred)
predict_true["实际值"] = list(y_test)
predict_true

# 模型在测试集上的准确率

from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_pred, y_test)
accuracy

# ROC-AUC曲线的绘制:
y_pred_proba = model.predict_proba(X_test)
y_pred_proba[:5]

from sklearn.metrics import roc_curve  # ROC-AUC曲线
fpr, tpr, thres = roc_curve(y_test, y_pred_proba[:,1])
plt.plot(fpr, tpr)
plt.title("ROC_AUC Curve of Default")
plt.show()

# 3、查看具体的AUC值:
from sklearn.metrics import roc_auc_score
score = roc_auc_score(y_test, y_pred_proba[:,1])

score
4.8 特征重要度
python 复制代码
model.feature_importances_
model.feature_name_

features_df = pd.DataFrame({"features": model.feature_name_,"importances": model.feature_importances_})
features_df
4.9 模型调优
python 复制代码
# 基于网格搜索的模型调优:
from sklearn.model_selection import GridSearchCV

# 设定待搜索的参数及其取值范围:
parameters = {"num_leaves": [10, 15, 13],
              "n_estimators":[10,20,30],
              "learning_rate":[0.05,0.1,0.2]
             }

model = LGBMClassifier()  #  基础模型实例化

# 定义搜索实例化对象
grid_search = GridSearchCV(model, # 基础模型
                           parameters,  # 搜索参数
                           scoring="roc_auc", # 评价指标
                           cv=5  # 交叉验证5次
                          )

grid_search.fit(X_train, y_train)  # 模型训练
4.10 K折交叉验证
python 复制代码
import os
import gc
import math

import pandas as pd
import numpy as np

import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from sklearn.linear_model import SGDRegressor, LinearRegression, Ridge
from sklearn.preprocessing import MinMaxScaler


from sklearn.model_selection import StratifiedKFold, KFold
from sklearn.metrics import log_loss
from sklearn.model_selection import train_test_split

from tqdm import tqdm
import matplotlib.pyplot as plt
import time
import warnings
warnings.filterwarnings('ignore')


def cv_model(clf, train_x, train_y, test_x, seed=2024):
    # 使用K折交叉验证训练和验证模型
    folds = 5
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
    
    # 初始化oof预测和测试集预测
    oof = np.zeros(train_x.shape[0])
    test_predict = np.zeros(test_x.shape[0])
    cv_scores = []
    
    # KFold交叉验证
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
        
        # 转换数据为lightgbm数据格式
        train_matrix = clf.Dataset(trn_x, label=trn_y)
        valid_matrix = clf.Dataset(val_x, label=val_y)
        
        # 定义lightgbm参数
        params = {
                'boosting_type': 'gbdt', # GBDT算法为基础
                'objective': 'multiclass', # 多分类任务
                'num_class': 4,          # 设置多分类问题的类别个数
                'num_leaves': 2 ** 5,    # 指定叶子的个数,默认值为31,大会更准,但可能过拟合。最大不能超过2^max_depth
                # 构建弱学习器,对特征随机采样的比例,默认值为1,可以防止过拟合,每次迭代中随机选择80%的参数来建树
                'feature_fraction': 0.8,   
                'bagging_fraction': 0.8, # 每次迭代时用的数据比例,用于加快训练速度和减小过拟合
                'bagging_freq': 4,   # 表示bagging(采样)的频率,0意味着没有使用bagging ,k意味着每k轮迭代进行一次bagging
                'learning_rate': 0.025,
                'seed': seed,
                # 使用线程数,一般设置成-1,使用所有线程。这个参数用来控制最大并行的线程数,如果你希望取得所有CPU的核,那么你就不用管它。
                'nthread': 28,  
                'n_jobs':24, # 使用多少个线性并构造模型
                'verbose': -1,
                'lambda_l1': 0.4,   # L1正则化权重项,增加此值将使模型更加保守。
                'lambda_l2': 0.5,   # L2正则化权重项,增加此值将使模型更加保守
                # 'device' : 'gpu'
            }

        # 使用训练集数据进行模型训练
        model = clf.train(params, 
                train_set=train_matrix, 
                valid_sets=valid_matrix, 
                num_boost_round=2000, 
                verbose_eval=100, 
                early_stopping_rounds=200)
        
        # 对验证集进行预测
        val_pred = model.predict(val_x, num_iteration=model.best_iteration)
        test_pred = model.predict(test_x, num_iteration=model.best_iteration) 
        
        oof[valid_index] = val_pred
        test_predict += test_pred / kf.n_splits
        
        # 计算打印当前折的分数
        score = np.sqrt(mean_squared_erroe(vale_pred, val_y))
        cv_scores.apped(score)
        print(cv_scores)
        
    return oof, test_predict
4.11 输出最优的参数,并在最优的参数上进行lightgbm模型的训练
python 复制代码
# 输出最佳的参数组合:
dict_params = grid_search.best_params_  

dict_params

# 基于最佳的参数组合建立新模型:
new_model = LGBMClassifier(num_leaves=10, # 使用最佳参数
                           n_estimators=30,
                           learning_rate=0.05
                          )
相关推荐
余炜yw10 分钟前
【LSTM实战】跨越千年,赋诗成文:用LSTM重现唐诗的韵律与情感
人工智能·rnn·深度学习
莫叫石榴姐26 分钟前
数据科学与SQL:组距分组分析 | 区间分布问题
大数据·人工智能·sql·深度学习·算法·机器学习·数据挖掘
如若1231 小时前
利用 `OpenCV` 和 `Matplotlib` 库进行图像读取、颜色空间转换、掩膜创建、颜色替换
人工智能·opencv·matplotlib
YRr YRr1 小时前
深度学习:神经网络中的损失函数的使用
人工智能·深度学习·神经网络
ChaseDreamRunner1 小时前
迁移学习理论与应用
人工智能·机器学习·迁移学习
Guofu_Liao1 小时前
大语言模型---梯度的简单介绍;梯度的定义;梯度计算的方法
人工智能·语言模型·矩阵·llama
我爱学Python!1 小时前
大语言模型与图结构的融合: 推荐系统中的新兴范式
人工智能·语言模型·自然语言处理·langchain·llm·大语言模型·推荐系统
果冻人工智能1 小时前
OpenAI 是怎么“压力测试”大型语言模型的?
人工智能·语言模型·压力测试
日出等日落1 小时前
Windows电脑本地部署llamafile并接入Qwen大语言模型远程AI对话实战
人工智能·语言模型·自然语言处理
麦麦大数据2 小时前
Python棉花病虫害图谱系统CNN识别+AI问答知识neo4j vue+flask深度学习神经网络可视化
人工智能·python·深度学习