机器学习是人工智能的一个重要分支,近年来在数据分析、图像识别、自然语言处理等领域发挥的作用越来越重要。机器学习的基本概念围绕着如何让计算机利用数据来进行学习和预测。而R语言,作为一种统计分析和图形表示的强大工具,因其丰富的包和灵活的数据处理能力,在机器学习领域中占有一席之地。今天我们开始R语言机器学习的第一篇,数据准备与包的批量安装。
机器学习是一门研究如何使计算机系统从数据中学习和改进性能的学科。它通过训练模型来识别模式、预测趋势和做出决策从而实现对数据的自动处理和分析。
机器学习算法通过对大量数据进行学习,提取出有用的特征并建立模型来预测新数据。这些模型可以不断优化,以适应不同类型的数据和任务。常见的机器学习算法包括KNN、决策树、随机森林、贝叶斯等。
我们先打开Rstudio,对于单个包的安装与加载想必大家都已经很熟悉:
rm(list=ls()) #移除所有变量数据
install.packages() #安装包
library() #加载包
然后读取和写入Excel的包需要用到readxl和writexl:
#读取Excel数据
install.packages("readxl")
library(readxl) #加载包
data <- read_excel("路径/示例数据.xlsx")
#写入Excel数据导出
install.packages("writexl")
library(writexl) #加载包
write_xlsx(data.all, "路径/总表.xlsx")
我们今天用到的示例数据是一个1000个个案的
数据库,我们用readxl读取进Rstudio进行处理。
我们可以
#定义要加载机器学习所需要的包列表,检查每个包是否已经安装,如果没有安装,则进行安装并加载
packages<-c("readxl","ggplot2","caret","lattice","gmodels",
"glmnet","Matrix","pROC","Hmisc","rms",
"tidyverse","Boruta","car","carData",
"rmda","dplyr","rpart","rattle","tibble","bitops",
"probably","tidymodels","fastshap",
"shapviz","e1071")
for(pkg in packages) {
if (!require(pkg, quietly = TRUE)) {
install.packages(pkg, dependencies = TRUE)
library(pkg, character.only = TRUE)
}
}
# 使用library()函数一次性加载多个包
lapply(packages,library,character.only = TRUE)
或者可以
#直接定义并批量安装包
packages<-c("readxl","ggplot2","caret",
"lattice","gmodels","glmnet","Matrix","pROC",
"Hmisc","rms","tidyverse","Boruta","car",
"carData","rmda","dplyr","rpart","rattle","tibble",
"bitops","probably","tidymodels","fastshap",
"shapviz","e1071")
install.packages(c("readxl","ggplot2","caret",
"lattice","gmodels","glmnet","Matrix","pROC",
"Hmisc","rms","tidyverse","Boruta","car","carData",
"rmda","dplyr","rpart","rattle","tibble","bitops", "probably","tidymodels","fastshap",
"shapviz","e1071"))
install.packages(packages)
# 使用library()函数一次性加载多个包
lapply(packages,library,character.only = TRUE)
进一步我们可以进行简单分析:
#独立样本t检验
t.test(data$指标1 ~ 结局, data = data, var.equal = TRUE)
t.test(data$指标2 ~ 结局, data = data, var.equal = TRUE)
t.test(data$指标3 ~ 结局, data = data, var.equal = TRUE)
#卡方检验
CrossTable(data$结局,data$指标8,expected = T,chisq = T,fisher = T, mcnemar = T, format = "SPSS")
#logistic回归
data$Group<-as.factor(data$结局)
model1 <- glm(Group ~ 指标1, data = data, family = "binomial")
summary(model1)
model2 <- glm(Group ~ 指标1+指标2, data = data, family = "binomial")
summary(model2)
model3 <- glm(Group ~ 指标1+指标2+指标3, data = data, family = "binomial")
summary(model3)
#ROC曲线
roc1 <- roc(data$结局,data$指标1);roc1
roc2 <- roc(data$结局,data$指标2);roc2
roc3 <- roc(data$结局,data$指标3);roc3
plot(roc1,
max.auc.polygon=FALSE, # 填充整个图像
smooth=F, # 绘制不平滑曲线
main="Comparison of ROC curves", # 添加标题
col="red", # 曲线颜色
legacy.axes=TRUE) # 使横轴从0到1,表示为1-特异度
plot.roc(roc2,
add=T, # 增加曲线
col="orange", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
plot.roc(roc3,
add=T, # 增加曲线
col="yellow", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
#列线图
dd<-datadist(data)
options(datadist="dd")
data$Group<-as.factor(data$结局)
f_lrm<-lrm(Group~指标1+指标2+指标3+指标4+指标5+指标6+指标7+指标8,data=data)
summary(f_lrm)
par(mgp=c(1.6,0.6,0),mar=c(5,5,3,1))
nomogram <- nomogram(f_lrm,fun=function(x)1/(1+exp(-x)),
fun.at=c(0.01,0.05,0.2,0.5,0.8,0.95,1),
funlabel ="Prob of 结局",
conf.int = F,
abbrev = F )
plot(nomogram)
训练集和测试集是深度学习技术中经常使用的一种数据划分方式。它可以将数据自动划分为训练集和测试集,用于模型开发的评估。
训练集是为训练模型而准备的一组数据,它通常是人类标记过的,表明它们拥有特定方面的属性。通常情况下,为了训练有效的模型,训练集的采样大小最好是足够大的,而且应该有足够的多样性,可以代表它们的数据集中的所有可能的情况
测试集是一组样本,用于测试训练好的模型,通过测试集检验训练好的模型,从而测试模型的正确率和准确性。它本质上是一组未知的数据样本,用于测试模型性能的时候,而不受训练集采样的偏向,可以更可靠的评估模型的性能。
那么怎么划分测试集与训练集呢?
#分层抽样划分训练集和测试集
set.seed(123)
train <- sample(1:nrow(data),nrow(data)*7/10) #取70%做训练集、其余30%为测试集
#数据读取拆分与组合
Train <- data[train,] #定义训练集数据
Test <- data[-train,] #定义测试集数据
All <- rbind(Train, Test) #将拆分数据合并
#写入Excel数据导出
install.packages("writexl")
library(writexl) #加载包
write_xlsx(Train, "C:/Users/L/Desktop/Train.xlsx")
write_xlsx(Test, "C:/Users/L/Desktop/Test.xlsx")
write_xlsx(All, "C:/Users/L/Desktop/All.xlsx")
Lasso回归(Least Absolute Shrinkage and Selection Operator Regression)是一种线性回归模型,通过引入L1正则化(即Lasso惩罚项),对模型中的系数进行压缩,使某些系数缩减至零,从而实现特征选择和模型稀疏性。Lasso回归由Robert Tibshirani提出,主要用于处理变量过多而样本量较少的情况,能够有效防止过拟合并解决多重共线性问题。
Lasso回归的基本原理
Lasso回归通过在目标函数中添加一项L1正则化项,即变量系数的绝对值之和,来压缩模型。这使得一些系数变为零,从而实现特征选择和模型稀疏性。具体来说,Lasso回归的优化目标函数如下:
[ \min_{\beta} \left( \sum_{i=1}^n (y_i - x_i^T \beta)^2 + \alpha \sum_{j=1}^p |\beta_j| \right) ]
其中,( n ) 是样本数量,( p ) 是特征数量,( y_i ) 是实际观测值,( x_i^T \beta ) 是预测值,( \beta ) 是模型参数(系数),( \alpha ) 是L1正则化项的权重。
Lasso回归的应用场景和优缺点
应用场景:
一、特征选择:Lasso回归可以用于选择最重要的特征,通过将不重要的特征系数缩减为零,简化模型并提高模型的泛化能力。
二、多重共线性问题:在存在多重共线性的情况下,Lasso回归可以通过将相关变量的系数变为零来降低其对回归结果的影响。
三、预测建模:在医学研究中,Lasso回归可以选择最相关的指标和变量,建立高效的预测模型。
Lasso回归的优点:
1.特征选择:能够有效进行变量选择,特别是在预测变量数量远大于样本量的情况下。
2.防止过拟合:通过压缩系数,避免模型过于复杂,提高模型的泛化能力。
Lasso回归的缺点:
1.计算复杂度较高:由于L1正则化的非光滑性,优化过程较为复杂,计算成本较高。
2.稳定性问题:由于某些系数可能完全为零,模型的稳定性可能受到影响。
岭回归(Ridge Regression)是一种用于处理多重共线性的有偏估计回归方法,它通过在普通最小二乘法的基础上加入L2正则化项来解决多重共线性问题,从而提高模型的泛化能力和鲁棒性。
基本概念和原理
岭回归通过在最小二乘损失函数中加入L2范数的惩罚项,即模型参数的平方和乘以一个称为岭参数的λ值。这个惩罚项确保了模型参数不会变得过大,从而减少过拟合的风险,提高模型的稳定性和泛化能力。岭回归的损失函数包括两部分:一部分是残差平方和,另一部分是模型参数平方和乘以λ值。
应用场景
岭回归特别适用于那些特征之间高度相关(即多重共线性问题)的数据集。在这种情况下,普通的线性回归模型可能会变得不稳定,并且模型的系数可能会变得非常大。岭回归通过惩罚模型参数,使其保持较小的值,从而使得模型更加稳健。
岭回归的优点:
1.处理多重共线性:岭回归能够有效处理特征之间的强相关性,避免参数估计的不稳定。
2.减少过拟合:通过惩罚大参数,岭回归能够提高模型的泛化能力,减少过拟合的风险。
3.计算简单:岭回归的实现相对简单,不需要复杂的计算过程。
岭回归的缺点:
1.有偏估计:岭回归通过牺牲无偏性来获得更稳定的估计,可能会导致模型预测的偏差。
2.参数选择:选择合适的λ值是一个挑战,不同的λ值会影响模型的性能。
岭回归的实际应用案例
在实际应用中,岭回归常用于生物信息学、金融数据分析等领域,特别是在处理具有高度相关特征的数据时表现出色。例如,在基因表达数据分析中,基因之间的相关性可能导致普通线性回归模型不稳定,此时岭回归可以提供更稳定的参数估计。
今天我们仍以熟悉的示例数据集为例,演示一下R语言glmnet包分别拟合二分类logistic模型的lasso回归和岭回归的简单示例。
我们先整理一下Rstudio的环境并加载数据
rm(list=ls()) #移除所有变量数据
install.packages("") #安装包
library() #加载包
#1.数据及包准备
#读取Excel数据
library(readxl) #加载包
data <- read_excel("C:/Users/hyy/Desktop/示例数据.xlsx")
data
#2.Lasso回归,加载所需的包
library(glmnet)
library(Matrix)
#设置自变量与因变量
lambdas <- seq(0,5, length.out = 1000)
X <- as.matrix(data[,3:9]) #指标1至7
Y <- as.matrix(data[,2]) #结局
set.seed(12345)
lassofit <- glmnet(X, Y, family = "binomial",alpha = 1)
plot(lassofit,label = T)
plot(lassofit, xvar = "lambda", label = TRUE)
plot(lassofit, xvar = "dev", label = TRUE)
print(lassofit)
#交叉验证
set.seed(12345)
lasso_model <- cv.glmnet(X,Y,alpha = 1,lambda = lambdas,nfolds =3)
plot(lasso_model)
plot(lasso_model$glmnet.fit, "lambda", label = T)
#查看具体筛选的变量系数值和Lambda值(lambda.min处)
coef<-coef(lasso_model,s="lambda.min")
coef
#查出lambda.min处的Lambda值
Lambda<-lasso_model$lambda.min
Lambda
#lambda.min处保留的变量的个数,也就是系数不为0
bl.index<-which(coef!=0)
bl.index
#lambda.min处保留的各变量的系数
bl.coef<-coef[bl.index]
bl.coef
#列出lambda.min处保留的各变量的变量名
rownames(coef)[bl.index]
#岭回归
set.seed(12345)
ridgefit <- glmnet(X, Y, family = "binomial",alpha = 0)
plot(ridgefit,label = T)
plot(ridgefit, xvar = "lambda", label = TRUE)
plot(ridgefit, xvar = "dev", label = TRUE)
print(ridgefit)
#交叉验证
set.seed(12345)
ridge_model <- cv.glmnet(X,Y,alpha = 0,lambda = lambdas,nfolds =3)
plot(ridge_model)
plot(ridge_model$glmnet.fit, "lambda", label = T)
#查看具体筛选的变量系数值和Lambda值(lambda.min处)
coefridge<-coef(ridge_model,s="lambda.min")
coefridge
#查出lambda.min处的Lambda值
Lambdaridge<-ridge_model$lambda.min
Lambdaridge
#lambda.min处保留的变量的个数,也就是系数不为0
ridge.index<-which(coefridge!=0)
ridge.index
#lambda.min处保留的各变量的系数
ridge.coef<-coef[ridge.index]
ridge.coef
#列出lambda.min处保留的各变量的变量名
rownames(coef)[ridge.index]
Lasso回归和岭回归(Ridge Regression)的主要区别在于正则化项的形式和应用场景。
一、正则化项的区别
Lasso回归采用L1正则化,即在损失函数中加入权重的绝对值之和作为惩罚项。其损失函数可以表示为:
[
J(\theta) = \frac{1}{2n} \sum_{i=1}^{n} (y_i - x_i^T \theta)^2 + \alpha |\theta|
]
其中,∥θ∥1是θ的L1范数,即θ中各元素的绝对值之和。L1正则化会导致一些权重严格为0,从而实现特征选择。
岭回归采用L2正则化,即在损失函数中加入权重的平方和作为惩罚项。其损失函数可以表示为:
[
J(\theta) = \frac{1}{2n} \sum_{i=1}^{n} (y_i - x_i^T \theta)^2 + \alpha |\theta|^2
]
其中,∥θ∥2是θ的L2范数,即θ中各元素的平方和。L2正则化会使所有权重趋近于0,但不会严格为0,这有助于处理多重共线性问题。
二、应用场景的区别
Lasso回归通过将一些权重压缩为0来实现特征选择,适合于特征之间有关联的情况,能够有效剔除无关特征,适用于特征选择和变量压缩。
在上一期的分享中,我们演示了
R语言glmnet包分别拟合二分类logistic模型的lasso回归和岭回归的简单示例,今天我们继续分享生存分析中glmnet包拟合cox比例风险回归模型的lasso回归和岭回归的简单操作。
常规数据在表示时,只需要一个值,比如患者的血压,性别等数据,不是连续型就是离散型;生存数据则有两个值,第一个是生存时间,可以看做是一个连续型的变量,第二个是生存事件,可以看做是离散型的变量。
生存分析是研究生存时间的分布规律,以及生存时间和相关因素之间关系的一种统计分析方法。在生存分析中,研究的主要对象是寿命超过某一时间的概率。还可以描述其他一些事情发生的概率,例如产品的失效、出狱犯人第一次犯罪、失业人员第一次找到工作等等。
Cox模型,也称为Cox回归模型或比例风险模型(Proportional Hazards Model),是由英国统计学家David Cox于1972年提出的一种半参数回归模型。该模型主要用于生存分析,能够同时分析多个风险因素对生存时间的影响,适用于医学随访研究和其他需要分析生存数据的领域。
Cox模型在医学研究中有广泛的应用,主要用于以下几个方面:
生存分析:研究患者的生存时间及其相关因素。
风险因素分析:确定与特定事件(如死亡、疾病复发)相关的风险因素。
生存率比较:比较不同组群之间的生存率。
预后评估:评估影响患者预后的因素,为治疗决策提供依据。
调整分析:调整其他变量的影响,更准确地评估特定因素对生存时间的影响。
今天我们仍以熟悉的示例数据集为例,演示一下R语言glmnet包分别拟合cox比例风险回归模型的lasso回归和岭回归的简单示例。
我们先整理一下Rstudio的环境并加载数据及常用包
rm(list=ls()) #移除所有变量数据
install.packages("") #安装包
library() #加载包
#1.数据及包准备
#读取Excel数据
library(readxl) #加载包
data <- read_excel("C:/Users/hyy/Desktop/示例数据.xlsx")
data
library(glmnet)
library(Matrix)
library(survival)
library(survminer)
library(ggplot2)
library(ggpubr)
library(Hmisc)
#Lasso回归前的生存分析
#根据变量在表中定位设置自变量、因变量、时间变量
lambdas <- seq(0,5, length.out = 1000)
X <- as.matrix(data[,3:9])
Y <- as.matrix(data[,2])
Time <- as.matrix(data[,10])
fit_sur <- Surv(Time,Y)
fit_sur
plot(fit_sur)
#根据分类指标分别绘制生存曲线
fit_sur2 <- survfit(Surv(Time,Y)~指标8, data=data)
fit_sur2
plot(fit_sur2)
ggsurvplot(fit_sur2, data = data)
#累积风险曲线
ggsurvplot(fit_sur2,
data = data,
fun = "cumhaz",
conf.int = TRUE, # 可信区间
palette = "lancet", # 支持ggsci配色,自定义颜色,brewer palettes中的配色,等
ggtheme = theme_bw() # 支持ggplot2及其扩展包的主题
)
#累积事件曲线:
ggsurvplot(fit_sur2,
data = data,
fun = "event",
conf.int = TRUE, # 可信区间
palette = "grey",
ggtheme = theme_pubclean()
)
#或者根据变量名设置自变量、因变量、时间变量,拟合cox模型
data$status <- as.matrix(data$结局)
survfit <- coxph(Surv(时间,status)~指标1+指标2+指标3+指标4+指标5+指标6+指标7,data=data)
summary(survfit)
## 绘制Schoenfeld残差图
p <- cox.zph(survfit)
p$table
p$residuals$schoenfeld %>% ggplot(aes(p$time,p$x)) +
geom_line() +
labs(title = "Schoenfeld Residuals Over Time")
#或者使用数据集合进行拟合cox模型开始进行Lasso回归
data$status <- as.numeric(data$结局)
x<-as.matrix(X)#指定自变量为矩阵
y<-as.matrix(Surv(data$时间,data$status))#指定因变量为矩阵
set.seed(12345)
coxfit<-glmnet(x,y,family = "cox",alpha = 1)
plot(coxfit,label = T)
plot(coxfit, xvar = "lambda", label = TRUE)
plot(coxfit, xvar = "dev", label = TRUE)
print(coxfit)
#交叉验证
set.seed(12345)
lscoxmodel <- cv.glmnet(x,y, family = "cox",alpha = 1)
plot(lscoxmodel)
plot(lscoxmodel$glmnet.fit, "lambda", label = T)
#查看具体筛选的变量系数值和Lambda值(lambda.min处)
coef<-coef(lscoxmodel,s="lambda.min")
coef
#查出lambda.min处的Lambda值
Lambda<-lscoxmodel$lambda.min
Lambda
#lambda.min处保留的变量的个数,也就是系数不为0
bl.index<-which(coef!=0)
bl.index
#lambda.min处保留的各变量的系数
bl.coef<-coef[bl.index]
bl.coef
#列出lambda.min处保留的各变量的变量名
rownames(coef)[bl.index]
#岭回归
set.seed(12345)
ridgecox <- glmnet(x, y, family = "cox",alpha = 0)
plot(ridgecox,label = T)
plot(ridgecox, xvar = "lambda", label = TRUE)
plot(ridgecox, xvar = "dev", label = TRUE)
#交叉验证
set.seed(12345)
rgcox_model <- cv.glmnet(x, y, family = "cox",alpha = 0,lambda = lambdas,nfolds =3)
plot(rgcox_model)
plot(rgcox_model$glmnet.fit, "lambda", label = T)
#查看具体筛选的变量系数值和Lambda值(lambda.min处)
coefridge<-coef(rgcox_model,s="lambda.min")
coefridge
#查出lambda.min处的Lambda值
Lambdaridge<-rgcox_model$lambda.min
Lambdaridge
#lambda.min处保留的变量的个数,也就是系数不为0
ridge.index<-which(coefridge!=0)
ridge.index
#lambda.min处保留的各变量的系数
ridge.coef<-coef[ridge.index]
ridge.coef
#列出lambda.min处保留的各变量的变量名
rownames(coef)[ridge.index]
logistic回归又称logistic回归分析,是一种广义的线性回归分析模型,常用于数据挖掘,疾病自动诊断,经济预测等领域。 逻辑回归根据给定的自变量数据集来估计事件的发生概率,由于结果是一个概率,因此因变量的范围在 0 和 1 之间。
例如,探讨引发疾病的危险因素,并根据危险因素预测疾病发生的概率等。以胃癌病情分析为例,选择两组人群,一组是胃癌组,一组是非胃癌组,两组人群必定具有不同的体征与生活方式等。因此因变量就为是否胃癌,值为“是”或“否”,自变量就可以包括很多了,如年龄、性别、饮食习惯、幽门螺杆菌感染等。
自变量既可以是连续的,也可以是分类的。然后通过logistic回归分析,可以得到自变量的权重,从而可以大致了解到底哪些因素是胃癌的危险因素。同时根据该权值可以根据危险因素预测一个人患癌症的可能性。
今天我们仍以熟悉的“示例数据”集来演示一下三种常用的logistic回归模型拟合方法及相关可视化实现,分别为:stats包的glm()函数、rms包的lrm()函数、caret包的train()函数。我们打开示例数据。
#1.数据及包准备
#读取Excel数据
install.packages("readxl")
library(readxl) #加载包
data <- read_excel("C:/Users/hyy/Desktop/示例数据.xlsx")
#加载数据包并读取数据
library(ggplot2) #绘图用包
library(caret) #分层抽样拆分数据库
library(lattice) #绘图可视化包
library(gmodels) #卡方检验包
library(glmnet) #回归分析用包
library(Matrix) #矩阵运算用包
library(pROC) #ROC曲线用包
library(Hmisc) #列线图用包
#1.stats包的glm()函数
#1. 什么是R语言stats包?
#R语言stats包是R语言的一个核心包,几乎每个R用户都会使用它。
#它包含了丰富的统计分析函数,用于执行各种统计分析和数据处理任务。
#stats包是R语言中的一个基础包,它提供了一系列的函数和数据结构用于统计分析。
#这个包中的函数和数据类型对于R语言的学习者来说非常重要。
#2. R语言stats包提供的主要功能或函数
#stats包提供了多种统计分析功能,包括但不限于:
#线性回归:lm() 函数用于拟合线性模型。
#假设检验:t.test()、chisq.test()、anova() 等函数用于执行各种假设检验。
#方差分析(ANOVA):aov() 函数用于方差分析。
#分布函数:提供了多种概率分布的函数,
#如正态分布 (dnorm(), pnorm(), qnorm(), rnorm())、
#二项分布 (dbinom(), pbinom(), qbinom(), rbinom())、
#泊松分布 (dpois(), ppois(), qpois(), rpois()) 等。
#时间序列分析:acf()、pacf()、arima() 等函数用于时间序列分析。
#聚类分析:kmeans()、hclust() 等函数用于聚类分析。
#3. 如何安装和加载R语言stats包
#stats包是R的内置包,通常不需要单独安装。
#当你安装R时,stats包已经包含在内。你可以通过以下代码加载stats包(通常默认情况下会自动加载)
#4.在R语言中,glm()函数用于拟合广义线性模型(Generalized Linear Models,GLM)
#R语言中的glm()函数是一个强大的工具,
#用于拟合广义线性模型(Generalized Linear Models, GLM)。
#与普通的线性模型相比,GLM能够处理响应变量不是连续的情况,例如二项分布、泊松分布等,
#这使得它在统计分析中非常受欢迎,特别是对于非标准数据的建模和预测
library(stats)#通常默认情况下会自动加载
#使用stats包的glm()函数拟合logistic回归过程
logit.model <- glm(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,
data=data, family=binomial(link="logit"))
logit.model
summary(logit.model)
#选择输出效应值、置信区间及P值
logit.result <- as.data.frame(summary(logit.model)$coefficients[, c(1, 4)])
logit.result <- cbind(logit.result, confint(logit.model))
colnames(logit.result) <- c("Coef", "p", "CI_lower", "CI_upper")
logit.result
#多用来绘制ROC曲线
logit.pred.prob <- predict(logit.model, newdata=data, type="response")
par(las=1, cex.axis=.8)
logit.roc <- roc(
y ~ pred,
data=data.frame(y=data$结局, pred=logit.pred.prob),
plot=T, ci=T, main="ROC Curve of Logistic Regression",
print.auc=T, print.auc.cex=.8,
print.thres=T, print.thres.cex=.8,
auc.polygon=T, max.auc.polygon=T, grid=T)
#2.rms包的lrm()函数
#rms包是一个用于回归模型分析的R语言扩展包,提供了多种工具和函数,
#rms包(Regression Modeling Strategies)是一个用于建立和评估预测模型的R语言包,
#主要用于回归模型的拟合、分析和诊断。其主要功能包括:
#回归模型的拟合和分析:
#提供ols函数用于拟合普通最小二乘回归模型,
#lrm函数用于拟合逻辑回归模型,
#coxph函数用于拟合Cox比例风险模型等。
#模型选择和比较:
#通过不同的模型拟合方法,帮助用户选择最适合数据的模型。
#模型的可视化和解释:
#提供多种可视化工具,帮助用户更好地理解和解释模型结果。
library(rms)
dd<-datadist(data); options(datadist='ddist')
f_lrm <- lrm(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,
data=data,
x=TRUE, y=TRUE)
f_lrm
summary(f_lrm)
#绘制简单列线图
par(family="Prob of 结局")
plot(nomogram(f_lrm))
#或优化绘制列线图
par(mgp=c(1.6,0.6,0),mar=c(5,5,3,1))
nomogram <- nomogram(f_lrm,fun=function(x)1/(1+exp(-x)), fun.at=c(0.01,0.05,0.2,0.5,0.9,0.99),
funlabel ="Prob of 结局",
conf.int = F,
abbrev = F )
plot(nomogram)
#绘制校准曲线
cal1<-calibrate(f_lrm,method="boot", B=1000)
plot(cal1)
# 在图表的底部插入文本
mtext("C=0.965 LR.chi2=920.78 d.f.=6 Pr(> chi2) <0.0001", side=1, line=3)
# 计算C统计量及置信度
library(Hmisc)
Cindex <- rcorrcens(data$结局~f_lrm[["linear.predictors"]])
Cindex
se<-0.028/2
ul<-0.901+1.96*se
dl<-0.901-1.96*se
CI<-c(ul,dl)
# 输出C统计量及其置信度
print(Cindex)
print(CI)
#c指数等价于ROC曲线下面积,计算AUC及CI
library(pROC)
modelROC<-roc(data$结局,f_lrm[["linear.predictors"]])
auc(modelROC)
ci(auc(modelROC))
#3.使用caret包的train()函数进行logistic回归
#caret包(Classification And REgression Training)是一个在R语言中广泛使用的包,
#主要用于简化机器学习的工作流程。
#该包提供了统一的接口,整合了多种机器学习算法,
#并支持数据预处理、特征选择、模型训练和评估等功能。
#caret包因其功能丰富、易于使用而备受推崇,
#特别适合数据科学家和研究人员进行高效的机器学习任务。
#caret包的主要功能
#数据预处理:caret包提供了多种数据预处理方法,
#包括处理缺失值、异常值和离群点,
#以及进行特征选择和降维技术,
#帮助从原始数据中提取最相关和最有信息量的特征。
#特征选择:caret支持多种特征选择方法,
#如过滤法、包装法和嵌入法,帮助从大量特征中选择对模型有用的特征,
#提高模型的准确性和效率。
#模型训练和评估:caret支持多种机器学习算法,
#如线性回归、逻辑回归、决策树、随机森林、支持向量机等。
#它通过交叉验证、网格搜索等技术进行模型参数调优,
#并提供模型评估和比较的工具,如混淆矩阵、ROC曲线等。
#模型集成:caret支持模型集成方法,
#如投票法、堆叠法和混合法,以提高模型的泛化能力和鲁棒性。
#模型解释和可视化:caret提供方法和函数帮助解释和可视化模型结果,
#如绘制学习曲线、特征重要性图等。
#caret包在模型与参数优化上面的应用,主要函数就是train函数
#train()函数作为接口,可以选择评估方法和度量性指标,自动寻找最优的参数。
#主要考虑的问题:
#(1)训练哪种模型法,
#(2)模型中哪些参数可以调整,可以调整的空间多大,
#(3)选择评价的标资
caret包可实现的主要功能如下:
library(caret)
names(getModelInfo())
control <- trainControl(method="cv", number=10)
lg.model <- train(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,
data=data, method="glm",
family="binomial",
trControl=control)
lg.model
summary(lg.model)
# 基于训练集进行预测
predictions <- predict(model, newdata = data)
predictions
#绘制ROC曲线
par(las=1, cex.axis=.8)
logit.roc <- roc(
y ~ pred,
data=data.frame(y=data$结局, pred=predictions),
plot=T, ci=T, main="ROC Curve of Logistic Regression",
print.auc=T, print.auc.cex=.8,
print.thres=T, print.thres.cex=.8,
auc.polygon=T, max.auc.polygon=T, grid=T)
#根据最佳预测值对预测概率量化为预测结果
lg.pred <- ifelse(predictions>0.525,1,0)
lg.pred
# 可视化混淆矩阵
cm <- confusionMatrix(as.factor(lg.pred),
as.factor(data$结局))
cm
plot(cm$table,main="")
title(main = "Logistic Regression Confusion Matrix")
# 使用heatmap函数创建热图,并自定义颜色
plotcm <- matrix(c(464, 53, 36, 447), nrow=2)
heatmap(plotcm, col=colorRampPalette(c("blue", "white", "red"))(100),
Rowv=NA, Colv=NA,
main="Confusion Matrix Heatmap",
xlab="Predicted Class",
ylab="True Class",
dendrogram="none")
今天,我们继续分享两种传统(或者说成熟)的机器学习方法:朴素贝叶斯(Naive Bayes)及K最近邻(KNN)的操作及拟合效果的两两比较。
朴素贝叶斯模型(Naive Bayes Model, NBM)是一种基于贝叶斯定理和特征条件独立性假设的分类算法。其核心思想是通过给定特征X的条件下,预测样本属于某类别c的后验概率P(c|X),选择后验概率最大的类别作为分类结果。
基本原理
朴素贝叶斯模型的基本原理基于贝叶斯定理,公式如下:
[ P(c|X) = \frac{P(X|c)P(c)}{P(X)} ]
其中:
( P(c|X) )表示在给定样本特征X的条件下,样本属于类别c的后验概率。
( P(X|c) )表示在类别c已知的情况下,样本特征X出现的概率。
( P(c) )表示类别c本身的概率。
( P(X) )表示样本特征X出现的总概率,通常用于归一化。
特征条件独立性假设
朴素贝叶斯模型的关键假设是特征之间在给定类别的情况下是相互独立的。这一假设极大地简化了计算,使得似然( P(X|c) )可以分解为各个特征的条件概率的乘积:
[ P(X|c) = \prod_{j=1}^n P(X^{(j)}|c) ]
这一假设虽然在实际中往往不完全成立,但在许多任务中仍然表现良好。
应用场景和优缺点
朴素贝叶斯模型在许多领域有广泛的应用,如文本分类、垃圾邮件识别等。其优点包括实现简单、计算效率高、所需估计的参数少;缺点是假设特征之间完全独立,这在现实中很少见,可能导致分类效果不佳。
K最近邻(KNN)模型是一种简单且有效的机器学习算法,主要用于分类和回归任务。KNN的基本思想是:一个样本的类别或数值取决于其最邻近的k个邻居的类别或数值。具体来说,KNN通过计算待分类点与训练数据集中所有点的距离,选择距离最近的k个点作为邻居,然后根据这些邻居的类别或数值来预测该点的类别或数值。
KNN模型的工作原理
KNN算法的工作流程如下:
距离度量:KNN使用距离度量(如欧几里得距离、曼哈顿距离等)来确定数据点之间的相似性。最常见的距离度量是欧几里得距离。
选择K值:K是一个超参数,表示在进行决策时考虑的最近邻居的数量。K的选择对模型的性能有很大影响,一般通过网格搜索等方法来确定最佳的K值。
决策:对于分类任务,KNN算法通过多数投票法来预测新样本的类别;对于回归任务,则计算K个最近邻居的目标值的平均值作为新样本的目标值。
KNN模型的优缺点
优点:
简单易懂:KNN算法概念简单,容易理解和实现。
无需训练阶段:KNN没有显式的训练阶段,只需存储训练数据集,因此在数据集规模和特征数量相同的条件下,建模训练速度较快。
适用于小数据集:对于小数据集,KNN通常表现良好。
缺点:
计算量大:对于大规模数据集,计算每个测试样本与训练集中所有样本的距离非常耗时。
内存消耗大:需要存储所有训练数据以进行距离计算。
对异常值敏感:近邻的选择对异常值非常敏感,可能导致模型不稳定。
应用场景和实际案例
KNN算法在实际应用中有广泛的应用,例如:
文本分类:用于将文本数据分类到不同的类别中。
图像识别:通过比较图像特征来识别图像内容。
推荐系统:根据用户的购买或浏览历史推荐相关商品或内容。
今天我们仍以熟悉的示例数据集为例,演示一下朴素贝叶斯(Naive Bayes)及K最近邻(KNN)的操作及拟合效果的两两比较。
#数据准备,划分训练集测试集并保存
#分层抽样划分训练集和测试集
set.seed(1234)
train <- sample(1:nrow(data),nrow(data)*8/10) #取80%做训练集
#数据读取拆分与组合
Train <- data[train,]
Test <- data[-train,]
All <- rbind(Train, Test)
#朴素贝叶斯(Naive Bayes)模型
# 加载必要的库
#使用klaR包中的NaiveBayes函数拟合朴素贝叶斯(Naive Bayes)模型
#安装加载包
install.packages("klaR")
library(klaR)
library(MASS)
library(e1071)
#因变量因子化与模型拟合
Train$Group<-as.factor(Train$结局)
Test$Group<-as.factor(Test$结局)
nb.fit<-NaiveBayes(Group ~ 指标1+指标2+指标3+指标4+指标5+指标6,
data =Train)
nb.fit
summary(nb.fit)
par(mfrow = c(2, 3)) #6个变量一起看
plot(nb.fit)
#预测测试集数据
nb.pred<-predict(nb.fit,newdata =Test)
nb.pred
nb.pred$class
#构建混淆矩阵
nb.freq<-table(nb.pred$class, Test$结局)
nb.freq
#模型的准确率
nb.accuracy<-sum(diag(nb.freq))/sum(nb.freq)
nb.accuracy
#模型的AUC值
nb.modelroc<-roc(as.integer(Test$结局),
as.integer(nb.pred$class))
#绘制朴素贝叶斯(Naive Bayes)模型ROC曲线
par(mfrow = c(1, 1))
plot(nb.modelroc,print.auc=TRUE,auc.polygon = TRUE,
grid =c(0.1,0.2),grid.col=c('green','red'),
max.auc.polygon =TRUE,auc.polygon.col='steelblue')
#.K最近邻(KNN)模型
#数据整理
install.packages("dplyr")
library(dplyr)
library(caret)
library(stringr)
Trainknn <- Train[,c("指标1", "指标2", "指标3","指标4","指标5","指标6")]
Testknn <- Test[,c("指标1", "指标2", "指标3","指标4","指标5","指标6")]
#变量处理标准化
Trainknn <- preProcess(Trainknn ,method = "scale") %>% predict(.,Trainknn )
Testknn <- preProcess(Testknn ,method = "scale") %>% predict(.,Testknn )
#使用class包拟合K-近邻(KNN)算法
library(class)
library(pROC)
knnmodel <- knn(train = Trainknn, test = Testknn, cl = Train$结局, k = 49)
knnmodel
#根据最佳预测值对预测概率量化为预测结果
knn.pred <- as.numeric(knnmodel)
knn.pred
knn.pred <- ifelse(knn.pred == 1, 0, 1)
knn.pred
#计算模型的AUC值(ROC曲线下面积)并绘制ROC曲线
auc <- auc(as.numeric(Test$结局),as.numeric(knnmodel))
auc
#ROC绘图
knn.modelroc<-roc(as.integer(Test$结局),
as.integer(knnmodel))
plot(knn.modelroc,print.auc=TRUE,auc.polygon = TRUE,
grid =c(0.1,0.2),grid.col=c('green','red'),
max.auc.polygon =TRUE,auc.polygon.col='steelblue')
# 计算准确率
mean(knnmodel == Test$CRBSI)
#组合绘制ROC曲线
roc01 <- roc(Test$结局,as.numeric(nb.pred$class));roc01
roc02 <- roc(Test$结局,as.numeric(knnmodel));roc02
plot(roc01,
max.auc.polygon=FALSE, # 填充整个图像
smooth=F, # 绘制不平滑曲线
main="ROC curves", # 添加标题
col="red", # 曲线颜色
legacy.axes=TRUE) # 使横轴从0到1,表示为1-特异度
plot.roc(roc02,
add=T, # 增加曲线
col="green", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
legend("bottomright",
legend = c("朴素贝叶斯模型AUC=0.953",
"KNN模型AUC=0.8965"),
col = c("red","green"),
lwd = 1.5, cex = 0.75)
#ROC曲线间的两两比较
roc.test(roc01,roc02,method = "delong") # 其他两种方法 “bootstrap”或“venkatraman”
plot(roc01,
print.auc=TRUE, print.auc.x=0.4, print.auc.y=0.5,
# 图像上输出AUC值,坐标为(x,y)
auc.polygon=TRUE, auc.polygon.col="#fff7f7", # 设置ROC曲线下填充色
max.auc.polygon=FALSE, # 填充整个图像
grid=c(0.5, 0.2), grid.col=c("black", "black"), # 设置间距为0.1,0.2,线条颜色
print.thres=TRUE, print.thres.cex=0.9, # 图像上输出最佳截断值,字体缩放倍数
smooth=F, # 绘制不平滑曲线
main="Comparison of two ROC curves", # 添加标题
col="red", # 曲线颜色
legacy.axes=TRUE) # 使横轴从0到1,表示为1-特异度
plot.roc(roc02,
add=T, # 增加曲线
col="green", # 曲线颜色为红色
print.thres=TRUE, print.thres.cex=0.9, # 图像上输出最佳截断值,字体缩放倍数
print.auc=TRUE, print.auc.x=0.4,print.auc.y=0.4,
# 图像上输出AUC值,坐标为(x,y)
smooth = F) # 绘制不平滑曲线
testobj <- roc.test(roc01,roc02) # 检验两条曲线
text(0.8, 0.2, labels=paste("P value =", format.pval(testobj$p.value)), adj=c(0, .5)) # 在图上添加P值
legend(0.35,0.30, # 图例位置
bty = "n", # 图例样式,默认为 "o"
title="", # 引号内添加图例标题
legend=c("朴素贝叶斯模型","KNN模型"), # 添加分组
col=c("red","green"), # 颜色跟前面一致
lwd=2) # 线条粗细
#绘制PR曲线
plot(as.numeric(roc01$sens), as.numeric(roc01$spec), col="red",
xlab="Recall", ylab="Precision",
type="l", lwd=2, main="PR Curve")
lines(as.numeric(roc02$sens), as.numeric(roc02$spec), col="green", lwd=2)
legend("bottomleft",
legend=c("朴素贝叶斯模型",
"KNN模型"),
col=c("red","green"),
lwd=2, lty=1)
#混淆矩阵因子转换及生成
library(ggplot2) #绘图用包
library(lattice) #绘图可视化包
library(caret)#加载混淆矩阵模型包
cm01 <-
confusionMatrix(as.factor(Test$结局),
as.factor(nb.pred$class))
cm01
cm02 <-
confusionMatrix(as.factor(Test$结局),
as.factor(knn.pred))
cm02
我们可以看到,上边的混淆矩阵评价指标中,
没有Precision 、Recall、F1三个指标,
我们在代码中加入
positive="1",
mode="everything"
然后,完整代码如下:
cm01 <- confusionMatrix(as.factor(Test$结局),
as.factor(nb.pred$class),
positive="1",
mode="everything")
cm01
cm02 <- confusionMatrix(as.factor(Test$结局),
as.factor(knn.pred),
positive="1",
mode="everything")
cm02
#批量计算输出各模型F1值
F1 <- data.frame(cm01[["byClass"]][["F1"]],
cm02[["byClass"]][["F1"]])
print(F1)
当然,我们后续的Logistic回归、决策树、随机森林、
支持向量机、神经网络、XGBoost、lightGBM七种模型,
也可以进行这样拟合效果的ROC、PR、混淆矩阵等方式
进行比较。
逻辑回归(Logistic Regression)是一种广泛使用的统计方法,用于预测一个二分类结果发生的概率。
Logistic Regression是一种广泛使用的分类算法,它的主要思想是将输入变量的线性组合映射到0到1之间的概率,用于预测二元输出变量的概率。
逻辑回归模型,是一种广义的线性回归分析模型。日常工作生活中我们会遇到很多的1,0分类问题,比如考试通过还是不通过、是否患某种疾病等等这样的问题都可以使用逻辑回归来解决。
尽管它被称为“回归”,但它实际上是用于分类问题的。逻辑回归的核心是使用逻辑函数(也称为sigmoid函数)来模拟因变量与自变量之间的关系。
我们还是使用上一期的示例数据
我们先用最常见的SPSS进行logistic回归演示,先用SPSS打开数据进行预览:
依次点击“分析”-“回归”-“二元logistic回归”
将结局变量选入“因变量”数据框,将需要分析的自变量选入“协变量”数据框,点击“保存”,预测值点击“概率”。
可以在输出中看到模型系数的omnibus检验结果、模型摘要、变量分类表、以及方程中的变量。
在数据视图也可以看到已经输出的预测概率值。
我们对输出的预测概率值进行下一步分析,继续在数据编辑器点击“分析”-“分类”-“ROC曲线”,状态变量选入“结局”,检验变量选入“预测概率”,显示ROC曲线、带对角参考线、标准误差和置信区间,可以选择ROC曲线的坐标点计算敏感度、特异度、最佳截断值。
我们继续在数据编辑器点击“分析”-“分类”-“ROC分析”,检验变量仍选入预测变量,状态变量选入结局,状态变量值为1,点击“显示”,图选择ROC曲线、精确率召回率曲线、总体模型质量等。然后可以看到ROC分析的结果输出
然后我们用Rstudio打开示例数据,批量安装并加载机器学习所需要的一系列包。
使用glm()函数进行logistic回归的运算,以及选择输出P值、coef值、95%置信区间的下限与上限。
logit.model <- glm(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,data=Train, family=binomial(link="logit))
logit.result<- as.data.frame(summary(logit.model)$coefficients[, c(1, 4)])
logit.result<- cbind(logit.result, confint(logit.model))
colnames(logit.result) <- c(Coef", "p", "CI_lower", "CI_upper")
logit.result
可以看到输出结果如下:
模型的检验我们可以继续用ROC曲线:
logit.pred.prob <- predict(logit.model, newdata=Test, type="response")
par(las=1, cex.axis=.8)
logit.roc <- roc(
y ~ pred,
data=data.frame(y=Test$结局, pred=logit.pred.prob),
plot=T, ci=T, main="ROC Curve of Logistic Regression",
print.auc=T, print.auc.cex=.8,
print.thres=T, print.thres.cex=.8,
auc.polygon=T, max.auc.polygon=T, grid=T)
绘制列线图:
library(rms)
library(Hmisc)
Train$Group<-as.factor(Train$结局)
Test$Group<-as.factor(Test$结局)
ddist <- datadist(Train); options(datadist='ddist')
f <- lrm(Group ~ 指标1+指标2+指标3+指标4+指标5+指标6, data=Train)
par(family="Prob of 结局")
plot(nomogram(f))
亦可以对logistic回归模型绘制DCA曲线:
#DCA参数运算
model1 <- decision_curve(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,
family=binomial(link='logit'),
data = Train,
thresholds = seq(0, .8, by = .05),
bootstraps = 10)
#绘制DCA曲线
plot_decision_curve(model1,
curve.names = "Model1",
col = c("red"),
confidence.intervals=T #不显示置信区间
)
在复杂的决策情况中,往往需要多层次或多阶段的决策。当一个阶段决策完成后,可能有m种新的不同自然状态发生;每种自然状态下,都有m个新的策略可选择,选择后产生不同的结果并再次面临新的自然状态,继续产生一系列的决策过程,这种决策被称为序列决策或多级决策。
此时,如果继续遵循上述的决策准则或采用效益矩阵分析问题,就容易使相应的表格关系十分复杂。决策树是一种能帮助决策者进行序列决策分析的有效工具,其方法是将问题中有关策略、自然状态、概率及收益值等通过线条和图形用类似于树状的形式表示出来。
决策树模型就是由决策点、策略点(事件点)及结果构成的树形图,一般应用于序列决策中,通常以最大收益期望值或最低期望成本作为决策准则,通过图解方式求解在不同条件下各类方案的效益值,然后通过比较,做出决策。
决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。在机器学习中,决策树是一个预测模型,他代表的是对象属性与对象值之间的一种映射关系。
决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。
分类树(决策树)是一种十分常用的分类方法。它是一种监督学习,所谓监督学习就是给定一堆样本,每个样本都有一组属性和一个类别,这些类别是事先确定的,那么通过学习得到一个分类器,这个分类器能够对新出现的对象给出正确的分类。这样的机器学习就被称之为监督学习。
我们以示例数据为例,演示一下在SPSS和R语言中决策树模型的分析过程。
在SPSS中进行数据决策树分析主要包括以下几个步骤:导入数据、选择决策树模型、设置参数、运行模型、解释结果。导入数据是第一步,需要确保数据格式正确且无缺失值。选择决策树模型时,SPSS提供了多种算法如CART和CHAID。设置参数阶段需要调整模型参数以优化结果。运行模型后,生成的决策树图和相关统计信息可以帮助解释结果。以下是详细的操作步骤和注意事项。
我们先用SPSS打开示例数据:
我们依次点击“分析”-“分类”-“决策树”,点击“确定”。
在模型参数选择中,因变量选入“结局”,自变量选入各自变量,生长法可选择“CHAID”、“穷举CHAID”、“CRT”、"QUEST"等。
在决策树输出中选择显示的方向、节点内容、标度等。在统计-模型中选择摘要、风险、分类表、成本、先验概率、得分和利润值等,节点性能摘要、目标分类等。
保存变量:终端节点数、预测值、预测概率,也可以根据预测概率绘制ROC曲线,进行ROC分析。然后得到决策树相关结果。
在R语言中,需要使用rpart包里的rpart()函数进行分析,我们先用Rstudio打开示例数据,并安装所需要的包:
install.packages(rpart) #安装包
install.packages("rattle") #安装包
install.packages("tibble") #安装包
install.packages("bitops") #安装包
library(rpart)
library(rattle)
library(tibble)
library(bitops)
library(pROC)
使用rpart()函数进行决策树模型拟合并绘图:
dt.model1 <- rpart(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6+指标7+指标8,
data=Train, method="class")
par(las=1, cex=1, family="Songti SC")
fancyRpartPlot(dt.model1, caption=NULL)
使用rpart()函数进行决策树模型拟合并绘图:
dt.model2 <- rpart(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,
data=Train, method="class")
par(las=1, cex=1, family="Songti SC")
fancyRpartPlot(dt.model2, caption=NULL)
使用rpart()函数进行决策树模型拟合并绘图:
dt.model3 <- rpart(结局 ~ 指标1+指标2+指标3+指标4,
data=Train, method="class")
par(las=1, cex=1, family="Songti SC")
fancyRpartPlot(dt.model3, caption=NULL)
对决策树模型进行评价,可用ROC曲线、混淆矩阵、DCA曲线等。
dt.pred.prob <- predict(dt.model, newdata=Test)[,2]
par(las=1, cex.axis=.8)
dt.roc <- roc(
y ~ pred,
data=data.frame(y=Test$结局, pred=dt.pred.prob),
plot=T, ci=T, main="ROC Curve of Decision Tree",
print.auc=T, print.auc.cex=.8,
print.thres=T, print.thres.cex=.8,
auc.polygon=T, max.auc.polygon=T, grid=T)
随机森林模型是一种集成学习方法,主要用于分类和回归任务。它由多个决策树组成,通过集成这些决策树的预测结果来提高模型的准确性和稳定性。
随机森林使用名为“bagging”的技术,通过数据集和特征的随机自助抽样样本并行构建完整的决策树。每棵树在称为自助聚集的过程中随机对训练数据子集进行抽样,模型适合这些较小的数据集,并汇总预测结果。通过有放回抽样,可以重复使用同一数据的几个实例,结果就是,这些树不仅基于不同的数据集进行训练,而且还使用不同的特征做出决策。
随机性:随机森林通过数据随机和特征随机来减少模型的偏差和过拟合问题。数据随机通过有放回抽样构成不同的样本数据集,特征随机则从所有特征中随机选择一部分特征用于每棵树的训练
泛化能力:由于每棵树都是基于不同的数据集和特征训练的,整体模型具有较好的泛化能力,能够适应不同的数据集。
运算速度快:随机森林在处理大数据时表现优异,运算速度较快。
总之,随机森林模型通过集成多个决策树的预测结果,提高了模型的准确性和稳定性,适用于多种机器学习任务。
我们仍以示例数据为例:
首先使用Rstudio打开示例数据:
首先使用caret包演示:
library(caret)
set.seed(1234)
rf.model <- train(
结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,
data=Train, method="rf",
preProcess=c(center", "scale),
trControl=trainControl(method="cv", number=10, classProbs=T))
print(rf.model)
plot(rf.model)
也可以使用randomForest包
library(randomForest)
modelFit <- randomForest(结局 ~ 指标1+指标2+指标3+指标4+指标5, data = Train, keep.forest = TRUE,
predict.all = TRUE, type = "prob")
print(modelFit)
plot(modelFit)
使用Train数据得到的模型预测test数据(caret包):
rf.pred.prob <- predict(rf.model, newdata=Test)
并绘制ROC曲线检验效果
par(las=1, cex.axis=.8)
rf.roc <- roc(
y ~ pred,
data=data.frame(y=Test$结局, pred=rf.pred.prob),
plot=T, ci=T, main="ROC Curve of Random Forest",
print.auc=T, print.auc.cex=.8,
print.thres=T, print.thres.cex=.8,
auc.polygon=T, max.auc.polygon=T, grid=T)
使用Train数据得到的模型预测test数据(randomForest包):
rf.pred.prob <- predict(modelFit, newdata=Test)
并绘制ROC曲线检验效果:
par(las=1, cex.axis=.8)
rf.roc <- roc(
y ~ pred,
data=data.frame(y=Test$结局, pred=rf.pred.prob),
plot=T, ci=T, main="ROC Curve of Random Forest",
print.auc=T, print.auc.cex=.8,
print.thres=T, print.thres.cex=.8,
auc.polygon=T, max.auc.polygon=T, grid=T)
对随机森林进行可视化
library(fastshap)
library(shapviz)
pfun <- function(model, newdata){
predict(model, newdata=newdata)
}
set.seed(1234)
rf.shap <- explain(rf.model, X=Test, pred_wrapper=pfun, shap_only=F,
feature_names=c("指标1", "指标2", "指标3", "指标4", "指标5", "指标6"))
sv_importance(shapviz(rf.shap), kind="beeswarm") +
theme_bw() +
theme(axis.text.y=element_text(family="Songti SC"),
panel.grid=element_blank())
支持向量机(SVM)是一类按监督学习方式对数据进行二元分类的广义线性分类器,其决策边界是对学习样本求解的最大边距超平面(maximum-margin hyperplane)。SVM通过铰链损失函数计算经验风险,并在求解系统中加入了正则化项以优化结构风险,是一个具有稀疏性和稳健性的分类器。SVM可以支持线性分类和非线性分类,通过核方法将数据映射到高维空间来实现非线性分类。
SVM的基本原理是通过找到一个超平面,将不同类别的数据分开。对于线性可分的数据,SVM寻找一个最优的超平面,使得不同类别的数据点距离这个超平面的距离最大化。对于非线性数据,SVM通过核函数将数据映射到高维空间,使其线性可分,然后再寻找最优超平面。
SVM通过核函数实现非线性分类。常用的核函数包括:
线性核函数:适用于线性可分的数据,计算速度快。
高斯径向基核函数(RBF):适用于各种类型的数据,应用广泛。
多项式核函数:适用于需要高阶映射的情况,但参数多,计算复杂。
Sigmoid核函数:实现一种多层神经网络的效果。
选择核函数时,可以通过交叉验证或网格搜索等方法来选择效果最好的核函数。
我们还是以Excel里示例数据为例,先用Rstudio打开数据:
安装并加载所需要的包:
install.packages(e1071) #安装包
install.packages("kernlab") #安装包
install.packages("visreg") #安装包
install.packages("GGally") #安装包
library(e1071)
library(kernlab)
library(visreg) #模型可视化
library(GGally)
library(RColorBrewer)
#绘制所有数据概览图
GGally::ggpairs(Train)
# 设置随机种子以保证结果可复现
set.seed(1234)
# 训练SVM模型
svm.model <- train(
结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,
data = Train,
method = "svmRadial", # 使用径向基核函数
preProcess = c("center", "scale"), # 数据标准化
trControl = trainControl(method = "cv", number = 10, classProbs = TRUE) # 10折交叉验证
)
print(svm.model)
plot(svm.model)
# 使用测试集进行预测
svm.pred.prob <- predict(svm.model, newdata = Test)
summary(svm.pred.prob)
print(svm.pred.prob)
set.seed(1234) # radial核SVM分类器
seedsvm <- svm(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,data = Train,kernel ="radial")
summary(seedsvm)
plot(seedsvm)
## 在二维空间可视化SVM分类器的分类面
visreg(seedsvm, "指标1", gg = TRUE, ylab = "指标1")#单个变量
par(mfrow = c(2, 3)) ##六个变量一起看
visreg(seedsvm)
set.seed(1234) # radial核SVM分类器
seedsvm2 <- svm(结局 ~ 指标1+指标2+指标3+指标4,data = Train,kernel ="radial")
summary(seedsvm2)
## 在二维空间可视化SVM分类器的分类面
par(mfrow = c(2, 2)) ##四个变量一起看
visreg(seedsvm2)
# 绘制ROC曲线
par(las = 1, cex.axis = .8)
par(mfrow = c(1, 1))
svm.roc <- roc(Test$结局 ~ svm.pred.prob, plot = TRUE, ci = TRUE,
main = "ROC Curve of SVM",
print.auc = TRUE, print.auc.cex = .8,
print.thres = TRUE, print.thres.cex = .8,
auc.polygon = TRUE, max.auc.polygon = TRUE, grid = TRUE)
# 计算Brier得分
brier <- function(data, reference) {
o <- as.numeric(reference) - 1
mean((data - o)^2)
}
brier_score <- brier(data = svm.pred.prob, reference = Test$结局)
print(brier_score)
神经网络模型是一种模拟人类神经系统的数学模型,广泛应用于人工智能、机器学习和深度学习领域。神经网络由大量的简单处理单元(称为神经元)广泛连接而成,反映了人脑的基本功能特征。神经网络具有自学习、自适应和并行处理的能力,特别适合处理复杂和不精确的信息。
神经网络通常由三个主要部分组成:输入层、隐藏层和输出层。每个神经元通过加权连接与其他神经元相连,每个连接都有一个权重,这些权重在训练过程中通过学习算法进行调整。此外,每个神经元还有一个偏置项,用于避免输出为零的情况。
前馈神经网络:信息从输入层向前传播,经过隐藏层,最终到达输出层,没有反馈连接。常见的前馈神经网络包括卷积神经网络(CNN)、全连接神经网络(FCN)和生成对抗网络(GAN)等。
反馈神经网络:神经元不仅可以接收其他神经元的信号,还可以接收自己的反馈信号,具有记忆功能。常见的反馈神经网络包括循环神经网络(RNN)、长短期记忆网络(LSTM)等。
神经网络在多个领域都有广泛应用,包括:
系统辨识:用于识别系统的动态特性。
模式识别:如图像和语音识别。
智能控制:用于自适应控制系统。
组合优化、金融预测与管理、通信、机器人技术和专家系统等领域。
我们仍以Excel示例数据为例,初步展示一下神经网络模型的初步做法,我们先用Rstudio打开示例数据。
R语言中的train函数位于caret包中。caret包是一个用于构建、训练和评估机器学习模型的R包,提供了丰富的功能来帮助用户进行模型训练和参数调优。train函数是caret包的核心功能之一,用于训练模型,支持多种算法和模型类型。我们先用train函数拟合神经网络模型。
set.seed(1234)
nn.model <- train(
结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,data = Train,
method="nnet",
preProcess=c(center", "scale),
trControl=trainControl(method="cv", number=10, classProbs=T),
tuneGrid=expand.grid(size = c(1, 5, 10), decay = c(0, 0.1, 0.01)))
print(nn.model)
plot(nn.model)
neuralnet包
#加载neuralnet包
install.packages("neuralnet") #安装包
# 加载Rattle图形库
install.packages("RGtk2")
install.packages("rattle")
library(neuralnet)
library(rattle)
rattle_gui()
#拟合并可视化神经网络模型
nnfit <- neuralnet(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,data = Train, hidden = 10, threshold = 0.01)
print(nnfit)
plot(nnfit)
summary(nnfit)
#安装并加载nnet包
install.packages("nnet")
library(nnet)
#使用nnet包拟合神经网络模型
nnmodel <- nnet(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,data = Train,
size = 10, decay = 0.01, maxit = 100)
# 输出模型摘要
summary(nnmodel)
plot(nnmodel)
#使用神经网络模型预测测试数据并绘制ROC曲线
nn.pred.prob <- predict(nn.model, newdata=Test)
par(las=1, cex.axis=.8)
nn.roc <- roc(
y ~ pred,
data=data.frame(y=Test$结局, pred=nn.pred.prob),
plot=T, ci=T, main="ROC Curve of Neural Network",
print.auc=T, print.auc.cex=.8,
print.thres=T, print.thres.cex=.8,
auc.polygon=T, max.auc.polygon=T, grid=T)
#计算brier评分
brier(data=nn.pred.prob, reference=Test$结局)
XGBoost是一种强大的机器学习算法,它在许多领域都取得了广泛的应用,包括临床医学。本文将介绍XGBoost模型的原理和概念,并通过一些具体的临床医学实例来展示其在这个领域的应用。
XGBoost全称为eXtreme Gradient Boosting,是一种基于梯度提升决策树(Gradient Boosting Decision Tree)的集成学习算法。它在GBDT的基础上进行了改进,引入了正则化项和二阶导数信息,提高了模型的性能和泛化能力。
XGBoost模型的核心思想是将多个弱分类器(决策树)组合成一个强分类器。每个决策树都在前一棵树的残差基础上进行训练,通过不断迭代优化损失函数来逐步减小残差。同时,模型通过控制树的复杂度和正则化项来减少过拟合风险。
XGBoost算法在临床医学中有着广泛的应用:
疾病诊断:XGBoost模型可以使用患者的临床特征和医学检查结果来预测某种疾病的发生概率。例如,可以利用患者的年龄、性别、血液指标等特征,建立一个XGBoost模型来预测心脏病的风险。
药物响应预测:XGBoost可以通过分析患者的基因信息以及其他关键特征,来预测某种药物对患者的治疗效果。这可以帮助医生选择最适合患者的治疗方案,提高治疗成功率。
生存分析:在肿瘤学中,XGBoost模型可以通过分析患者的临床特征和病理学信息,来预测患者的生存期或复发风险。这有助于医生为患者制定个性化的治疗方案。
医疗资源优化:XGBoost模型可以通过分析大量的临床数据,预测患者的住院时间、手术风险等信息,帮助医疗机构进行资源分配和管理。
我们今天简要介绍一下使用xgboost包和tidymodels包进行XGBoost模型相关分析及可视化的方法。我们仍以Excel示例数据为例,先用Rstudio打开示例数据。
#安装并加载包
install.packages(DALEXtra)
install.packages("auditor")
install.packages("vivo")
library(xgboost)
library(tidymodels)
将结局变量转换为因子,使用as.factor()函数
Train$结局<-as.factor(Train$结局)
#XGBoost模型拟合
xgb_fit <- boost_tree() %>%
set_engine("xgboost") %>%
set_mode("classification") %>%
fit(结局 ~ 指标1+指标2+指标3+指标4+指标5+指标6,data=Train)
summary(xgb_fit)
print(xgb_fit)
#构建解释器
library(DALEXtra)
xgb_exp <- explain_tidymodels(xgb_fit,
data = Train[,-1],
y=Train$结局,
label = "xgboost")
summary(xgb_exp)
print(xgb_exp)
#模型解释Breakdown
xgb_bd <- predict_parts(xgb_exp,
new_observation=Train[2,])
plot(xgb_bd)
#模型解释SHAP值
xgb_shap <- predict_parts(xgb_exp,
type = "shap",
new_observation=Train[2,])
plot(xgb_shap,show_boxplots=FALSE)
#模型解释绘制ROC曲线
library(auditor)
plot(model_evaluation(xgb_exp))
#模型解释部分依赖图(PDP)
xgb_profiles <- model_profile(xgb_exp)
plot(xgb_profiles)
#模型解释变量重要性
library(vivo)
xgb_vp <- global_variable_importance(xgb_profiles)
plot(xgb_vp)
#模型解释CP图
xgb_cp <- predict_profile(xgb_exp,
new_observation = Train[2,])
plot(xgb_cp)
LightGBM(Light Gradient Boosting Machine)是一种基于决策树的梯度提升框架,主要用于分类、回归和排序等多种机器学习任务。其核心原理是利用基分类器(决策树)进行训练,通过集成学习得到最优模型。LightGBM相比其他模型如XGBoost,在处理大规模数据集时具有更高的计算效率和可扩展性。
直方图算法:LightGBM使用直方图算法来加速决策树的构建过程。它将连续的特征值离散化为k个整数,形成直方图,从而减少计算复杂度。
单边梯度采样算法(GOSS):GOSS通过采样保留梯度大的样本并随机采样一些梯度小的样本,以减少计算复杂度,同时保持数据分布的准确性。
互斥特征捆绑算法(EFB):EFB通过将互斥特征捆绑在一起,减少特征数量,进一步加速训练过程。
并行学习:LightGBM支持特征并行和数据并行,通过分散规则和直方图加速训练,减少通信和计算开销。
支持类别特征lightGBM可以直接处理类别特征,无需转换为one-hot编码,大大提高了处理速度。
LightGBM以其高效率和准确性在多个领域得到广泛应用。由于其能够处理大规模数据集,适合于实时预测和大规模在线学习。此外,LightGBM在处理稀疏数据时表现出色,能够有效地减少特征维度,提高训练速度。
LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架,支持高效率的并行训练,并且具有更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以快速处理海量数据等优点。
今天我们仍以Excel示例数据为例,简单演示一下LightGBM模型的基础操作。我们先用Rstudio打开示例数据。
#加载包
install.packages(lightgbm)
install.packages("Graphviz")
library(lightgbm)
library(Graphviz)
#准备数据
Train$结局 <- as.factor(Train$结局)
Train.matrix<-as.matrix(Train[,-ncol(Train)])
Test.matrix<-as.matrix(Test[,-ncol(Test)])
Train.labels<-as.numeric(Train$结局)
lgb.Train<-lgb.Dataset(data=Train.matrix,label=Train.labels-1) #LightGBM需要0和1标签
#设置LightGBM参数
params <- list(
objective="binary",
num_leaves=31,
learning_rate=0.1,
nrounds=1000)
#训练模型
lgb.model<-lgb.train(params=params,data=lgb.Train,
nrounds=params[['nrounds']],verbose=-1)
summary(lgb.model)
#预测测试集
pred <- predict(lgb.model, as.matrix(Test[, -ncol(Test)]))
head(pred)
pred
#绘制ROC曲线
library(pROC)
roc.curve<-roc(Test$结局,pred)
plot(roc.curve,legacy.axes=TRUE,main="ROC Curve for Clinical Data")
summary(roc.curve)
#真实值与预测值散点图
library(dplyr)
library(ggplot2)
library(tune)
# 整合预测值和真实值
lgb.res <- bind_cols(truevalue=Test$结局,estimator=pred)
ggplot(lgb.res,mapping=aes(truevalue,estimator))+
geom_point(alpha=0.3,size=2)+
geom_abline(intercept=0,slope=1,col="red")+
labs(x = "observed", y = "predicted") +
coord_obs_pred()
#模型解释
library(DALEX)
library(DALEXtra)
# 构建模型解释器
exp <- DALEXtra::explain_tidymodels(lgb.model,
Test.matrix,
y=Test.matrix,
label = "LightGBM")
#变量重要性
lgb_mp <- model_parts(exp)
plot(lgb_mp)
#模型诊断
plot(model_diagnostics(exp))
#waterfall图
library(shapviz)
shap <- shapviz(lgb.model,X_pred=Test.matrix)
# 每个变量对预测的贡献
sv_waterfall(shap,row_id = 1)
#基于SHAP值的变量重要性
sv_importance(shap,kind = "beeswarm")
机器学习是人工智能的一个重要分支,近年来在数据分析、图像识别、自然语言处理等领域发挥的作用越来越重要。机器学习的基本概念围绕着如何让计算机利用数据来进行学习和预测。而R语言,作为一种统计分析和图形表示的强大工具,因其丰富的包和灵活的数据处理能力,在机器学习领域中占有一席之地。今天我们开始R语言机器学习的第一篇,数据准备与包的批量安装。
机器学习是一门研究如何使计算机系统从数据中学习和改进性能的学科。它通过训练模型来识别模式、预测趋势和做出决策从而实现对数据的自动处理和分析。
机器学习算法通过对大量数据进行学习,提取出有用的特征并建立模型来预测新数据。这些模型可以不断优化,以适应不同类型的数据和任务。常见的机器学习算法包括KNN、决策树、随机森林、贝叶斯等。
今天我们分享一下Logistic回归、决策树、随机森林、支持向量机(SVM)、神经网络、XGBoost、lightGBM七种模型预测效果的ROC曲线综合评价方法。
ROC曲线(Receiver Operating Characteristic Curve)和AUC(Area Under the Curve)是评估二分类模型性能的常用工具。
ROC曲线描绘了在不同阈值下真正例率(TPR,也称为召回率)和假正例率(FPR)之间的关系。真正例率定义为真正例数与所有实际正例数的比例,假正例率定义为假正例数与所有实际负例数的比例。ROC曲线上的每个点对应于模型在不同阈值下的性能,曲线越向左上角凸起,表示模型性能越好。
AUC(Area Under the Curve)是ROC曲线下的面积,用于量化模型性能的综合指标。AUC的取值范围在0到1之间,越接近1表示模型性能越好,0.5表示随机性能。一个完全随机的分类器的AUC为0.5,而一个完美分类器的AUC为1。
ROC曲线和AUC值在机器学习领域有着广泛的应用。它们常用于评估二分类模型的性能,特别是在医疗诊断、欺诈检测、图像识别等领域。通过观察ROC曲线和AUC值,可以直观地了解模型在不同阈值下的表现,从而选择最优的模型参数。
综上所述,ROC曲线和AUC值是评估二分类模型性能的重要工具,通过观察ROC曲线和计算AUC值,可以有效地评估和选择最优的机器学习模型。
在前期的分享中,我们以示例数据为例,分别进行了Logistic回归、决策树、随机森林、支持向量机(SVM)、神经网络、XGBoost、lightGBM七种模型的训练及测试集数据拟合。
分别绘制了模型效果评价的ROC曲线:
我们今天继续分享一下这其中模型综合评价的方法中,ROC曲线及曲线下面积AUC组合绘制的方法。我们先找到各个模型的pred.prob预测概率。
我们先用代码找出pred.prob预测概率,并一测试集数据的因变量(结局)进行ROC曲线组合绘制的组装:
#七种模型ROC曲线组合绘图
roc01 <- roc(Test$结局,logit.pred.prob);roc01
roc02 <- roc(Test$结局,dt.pred.prob);roc02
roc03 <- roc(Test$结局,rf.pred.prob);roc03
roc04 <- roc(Test$结局,svm.pred.prob);roc04
roc05 <- roc(Test$结局,nn.pred.prob);roc05
roc06 <- roc(Test$结局,xg.pred.prob);roc06
roc07 <- roc(Test$结局,lt.pred);roc07
然后直接绘图:
plot(roc01,
max.auc.polygon=FALSE, # 填充整个图像
smooth=F, # 绘制不平滑曲线
main="Comparison of ROC curves", # 添加标题
col="red", # 曲线颜色
legacy.axes=TRUE) # 使横轴从0到1,表示为1-特异度
plot.roc(roc02,
add=T, # 增加曲线
col="orange", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
plot.roc(roc03,
add=T, # 增加曲线
col="yellow", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
plot.roc(roc04,
add=T, # 增加曲线
col="green", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
plot.roc(roc05,
add=T, # 增加曲线
col="skyblue", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
plot.roc(roc06,
add=T, # 增加曲线
col="blue", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
plot.roc(roc07,
add=T, # 增加曲线
col="purple", # 曲线颜色为红色
smooth = F) # 绘制不平滑曲线
在图例部分,可以标明各个模型的AUC值,注意图例部分曲线颜色与前边画的曲线颜色一致:
legend("bottomright",
legend = c("Logistic回归模型AUC=0.9705",
"决策树模型AUC=0.8995",
"随机森林模型AUC=0.9016",
"SVM模型AUC=0.9837",
"神经网络模型AUC=0.9787",
" XGBoost模型AUC=0.9629",
"lightGBM模型AUC=0.999"),
col = c("red", "orange","yellow","green",
"skyblue","blue","purple"),
lwd = 1.5, cex = 0.75)
医学统计数据分析分享交流SPSS、R语言、Python、ArcGis、Geoda、GraphPad、数据分析图表制作等心得。承接数据分析,论文修回,医学统计,空间分析,问卷分析业务。若有投稿和数据分析代做需求,可以直接联系我,谢谢!