【问题标题】:Analysis using linear regression based on subgroups使用基于亚组的线性回归分析
【发布时间】:2016-11-23 13:30:15
【问题描述】:

假设我有数据(t,y),我期望线性依赖y(t)。此外,每个观察都存在属性par1, par2, par3。是否有算法或技术来决定(一个或两个或所有参数)是否与拟合相关?我尝试了leaps::regsubsets(y ~ t + par1 + par2 + par3, data = mydata, nbest = 10),但无法获得最合适的公式。

最终结果如果被绘制应该如下所示。数据见下文。


因此,我想要信息

  • 添加 par1par2 最合适
  • 模型是y_i = a_i * t_i + b_i,给定a_ib_i

可重现的例子

t <- seq(0,10, length.out = 1000) # large sample of x values
# Create 3 linear equations of the form y_i = a*t_i + b
a <- c(1, 0.3, 0.2) # slope
b <- c(-0.5, 0.5, 0.1) # offset

# create t_i, y_ti and y_i (including noise)
d <- list()
y <- list()
y_t <- list()
for (i in 1:3) {
  set.seed(33*i)
  d[[i]] <- sort(sample(t, 50, replace = F))
  set.seed(33*i)
  noise <- rnorm(10)
  y[[i]] <- a[i]*d[[i]] + b[i] + noise
  y_t[[i]] <- a[i]*d[[i]] + b[i]
}
# Final data set
df1 <- data.frame(t=d[[1]], y=y[[1]], par1=rep(1), par2=rep(10), par3=sample(c(100, 200, 300), length(d[[1]]), replace = T))
df2 <- data.frame(t=d[[2]], y=y[[2]], par1=rep(2), par2=rep(20), par3=sample(c(100, 200, 300), length(d[[1]]), replace = T))
df3 <- data.frame(t=d[[3]], y=y[[3]], par1=rep(2), par2=rep(30), par3=sample(c(100, 200, 300), length(d[[1]]), replace = T))
mydata <- rbind(df1, df2, df3)
mydata <- mydata[sample(nrow(mydata)), ]

# That is what the data is looking like:
plot(mydata$t, mydata$y)

# This is the result I am looking for (ideally):
plot(d[[1]], y[[1]], col = "black", xlim = c(0, 10), ylim = c(-2, 10), xlab = "t", ylab = "y",
     main = "Fit for three different groups")
points(d[[2]], y[[2]], col = "red")
points(d[[3]], y[[3]], col = "blue")
lines(d[[1]], y_t[[1]],col = "black")
lines(d[[2]], y_t[[2]], col = "red")
lines(d[[3]], y_t[[3]], col = "blue")

评论和提问@Roland 的回答

我知道,对于给定的三个参数,2^3=8 组具有2*3*3=18 因子水平。但我希望我们只有 8 个相关组,因为我总是可以在“是否包含参数 x”之间进行选择。对我来说,仅“包含参数 y 的级别 x”是没有意义的。

我尝试了以下

g <- 0
t_lin1 <- mydata$t[mydata$g == g]
y_lin1 <- mydata$y[mydata$g == g]
plot(mydata$t, mydata$y)
points(t_lin1, y_lin1, col = "red")
abline(lm(y_lin1 ~ t_lin1), col = "red")
points(pred.1se ~ t, data = mydata, col = as.integer(mydata$g), pch = 16)

并意识到不合适。回想起来,这很清楚,因为

  • 我包含了错误的因子水平(很可能参数 3 不相关)
  • 从而得到错误的拟合数据

所以我的最后一个问题是:

  • 在哪里可以找到最佳模型中包含的相关组
  • 回归中对应的拟合参数是什么?

对不起,如果这很明显,但对我来说这是个谜

【问题讨论】:

  • 请提供不带eval(parse()) 的可重现示例。要么编写正确的 R 代码,要么使用dput 的输出来共享结果。原则上,我不会在我的机器上运行来自互联网的eval(parse()) 代码。
  • @Roland 您是否有理由不从互联网上运行eval(parse())?我知道它很慢(而且风格很糟糕),但在上述情况下,脚本运行时间不到一秒。如果您有一个优雅的建议如何获取测试数据,我会很高兴。只需对问题进行编辑即可。
  • 这是一个安全风险。我不倾向于详细研究此类代码以确保它可以安全运行。通常的建议适用于此处,而不是创建对象 a1a2、... 使用您可以子集到 a[1]a[2]、...的对象(向量、列表、矩阵) >
  • 好的。我dput数据。查看我的编辑...

标签: r linear-regression


【解决方案1】:

LASSO 可以非常接近(尽管它识别出的效果仍然太多):

#I assume these are supposed to be factors:
mydata$par1 <- factor(mydata$par1)
mydata$par2 <- factor(mydata$par2)
mydata$par3 <- factor(mydata$par3)

#create model matrix, remove intercept since glmnet adds it
x <- model.matrix(y ~ (par1 * par2 * par3) * t, data = mydata)[,-1]

#cross-validated LASSO
library(glmnet)
set.seed(42)
fit <- cv.glmnet(x, mydata$y, intercept = TRUE, nfolds = 10, alpha = 1)
plot(fit)

coef <- as.matrix(coef(fit, s = "lambda.1se"))
coef[coef != 0,]
#(Intercept)      par230           t     par12:t    par230:t   par3300:t 
# 0.47542479 -0.27612966  0.75497711 -0.42493030 -0.15044371  0.03033057

#The groups:
mydata$g <- factor((mydata$par2 == 30) + 10 * (mydata$par1 == 2) + 100 * (mydata$par3 == 300))



mydata$pred.1se <- predict(fit, newx = x, s = "lambda.1se")

library(ggplot2)
ggplot(mydata, aes(x = t, color = g)) +
  geom_point(aes(y = y)) +
  geom_line(aes(y = pred.1se))

然后您可以根据系数计算所需的截距和斜率。

【讨论】:

  • predict 是函数glmnet::predict.cv.glmnet?如果我理解正确,预测是否适合所有可能的模型(以某种我不理解的方式)?为什么缺少一个模型(3 个 par 产生 7 个模型)是否很明显?抱歉问了这么多问题...
  • 是的。请注意我是如何设置s = "lambda.1se" 的,即使用上面显示的系数要求预测“lambda 的最大值使得误差在最小值的 1 个标准误差之内”。
  • 我不明白“为什么缺少一个模型很明显(3 个 par 产生 7 个模型)?”
  • 有以下几种可能(我们称参数为1、2、3):1、2、3、12、13、23、123的组合相关=>七种可能(我排除了“非重要的参数”,因为在我的情况下这是不可能的)。一般来说,有 2^(参数数量)的可能性。
  • 但并非所有这些都存在于您的数据中。 (参数的因子水平有 2*3*3=18 种可能的组合。)
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 2012-12-07
  • 1970-01-01
  • 2016-03-04
  • 2012-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多