使用标准化Y

时间:2018-08-23 10:59:30

标签: r dataframe regression simulation linear-regression

基于this topic,我创建了一个函数,该函数返回通过特定线性系数返回与结果(y)相关的变量的数据集。

simulate_data_regression <- function(sample=10, coefs=0, error=0){

  n_var <- length(coefs)
  X <- matrix(0, ncol=n_var, nrow=sample)

  beta <- as.matrix(coefs)

  for (i in 1:n_var){
    X[,i] <- scale(rnorm(sample, 0, 1))
  }

  y <- X %*% beta

  if(error != 0){
    y <- y + rnorm(sample, 0, error)
  }


  data = data.frame(X=X)
  names(data) <- paste0("V", 1:n_var)
  data$y <- as.vector(y)

  return(data)
}

data <- simulate_data_regression(sample=50, coefs=c(0.1, 0.8), error=0)
summary(data)
sd(data$V1)
sd(data$y)

效果很好。但是,我需要有一个标准化的y(平均0和SD 1)。但是当我尝试缩放它时,系数会改变:

data <- simulate_data_regression(sample=50, coefs=c(0.1, 0.8), error=0)
data$y <- as.vector(scale(data$y))
coef(lm(y ~ ., data=data))

有可能这样做吗?非常感谢你!


编辑

换句话说,我希望指定为标准化的coef(在结果的SD中表示)。

按比例缩放y后验将1/sd(y)改变系数。但是,我想不出任何方法在生成y之前更改beta,以便在缩放y之后,beta返回其指定值。


编辑2:尝试失败

我尝试过两次运行该函数,首先提取sd(y)并用它缩放系数,希望一旦我缩放y后那些缩放系数将变为指定的系数。但这是行不通的,这是可以预期的,因为当我更改系数时sd(y)会发生变化:'(

这是失败的尝试:

simulate_data_regression <- function(sample=10, coefs=0, error=0, standardized=TRUE){

  stuff <- .simulate_data_regression(sample=sample, coefs=coefs, error=error)
  if(standardized == TRUE){
    y_sd <- sd(data$y)
    data <- .simulate_data_regression(sample=sample, coefs=y_sd*coefs, error=error, X=stuff$X)$data
    data$y <- as.vector(scale(data$y))
  } else{
    data <- stuff$data
  }
  return(data)
}


.simulate_data_regression <- function(sample=10, coefs=0, error=0, X=NULL, y=NULL){

  n_var <- length(coefs)

  if(is.null(X)){
    X <- matrix(0, ncol=n_var, nrow=sample)
    for (i in 1:n_var){
      X[,i] <- scale(rnorm(sample, 0, 1))
    }
  }

  beta <- as.matrix(coefs)
  y <- X %*% beta

  if(error != 0){
    y <- y + rnorm(sample, 0, error)
  }


  data = data.frame(X=X)
  names(data) <- paste0("V", 1:n_var)
  data$y <- as.vector(y)

  return(list(X=X, y=y, data=data))
}

1 个答案:

答案 0 :(得分:2)

如果缩放y,则推论是相同的,只有截距的p值会改变,系数的p值不会改变。
在此示例中,我设置了error = 1

set.seed(1234)    # Make the results reproducible
data <- simulate_data_regression(sample = 50, coefs = c(0.1, 0.8), error = 1)
data2 <- data
data2$y <- scale(data2$y)

fit <- lm(y ~ ., data)
fit2 <- lm(y ~ ., data2)

summary(fit)
summary(fit2)

您可以看到,尽管系数本身不同,但是系数的p值完全相同。您会期望,因为您是按回归器的标准误差进行缩放,因此系数将按这些标准误差的反比例进行缩放。

下面的函数版本带有一个参数which,该参数允许指定要缩放的回归变量。它的默认值是全部。

simulate_data_regression2 <- function(sample = 10, coefs = 0, error = 0, which = seq_along(coefs)){
  n_var <- length(coefs)
  X <- matrix(0, ncol=n_var, nrow=sample)
  beta <- as.matrix(coefs)
  for (i in 1:n_var){
    X[,i] <- rnorm(sample, 0, 1)
    if(i %in% which) X[, i] <- scale(X[, i])
  }
  y <- X %*% beta
  if(error != 0){
    y <- y + rnorm(sample, 0, error)
  }
  data = data.frame(X=X)
  names(data) <- paste0("V", 1:n_var)
  data$y <- as.vector(y)
  data
}

现在测试该功能。

set.seed(1234)    # Make the results reproducible
data <- simulate_data_regression2(sample=50, coefs=c(0.1, 0.8), error=1)

set.seed(1234)    # Reproduce the data generation process
data2 <- simulate_data_regression2(sample=50, coefs=c(0.1, 0.8), error=1, which = 2)

fit <- lm(y ~ ., data)
fit2 <- lm(y ~ ., data2)

您可以看到V2的系数相等。

coef(fit)
#(Intercept)          V1          V2 
# 0.01997809  0.19851020  0.96310013

coef(fit2)
#(Intercept)          V1          V2 
# 0.07040538  0.21130549  0.96310013

系数V2的估计值的p值也相等

summary(fit)
summary(fit2)