03-决策树机器学习模型
概念:决策树是一种模拟人类决策过程的树形结构模型,通过一系列规则对实例进行分类。
原理:从根节点开始,根据某个特征的值对数据进行划分,每个内部节点代表一个特征测试,每个分支代表测试结果,每个叶节点代表一个类别标签。划分标准通常基于信息增益、基尼不纯度等指标。
思想:通过递归地分割数据,构建一个树形结构,使得每个子集内的样本尽可能属于同一类别,即“分而治之”。
应用:因其可解释性强,常用于需要清晰规则的应用,如客户分群、医疗诊断辅助系统等。
进一步阐释:
概念:基于树状结构的分类模型,通过一系列if-then规则进行决策
原理:
- 节点分裂:选择最佳特征和分割点(基尼系数、信息增益)
- 递归分割:直到满足停止条件(深度限制、节点样本数等)
- 叶节点:包含最终的类别标签
思想:
"分而治之"策略,将复杂问题分解为简单子问题
应用:
- 客户细分
- 疾病诊断
- 金融欺诈检测
一、设置环境和中文字体支持。
二、创建结果文件夹。
三、数据准备:读取Excel数据,预处理分类变量。
四、数据划分:分层抽样划分训练集和测试集。
五、模型构建:使用DecisionTreeClassifier构建决策树。
六、模型可视化:使用plot_tree和graphviz绘制决策树图。
七、模型评估:预测、计算准确率、灵敏度、特异性、AUC、ROC曲线。
八、变量重要性分析:提取并可视化特征重要性。
九、结果保存:保存预测结果、变量重要性、性能指标、混淆矩阵为Excel文件。
十、报告生成:使用python-docx生成Word报告,包含数据概览、方法、参数、性能、变量重要性、可视化等。
Python代码实现了一个完整的决策树机器学习分析流程,专门用于处理二元分类问题,涵盖了从数据准备到报告生成的自动化过程。
# pip install pandas numpy matplotlib seaborn scikit-learn graphviz python-docx openpyxl
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree, export_text
from sklearn.metrics import accuracy_score, confusion_matrix, roc_curve, auc, classification_report
from sklearn.preprocessing import LabelEncoder
from sklearn import tree
import graphviz
import os
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 创建结果文件夹
results_dir = os.path.expanduser("~/Desktop/Results模型-dt")
if not os.path.exists(results_dir):
os.makedirs(results_dir)
# 1. 数据准备
# 读取Excel数据
data = pd.read_excel("~/Desktop/示例数据.xlsx")
# 数据预处理 - 将分类变量转换为数值
categorical_cols = ['指标8', '肥胖程度', '教育水平', '血型']
label_encoders = {}
for col in categorical_cols:
le = LabelEncoder()
data[col] = le.fit_transform(data[col].astype(str))
label_encoders[col] = le
# 准备自变量和因变量
X = data.drop(['序号', '结局'], axis=1)
y = data['结局']
plt.title('决策树模型')
plt.tight_layout()
plt.savefig(os.path.join(results_dir, 'decision_tree.jpg'), dpi=300, bbox_inches='tight')
plt.savefig(os.path.join(results_dir, 'decision_tree.pdf'), bbox_inches='tight')
plt.close()
# 使用graphviz绘制更美观的决策树
dot_data = tree.export_graphviz(
dt_model,
out_file=None,
feature_names=X.columns,
class_names=['0', '1'],
filled=True,
rounded=True,
special_characters=True
)
graph = graphviz.Source(dot_data)
graph.render(os.path.join(results_dir, 'decision_tree_graphviz'), format='pdf', cleanup=True)
graph.render(os.path.join(results_dir, 'decision_tree_graphviz'), format='png', cleanup=True)
# 4. 模型评估
# 5. 变量重要性分析
feature_importance = dt_model.feature_importances_
feature_importance_df = pd.DataFrame({
'Variable': X.columns,
'Importance': feature_importance
}).sort_values('Importance', ascending=False)
# 绘制变量重要性图
plt.figure(figsize=(12, 8))
plt.barh(range(len(feature_importance_df)), feature_importance_df['Importance'], align='center')
plt.yticks(range(len(feature_importance_df)), feature_importance_df['Variable'])
plt.xlabel('重要性')
plt.title('变量重要性')
plt.tight_layout()
plt.savefig(os.path.join(results_dir, 'variable_importance.jpg'), dpi=300, bbox_inches='tight')
plt.savefig(os.path.join(results_dir, 'variable_importance.pdf'), bbox_inches='tight')
plt.close()
# 绘制前10个最重要变量
top_10 = feature_importance_df.head(10)
plt.figure(figsize=(12, 6))
plt.barh(range(len(top_10)), top_10['Importance'], align='center')
plt.yticks(range(len(top_10)), top_10['Variable'])
plt.xlabel('重要性')
plt.title('前10个最重要变量')
plt.tight_layout()
plt.savefig(os.path.join(results_dir, 'variable_importance_top10.jpg'), dpi=300, bbox_inches='tight')
plt.savefig(os.path.join(results_dir, 'variable_importance_top10.pdf'), bbox_inches='tight')
plt.close()
# 6. 保存结果表格
# 保存预测结果
predictions = pd.DataFrame({
'Actual': y_test.values,
'Predicted_Class': y_pred,
'Predicted_Probability': y_pred_prob
})
predictions.to_excel(os.path.join(results_dir, 'predictions.xlsx'), index=False)
# 保存变量重要性
feature_importance_df.to_excel(os.path.join(results_dir, 'variable_importance.xlsx'), index=False)
# 保存性能指标
performance_metrics = pd.DataFrame({
'Metric': ['准确率', '灵敏度', '特异性', 'AUC'],
'Value': [accuracy, sensitivity, specificity, roc_auc]
})
performance_metrics.to_excel(os.path.join(results_dir, 'performance_metrics.xlsx'), index=False)
# 保存混淆矩阵
conf_matrix_df = pd.DataFrame(conf_matrix,
index=['实际0', '实际1'],
columns=['预测0', '预测1'])
conf_matrix_df.to_excel(os.path.join(results_dir, 'confusion_matrix.xlsx'))
# 7. 生成Word报告
doc = Document()
# 添加标题
title = doc.add_heading('决策树模型分析报告', 0)
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
doc.add_paragraph(f'生成日期: {pd.Timestamp.now().strftime("%Y-%m-%d")}')
doc.add_paragraph()
# 添加数据概览
doc.add_heading('数据概览', level=1)
doc.add_paragraph(f'总样本量: {len(data)}')
doc.add_paragraph(f'训练集样本量: {len(X_train)}')
doc.add_paragraph(f'测试集样本量: {len(X_test)}')
doc.add_paragraph(f'结局变量分布 - 0: {sum(y == 0)}, 1: {sum(y == 1)}')
doc.add_paragraph()
# 添加方法说明
doc.add_heading('分析方法', level=1)
doc.add_paragraph('本报告使用了决策树分类方法:')
doc.add_paragraph('- 使用所有变量构建决策树模型')
doc.add_paragraph('- 采用分层抽样划分训练集和测试集')
doc.add_paragraph('- 所有分类变量已转换为数值进行处理')
doc.add_paragraph()
# 添加模型参数
doc.add_heading('模型参数', level=1)
doc.add_paragraph(f'最大深度: {dt_model.get_params()["max_depth"]}')
doc.add_paragraph(f'最小分裂样本数: {dt_model.get_params()["min_samples_split"]}')
doc.add_paragraph(f'最小叶节点样本数: {dt_model.get_params()["min_samples_leaf"]}')
doc.add_paragraph(f'随机种子: {dt_model.get_params()["random_state"]}')
doc.add_paragraph()
# 添加模型性能
doc.add_heading('模型性能', level=1)
doc.add_paragraph(f'准确率: {accuracy:.4f}')
doc.add_paragraph(f'灵敏度: {sensitivity:.4f}')
doc.add_paragraph(f'特异性: {specificity:.4f}')
doc.add_paragraph(f'AUC: {roc_auc:.4f}')
doc.add_paragraph()
# 添加变量重要性说明
doc.add_heading('变量重要性', level=1)
doc.add_paragraph('基于决策树的特征重要性,前10个最重要变量排序如下:')
for i, (_, row) in enumerate(feature_importance_df.head(10).iterrows(), 1):
doc.add_paragraph(f'{i}. {row["Variable"]} ({row["Importance"]:.4f})')
doc.add_paragraph()
doc.add_paragraph('完整变量重要性图表已保存至Results模型-dt文件夹。')
# 添加混淆矩阵
doc.add_heading('混淆矩阵', level=1)
table = doc.add_table(rows=3, cols=3)
table.style = 'Table Grid'
# 设置表头
hdr_cells = table.rows[0].cells
hdr_cells[0].text = ''
hdr_cells[1].text = '预测0'
hdr_cells[2].text = '预测1'
# 设置第一列
table.rows[1].cells[0].text = '实际0'
table.rows[2].cells[0].text = '实际1'
# 填充数据
table.rows[1].cells[1].text = str(tn)
table.rows[1].cells[2].text = str(fp)
table.rows[2].cells[1].text = str(fn)
table.rows[2].cells[2].text = str(tp)
doc.add_paragraph()
# 添加图片说明
doc.add_heading('模型可视化', level=1)
doc.add_paragraph('决策树结构图展示了模型的决策路径和规则:')
doc.add_picture(os.path.join(results_dir, 'decision_tree.jpg'), width=Inches(6))
doc.add_paragraph()
doc.add_paragraph('ROC曲线展示了模型在不同阈值下的性能表现:')
doc.add_picture(os.path.join(results_dir, 'roc_curve.jpg'), width=Inches(5))
doc.add_paragraph()
doc.add_paragraph('变量重要性图展示了各特征对预测结果的贡献程度:')
doc.add_picture(os.path.join(results_dir, 'variable_importance_top10.jpg'), width=Inches(5))
doc.add_paragraph()
doc.add_paragraph('所有可视化图表已保存至Results模型-dt文件夹。')
# 保存Word文档
doc.save(os.path.join(results_dir, 'decision_tree_analysis_report.docx'))
print("分析完成!所有结果已保存到Results模型-dt文件夹中,包括:")
print("- 决策树结构图 (JPG和PDF格式)")
print("- ROC曲线图 (JPG和PDF格式)")
print("- 变量重要性图 (JPG和PDF格式)")
print("- 预测结果表格 (Excel格式)")
print("- 变量重要性表格 (Excel格式)")
print("- 性能指标表格 (Excel格式)")
print("- 混淆矩阵表格 (Excel格式)")
print("- 完整分析报告 (Word格式)")
- 环境设置与数据准备:初始化分析环境,设置中文字体支持,并创建结果文件夹;随后读取Excel格式的示例数据,对分类变量(如指标8、肥胖程度)进行标签编码转换为数值,并划分数据为训练集和测试集。
- 模型构建与可视化:使用决策树算法(设置最大深度、最小分裂样本数等参数)训练模型,并通过matplotlib和graphviz生成决策树结构图,保存为多种格式(如JPG、PDF)。
- 模型评估与性能分析:在测试集上进行预测,计算准确率、灵敏度、特异性等指标,绘制ROC曲线并计算AUC值,同时生成混淆矩阵以评估模型性能。
- 变量重要性分析:提取特征重要性排名,绘制条形图展示所有变量及前10个最重要变量的贡献程度,并将结果保存为Excel表格。
- 结果保存与报告生成:自动化输出预测结果、性能指标和混淆矩阵为Excel文件,并使用python-docx库创建Word报告,整合数据概览、模型参数、性能摘要、可视化图表和变量排序。
- pandas:用于数据读取(如Excel文件)、数据处理和DataFrame操作,支持数据清洗和转换。
- numpy:提供数值计算支持,辅助数组操作和数学运算。
- matplotlib.pyplot 和 seaborn:负责数据可视化,如绘制决策树图、ROC曲线和变量重要性图,并设置中文字体显示。
- scikit-learn:核心机器学习库,其中train_test_split用于数据划分,DecisionTreeClassifier构建模型,metrics模块计算评估指标,preprocessing处理标签编码。
- graphviz:生成更美观的决策树可视化图形,增强可读性。
- python-docx:创建和格式化Word报告,插入表格、图片和文本内容。
- os:处理文件路径和文件夹创建,确保输出结果有序保存。
- warnings:忽略运行时警告,保持代码输出整洁。
- 整段代码的应用:
- 该代码适用于需要透明、可解释的分类预测场景,例如在医疗诊断中预测疾病结局、金融领域评估客户风险,或社会科学研究中分析变量影响。
- 自动化流程提高了分析效率性和可重复性,适合快速生成学术论文、商业分析报告或教学演示材料,降低人工操作错误。
- 决策树的直观可视化特性便于向非技术人员解释模型决策过程,支持决策制定和模型优化迭代。
医学统计数据分析分享交流SPSS、R语言、Python、ArcGis、Geoda、GraphPad、数据分析图表制作等心得。承接数据分析,论文返修,医学统计,机器学习,生存分析,空间分析,问卷分析业务。若有投稿和数据分析代做需求,可以直接联系我,谢谢!
“医学统计数据分析”公众号右下角;
找到“联系作者”,
可加我微信,邀请入粉丝群!
有临床流行病学数据分析
如(t检验、方差分析、χ2检验、logistic回归)、
(重复测量方差分析与配对T检验、ROC曲线)、
(非参数检验、生存分析、样本含量估计)、
(筛检试验:灵敏度、特异度、约登指数等计算)、
(绘制柱状图、散点图、小提琴图、列线图等)、
机器学习、深度学习、生存分析
等需求的同仁们,加入【临床】粉丝群。
疾控,公卫岗位的同仁,可以加一下【公卫】粉丝群,分享生态学研究、空间分析、时间序列、监测数据分析、时空面板技巧等工作科研自动化内容。
有实验室数据分析需求的同仁们,可以加入【生信】粉丝群,交流NCBI(基因序列)、UniProt(蛋白质)、KEGG(通路)、GEO(公共数据集)等公共数据库、基因组学转录组学蛋白组学代谢组学表型组学等数据分析和可视化内容。
或者可扫码直接加微信进群!!!
精品视频课程-“医学统计数据分析”视频号付费合集
在“医学统计数据分析”视频号-付费合集兑换相应课程后,获取课程理论课PPT、代码、基础数据等相关资料,请大家在【医学统计数据分析】公众号右下角,找到“联系作者”,加我微信后打包发送。感谢您的支持!!
【二分类因变量机器学习】图文教程
往期推荐:【监测预警自动化】系列教程
往期推荐:样本含量估计(样本量计算与功效分析)
往期推荐:SPSS、R语言、Python等临床数据分析专题
往期推荐:科研图表绘制专题
往期推荐:重复测量数据分析专题
往期推荐:生信分析、基因测序数据、实验室数据专题
往期推荐:生存分析及机器学习
往期推荐:时间序列分析
往期推荐:地统计分析-GIS、地图、相关、聚类、回归
往期推荐:科研自动化探究
往期推荐:趣味阅读
统计评书系列

