机器学习实战——基于随机森林与决策树模型的贷款违约预测全过程(附完整代码和可视化分析)
关于作者
作者:小白熊
作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测,图像分类,姿态识别,语义分割,路径规划,智能优化算法,数据分析,各类创新融合等等。
联系邮箱:xbx3144@163.com
引言
在数据科学领域,分类问题是一类常见且重要的任务。分类模型旨在根据输入的特征数据预测目标变量的类别。本文将通过一个实际的案例,使用Python编程语言及sklearn机器学习库,演示如何使用随机森林和决策树这两种经典的分类算法进行模型训练、评估及对比。我们将从数据预处理、模型训练、性能评估及可视化等方面进行详细讲解。
1. 环境准备与数据加载
首先,我们需要导入必要的Python库,并加载数据集。数据集涉及隐私,读者参考流程和方法应用于自己的数据集。
python">import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_curve, roc_auc_score, confusion_matrix, auc
from sklearn import tree
import time
from imblearn.under_sampling import RandomUnderSampler
from collections import Counter
import warnings warnings.filterwarnings("ignore") plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False data = pd.read_csv('train.csv')
2. 数据预处理
2.1 筛选数值特征
从原始数据集中筛选出数值型特征,并排除ID列。
python">numerical_feature = list(data.select_dtypes(exclude=['object']).columns)
numerical_feature.remove('id')
2.2 处理缺失值
使用中位数填充数值型特征的缺失值。
python">data[numerical_feature] = data[numerical_feature].fillna(data[numerical_feature].median())
2.3 提取特征与目标变量
将isDefault
列作为目标变量,其余数值型特征作为特征变量。
python">numerical_feature.remove('isDefault')
labels = data['isDefault']
features = data[numerical_feature]
2.4 类别不平衡处理
通过随机下采样方法平衡类别分布。
python">sampler = RandomUnderSampler(sampling_strategy='majority')
features, labels = sampler.fit_resample(features, labels)
2.5 数据分布可视化
使用Seaborn绘制数值特征的分布图,以初步了解数据特性。
python">num_cols = 3
num_features = len(numerical_feature)
num_rows = num_features // num_cols + (1 if num_features % num_cols != 0 else 0) for i in range(0, num_features, num_cols): plt.figure(figsize=(15, 5)) for j, feature in enumerate(numerical_feature[i:i + num_cols]): plt.subplot(1, num_cols, j + 1) sns.distplot(features[feature]) plt.title(feature) plt.tight_layout() plt.show()
3. 模型训练与评估
3.1 数据划分
将数据集划分为训练集和测试集,比例为8:2。
python">features_train, features_test = train_test_split(features, test_size=0.2, random_state=42)
labels_train, labels_test = train_test_split(labels, test_size=0.2, random_state=42)
3.2 决策树模型
决策树模型基于递归地将数据集分割成越来越小的子集,直到满足特定条件,如达到某个纯度标准或子集中的样本数量小于预定阈值。每个分割决策都是基于特征的某个值来做出的,目的是最大化子集内部的同质性(即同一个类别的样本尽可能多)和不同子集之间的异质性(即不同类别的样本尽可能少)。
特征选择的目的是找到最好的分割点,可以使用信息增益、信息增益率、基尼不纯度等指标来衡量分割的效果。信息增益是衡量通过分割数据获得的信息量,它基于熵的概念,而熵是度量数据集不确定性的指标,信息增益高的分割可以更有效地减少不确定性。基尼不纯度则是决策树算法中用于衡量一个节点内样本类别多样性的指标,它基于概率理论,用于评估数据集的纯净度或不纯度。基尼不纯度越低,表示数据集的纯净度越高。
训练决策树模型,并进行类似的性能评估与可视化分析。
python">clf1 = tree.DecisionTreeClassifier()
clf1.fit(features_train, labels_train)
labels_train_pre = clf1.predict(features_train)
labels_test_pre = clf1.predict(features_test)
acc_train1 = accuracy_score(labels_train, labels_train_pre)
acc_test1 = accuracy_score(labels_test, labels_test_pre)
使用混淆矩阵热力图进行可视化分析。
python"># 绘制混淆矩阵热力图
conf_matrix = confusion_matrix(labels_test, labels_test_pre)
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.title('决策树-Confusion Matrix Heatmap')
plt.show()
决策树" />
3.3 随机森林模型
随机森林是一种集成学习方法,通过构建多个决策树并结合其预测结果来提高模型的准确性和稳定性。每棵树在训练时都使用了不同的子集数据,并且每个节点的分裂只使用了随机选择的特征子集。最终的预测结果是所有决策树预测结果的平均或投票结果。
训练随机森林模型,并评估其在训练集和测试集上的性能。
python">clf2 = RandomForestClassifier(n_estimators=100, max_depth=None, min_samples_split=2, random_state=0)
clf2.fit(features_train, labels_train)
labels_train_pre = clf2.predict(features_train)
labels_test_pre = clf2.predict(features_test)
acc_train2 = accuracy_score(labels_train, labels_train_pre)
acc_test2 = accuracy_score(labels_test, labels_test_pre)
使用混淆矩阵热力图进行可视化分析。
python"># 绘制混淆矩阵热力图
conf_matrix = confusion_matrix(labels_test, labels_test_pre)
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.title('随机森林-Confusion Matrix Heatmap')
plt.show()
随机森林" />
4. 完整代码
python">import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_curve, roc_auc_score, \confusion_matrix, auc
from sklearn import tree
import time
from imblearn.under_sampling import RandomUnderSampler
from collections import Counter
import warningswarnings.filterwarnings("ignore")plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = Falsedata = pd.read_csv('train.csv')# 筛选数据
numerical_feature = list(data.select_dtypes(exclude=['object']).columns)
numerical_feature.remove('id')# 缺失值处理
data[numerical_feature] = data[numerical_feature].fillna(data[numerical_feature].median())# 提取数据
numerical_feature.remove('isDefault')
labels = data['isDefault']
features = data[numerical_feature]# 打印每个类别的数量
label_counts = Counter(labels)
print('原始数据:')
for label, count in label_counts.items():print(f'类别 {label}: 数量 {count}')
print("--" * 50)# 进行下采样
sampler = RandomUnderSampler(sampling_strategy='majority')
features, labels = sampler.fit_resample(features, labels)label_counts = Counter(labels)
print('下采样后:')
for label, count in label_counts.items():print(f'类别 {label}: 数量 {count}')
print("--" * 50)# 绘图
num_cols = 3 # 每行显示的图像数量
num_features = len(numerical_feature)
num_rows = num_features // num_cols + (1 if num_features % num_cols != 0 else 0)for i in range(0, num_features, num_cols):plt.figure(figsize=(15, 5))for j, feature in enumerate(numerical_feature[i:i + num_cols]):plt.subplot(1, num_cols, j + 1)sns.distplot(features[feature])plt.title(feature)plt.tight_layout()plt.show()# 划分数据
features_train, features_test = train_test_split(features, test_size=0.2, random_state=42)
labels_train, labels_test = train_test_split(labels, test_size=0.2, random_state=42)########################################################################### 决策树
print('开始训练决策树 | ', '时间:', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
clf1 = tree.DecisionTreeClassifier()
clf1.fit(features_train, labels_train)
labels_train_pre = clf1.predict(features_train)
labels_test_pre = clf1.predict(features_test)
acc_train1 = accuracy_score(labels_train, labels_train_pre)
acc_test1 = accuracy_score(labels_test, labels_test_pre)
print("训练完毕 | 结果如下: ")
print("训练集准确率:", acc_train1)
print("验证集准确率:", acc_test1)
print("--" * 50)# 绘制混淆矩阵热力图
conf_matrix = confusion_matrix(labels_test, labels_test_pre)
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.title('决策树-Confusion Matrix Heatmap')
plt.show()########################################################################### 随机森林
print('开始训练随机森林 | ', '时间:', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
clf2 = RandomForestClassifier(n_estimators=100, max_depth=None, min_samples_split=2, random_state=0)
clf2.fit(features_train, labels_train)
labels_train_pre = clf2.predict(features_train)
labels_test_pre = clf2.predict(features_test)
acc_train2 = accuracy_score(labels_train, labels_train_pre)
acc_test2 = accuracy_score(labels_test, labels_test_pre)
print("训练完毕 | 结果如下: ")
print("训练集准确率:", acc_train2)
print("验证集准确率:", acc_test2)
print("--" * 50)# 绘制混淆矩阵热力图
conf_matrix = confusion_matrix(labels_test, labels_test_pre)
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('True')
plt.title('随机森林-Confusion Matrix Heatmap')
plt.show()
5. 模型对比分析
通过对比随机森林和决策树在训练集和测试集上的准确率,我们可以发现随机森林通常具有更高的泛化能力,即测试集准确率更高。这是因为随机森林通过集成多个决策树的结果,减少了单个决策树容易过拟合的风险。
6. 结论
本文通过实际案例展示了如何使用随机森林和决策树进行分类任务,包括数据预处理、模型训练、性能评估及可视化分析。通过对比分析,我们发现随机森林在大多数情况下表现更优,尤其是在处理类别不平衡和高维数据时。然而,决策树作为一种基础模型,其简单性和可解释性在某些场景下仍然具有不可替代的价值。
希望本文能为读者在分类任务中选择合适的模型提供有益的参考,并激发进一步探索和实践的兴趣。