基于R语言的机器学习学习笔记(多元线性回归, 随机森林,XGBoost)

随机森林

使用R语言实现随机森林(randomFores)

## 本例使用的数据集来自R语言, 预测变量是连续值变量, 
## 随机森林执行回归任务, 而不是其它博客常用的分类变量,执行分类任务 

# 安装包
# install.package("randomForest")
library("randomForest")

# 加载数据
data(airquality)             # 使用R语言自带数据(data()可以查看所有可用数据), airquality数据集为连续变量, iris数据集有分类变量
summary(airquality)          # 查看数据统计信息; str(),查看数据结构; head()和tail(), 查看数据的首尾; dim() 查看行列号
# read.csv("C:/test.csv")    # 也可读取自己的数据

# 处理数据
# 划分数据集为训练集(建模)和测试集(预测), 训练集和测试集的比例为7:3或者8:2. caret::createDataPartition函数也可分割数据集
D <- na.omit(airquality)    # 去除NA值
nrow <- nrow(D)             # 计算行数
set.seed(1)                 # 设置随机种子, 不然每次随机的结果都不一样, 无法复现结果
sample <- sample(1:nrow, round(nrow*0.7))    # 随机选择, 7:3分割数据集
D_trainSet <- D[sample, ]      # 训练数据集
D_testSet <- D[-sample, ]	    # 验证数据集

# 构建随机森林模型
set.seed(2)          # 设置种子, 用于复现
# RF预测Ozone(连续的数值变量). ntree设置构建树的数量, 默认为500. maxnodes设置每棵树的最大节点数
RF <- randomForest(Ozone ~ ., data=D_trainSet, importance=TRUE, na.action = na.omit)    
print(RF)                 # 查看变量解释百分比
plot(RF)                  # 绘图, error随着trees变化的折线图, 预测变量为连续变量时, error指的是MSE
hist(treesize(RF))        # 每棵树的节点数, 直方图显示

# 变量重要性排序
imp <- importance(RF)                                 # 没有设置type参数,两种方法计算的重要性的都会输出
varImpPlot(RF, main = "variable importance")          # 图可视化重要性排序(Dotchart)
# write.csv(imp, file = 'D:/RF_importance.csv')       # 保存为csv

# 使用构建的随机森林模型预测新数据集
predict <- predict(RF, D_testSet)
plot(D_testSet$Ozone, predictSet)                         # 简单绘制散点图

# 对比训练数据集和预测数据集的预测精度
pred_trainSet <- predict(RF, D_trainSet)                                     # 使用训练数据预测变量
cat('R2_trainSet', summary(lm(D_trainSet$Ozone ~ pred_trainSet))$r.squared)  # 计算模型精度

pred_testSet <- predict(RF, D_testSet)                                        # 使用测试数据预测变量,并计算模型精度
cat('R2_testSet', summary(lm(D_testSet$Ozone ~ pred_testSet))$r.squared)      # 计算模型精度

# 关于网上教程提到的混淆矩阵和ROC曲线应该是分类变量的分析工具, 连续变量用不了
# 下面代码不重要了----------------------------------------------------------------------------

# 统计模型的预测精度--------------------------------------------------
df <- data.frame( obs = D_testSet$Ozone, pred = pred_testSet ) |> na.omit()           # 构建数据框, 并去除空值
summ <- summary(lm(df$obs ~ df$pred) )
N <- length(df$obs)
intercept <-  round(summ$coefficients[1,1], 4)
slope <- round(summ$coefficients[2,1], 4)
R2 <- round(summ$r.squared, 3); R <- round(cor(df)[1,2], 3)
P <- formatC(summ$coefficients[2,4], digits = 4, format = "f")     
residual <- df$obs - df$pred
MSE <- mean(residual^2)
MAE <- mean(abs(residual))
RMSE <- roune(sqrt(MSE), 2)                 # 均方根误差(残差平方和的均值的平方根),表示模型的误差大小
NRMSE <- round(RMSE/mean(df$obs)*100, 2)    # 相对均方根误差,使用百分比的形式表示模型的误差大小
NRMAE <-  round(MAE/mean(df$obs)*100, 2)

# 使用ggplot绘制散点图-------------------------------------
library(ggplot2)
min <- min(df, na.rm = T); max <- max(df, na.rm = T)
str <- paste0('RMSE = ', round(RMSE,3), '\n',
              'NRMSE = ', round(NRMSE,2), ' %', '\n',
              'R^2 = ', round(R2,3), '\n')
# 绘制散点图
F <- ggplot(df, aes(obs, pred)) + geom_point() +  
  geom_abline(intercept = 0, slope = 1, linetype ="longdash", colour = 'black', size=0.5) +  # 绘制对角线
  geom_smooth(se = T, method = 'lm', size = 0.5, colour = 'black',fill = 'gray') +            # 绘制拟合曲线
  lims(x=c(min, max), y=c(min, max)) +
  labs(x = paste('Observation'), y = paste('Prediction') ) + 
  annotate('text', x = min, y = max, hjust = 'left', vjust = 'top',label = str, size = 4,  family = "sans") + # 标注模型精度
  theme_bw()
F
ggsave(paste0('D:/','point_RF','.tiff'), F, width = 10, height = 9, units = c("cm"), dpi = 600)

相关知识

注意事项:
(一) 模型中关于分类任务以及回归预测任务的区别:
随机森林模型,分类和回归预测的操作不同之处在于预测变量(因变量)的类型。
如果因变量是因子则执行分类任务
如果因变量是连续性变量,则执行回归预测任务
不同因变量类型对应的分析也不一样,很多教程没有说明, 就用分类变量开始演示了,混淆矩阵和ROC曲线是分类变量的分析工具, 连续变量的回归预测用不了的。

其实无论是决策树回归还是分类,思路都是一样的。
遍历所有的特征的特征值,来作为分割点,然后看哪一个分割点的效果最好。
效果好不好可以通过各种特征选择算法量化,主要看分割后的子集的纯度。

分类问题看的是信息增益(C3),信息增益比(C4.5)以及gini指数(CART)。随机森林采用的CART决策树就是基于基尼系数选择特征的。
回归问题就是看子节点的残差平方和之和。然后再在各个子节点中继续选择分割点,直到层次达到了指定阈值或者子节点只有一个样本。


(二) 随机森林的过拟合问题
随机森林容易产生过拟合,特别是在数据集相对小的时候。
当你的模型对于测试集合做出“太好”的预测的时候就应该怀疑一下了。
避免过拟合的一个方法是在模型中只使用有相关性的特征,比如使用之前提到的特征选择。


(三)随机森林的两个参数(候选特征数和决策树数量)
候选特征数K
K越大,单棵树的效果会提升,但树之间相关性也会增强(proximity参数可以输出)。
决策树数量M
M越大,模型效果会有提升(可以绘图查看),但计算量会变大。


(四) 关于袋外数据OOD

  • OOD

首先回顾一下随机森林的装袋(Bagging)
由于采用放回随机抽样, 从总数据集(N个样本)随机抽取的N个样本组成的子集有一个特点.
约1/3的样本没被抽到, 也就是说约1/3的样本是重复的.
这样导致每次得到的子集都不一样(之间会有部分重复), 每个子集都可以用来构建一个树.
对于每个测试样本, 随机森林的每棵树的预测结果汇总在一起, 概率最大的就是随机森林的分类结果. (当然中间还有比较重要的其步骤, 特征装袋)

在上面描述中每个子集没有抽到的1/3, 就是袋外数据.


  • OOD_score

每棵树的OOD袋外数据都可以被用来验证这棵树的分类精度, 袋外数据的预测结果相对于袋外数据可以计算OOD_score(对于回归分析是R平方,对于分类分析是).
所有树OOD_score的均值就是随机森林模型可解释性(决定系数).


  • 通过OOD计算特征重要性

用oob样本在训练好的单棵决策树上运行,可以得到袋外数据误差 e1
然后保持其他列不变,permutate(随机重排/洗牌)第 i 列特征的特征值或者加噪音在 oob中第 i 列特征的特征值上,得到袋外数据误差 e2(误差会增大)。
特征的重要性计算为 这个特征在所有树的(e2-e1)均值。值越高的特征越重要。


  • R语言关于变量重要性的定义

R语言importance {randomForest}关于变量重要性度量(the variable importance measures)的定义。

以下是变量重要性测量的定义。
第一个衡量标准是通过permuting OOB数据计算的:
对于每一棵树,记录数据中袋外部分的预测误差(分类的误差率,回归的MSE)。
然后在对每个预测变量进行排列组合后进行同样的操作。
然后将两者之间的差异在所有树上取平均值,并以差异的标准差进行标准化。
如果某个变量的差异标准差等于0,则不进行划分(但在这种情况下,平均数几乎总是等于0)。

第二个衡量标准是对变量进行拆分后的节点杂质的总减少量,所有树的平均值。
对于分类,节点杂质是由基尼指数来衡量的。
对于回归来说,它是由残差平方和来衡量的。


参考链接:
R语言代码实现

  • R语言实现随机森林
    https://blog.csdn.net/water200101/article/details/124384878
  • 随机森林实例(R语言实现)
    https://blog.csdn.net/qq_51165184/article/details/123362161
  • R语言之Random Forest随机森林
    https://www.cnblogs.com/nxld/p/6374945.html

关于OOD

  • ROC曲线
    https://zhuanlan.zhihu.com/p/573964757
  • 随机森林oob_score及oob判断特征重要性
    https://blog.csdn.net/qq_36535820/article/details/119797794

随机森林与其他模型的区别

  • R语言︱决策树族——随机森林算法
    https://zhuanlan.zhihu.com/p/44545822

算法

  • 决策树是怎么做回归的?
    https://zhuanlan.zhihu.com/p/159600175
  • 决策树 – 回归
    https://blog.csdn.net/sakura_saku/article/details/116401456
  • 将决策树用于回归
    https://blog.csdn.net/SunJW_2017/article/details/125741763
    -「西瓜书」阅读笔记——决策树
    https://blog.csdn.net/SunJW_2017/article/details/122590515

多元线性回归

使用R语言实现多元线性回归

# 获取数据----
data(state.x77)                             # 使用R语言数据
D <- data.frame(state.x77) |> na.omit()     # 转数据框格式, 并移除NA
str(D); head(D)                             # 查看数据

# 处理数据(分割数据集为训练和预测)----
set.seed(11)                                # 设置随机种子,用于复现
ind <- sample(nrow(D), nrow(D)*0.7)         # 按照7:3分割数据集为训练和预测
trainSet <- D[, ind]                        # 训练集           
testSet <- D[, -ind]                        # 预测集

# 构建模型----
model <- lm(Murder~., trainSet)                    # 使用数据框其他变量预测Murder变量
summary(model)                                     # 查看模型拟合结果

# 多重共线性----
cor(D)                         # 相关性矩阵, 查看特征之间的相关性
model_step <- step(model)      # 逐步回归,剔除存在共线性的变量
summary(model_step)

# 使用模型预测----
pred <- predict(model_step, newdata = testSet)            # 使用测试集和逐步回归的多元线性模型预测Murder
df_pred <- data.frame(obs = testSet$Murder, pred = pred)  #  
summ <- summary(lm(obs ~ pred, df_pred))      

# 统计模型的精度----
residual <- df_pred$obs - df_pred$pred               
MSE <- mean(residual^2) 
RMSE <- sqrt(MSE)
NRMSE <- RMSE/mean(df$obs)*100
R2 <- summ$r.squared
P <- summ$coefficients[2,4]

# 绘制散点图----
library(ggplot2); library(ggpubr)
min <- min(df, na.rm = T); max <- max(df, na.rm = T)
str <- paste0('RMSE = ', round(RMSE,3), '\n',
              'NRMSE = ', round(NRMSE,2), '%', '\n',
              'R^2 = ', round(R2,3), '\n')
F <- ggplot(df_pred, aes(obs, pred)) + geom_point() +  
  geom_abline(intercept = 0, slope = 1, linetype ="longdash", colour = 'black', size=0.5) +   # 绘制对角线
  geom_smooth(se = T, method = 'lm', size = 0.5, colour = 'black',fill = 'gray') +            # 绘制拟合线
  lims( x=c(min, max), y=c(min, max) ) +
  labs(x = paste('Observation'), y = paste('Prediction') ) + 
  annotate('text', x = min, y = max, hjust = 'left', vjust = 'top',label = str, size = 4,  family = "sans") + # 标注模型精度
  theme_bw()
F
ggsave(paste0('D:/','point_MLR','.tiff'), F, width = 10, height = 9, units = c("cm"), dpi = 600)
参考链接:
# R语言 —— 多元线性回归
https://blog.csdn.net/m0_51339444/article/details/124590708
# R语言——多元线性回归
https://blog.csdn.net/weixin_41030360/article/details/80891738

XGboost(eXtreme Gradient Boosting)

使用R语言的xgboost包

# 安装并加载包 ----
#install.packages("xgboost", repos="http://dmlc.ml/drat/", type = "source")
library(xgboost)
library(ggplot2)

#  加载数据 ----
data(airquality)   
str(airquality)

# 分割数据 -----
D <- na.omit(airquality)        # 去除NA值
set.seed(1)                          # 设置随机种子, 不然每次随机的结果都不一样, 无法复现结果
sample <- sample(nrow(D),  nrow(D)*0.7)    # 随机选择, 7:3分割数据集
trainSet <- D[sample, ]        # 训练数据集
testSet <- D[-sample, ]	    # 验证数据集

# 将数据处理成XGboost的xgb.DMatrix格式 ------
dtrain <- xgb.DMatrix(data = as.matrix(trainSet[,-1]), label = trainSet[, 1] )   
dtest <- xgb.DMatrix(data = as.matrix(testSet[,-1]), label = testSet[, 1] )   
watchlist <- list(train = dtrain, test = dtest)

# 构建模型 ----
params <- list(eta = 0.5,                    # 学习率, 默认是0.3
               max_depth = 3                   # 每棵树的最大树深, 默认是6
             # objective 默认值是"reg:squarederror", 指定学习任务(回归:reg)和学习目标(squarederror)
             # nthread 默认为最大可用线程数
             )
xgb <- xgb.train(params = params, data = dtrain, nrounds = 10, watchlist = watchlist)   # booster默认为"gbtree";eta默认0.3;max_dept

# 重要性排序
importance <- xgb.importance(xgb)
print(importance) 
xgb.ggplot.importance(importance)    #  重要性排序绘图

# 查看模型的单颗决策数
# xgb.plot.tree(model = xgb, trees = 1, plot_width = 500, plot_height = 500)
# xgb.plot.tree(model = xgb, trees = 1:3, plot_width = 500, plot_height = 500)

# 模型预测 -----
pred_test <- predict(xgb, newdata = dtest)

# 统计模型的精度RMSE -----
df <- data.frame(obs = testSet[,1], pred = pred)
residual <- (df$obs - df$pred); MSE <- mean(residual^2)
RMSE <- sqrt(MSE);  NRMSE <- RMSE/mean(df$obs)*100
# 统计实测值和预测值线性模型的进度
summ <- summary(lm(obs ~ pred, df))
# intercept <-  round(summ$coefficients[1,1],4);  slope <- round(summ$coefficients[2,1],4)
# P <- formatC(summ$coefficients[2,4], digits = 4, format = "f" )
R2 <- summ$r.squared;  R <- cor(df)[1,2]

# 绘制散点图 ----
library(ggplot2); library(ggpubr)
min <- min(df, na.rm = T); max <- max(df, na.rm = T)
str <- paste0('RMSE = ', round(RMSE,3), '\n',
                     'NRMSE = ', round(NRMSE,2), '%', '\n',
                      'R^2 = ', round(R2,3), '\n')
F <- ggplot(df_pred, aes(obs, pred)) + geom_point() +  
  geom_abline(intercept = 0, slope = 1, linetype ="longdash", colour = 'black', size=0.5) +   # 绘制对角线
  geom_smooth(se = T, method = 'lm', size = 0.5, colour = 'black',fill = 'gray') +                    # 绘制拟合线
  lims( x=c(min, max), y=c(min, max) ) +                                                      
  labs(x = paste('Observation'), y = paste('Prediction') ) + 
  annotate('text', x = min, y = max, hjust = 'left', vjust = 'top', label = str, size = 4) +               # 标注模型精度
  theme_bw()
F
ggsave(paste0('D:/','point_MLR','.tiff'), F, width = 10, height = 9, units = c("cm"), dpi = 500)
  • XGBoost(eXtreme Gradient Boosting)原理:
    是在决策树的基础上产生迭代,它以 boosting 的方式结合了多个决策树。通常创建每棵新树是为了通过梯度提升来减少先前模型的误差,误差指的是实际值和预测值之间的差异。把误差作为协变量参与下一个模型的预测,反复执行这个过程,降低出错率,直到决策树指定阈值,模型已经被训练成功。

  • 主要参数介绍:
    在这里插入图片描述

  • 调参注意事项:
    当我们允许模型变得更复杂(例如更深)时,模型具有更好的拟合训练数据的能力,从而产生更少偏差的模型。
    然而,如此复杂的模型需要更多的数据来拟合。
    控制过拟合
    当你观察到训练准确率很高,但测试准确率很低时,很可能你遇到了过拟合问题。
    通常有两种方法可以控制 XGBoost 中的过度拟合:
    第一种方式是直接控制模型复杂度。
    这包括max_depth 和 min_child_weight 和 gamma。
    第二种方法是添加随机性以使训练对噪声具有鲁棒性。
    这包括 subsample 和 colsample_bytree。
    您还可以减步长eta。这样做时请记住增加num_round。
    更快的训练性能
    有一个名为tree_method的参数,将其设置为historgpu_hist以加快计算速度。

参考链接:
# XGBoost(二):R语言实现
https://www.jianshu.com/p/38009bec6a55
# R语言机器学习-xgboost (知乎)
https://zhuanlan.zhihu.com/p/607919007
# 官方文档(这里很全面, 有时间建议浏览一下)
https://xgboost.readthedocs.io/en/stable/index.html
# 官方文档 (调参注意事项)
https://xgboost.readthedocs.io/en/stable/tutorials/param_tuning.html#

  • 3
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我不太了解r语言xgboost代码,但是我可以给你一些关于xgboost的基本信息。Xgboost是一种机器学习算法,通过构建弱学习器(比如决策树)进行提升,以获得更好的性能。它可以应用于回归、分类和其他任务,并可以处理稀疏和非稀疏数据。 ### 回答2: R语言是一种用于统计计算和数据分析的编程语言,而xgboost是一种基于梯度提升算法的机器学习框架。下面以300字来简单介绍R语言xgboost的代码实现。 使用R语言中的xgboost框架,我们首先需要安装xgboost包。命令如下: ``` install.packages("xgboost") ``` 加载xgboost包: ``` library(xgboost) ``` 接下来,我们需要准备训练数据和测试数据。假设我们的训练数据存储在train_data变量中,其中包含了特征和标签。测试数据存储在test_data变量中,也包含了特征和标签。 创建xgboost的训练集和测试集: ``` train_matrix <- xgb.DMatrix(data = as.matrix(train_data[,-1]), label = train_data$label) test_matrix <- xgb.DMatrix(data = as.matrix(test_data[,-1]), label = test_data$label) ``` 定义模型的参数,例如学习率、树的数量、最大深度等: ``` params <- list( booster = "gbtree", objective = "binary:logistic", eval_metric = "logloss", eta = 0.1, max_depth = 6, nrounds = 100, nthread = 2 ) ``` 使用训练数据和参数来训练模型: ``` model <- xgboost(params = params, data = train_matrix, nrounds = params$nrounds) ``` 使用训练好的模型进行预测: ``` predictions <- predict(model, newdata = test_matrix) ``` 接下来,我们可以使用适当的评估指标(如准确率、召回率等)来评估模型的性能,比较预测结果和真实标签之间的差异。 以上是R语言中使用xgboost的简单代码实现,该框架在机器学习和数据分析领域有广泛的应用,通过调节参数和优化模型,我们可以获得更好的预测结果。 ### 回答3: xgboost是一种集成学习算法,常用于解决回归和分类问题。下面是一个示例的R语言xgboost代码: ```R # 加载所需的库 library(xgboost) # 读取数据集 data <- read.csv("data.csv") # 划分数据集为训练集和测试集 train_idx <- sample(1:nrow(data), 0.8 * nrow(data)) train_data <- data[train_idx, ] test_data <- data[-train_idx, ] # 创建xgboost模型 xgb_model <- xgboost(data = as.matrix(train_data[,-1]), label = train_data[,1], objective = "reg:linear", eval_metric = "rmse", nrounds = 100, eta = 0.1, max_depth = 3) # 在测试集上进行预测 pred <- predict(xgb_model, as.matrix(test_data[,-1])) # 计算RMSE评估模型性能 rmse <- sqrt(mean((pred - test_data[,1])^2)) print(paste("RMSE:", rmse)) ``` 以上代码中,首先我们加载了xgboost库,然后读取一个名为data.csv的数据集。接下来,我们将数据集划分为80%的训练集和20%的测试集。然后,我们使用xgboost函数创建了一个xgboost模型。其中,as.matrix函数将数据集转换为矩阵形式,label参数指定了目标变量,objective参数表示我们进行的是回归分析,eval_metric参数是评估指标,nrounds参数是迭代的次数,eta参数是学习率,max_depth参数表示树的深度。创建完模型后,我们使用predict函数在测试集上进行预测,并计算了预测结果与实际结果的RMSE(均方根误差)。最后,我们输出了RMSE的值。 这个代码示例可以作为一个介绍xgboostR语言中使用的起点,你可以根据具体的需求进行参数的调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值