机器学习实验--决策树
·
一、决策树介绍
1.1 算法核心
本次实验针对贷款审批场景,采用ID3 决策树算法,以信息增益为特征选择准则:
- 信息熵:衡量贷款数据集的类别不纯度,公式为 H(D)=−∑k=1Kpklog2pk(pk为 “给贷款”/“不给贷款” 的样本占比);
- 信息增益:划分后信息熵的减少量,公式为 Gain(D,a)=H(D)−∑v=1V∣D∣∣Dv∣H(Dv)(a为贷款特征,如 “有自己的房子”;Dv为特征a取v值的子集);
- 核心逻辑:优先选择信息增益最大的特征作为节点划分依据,递归构建树形模型。
二、实践代码部分
1. 数据加载与预处理
# 1. 导入依赖库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.metrics import accuracy_score, confusion_matrix
# 配置中文字体
plt.rcParams["font.family"] = ["SimHei", "Microsoft YaHei"]
plt.rcParams["axes.unicode_minus"] = False
# 2. 数据加载与预处理
def load_and_preprocess_data():
columns = ["年龄段", "有工作", "有自己的房子", "信贷情况", "类别"]
train_data = pd.read_csv("dataset.txt", sep=",", header=None, names=columns)
test_data = pd.read_csv("testset.txt", sep=",", header=None, names=columns)
X_train = train_data.drop("类别", axis=1)
y_train = train_data["类别"]
X_test = test_data.drop("类别", axis=1)
y_test = test_data["类别"]
print("-"*30)
print("数据基本信息")
print("-"*30)
print(f"训练集样本数:{len(train_data)},测试集样本数:{len(test_data)}")
print("特征编码规则:")
print("- 年龄段:青年(0)/中年(1)/老年(2)")
print("- 有工作/有自己的房子:否(0)/是(1)")
print("- 信贷情况:一般(0)/好(1)/非常好(2)")
print("- 类别:不给贷款(0)/给贷款(1)")
return X_train, X_test, y_train, y_test
2. 模型构建与训练
# 3. 模型构建与训练
def build_and_train_model(X_train, y_train):
dt_model = DecisionTreeClassifier(
criterion="entropy",
random_state=42
)
dt_model.fit(X_train, y_train)
print("\n" + "-"*30)
print("模型训练完成")
print("-"*30)
print(f"训练集拟合准确率:{dt_model.score(X_train, y_train):.4f}")
return dt_model
# 4. 手动计算指标
def calculate_metrics(y_true, y_pred, class_names):
cm = confusion_matrix(y_true, y_pred)
n_classes = len(class_names)
precision = []
recall = []
f1_score = []
support = []
for i in range(n_classes):
tp = cm[i, i]
fp = cm[:, i].sum() - tp
fn = cm[i, :].sum() - tp
sup = cm[i, :].sum()
support.append(sup)
prec = tp / (tp + fp) if (tp + fp) != 0 else 0.0
rec = tp / (tp + fn) if (tp + fn) != 0 else 0.0
f1 = 2 * (prec * rec) / (prec + rec) if (prec + rec) != 0 else 0.0
precision.append(prec)
recall.append(rec)
f1_score.append(f1)
macro_prec = np.mean(precision)
macro_rec = np.mean(recall)
macro_f1 = np.mean(f1_score)
weighted_prec = np.average(precision, weights=support)
weighted_rec = np.average(recall, weights=support)
weighted_f1 = np.average(f1_score, weights=support)
accuracy = accuracy_score(y_true, y_pred)
return (precision, recall, f1_score, support,
macro_prec, macro_rec, macro_f1,
weighted_prec, weighted_rec, weighted_f1,
accuracy)
3. 指标手动计算
# 5. 分类报告
def evaluate_model(dt_model, X_test, y_test):
y_pred = dt_model.predict(X_test)
class_names = ["不给贷款", "给贷款"]
(precision, recall, f1_score, support,
macro_prec, macro_rec, macro_f1,
weighted_prec, weighted_rec, weighted_f1,
accuracy) = calculate_metrics(y_test, y_pred, class_names)
print("\n" + "-"*30)
print("模型评估结果")
print("-"*30)
print(f"测试集准确率:{accuracy:.4f}")
print("\n分类报告:")
header = f"{'':<12} {'精确率':<8} {'召回率':<8} {'F1分数':<8} {'支持数'}"
print(header)
print("-" * 45)
for i, name in enumerate(class_names):
line = f"{name:<12} {precision[i]:<8.2f} {recall[i]:<8.2f} {f1_score[i]:<8.2f} {support[i]}"
print(line)
print()
print(f"{'准确率':<12} {'':<8} {'':<8} {'':<8} {accuracy:.2f} {sum(support)}")
print(f"{'宏观平均':<12} {macro_prec:<8.2f} {macro_rec:<8.2f} {macro_f1:<8.2f} {sum(support)}")
print(f"{'加权平均':<12} {weighted_prec:<8.2f} {weighted_rec:<8.2f} {weighted_f1:<8.2f} {sum(support)}")
return accuracy
4. 决策树可视化
# 6. 决策树可视化
def visualize_tree(dt_model, X_train):
plt.figure(figsize=(15, 10))
plot_tree(
dt_model,
filled=True,
rounded=True,
feature_names=X_train.columns,
class_names=["不给贷款", "给贷款"],
fontsize=10
)
plt.title("贷款审批决策树", fontsize=15, pad=20)
plt.savefig("贷款审批决策树.png", dpi=300, bbox_inches="tight")
plt.show()
print("\n决策树可视化文件已保存:贷款审批决策树.png")
# 主函数执行
if __name__ == "__main__":
X_train, X_test, y_train, y_test = load_and_preprocess_data()
dt_model = build_and_train_model(X_train, y_train)
accuracy = evaluate_model(dt_model, X_test, y_test)
visualize_tree(dt_model, X_train)
三、实验结果
3.1 终端输出

3.2 可视化结果

四、实验报告
4.1 实验目的
- 掌握 ID3 决策树算法的核心原理:信息增益计算、特征选择逻辑;
- 完成贷款审批数据集的端到端分类实验,掌握数据加载、模型训练、评估的完整流程;
4.2 实验环境
- 操作系统:Windows
- 开发工具:Visual Studio Code
- 编程语言:Python
- 依赖库:pandas、numpy、scikit-learn 、matplotlib
4.3 实验原理
本次实验基于 ID3 算法,通过计算 “年龄段”“有工作”“有自己的房子”“信贷情况” 4 个特征的信息增益,优先选择信息增益最大的特征作为根节点,递归划分数据集:
- 若 “有自己的房子 = 是”,直接判定为 “给贷款”;
- 若 “有自己的房子 = 否”,则以 “有工作” 为下一层节点,“有工作 = 是” 判定为 “给贷款”,“有工作 = 否” 进一步按 “信贷情况” 划分;
- 当子集样本类别一致或无剩余特征时,停止划分,形成叶节点。
4.4 实验步骤
- 环境配置:安装所需 Python 依赖库,无需额外安装字体;
- 数据准备:将训练集
dataset.txt、测试集testset.txt放入代码同级目录; - 数据加载:通过
pandas读取数据集,分离特征与标签,打印数据基本信息; - 模型构建:初始化 ID3 决策树分类器,设置信息熵准则与随机种子;
- 模型训练:使用训练集拟合模型,输出训练集拟合准确率;
- 模型评估:手动计算分类指标,输出纯中文分类报告与测试集准确率;
- 可视化:绘制全中文决策树,保存高分辨率图片并展示;
- 结果分析:整理终端输出与可视化结果,总结实验结论。
五、实验总结
1. 模型效果
本次实验用 ID3 算法训练的决策树在测试集上达到了 88% 的准确率,能有效根据 “是否有房、是否有工作” 等核心特征判断是否给贷款,符合实际信贷场景的逻辑。
2. 结论
- 贷款决策中“是否有自己的房子” 是最核心的特征 (信息增益最大);
- 若需进一步提升准确率,可尝试增加训练样本量、调整树的最大深度。
更多推荐

所有评论(0)