05-SVM机器学习模型
概念:支持向量机是一种寻找能够将不同类别样本尽可能分开且间隔最大的超平面的模型。
原理:对于线性可分数据,SVM寻找具有最大几何间隔的分离超平面。对于非线性数据,通过核技巧将数据映射到高维特征空间,使其在该空间中线性可分。对于重叠数据,引入软间隔概念,允许部分样本分类错误。
思想:结构风险最小化,旨在于在保证分类准确性的同时,最大化分类间隔,从而提升模型的泛化能力。
应用:在文本分类、生物信息学(如蛋白质结构预测)、图像识别等领域有广泛应用。
一、设置了工作目录和环境。
二、加载必要的R包。
三、数据准备:读取Excel数据,预处理分类变量。
四、分层抽样划分训练集和测试集。
五、探索性数据分析:生成变量关系图。
六、训练SVM模型:使用caret包和e1071包。
七、模型预测和评估:包括混淆矩阵、ROC曲线、AUC、Brier得分等。
八、可视化:如ROC曲线、变量重要性图、决策边界图。
九、保存结果:导出Excel文件、生成Word报告。
十、最后保存工作空间。
R语言代码实现了一个完整的支持向量机(SVM)机器学习分析流程,专为处理二元分类问题设计,涵盖了从数据预处理到报告生成的自动化过程。
# 设置工作目录和清理环境
rm(list = ls())
if (!is.null(dev.list())) dev.off()
setwd("C:/Users/hyy/Desktop/")
# 创建结果文件夹
if (!dir.exists("Results-svm")) dir.create("Results-svm")
# 加载必要的包
if (!require(pacman)) install.packages("pacman")
pacman::p_load(readxl, writexl, e1071, kernlab, caret, pROC, ggplot2, visreg, GGally,
RColorBrewer, officer, flextable, gridExtra, DALEX, showtext)
# 设置全局中文字体支持
# 方法1: 使用showtext包自动加载系统字体
font_add(family = "simhei", regular = "simhei.ttf") # 添加黑体
font_add(family = "simsun", regular = "simsun.ttc") # 添加宋体
showtext_auto(enable = TRUE) # 启用showtext
# 方法2: 设置图形设备参数(适用于基础绘图)
if (.Platform$OS.type == "windows") {
windowsFonts(SimHei = windowsFont("SimHei"))
windowsFonts(SimSun = windowsFont("SimSun"))
chinese_font <- "SimHei"
} else {
chinese_font <- "sans"
}
# 1. 数据准备
data <- read_excel("示例数据.xlsx")
# 将分类变量转换为因子,并确保结局变量有有效的水平名称
data$`肥胖程度` <- as.factor(data$`肥胖程度`)
data$`教育水平` <- as.factor(data$`教育水平`)
data$`血型` <- as.factor(data$`血型`)
data$`指标8` <- as.factor(data$`指标8`)
data$`结局` <- as.factor(ifelse(data$`结局` == 1, "Yes", "No")) # 将0/1转换为有效的因子水平
# 分层抽样划分训练集和测试集
set.seed(123)
train_index <- sample(1:nrow(data), nrow(data)*0.7)
Train <- data[train_index, ]
Test <- data[-train_index, ]
# 保存数据集
write_xlsx(Train, "Results-svm/Train.xlsx")
write_xlsx(Test, "Results-svm/Test.xlsx")
# 模型性能图
jpeg("Results-svm/model_tuning.jpg", width = 800, height = 600)
plot(svm_model)
dev.off()
pdf("Results-svm/model_tuning.pdf", width = 8, height = 6)
plot(svm_model)
dev.off()
# 4. 使用e1071包训练SVM模型
set.seed(1234)
seedsvm <- svm(结局 ~ 指标1 + 指标2 + 指标3 + 指标4 + 指标5 + 指标6,
data = Train, kernel = "radial", probability = TRUE)
# 保存模型摘要
sink("Results-svm/e1071_model_summary.txt", append = TRUE)
summary(seedsvm)
sink()
# 变量重要性 - 使用替代方法
# 方法1: 使用permutation importance
explainer <- explain(
model = svm_model,
data = Train[, c("指标1", "指标2", "指标3", "指标4", "指标5", "指标6")],
y = as.numeric(Train$结局 == "Yes"),
label = "SVM"
)
variable_importance <- model_parts(explainer)
vi_data <- as.data.frame(variable_importance)
# 绘制变量重要性图
jpeg("Results-svm/variable_importance.jpg", width = 800, height = 600)
plot(variable_importance) +
ggtitle("变量重要性 (基于排列重要性)") +
theme_minimal()
dev.off()
pdf("Results-svm/variable_importance.pdf", width = 8, height = 6)
plot(variable_importance) +
ggtitle("变量重要性 (基于排列重要性)") +
theme_minimal()
dev.off()
# 保存变量重要性数据
write_xlsx(vi_data, "Results-svm/variable_importance.xlsx")
# SVM分类面可视化 - 使用英文变量名避免编码问题
# 创建临时数据集,将变量名改为英文
Train_eng <- Train
colnames(Train_eng) <- c("ID", "Outcome", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8",
"Time", "BMI", "Obesity", "Education", "BloodType")
# 使用英文变量名训练模型
seedsvm_eng <- svm(Outcome ~ X1 + X2 + X3 + X4 + X5 + X6,
data = Train_eng, kernel = "radial", probability = TRUE)
# 绘制决策边界
jpeg("Results-svm/svm_decision_boundary.jpg", width = 800, height = 600)
plot(seedsvm_eng, Train_eng, X1 ~ X2)
dev.off()
pdf("Results-svm/svm_decision_boundary.pdf", width = 8, height = 6)
plot(seedsvm_eng, Train_eng, X1 ~ X2)
dev.off()
# 8. 保存结果
# 保存预测结果
results_table <- data.frame(
实际值 = Test$结局,
预测概率 = svm_pred_prob,
预测类别 = svm_pred_class
)
write_xlsx(results_table, "Results-svm/predictions.xlsx")
# 保存模型性能指标
performance_table <- data.frame(
指标 = c("准确率", "灵敏度", "特异度", "AUC", "Brier得分"),
值 = c(round(conf_matrix$overall[1], 4),
round(conf_matrix$byClass[1], 4),
round(conf_matrix$byClass[2], 4),
round(auc_value, 4),
round(brier_score, 4))
)
write_xlsx(performance_table, "Results-svm/performance_metrics.xlsx")
# 9. 创建Word报告
doc <- read_docx()
doc <- body_add_par(doc, "SVM模型分析报告", style = "heading 1")
doc <- body_add_par(doc, paste0("分析日期: ", Sys.Date()), style = "Normal")
doc <- body_add_par(doc, "数据概览", style = "heading 2")
doc <- body_add_par(doc, paste0("总样本量: ", nrow(data)), style = "Normal")
doc <- body_add_par(doc, paste0("训练集样本量: ", nrow(Train)), style = "Normal")
doc <- body_add_par(doc, paste0("测试集样本量: ", nrow(Test)), style = "Normal")
doc <- body_add_par(doc, "模型性能指标", style = "heading 2")
doc <- body_add_flextable(doc, flextable(performance_table))
doc <- body_add_par(doc, "ROC曲线", style = "heading 2")
doc <- body_add_img(doc, "Results-svm/ROC_curve.jpg", width = 6, height = 5)
doc <- body_add_par(doc, "变量重要性", style = "heading 2")
doc <- body_add_img(doc, "Results-svm/variable_importance.jpg", width = 6, height = 5)
doc <- body_add_par(doc, "SVM决策边界可视化", style = "heading 2")
doc <- body_add_img(doc, "Results-svm/svm_decision_boundary.jpg", width = 7, height = 6)
doc <- body_add_par(doc, "结论", style = "heading 2")
doc <- body_add_par(doc, paste0(
"SVM模型在测试集上表现",
ifelse(auc_value > 0.7, "良好", "一般"),
",AUC值为", round(auc_value, 3),
"。模型准确率为", round(conf_matrix$overall[1], 3), "。"
), style = "Normal")
print(doc, target = "Results-svm/SVM分析报告.docx")
# 10. 保存工作空间
save.image("Results-svm/SVM分析.RData")
cat("分析完成!所有结果已保存到 Results-svm 文件夹中。")
- 环境初始化与数据准备:设置工作目录、清理环境,并创建结果文件夹;随后读取Excel格式的示例数据,对分类变量(如肥胖程度、教育水平、血型等)进行预处理,转换为因子类型,并将结局变量从0/1转换为"Yes"/"No"标签,以确保数据适合建模。
- 数据划分与探索性分析:通过分层抽样将数据划分为训练集(70%)和测试集(30%),并保存为Excel文件;使用ggpairs函数生成变量间关系图,可视化连续变量(如指标1-6)与结局的关联。
- 模型训练与优化:使用caret包进行10折交叉验证的SVM模型训练(核函数为径向基),并优化参数;同时使用e1071包训练另一SVM模型以支持详细分析;模型性能通过调优图可视化。
- 模型评估与可视化:在测试集上预测结局变量,生成混淆矩阵(计算准确率、灵敏度、特异度等指标),绘制ROC曲线并计算AUC值,同时计算Brier得分以评估校准性能;通过DALEX包进行变量重要性分析(基于排列重要性),并绘制决策边界图展示分类面。
- 结果保存与报告生成:自动化输出预测结果、性能指标和变量重要性数据为Excel文件,并使用officer和flextable包创建Word报告,整合数据概览、模型性能、可视化图表和结论;所有输出保存到"Results-svm"文件夹中。
| pacman | 简化包的安装和加载管理,确保分析依赖就绪。 |
| readxl | 读取Excel格式的数据文件(如"示例数据.xlsx"),实现数据导入。 |
| writexl | 将数据集(如训练集、测试集)导出为Excel文件。 |
| e1071 | 核心SVM建模包,提供svm函数训练径向基核模型,并支持概率预测。 |
| caret | 提供机器学习流程工具,如数据预处理(中心化、标准化)、交叉验证训练和参数调优。 |
| pROC | 绘制ROC曲线并计算AUC值,评估模型区分能力。 |
| ggplot2 | 创建高质量可视化图形,如变量重要性图。 |
| GGally | 生成变量间关系矩阵图(ggpairs),用于探索性数据分析。 |
| DALEX | 进行模型解释,通过排列重要性方法计算变量贡献度。 |
| officer 和 flextable | 生成和格式化Word报告,插入文本、表格和图片。 |
| showtext | 设置中文字体支持,确保图表中的中文标签正确渲染。 |
该代码适用于需要处理非线性分类问题的场景,例如在医学研究中预测疾病结局(如基于指标1-6等变量)、金融领域评估客户信用风险,或社会科学中分析影响因素。
自动化流程提高了分析的可重复性和效率,适合快速生成学术论文、商业分析报告或教学演示材料,提供直观的模型解释和可视化输出。
通过SVM模型处理高维数据和非线性关系,代码有助于构建稳健的预测工具,为决策制定或后续研究提供基础。
医学统计数据分析分享交流SPSS、R语言、Python、ArcGis、Geoda、GraphPad、数据分析图表制作等心得。承接数据分析,论文返修,医学统计,机器学习,生存分析,空间分析,问卷分析业务。若有投稿和数据分析代做需求,可以直接联系我,谢谢!
“医学统计数据分析”公众号右下角;
找到“联系作者”,
可加我微信,邀请入粉丝群!
有临床流行病学数据分析
如(t检验、方差分析、χ2检验、logistic回归)、
(重复测量方差分析与配对T检验、ROC曲线)、
(非参数检验、生存分析、样本含量估计)、
(筛检试验:灵敏度、特异度、约登指数等计算)、
(绘制柱状图、散点图、小提琴图、列线图等)、
机器学习、深度学习、生存分析
等需求的同仁们,加入【临床】粉丝群。
疾控,公卫岗位的同仁,可以加一下【公卫】粉丝群,分享生态学研究、空间分析、时间序列、监测数据分析、时空面板技巧等工作科研自动化内容。
有实验室数据分析需求的同仁们,可以加入【生信】粉丝群,交流NCBI(基因序列)、UniProt(蛋白质)、KEGG(通路)、GEO(公共数据集)等公共数据库、基因组学转录组学蛋白组学代谢组学表型组学等数据分析和可视化内容。
或者可扫码直接加微信进群!!!
精品视频课程-“医学统计数据分析”视频号付费合集
在“医学统计数据分析”视频号-付费合集兑换相应课程后,获取课程理论课PPT、代码、基础数据等相关资料,请大家在【医学统计数据分析】公众号右下角,找到“联系作者”,加我微信后打包发送。感谢您的支持!!
【二分类因变量机器学习】图文教程
往期推荐:【监测预警自动化】系列教程
往期推荐:样本含量估计(样本量计算与功效分析)
往期推荐:SPSS、R语言、Python等临床数据分析专题
往期推荐:科研图表绘制专题
往期推荐:重复测量数据分析专题
往期推荐:生信分析、基因测序数据、实验室数据专题
往期推荐:生存分析及机器学习
往期推荐:时间序列分析
往期推荐:地统计分析-GIS、地图、相关、聚类、回归
往期推荐:科研自动化探究
往期推荐:趣味阅读
统计评书系列

