大数据分析案例-基于随机森林算法构建银行贷款审批预测模型

news2024/11/29 1:31:47

🤵‍♂️ 个人主页:@艾派森的个人主页

✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+


喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章

大数据分析案例合集
大数据分析案例-基于随机森林算法预测人类预期寿命
大数据分析案例-基于随机森林算法的商品评价情感分析
大数据分析案例-用RFM模型对客户价值分析(聚类)
大数据分析案例-对电信客户流失分析预警预测
大数据分析案例-基于随机森林模型对北京房价进行预测
大数据分析案例-基于RFM模型对电商客户价值分析
大数据分析案例-基于逻辑回归算法构建垃圾邮件分类器模型
大数据分析案例-基于决策树算法构建员工离职预测模型

大数据分析案例-基于KNN算法对茅台股票进行预测

大数据分析案例-基于多元线性回归算法构建广告投放收益模型
大数据分析案例-基于随机森林算法构建返乡人群预测模型
大数据分析案例-基于决策树算法构建金融反欺诈分类模型

目录

1.项目背景

2.项目简介

2.1项目说明

2.2数据说明

2.3技术工具

3.算法原理

4.项目实施步骤

4.1理解数据

4.2数据预处理

4.3探索性数据分析

4.4特征工程

4.5模型构建

4.6模型评估

5.实验总结

源代码


1.项目背景

        随着金融科技的发展和数字化浪潮的推进,银行和其他金融机构越来越依赖数据分析来做出决策,特别是在贷款审批领域。传统的贷款审批过程往往依赖于人工审核和有限的信用评分系统,这种方法不仅效率低下,而且可能受到主观偏见和人为错误的影响。因此,开发一种能够自动、准确并高效地评估贷款申请人信用风险的模型变得至关重要。

        近年来,机器学习算法,特别是随机森林算法,在信用风险评估领域的应用逐渐受到关注。随机森林算法是一种集成学习方法,它通过构建多个决策树并结合它们的输出来提高预测精度和稳定性。该算法能够处理大量高维数据,自动捕捉数据中的非线性关系,并且对噪声和异常值具有较强的鲁棒性。       

        本研究不仅有助于推动银行贷款审批流程的数字化转型,还可为其他金融领域的风险管理提供有益的参考和借鉴。随着数据科学和人工智能技术的不断发展,未来贷款审批预测模型将更加精准、高效,为金融业的稳定发展提供有力支持。

2.项目简介

2.1项目说明

        本项目旨在利用借款人的历史信用记录、财务状况、个人背景等多维度信息,通过机器学习和数据分析技术,构建一个自动化的贷款审批流程。该模型能够快速、准确地评估申请人的信用风险,帮助银行做出更加明智的贷款决策,减少坏账风险,提高贷款业务的盈利能力。

        此外,该模型还有助于银行实现客户细分和个性化服务。通过对不同申请人群体进行特征分析和风险预测,银行可以更加精准地满足不同客户群体的需求,优化贷款产品设计和定价策略,提升客户满意度和忠诚度。因此,基于随机森林算法的银行贷款审批模型不仅具有重要的理论价值,还具有广阔的应用前景和巨大的市场潜力。

2.2数据说明

        本数据集来源于Kaggle,在这个贷款状态预测数据集中,我们有以前根据property Loan的属性申请贷款的申请人的数据。银行将根据申请人的收入、贷款金额、以前的信用记录、共同申请人的收入等因素来决定是否向申请人提供贷款。我们的目标是建立一个机器学习模型来预测申请人的贷款被批准或被拒绝。原始数据集共有381条,13个变量。各变量含义如下:

Loan_ID:唯一的贷款ID。

Gender:男性或女性。

Married:天气结婚(是)或不结婚(否)。

Dependents:依赖于客户端的人数。

Education   :申请人学历(研究生或本科)。

Self_Employed:自雇(是/否)。

ApplicantIncome:申请人收入。

CoapplicantIncome:共同申请人收入。

LoanAmount:以千为单位的贷款金额。

Loan_Amount_Term:以月为单位的贷款期限。

Credit_History:信用记录符合指导原则。

Property_Area:申请人居住在城市、半城市或农村。

Loan_Status:贷款批准(Y/N)。

2.3技术工具

Python版本:3.9

代码编辑器:jupyter notebook

3.算法原理

        随机森林是一种有监督学习算法。就像它的名字一样,它创建了一个森林,并使它拥有某种方式随机性。所构建的“森林”是决策树的集成,大部分时候都是用“bagging”方法训练的。bagging 方法,即 bootstrapaggregating,采用的是随机有放回的选择训练数据然后构造分类器,最后组合学习到的模型来增加整体的效果。简而言之,随机森林建立了多个决策树,并将它们合并在一起以获得更准确和稳定的预测。其一大优势在于它既可用于分类,也可用于回归问题,这两类问题恰好构成了当前的大多数机器学习系统所需要面对的。

        随机森林分类器使用所有的决策树分类器以及 bagging 分类器的超参数来控制整体结构。与其先构建 bagging分类器,并将其传递给决策树分类器,我们可以直接使用随机森林分类器类,这样对于决策树而言,更加方便和优化。要注意的是,回归问题同样有一个随机森林回归器与之相对应。

        随机森林算法中树的增长会给模型带来额外的随机性。与决策树不同的是,每个节点被分割成最小化误差的最佳指标,在随机森林中我们选择随机选择的指标来构建最佳分割。因此,在随机森林中,仅考虑用于分割节点的随机子集,甚至可以通过在每个指标上使用随机阈值来使树更加随机,而不是如正常的决策树一样搜索最佳阈值。这个过程产生了广泛的多样性,通常可以得到更好的模型。

4.项目实施步骤

4.1理解数据

导入本次实验的第三方库

import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt
import seaborn as sns 
import warnings
from sklearn.metrics import accuracy_score, confusion_matrix, roc_curve, auc
from sklearn.preprocessing import MinMaxScaler
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.linear_model import LogisticRegression
import xgboost as xgb
from xgboost import XGBClassifier
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
import plotly.express as px
warnings.simplefilter(action='ignore', category=FutureWarning)

接着加载数据集

data = pd.read_csv("loan_data.csv")
data.head()

查看数据大小 

查看数据基本信息

查看数值型变量的描述性统计

查看非数值型变量的描述性统计

4.2数据预处理

查看缺失值情况

发现数据存在缺失值,需要进行处理

处理缺失值

# 处理分类列中缺失的值
for col in categorical_columns:
    data[col].fillna(data[col].mode()[0], inplace=True)

# 处理数值列中的缺失值
data['Loan_Amount_Term'].fillna(data['Loan_Amount_Term'].median(), inplace=True)
data['Credit_History'].fillna(data['Credit_History'].mode()[0], inplace=True)
data.isnull().sum() 

编码处理

# 编码处理
data['Dependents'] = data['Dependents'].replace(['0', '1', '2', '3+'], [0,1,2,3])
data['Credit_History'] = data['Credit_History'].astype(int)
label_encoder_columns = ['Gender', 'Married', 'Education', 'Self_Employed','Property_Area', 'Loan_Status']

label_encoder = LabelEncoder()
for col in label_encoder_columns:
    data[col] = label_encoder.fit_transform(data[col])

data.head()

4.3探索性数据分析

相关系数热力图

plt.figure(figsize=(10,8))
corr_df = data.corr()
sns.heatmap(corr_df,annot=True)
plt.show()

自定义两个绘图函数

# 自定义绘图函数
def violin(col):
    fig = px.violin(data, y=col, x="Loan_Status", color="Loan_Status", box=True)
    return fig.show()

def kde_plot(feature):
    grid = sns.FacetGrid(data, hue="Loan_Status",aspect=2)
    grid.map(sns.kdeplot, feature)
    grid.add_legend()
violin('LoanAmount')

kde_plot('LoanAmount')

categorical_columns = ['Gender', 'Married', 'Education','Self_Employed', 'Loan_Status']

fig, ax = plt.subplots(3, 2, figsize=(12, 15))
for index, cat_col in enumerate(categorical_columns):
    row, col = index // 2, index % 2
    sns.countplot(x=cat_col, data=data, hue='Loan_Status', ax=ax[row, col], palette='Set2')
    ax[row, col].set_title(f'Distribution of Loan Approval by {cat_col}', fontsize=14)

    for p in ax[row, col].patches:
        ax[row, col].annotate(f'{p.get_height()}', (p.get_x() + p.get_width() / 2., p.get_height()),
                              ha='center', va='center', xytext=(0, 10), textcoords='offset points', fontsize=10)

plt.subplots_adjust(hspace=0.5, wspace=0.3)
plt.suptitle('Loan Approval Distribution Across Categorical Variables', fontsize=16, y=1.02)
plt.show()

numerical_columns = ['ApplicantIncome', 'CoapplicantIncome', 'LoanAmount', 'Loan_Amount_Term']

fig, axes = plt.subplots(1, 4, figsize=(25, 7))

for idx, num_col in enumerate(numerical_columns):
    sns.boxplot(x='Loan_Status', y=num_col, data=data, ax=axes[idx], palette='Set2')
    axes[idx].set_title(f'Distribution of {num_col} by Loan Approval', fontsize=14)
    axes[idx].set_ylabel(num_col, fontsize=12)

plt.suptitle('Distribution of Numerical Variables by Loan Approval', fontsize=16, y=1.02)
plt.subplots_adjust(wspace=0.4)
print(data[numerical_columns].describe())
plt.show()

4.4特征工程

准备建模数据

# 准备建模数据
ind_col = [col for col in data.columns if col != 'Loan_Status']
dep_col = 'Loan_Status'
X = data[ind_col]
y = data[dep_col]

特征筛选 

# 应用SelectKBest类提取前8个最佳特征
bestfeatures = SelectKBest(score_func=chi2, k=8)
fit = bestfeatures.fit(X, y)
# 创建一个DataFrame来显示所选的特性及其分数
featureScores = pd.DataFrame({'Specs': X.columns, 'Score': fit.scores_})
# 打印10个最佳特征
print(featureScores.nlargest(10, 'Score'))

# 拟合ExtraTreesClassifier模型
model = ExtraTreesClassifier()
model.fit(X, y)

# 特征重要性
feat_importances = pd.Series(model.feature_importances_, index=X.columns)
feat_importances.nlargest(8).plot(kind='barh')
plt.show()

# 特征挑选
selected_features = feat_importances.nlargest(8).index
X_new = data.loc[:, selected_features].copy()
X_new.head()

数据标准化

# 数据标准化
scaler = MinMaxScaler()
for column in numerical_columns:
    X_new[column] = scaler.fit_transform(X_new[[column]])
X_new.head()

拆分数据集

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_new,y,train_size=0.8,random_state=0)
print(X_train.shape)
print(X_test.shape)

4.5模型构建

确定各模型最优参数

## 关于XGBoost的超参数优化

XGBoost_params={
 "learning_rate"    : [0.05, 0.20, 0.25 ] ,
 "max_depth"        : [ 5, 8, 10, 12],
 "min_child_weight" : [ 1, 3, 5, 7 ],
 "gamma"            : [ 0.0, 0.1, 0.2 , 0.4 ],
 "colsample_bytree" : [ 0.3, 0.4, 0.7 ]
    
}

## 关于随机森林的超参数优化
RF_params = {
    'n_estimators': [50, 100, 200, 300],  # Number of trees in the forest
    'max_depth': [None, 10, 20, 30],  # Maximum depth of the tree
    'min_samples_split': [2, 5, 10],  # Minimum number of samples required to split an internal node
    'min_samples_leaf': [1, 2, 4],  # Minimum number of samples required to be at a leaf node
    'max_features': ['sqrt', 'log2', None],  # Number of features to consider at every split
    'bootstrap': [True, False]  # Method of selecting samples for training each tree
}

## 关于决策树的超参数优化
DT_params = {
    'criterion': ['gini', 'entropy','log_loss'],  # Measure of impurity
    'splitter': ['best', 'random'],  # Strategy to choose the split at each node
    'max_depth': [None, 10, 20, 30],  # Maximum depth of the tree
    'min_samples_split': [2, 5, 10],  # Minimum number of samples required to split an internal node
    'min_samples_leaf': [1, 2, 4],  # Minimum number of samples required to be at a leaf node
    'max_features': [None, 'sqrt', 'log2'],  # Number of features to consider at every split
}

初始化模型

# XGBoost 
xgboost = XGBClassifier()
# Random Forest
random_forest = RandomForestClassifier()
# Decision Tree
decision_tree = DecisionTreeClassifier()

XGBoost模型的随机搜索

# RandomizedSearchCV for XGBoost
XGBoost_random_search = RandomizedSearchCV(xgboost,param_distributions=XGBoost_params,n_iter=5,scoring='roc_auc',n_jobs=-1,cv=5,verbose=3)
XGBoost_random_search.fit(X_train, y_train)

随机森林模型的随机搜索

# RandomizedSearchCV for Random Forest
RF_random_search = RandomizedSearchCV(random_forest, param_distributions=RF_params, n_iter=5, scoring='roc_auc', n_jobs=-1, cv=5, verbose=3)
RF_random_search.fit(X_train, y_train)

决策树模型的随机搜索

# RandomizedSearchCV for Decision Tree
DT_random_search = RandomizedSearchCV(decision_tree, param_distributions=DT_params, n_iter=5, scoring='roc_auc', n_jobs=-1, cv=5, verbose=3)
DT_random_search.fit(X_train, y_train)

打印模型的最佳参数

# 打印每个模型的最佳参数
print("Best Parameters for XGBoost:")
print(XGBoost_random_search.best_params_)

print("\nBest Parameters for Random Forest:")
print(RF_random_search.best_params_)

print("\nBest Parameters for Decision Tree:")
print(DT_random_search.best_params_)

定义模型 

# Define final XGBoost Classifier 
xgboost_classifier = XGBClassifier(min_child_weight = 1, max_depth = 5, learning_rate = 0.2, gamma = 0.2, colsample_bytree  = 0.7)

# Define final Random Forest Classifier
rf_classifier = RandomForestClassifier(n_estimators = 50, min_samples_split = 10, min_samples_leaf = 4, max_features = 'sqrt', max_depth = 30, bootstrap = True)

# Define final Decision Tree Classifier
dt_classifier = DecisionTreeClassifier(splitter =  'best', min_samples_split = 10, min_samples_leaf = 4, max_features = None, max_depth = 10, criterion = 'log_loss')

# Define Logistic Regression Classifier
lr_classifier = LogisticRegression()

训练模型

# Train XGBoost Classifier
xgboost_classifier.fit(X_train, y_train)

# Train Random Forest Classifier
rf_classifier.fit(X_train, y_train)

# Train Decision Tree Classifier
dt_classifier.fit(X_train, y_train)

# Train Logistic Regression Classifier 
lr_classifier.fit(X_train, y_train)

4.6模型评估

打印模型混淆矩阵

xgboost_pred = xgboost_classifier.predict(X_test)
rf_pred = rf_classifier.predict(X_test)
dt_pred = dt_classifier.predict(X_test) 
lr_pred = lr_classifier.predict(X_test)
# Confusion Matrix for XGBoost
confusion_xgboost = confusion_matrix(y_test, xgboost_pred)
print('Confusion Matrix for XGBoost:')
print(confusion_xgboost)

# Confusion Matrix for Random Forest
confusion_rf = confusion_matrix(y_test, rf_pred)
print('\nConfusion Matrix for Random Forest:')
print(confusion_rf)

# Confusion Matrix for Decision Tree
confusion_dt = confusion_matrix(y_test, dt_pred)
print('\nConfusion Matrix for Decision Tree:')
print(confusion_dt)

# Confusion Matrix for Logistic Regression
confusion_lr = confusion_matrix(y_test, lr_pred)
print('\nConfusion Matrix for Logistic Regression:')
print(confusion_lr)

打印模型准确率

# Accuracy of XGBoost 
xgboost_accuracy = accuracy_score(y_test, xgboost_pred)
print("Accuracy of XGBoost:")
print(xgboost_accuracy)

# Accuracy of Random Forest
RF_accuracy = accuracy_score(y_test, rf_pred)
print("Accuracy of Random Forest:")
print(RF_accuracy)

# Accuracy of Decision Tree
DT_accuracy = accuracy_score(y_test, dt_pred)
print("Accuracy of Decision Tree:")
print(DT_accuracy)

# Accuracy of Logistic Regression
LR_accuracy = accuracy_score(y_test, lr_pred)
print("Accuracy of Logistic Regression:")
print(LR_accuracy)

ROC曲线 

# XGBoost
y_prob_xgb = xgboost_classifier.predict_proba(X_test)[:, 1]
fpr_xgb, tpr_xgb, thresholds_xgb = roc_curve(y_test, y_prob_xgb)
roc_auc_xgb = auc(fpr_xgb, tpr_xgb)

# RandomForestClassifier
y_prob_rf = rf_classifier.predict_proba(X_test)[:, 1]
fpr_rf, tpr_rf, thresholds_rf = roc_curve(y_test, y_prob_rf)
roc_auc_rf = auc(fpr_rf, tpr_rf)

# Decision Tree Classifier
y_prob_dt = dt_classifier.predict_proba(X_test)[:, 1]
fpr_dt, tpr_dt, thresholds_dt = roc_curve(y_test, y_prob_dt)
roc_auc_dt = auc(fpr_dt, tpr_dt)

# Logistic Regression
y_prob_lr = lr_classifier.predict_proba(X_test)[:, 1]
fpr_lr, tpr_lr, thresholds_lr = roc_curve(y_test, y_prob_lr)
roc_auc_lr = auc(fpr_lr, tpr_lr)

# Create a subplot with 2 rows and 2 columns
plt.figure(figsize=(15, 10))

# Plot for XGBoost
plt.subplot(2, 2, 1)
plt.plot(fpr_xgb, tpr_xgb, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_xgb))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('XGBoost\nAccuracy: {:.2f}%'.format(xgboost_accuracy * 100))
plt.legend(loc="lower right")

# Plot for RandomForestClassifier
plt.subplot(2, 2, 2)
plt.plot(fpr_rf, tpr_rf, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_rf))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Random Forest\nAccuracy: {:.2f}%'.format(RF_accuracy * 100))
plt.legend(loc="lower right")

# Plot for Decision Tree
plt.subplot(2, 2, 3)
plt.plot(fpr_dt, tpr_dt, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_dt))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Decision Tree\nAccuracy: {:.2f}%'.format(DT_accuracy * 100))
plt.legend(loc="lower right")

# Plot for Logistic Regression
plt.subplot(2, 2, 4)
plt.plot(fpr_lr, tpr_lr, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_lr))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Logistic Regression\nAccuracy: {:.2f}%'.format(LR_accuracy * 100))
plt.legend(loc="lower right")

# Adjust layout to prevent overlap
plt.tight_layout()

# Show the plots
plt.show()

5.实验总结

心得与体会:

通过这次Python项目实战,我学到了许多新的知识,这是一个让我把书本上的理论知识运用于实践中的好机会。原先,学的时候感叹学的资料太难懂,此刻想来,有些其实并不难,关键在于理解。

在这次实战中还锻炼了我其他方面的潜力,提高了我的综合素质。首先,它锻炼了我做项目的潜力,提高了独立思考问题、自我动手操作的潜力,在工作的过程中,复习了以前学习过的知识,并掌握了一些应用知识的技巧等

在此次实战中,我还学会了下面几点工作学习心态:

1)继续学习,不断提升理论涵养。在信息时代,学习是不断地汲取新信息,获得事业进步的动力。作为一名青年学子更就应把学习作为持续工作

用心性的重要途径。走上工作岗位后,我会用心响应单位号召,结合工作实际,不断学习理论、业务知识和社会知识,用先进的理论武装头脑,用精良的业务知识提升潜力,以广博的社会知识拓展视野。

2)努力实践,自觉进行主角转化。只有将理论付诸于实践才能实现理论自身的价值,也只有将理论付诸于实践才能使理论得以检验。同样,一个人的价值也是透过实践活动来实现的,也只有透过实践才能锻炼人的品质,彰显人的意志。

3)提高工作用心性和主动性。实习,是开端也是结束。展此刻自我面前的是一片任自我驰骋的沃土,也分明感受到了沉甸甸的职责。在今后的工作和生活中,我将继续学习,深入实践,不断提升自我,努力创造业绩,继续创造更多的价值。

这次Python实战不仅仅使我学到了知识,丰富了经验。也帮忙我缩小了实践和理论的差距。在未来的工作中我会把学到的理论知识和实践经验不断的应用到实际工作中,为实现理想而努力。

源代码

import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt
import seaborn as sns 
import warnings
from sklearn.metrics import accuracy_score, confusion_matrix, roc_curve, auc
from sklearn.preprocessing import MinMaxScaler
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.linear_model import LogisticRegression
import xgboost as xgb
from xgboost import XGBClassifier
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
import plotly.express as px
warnings.simplefilter(action='ignore', category=FutureWarning)
data = pd.read_csv("loan_data.csv")
data.head()
data.shape
data.info()
data.describe()
data.describe(include='O')
data.isnull().sum()
categorical_columns=[col for col in data.columns if data[col].dtype=='O']
categorical_columns
# 处理分类列中缺失的值
for col in categorical_columns:
    data[col].fillna(data[col].mode()[0], inplace=True)

# 处理数值列中的缺失值
data['Loan_Amount_Term'].fillna(data['Loan_Amount_Term'].median(), inplace=True)
data['Credit_History'].fillna(data['Credit_History'].mode()[0], inplace=True)
data.isnull().sum() 
# 删除不相关的列
data.drop('Loan_ID', axis=1, inplace=True)
# 编码处理
data['Dependents'] = data['Dependents'].replace(['0', '1', '2', '3+'], [0,1,2,3])
data['Credit_History'] = data['Credit_History'].astype(int)
label_encoder_columns = ['Gender', 'Married', 'Education', 'Self_Employed','Property_Area', 'Loan_Status']

label_encoder = LabelEncoder()
for col in label_encoder_columns:
    data[col] = label_encoder.fit_transform(data[col])

data.head()
plt.figure(figsize=(10,8))
corr_df = data.corr()
sns.heatmap(corr_df,annot=True)
plt.show()
# 自定义绘图函数
def violin(col):
    fig = px.violin(data, y=col, x="Loan_Status", color="Loan_Status", box=True)
    return fig.show()

def kde_plot(feature):
    grid = sns.FacetGrid(data, hue="Loan_Status",aspect=2)
    grid.map(sns.kdeplot, feature)
    grid.add_legend()
violin('LoanAmount')
kde_plot('LoanAmount')
categorical_columns = ['Gender', 'Married', 'Education','Self_Employed', 'Loan_Status']

fig, ax = plt.subplots(3, 2, figsize=(12, 15))
for index, cat_col in enumerate(categorical_columns):
    row, col = index // 2, index % 2
    sns.countplot(x=cat_col, data=data, hue='Loan_Status', ax=ax[row, col], palette='Set2')
    ax[row, col].set_title(f'Distribution of Loan Approval by {cat_col}', fontsize=14)

    for p in ax[row, col].patches:
        ax[row, col].annotate(f'{p.get_height()}', (p.get_x() + p.get_width() / 2., p.get_height()),
                              ha='center', va='center', xytext=(0, 10), textcoords='offset points', fontsize=10)

plt.subplots_adjust(hspace=0.5, wspace=0.3)
plt.suptitle('Loan Approval Distribution Across Categorical Variables', fontsize=16, y=1.02)
plt.show()
numerical_columns = ['ApplicantIncome', 'CoapplicantIncome', 'LoanAmount', 'Loan_Amount_Term']

fig, axes = plt.subplots(1, 4, figsize=(25, 7))

for idx, num_col in enumerate(numerical_columns):
    sns.boxplot(x='Loan_Status', y=num_col, data=data, ax=axes[idx], palette='Set2')
    axes[idx].set_title(f'Distribution of {num_col} by Loan Approval', fontsize=14)
    axes[idx].set_ylabel(num_col, fontsize=12)

plt.suptitle('Distribution of Numerical Variables by Loan Approval', fontsize=16, y=1.02)
plt.subplots_adjust(wspace=0.4)
print(data[numerical_columns].describe())
plt.show()
# 准备建模数据
ind_col = [col for col in data.columns if col != 'Loan_Status']
dep_col = 'Loan_Status'
X = data[ind_col]
y = data[dep_col]
# 应用SelectKBest类提取前8个最佳特征
bestfeatures = SelectKBest(score_func=chi2, k=8)
fit = bestfeatures.fit(X, y)
# 创建一个DataFrame来显示所选的特性及其分数
featureScores = pd.DataFrame({'Specs': X.columns, 'Score': fit.scores_})
# 打印10个最佳特征
print(featureScores.nlargest(10, 'Score'))
# 拟合ExtraTreesClassifier模型
model = ExtraTreesClassifier()
model.fit(X, y)

# 特征重要性
feat_importances = pd.Series(model.feature_importances_, index=X.columns)
feat_importances.nlargest(8).plot(kind='barh')
plt.show()
# 特征挑选
selected_features = feat_importances.nlargest(8).index
X_new = data.loc[:, selected_features].copy()
X_new.head()
# 数据标准化
scaler = MinMaxScaler()
for column in numerical_columns:
    X_new[column] = scaler.fit_transform(X_new[[column]])
X_new.head()
# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_new,y,train_size=0.8,random_state=0)
print(X_train.shape)
print(X_test.shape)
## 关于XGBoost的超参数优化

XGBoost_params={
 "learning_rate"    : [0.05, 0.20, 0.25 ] ,
 "max_depth"        : [ 5, 8, 10, 12],
 "min_child_weight" : [ 1, 3, 5, 7 ],
 "gamma"            : [ 0.0, 0.1, 0.2 , 0.4 ],
 "colsample_bytree" : [ 0.3, 0.4, 0.7 ]
    
}

## 关于随机森林的超参数优化
RF_params = {
    'n_estimators': [50, 100, 200, 300],  # Number of trees in the forest
    'max_depth': [None, 10, 20, 30],  # Maximum depth of the tree
    'min_samples_split': [2, 5, 10],  # Minimum number of samples required to split an internal node
    'min_samples_leaf': [1, 2, 4],  # Minimum number of samples required to be at a leaf node
    'max_features': ['sqrt', 'log2', None],  # Number of features to consider at every split
    'bootstrap': [True, False]  # Method of selecting samples for training each tree
}

## 关于决策树的超参数优化
DT_params = {
    'criterion': ['gini', 'entropy','log_loss'],  # Measure of impurity
    'splitter': ['best', 'random'],  # Strategy to choose the split at each node
    'max_depth': [None, 10, 20, 30],  # Maximum depth of the tree
    'min_samples_split': [2, 5, 10],  # Minimum number of samples required to split an internal node
    'min_samples_leaf': [1, 2, 4],  # Minimum number of samples required to be at a leaf node
    'max_features': [None, 'sqrt', 'log2'],  # Number of features to consider at every split
}
# XGBoost 
xgboost = XGBClassifier()
# Random Forest
random_forest = RandomForestClassifier()
# Decision Tree
decision_tree = DecisionTreeClassifier()
# RandomizedSearchCV for XGBoost
XGBoost_random_search = RandomizedSearchCV(xgboost,param_distributions=XGBoost_params,n_iter=5,scoring='roc_auc',n_jobs=-1,cv=5,verbose=3)
XGBoost_random_search.fit(X_train, y_train)
# RandomizedSearchCV for Random Forest
RF_random_search = RandomizedSearchCV(random_forest, param_distributions=RF_params, n_iter=5, scoring='roc_auc', n_jobs=-1, cv=5, verbose=3)
RF_random_search.fit(X_train, y_train)
# RandomizedSearchCV for Decision Tree
DT_random_search = RandomizedSearchCV(decision_tree, param_distributions=DT_params, n_iter=5, scoring='roc_auc', n_jobs=-1, cv=5, verbose=3)
DT_random_search.fit(X_train, y_train)
# 打印每个模型的最佳参数
print("Best Parameters for XGBoost:")
print(XGBoost_random_search.best_params_)

print("\nBest Parameters for Random Forest:")
print(RF_random_search.best_params_)

print("\nBest Parameters for Decision Tree:")
print(DT_random_search.best_params_)
# Define final XGBoost Classifier 
xgboost_classifier = XGBClassifier(min_child_weight = 1, max_depth = 5, learning_rate = 0.2, gamma = 0.2, colsample_bytree  = 0.7)

# Define final Random Forest Classifier
rf_classifier = RandomForestClassifier(n_estimators = 50, min_samples_split = 10, min_samples_leaf = 4, max_features = 'sqrt', max_depth = 30, bootstrap = True)

# Define final Decision Tree Classifier
dt_classifier = DecisionTreeClassifier(splitter =  'best', min_samples_split = 10, min_samples_leaf = 4, max_features = None, max_depth = 10, criterion = 'log_loss')

# Define Logistic Regression Classifier
lr_classifier = LogisticRegression()
# Train XGBoost Classifier
xgboost_classifier.fit(X_train, y_train)

# Train Random Forest Classifier
rf_classifier.fit(X_train, y_train)

# Train Decision Tree Classifier
dt_classifier.fit(X_train, y_train)

# Train Logistic Regression Classifier 
lr_classifier.fit(X_train, y_train)
xgboost_pred = xgboost_classifier.predict(X_test)
rf_pred = rf_classifier.predict(X_test)
dt_pred = dt_classifier.predict(X_test) 
lr_pred = lr_classifier.predict(X_test)
# Confusion Matrix for XGBoost
confusion_xgboost = confusion_matrix(y_test, xgboost_pred)
print('Confusion Matrix for XGBoost:')
print(confusion_xgboost)

# Confusion Matrix for Random Forest
confusion_rf = confusion_matrix(y_test, rf_pred)
print('\nConfusion Matrix for Random Forest:')
print(confusion_rf)

# Confusion Matrix for Decision Tree
confusion_dt = confusion_matrix(y_test, dt_pred)
print('\nConfusion Matrix for Decision Tree:')
print(confusion_dt)

# Confusion Matrix for Logistic Regression
confusion_lr = confusion_matrix(y_test, lr_pred)
print('\nConfusion Matrix for Logistic Regression:')
print(confusion_lr)
# Accuracy of XGBoost 
xgboost_accuracy = accuracy_score(y_test, xgboost_pred)
print("Accuracy of XGBoost:")
print(xgboost_accuracy)

# Accuracy of Random Forest
RF_accuracy = accuracy_score(y_test, rf_pred)
print("Accuracy of Random Forest:")
print(RF_accuracy)

# Accuracy of Decision Tree
DT_accuracy = accuracy_score(y_test, dt_pred)
print("Accuracy of Decision Tree:")
print(DT_accuracy)

# Accuracy of Logistic Regression
LR_accuracy = accuracy_score(y_test, lr_pred)
print("Accuracy of Logistic Regression:")
print(LR_accuracy)
# XGBoost
y_prob_xgb = xgboost_classifier.predict_proba(X_test)[:, 1]
fpr_xgb, tpr_xgb, thresholds_xgb = roc_curve(y_test, y_prob_xgb)
roc_auc_xgb = auc(fpr_xgb, tpr_xgb)

# RandomForestClassifier
y_prob_rf = rf_classifier.predict_proba(X_test)[:, 1]
fpr_rf, tpr_rf, thresholds_rf = roc_curve(y_test, y_prob_rf)
roc_auc_rf = auc(fpr_rf, tpr_rf)

# Decision Tree Classifier
y_prob_dt = dt_classifier.predict_proba(X_test)[:, 1]
fpr_dt, tpr_dt, thresholds_dt = roc_curve(y_test, y_prob_dt)
roc_auc_dt = auc(fpr_dt, tpr_dt)

# Logistic Regression
y_prob_lr = lr_classifier.predict_proba(X_test)[:, 1]
fpr_lr, tpr_lr, thresholds_lr = roc_curve(y_test, y_prob_lr)
roc_auc_lr = auc(fpr_lr, tpr_lr)

# Create a subplot with 2 rows and 2 columns
plt.figure(figsize=(15, 10))

# Plot for XGBoost
plt.subplot(2, 2, 1)
plt.plot(fpr_xgb, tpr_xgb, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_xgb))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('XGBoost\nAccuracy: {:.2f}%'.format(xgboost_accuracy * 100))
plt.legend(loc="lower right")

# Plot for RandomForestClassifier
plt.subplot(2, 2, 2)
plt.plot(fpr_rf, tpr_rf, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_rf))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Random Forest\nAccuracy: {:.2f}%'.format(RF_accuracy * 100))
plt.legend(loc="lower right")

# Plot for Decision Tree
plt.subplot(2, 2, 3)
plt.plot(fpr_dt, tpr_dt, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_dt))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Decision Tree\nAccuracy: {:.2f}%'.format(DT_accuracy * 100))
plt.legend(loc="lower right")

# Plot for Logistic Regression
plt.subplot(2, 2, 4)
plt.plot(fpr_lr, tpr_lr, color='darkorange', lw=2, label='ROC curve (AUC = {:.2f})'.format(roc_auc_lr))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Logistic Regression\nAccuracy: {:.2f}%'.format(LR_accuracy * 100))
plt.legend(loc="lower right")

# Adjust layout to prevent overlap
plt.tight_layout()

# Show the plots
plt.show()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

123. SQL优化技巧汇总

文章目录 1 避免使用select *2 用union all代替union3 小表驱动大表4 批量操作5 多用limit6 in中值太多7 增量查询8 高效的分页9 用连接查询代替子查询10 join的表不宜过多11 join时要注意12 控制索引的数量13 选择合理的字段类型14 提升group by的效率15 索引优化 sql优化是一…

绝地求生:杜卡迪联动下架,兰博基尼联动预计在下半年上线!

杜卡迪联名活动即将在5月8日上午八点下架,届时商城内购买-升阶活动将不可用。 杜卡迪下架 本次杜卡迪联名是蓝洞首次以非通行证方式进行的载具联名活动,玩家认为有利有弊。 多数玩家表示非通行证-仅抽奖获取的方式成本太高,部分脸黑玩家本次…

科林算法_3 图

一、图论基础 多对多的关系 定义&#xff1a;G(V,E) Vertex顶点 Edge边 顶点的集合V{v1,v2} 边的结合E{(v1,v2)} 无向图(1,2) 有向图<1,2> 依附&#xff1a;边(v1,v2)依附于顶点v1,v2 路径&#xff1a;&#xff08;v1,v2)(v2,v3) 无权路径最短&#xff1a;边最少…

CMake创建跨平台OPenGL工程(学习笔记)

一、跨平台环境基本配置 1、环境搭建 1&#xff09;linux OpenGL环境搭建参考&#xff1a;ubuntu18.04 OpenGL开发&#xff08;显示YUV&#xff09;_ubuntu opengl-CSDN博客 https://blog.51cto.com/cerana/6433535 2&#xff09;windows下环境搭建 OpenGLVisual Studio20…

前端css中线性渐变(linear-gradient)的使用

前端css中线性渐变 一、前言二、关键词句三、主要内容说明&#xff08;一&#xff09;、线性渐变方向1.角度调整方向2.负值角度&#xff0c;源码13.源码1运行效果4.关键字调整方向5.to right向右线性渐变&#xff0c;源码26.源码2运行效果 &#xff08;二&#xff09;、线性渐变…

hyper-v启动centos7虚拟机不能联网

虚拟网卡要和之前虚拟机里面设置的GATEWAY一致。 安装CentOS遇到Error setting up base repository换url 或者换镜像包iso(这个有用&#xff09; 没掌握摸Yu的精髓 好累啊

Linux 中 POSIX 互斥信号量(互斥锁)的使用

目录 一、互斥锁的介绍二、使用方法三、测试代码 一、互斥锁的介绍 在Linux系统中&#xff0c;特别是在ARM架构的嵌入式系统中&#xff0c;互斥量&#xff08;Mutex&#xff09;用于保护共享资源不被多个线程或任务同时访问&#xff0c;从而防止数据竞争和不一致性。 POSIX 互斥…

Springboot集成Mybatispuls操作mysql数据库-04

MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强而不做改变。它支持所有MyBatis原生的特性&#xff0c;因此引入MyBatis-Plus不会对现有的MyBatis构架产生任何影响。MyBatis-Plus旨在简化开发、提高效率&#xff0c;…

JavaEE企业级开发中常用的Stream流

介绍 在Java编程中&#xff0c;Stream流是Java 8引入的一个重要概念&#xff0c;它提供了一种新的处理集合的方式&#xff0c;可以更加简洁、高效地进行数据操作。Stream流支持各种常见的操作&#xff0c;比如过滤、映射、排序、聚合等&#xff0c;同时也支持并行处理&#xf…

Go的安装与配置

安装 https://go.dev/dl/ 以Windows上安装为例&#xff1a; 下一步下一步&#xff0c;记住安装位置 安装完成后 win rcmd 键入go version检查是否安装成功 配置 Go 工作区 Go 在组织项目文件方面与其他编程语言不同。 Go 是在工作区的概念下工作的。但是从版本 1.11 开始&…

Dreamweaver 2021 for Mac 激活版:网页设计工具

在追求卓越的网页设计道路上&#xff0c;Dreamweaver 2021 for Mac无疑是您的梦幻之选。这款专为Mac用户打造的网页设计工具&#xff0c;集强大的功能与出色的用户体验于一身。 Dreamweaver 2021支持多种网页标准和技术&#xff0c;让您能够轻松创建符合现代网页设计的作品。其…

RespeakPro对口型数字人使用教程

RespeakPro可以将您的视频与音频生成100%精准对口型的视频。与Respeak差别是效率高效果更好。是自媒体制作数字人视频必备黑科技AI. 支持多国语言音频和唱歌音频对口型! 1&#xff1a;系统要求 软件运行支持32/64位window 10/11系统, 无硬件要求,不用显卡也能快速运行。 2&a…

vue+springboot实现excel批量数据的导入导出

①后端配置端口&#xff1a;修改UserController UserController&#xff1a; package com.example.springboot.controller;import cn.hutool.core.util.StrUtil; import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.…

教大家一键下载1688图片信息

电商图片是商品的视觉身份证&#xff0c;对销量有着决定性影响。它们不仅是展示产品&#xff0c;更是讲述品牌故事&#xff0c;激发情感共鸣的工具。高质量的图片能瞬间吸引顾客目光&#xff0c;准确传达产品细节&#xff0c;建立起顾客的信任与购买意愿。在无法亲身体验商品的…

全自动减压器法二氧化碳气容量测试仪:饮料行业的革新与未来

全自动减压器法二氧化碳气容量测试仪&#xff1a;饮料行业的革新与未来 一、引言 在追求品质与效率的现代饮料生产领域&#xff0c;全自动减压器法二氧化碳气容量测试仪凭借其高精度、高效率及无人工干预的显著优势&#xff0c;正逐渐成为行业的标杆。特别是在碳酸饮料的生产中…

【考古篇】Attension is all you need

Transformer 文章目录 Transformer1. What2. Why3. How3.1 Encoder3.2 Decoder3.3 Attention3.4 Application3.5 Position-wise Feed-Forward Networks(The second sublayer)3.6 Embeddings and Softmax3.7 Positional Encoding3.8 Why Self-Attention 1. What A new simple n…

labview技术交流-字符串数组连接成字符串

应用场景 我们可能需要将一维的字符串数组转换成一整条字符串&#xff0c;然后方便记录在数据库或表格中的一个单元格中。 代码展示 方案一 我们使用for循环完成这样的功能需求&#xff0c;见下图&#xff1a; 这种方案可能相对基础和普通&#xff0c;但是它更方便和易于扩展…

JavaSwing技术实现一个电子表程序

使用JavaSwing技术实现一个简单的电子表盘&#xff0c;如下所示。 下载链接 有兴趣的读者可以点击链接下载&#xff0c;博主承诺绝对真实有效。

PyQt5中的事件与信号处理

文章目录 1. 简介1.1事件(Event)1.2 信号(Signal)与槽(Slot)1.3 自定义信号 2. 一个信号与槽的简单示例13. 一个信号与槽的简单示例24. 事件发送者5. 创建自定义信号6. 一个简单计算器 1. 简介 在PyQt5中&#xff0c;事件和信号处理是GUI编程的核心概念。事件是指用户操作或系…

2024年数维杯数维杯数学建模A题思路+论文+代码+结果

A 题 多源机会信号建模与导航分析 尽管全球卫星定位系统下的定位导航技术已成熟&#xff0c;但考虑到室内、 隧道、建筑密集区等复杂环境或全球卫星定位系统被毁失灵等突发场 景&#xff0c;会发生全球卫星定位系统拒止情况&#xff0c;无法有效定位导航。因此&#xff0c; 需要…