【问题标题】:glmnet model performance compared to boosting algorithmsglmnet 模型性能与提升算法相比
【发布时间】:2019-02-12 20:41:04
【问题描述】:

为了帮助了解机器学习,我编写了一些示例,并不是为了说明一种方法比另一种方法更好,而是为了说明如何使用各种函数以及调整哪些参数。我从比较 BooST 和 xgboost 的 this blog 开始,然后我成功地将 gbm 添加到示例中。现在我正在尝试添加 glmnet,但是返回的模型对于两个系数都具有(接近)零。要么我做错了什么,要么 glmnet 不是该数据的正确算法。我试图弄清楚它是什么。这是我的可重现示例:

# Uncomment the following 2 lines if you need to install BooST (requires devtools)
#library(devtools)
#install_github("gabrielrvsc/BooST")

library(BooST)
library(xgboost)
library(gbm)
library(glmnet)

# Data generating process
dgp = function(N, r2){
  X = matrix(rnorm(N*2,0,1),N,2)
  X[,ncol(X)] = base::sample(c(0,1),N,replace=TRUE)
  aux = X
  yaux = cos(pi*(rowSums(X)))
  vyaux = var(yaux)
  ve = vyaux*(1-r2)/r2
  e = rnorm(N,0,sqrt(ve))
  y = yaux+e
  return(list(y = y, X = X))
}

# Real data
x1r = rep(seq(-4,4,length.out = 1000), 2)
x2r = c(rep(0,1000), rep(1,1000))
yr = cos(pi*(x1r+x2r))
real_function = data.frame(x1 = x1r, x2 = as.factor(x2r), y = yr)

# Train data (noisy)
set.seed(1)
data = dgp(N = 1000, r2 = 0.5)
y = data$y
x = data$X

# Test data (noisy)
set.seed(2)
dataout=dgp(N = 1000, r2 = 0.5)
yout = dataout$y
xout = dataout$X

# Set seed and train all 4 models
set.seed(1)
BooST_Model = BooST(x, y, v = 0.18, M = 300 , display = TRUE)
xgboost_Model = xgboost(x, label = y, nrounds = 300, params = list(eta = 0.14, max_depth = 2))
gbm_Model = gbm.fit(x, y, distribution = "gaussian", n.trees = 10000, shrinkage = .001, interaction.depth=5)
glmnet_Model = cv.glmnet(x, y, family = "gaussian", alpha=0)
coef(glmnet_Model)

coef(glmnet_Model)

“dgCMatrix”类的 3 x 1 稀疏矩阵 1

(拦截)0.078072154632597062784427066617354284971952438

V1 -0.000000000000000000000000000000000000003033534

V2 -0.000000000000000000000000000000000000044661342

# Predict from test data
p_BooST = predict(BooST_Model, xout)
p_xgboost = predict(xgboost_Model, xout)
p_gbm = predict(gbm_Model, xout, n.trees=10000)
p_glmnet = predict(glmnet_Model, xout)

# Show RMSE
sqrt(mean((p_BooST - yout)^2))
sqrt(mean((p_xgboost - yout)^2))
sqrt(mean((p_gbm - yout)^2))
sqrt(mean((p_glmnet - yout)^2))

fitted = data.frame(x1 = x[,1], x2 = as.factor(x[,2]),
  BooST = fitted(BooST_Model),
  xgboost = predict(xgboost_Model, x),
  gbm = predict(object = gbm_Model, newdata = x, n.trees = 10000),
  glmnet = predict(glmnet_Model, newx = x, s=glmnet_Model$lambda.min)[, 1], y = y)

# Plot noisy Y
ggplot() + geom_point(data = fitted, aes(x = x1, y = y, color = x2)) + geom_line(data = real_function, aes(x = x1, y = y, linetype = x2))

# Plot xgboost
ggplot() + geom_point(data = fitted, aes(x = x1, y = y), color = "gray") + geom_point(data = fitted, aes(x = x1, y = xgboost, color = x2)) + geom_line(data = real_function, aes(x = x1, y = y, linetype = x2))

# Plot BooST
ggplot() + geom_point(data = fitted, aes(x = x1, y = y), color = "gray") + geom_point(data = fitted, aes(x = x1, y = BooST, color = x2)) + geom_line(data = real_function, aes(x = x1, y = y, linetype = x2))

# Plot gbm
ggplot() + geom_point(data = fitted, aes(x = x1, y = y), color = "gray") + geom_point(data = fitted, aes(x = x1, y = gbm, color = x2)) + geom_line(data = real_function, aes(x = x1, y = y, linetype = x2))

# Plot glmnet
ggplot() + geom_point(data = fitted, aes(x = x1, y = y), color = "gray") + geom_point(data = fitted, aes(x = x1, y = glmnet, color = x2)) + geom_line(data = real_function, aes(x = x1, y = y, linetype = x2))

【问题讨论】:

  • 因为,正如您所说,您的问题在于系数,请更新您的问题以明确包含它们,并可能解释为什么您认为这些值有问题......
  • 另外,作为一般原则,注释掉的代码行不应包含在此处(它们没有用,只会产生噪音 - 已编辑和删除)。
  • 那些 cmets 用于帮助某人安装 BooST 包,因为它不在 CRAN 上,从而使示例更易于其他人运行。零系数是一个问题,因为它在复制余弦函数方面做得很糟糕,而其他三种方法在复制余弦函数方面做得很好。
  • 我想保持我的代码示例简短,但如果你想要一个视觉效果,这里是所有四种方法的图。您会看到 glmnet 图看起来与其他图大不相同。问题是,glmnet模型可以改进吗?
  • 好的,我运行你的代码——你没有做错任何事,除了你试图将 glmnet 与一些更多强大的算法进行比较......

标签: r machine-learning glmnet


【解决方案1】:

请记住,glmnet 适合 线性 模型,这意味着响应可以写为预测变量的线性组合:

 y = b0 + b1*x1 + b2*x2 + ...

在您的数据集中,您将响应定义为不同的

yaux = cos(pi*(rowSums(X)))

yr = cos(pi*(x1r+x2r))

这两种情况显然不是预测变量的线性组合。

【讨论】:

    【解决方案2】:

    要么我做错了事

    至少在编程方面你不是

    或者 glmnet 不是该数据的正确算法

    并不是说 glmnet 是“不正确的”(尽管它应该主要用于大量预测变量的问题,而不仅仅是一对);这是您的比较从根本上说是“不公平”且不合适的:您使用的所有其他 3 种算法都是 ensemble 的 - 例如,您的 gbm 包含 一万 (10,000) 个人决策树...!尝试将 this 与单个回归器(例如 glmnet)进行比较,嗯,这几乎就像将苹果与橙子进行比较......

    尽管如此,这应该是一个很好的练习并提醒您,从编程的角度来看,所有这些工具似乎“等效”(“好吧,我只是使用@987654324 @ 加载它们中的每一个,对吗?那么,为什么它们不应该是等价的和可比的?"),隐藏了 很多...这就是为什么至少一个基本的熟悉统计学习的原理总是一个好主意(我强烈建议免费提供Introduction to Statistical Learning,对于初学者 - 还包括 R 代码 sn-ps)。

    特别是Adaboost 的集成方法(这是您在此处使用的所有其他 3 种算法背后的统一元素),这不是开玩笑!当它问世时(大约比深度学习时代早 10 年)真正改变了游戏规则,并且在 xgboost 实现中,它仍然是大多数 Kaggle 竞赛的获胜选择,涉及“传统”结构化数据(即没有文本或图像)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 2013-07-23
      • 2014-09-06
      • 2011-10-28
      • 2021-12-19
      • 2012-05-06
      • 1970-01-01
      相关资源
      最近更新 更多