PCA:princomp()如何工作,我可以用它来为ARIMA获取变量吗?

use*_*463 3 r machine-learning time-series forecasting pca

我正在尝试使用PCA来挑选好的预测变量,以便在模型的xreg参数中使用,arima以尝试预测tVar下面的变量.我只是使用下面的简化数据集,只需几个变量就可以使示例变得简单.

我试图理解公式参数是如何princomp工作的.对于pc下面的对象,是说"使用xVar1xVar2解释方差na.omit(dfData[,c("tVar","xVar1","xVar2")])"?

我最终想要做的是创建一个新的变量来解释大部分的变化tVar.这是我可以用PCA做的事吗?如果是这样,有人可以解释一下如何或指出我的榜样吗?

码:

pc <- princomp(~xVar1+xVar2,
               data = na.omit(dfData[,c("tVar","xVar1","xVar2")]), 
               cor=TRUE)
Run Code Online (Sandbox Code Playgroud)

数据:

dput(na.omit(dfData[1:100,c("tVar","xVar1","xVar2")]))
structure(list(tVar = c(11, 14, 17, 5, 5, 5.5, 8, 5.5, 
          6.5, 8.5, 4, 5, 9, 10, 11, 7, 6, 7, 7, 5, 6, 9, 9, 6.5, 9, 3.5, 
          2, 15, 2.5, 17, 5, 5.5, 7, 6, 3.5, 6, 9.5, 5, 7, 4, 5, 4, 9.5, 
          3.5, 5, 4, 4, 9, 4.5, 6, 10, 9.5, 15, 9, 5.5, 7.5, 12, 17.5, 
          19, 7, 14, 17, 3.5, 6, 15, 11, 10.5, 11, 13, 9.5, 9, 7, 4, 6, 
          15, 5, 18, 5, 6, 19, 19, 6, 7, 7.5, 7.5, 7, 6.5, 9, 10, 5.5, 
          5, 7.5, 5, 4, 10, 7, 5, 12), xVar1 = c(0L, 0L, 0L, 0L, 
          0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
          0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 
          0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
          0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 
          1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
          0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L),
          xVar2  = c(0L, 
          1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 
          2L, 3L, 0L, 0L, 1L, 0L, 0L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 1L, 0L, 
          0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 
          0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 3L, 1L, 0L, 1L, 2L,
          0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 
          1L, 1L, 0L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 
          0L)), .Names = c("tVar", "xVar1", "xVar2"
          ), row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 9L, 10L, 11L, 12L, 
          13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L,25L, 
          26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L,38L, 
          39L, 40L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L,51L, 
          52L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 65L,
          66L, 67L, 68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 76L, 77L, 78L, 
          79L, 80L, 81L, 82L, 83L, 84L, 85L, 86L, 87L, 88L, 89L, 90L, 91L, 
          92L, 93L, 94L, 95L, 96L, 97L, 98L, 99L, 100L),
          class  = "data.frame", na.action = structure(c(8L,53L),
          .Names = c("8", "53"), class = "omit"))
Run Code Online (Sandbox Code Playgroud)

李哲源*_*李哲源 11

(这是一个非常好的帖子!有趣的是,有另一篇文章今天关于PCA.虽然这个问题是比较基本的,有关的区别princompprcomp,但是与R代码的数学细节我做出的回答可能是对任何一个有益学习PCA.)

在以下情况下,PCA用于降维(低秩近似):

  1. 你有很多(比方说p)相关变量x1, x2, ..., xp;
  2. 你想把它们缩小到少数(比如说k < p)新的线性自变量z1, z2, ..., zk;
  3. 您想要使用z1, z2, ..., zk而不是x1, x2, ..., xp预测响应变量y.

一个基本的图片和一点点数学

假设您有一个响应变量y,完全线性回归而不丢弃任何变量应该采用以下公式:

y ~ x1 + x2 + ... + xp
Run Code Online (Sandbox Code Playgroud)

但是,我们可以在PCA之后做一个合理的近似模型.让X是上面的模型矩阵,即,通过的所有观察结合矩阵x1, x2, ... , xp通过柱,然后

S <- cor(X)  ## get correlation matrix S
E <- eigen(S)  ## compute eigen decomposition of S
root_eigen_value <- sqrt(E$values)  ## square root of eigen values
eigen_vector_mat <- E$vectors  ## matrix of eigen vectors
X1 <- scale(X) %*% eigen_vector_mat  ## transform original matrix
Run Code Online (Sandbox Code Playgroud)

现在,root_eigen_value(长度p向量)单调递减,即对总协方差的贡献正在减小,因此我们只能选择第一个k值.因此,我们可以选择k变换矩阵的第一列X1.让我们做:

Z <- X1[, 1:k]
Run Code Online (Sandbox Code Playgroud)

现在,我们已成功将p变量减少为k变量,并且每列Z都是新变量z1, z2, ..., zk.请记住,这些变量不是原始变量的子集; 他们是全新的,没有名字.但由于我们只对预测感兴趣y,因此我们给出的名称并不重要z1, z2, ..., zk.然后我们可以拟合近似线性模型:

y ~ z1 + z2 + ... + zk
Run Code Online (Sandbox Code Playgroud)

使用 princomp()

事实上,事情变得更容易,因为princomp()我们所有的计算都是如此.致电:

pc <- princomp(~ x1 + x2 + ... + xp, data, cor = TRUE)
Run Code Online (Sandbox Code Playgroud)

我们可以得到我们想要的一切.在以下几个返回值中pc:

  1. pc$sdevroot_eigen_value.如果你这样做plot(pc),你可以看到一个显示这个的条形图.如果您的输入数据高度相关,那么您需要在此图中看到接近指数的衰减,只有少数变量支配协方差.(不幸的是,你的玩具数据不会起作用.xVar1并且xVar2它们是二元的,并且它们已经是线性独立的,因此在PCA之后,你会发现它们都给予了相同的贡献.)
  2. pc$loadingseigen_vector_mat;
  3. pc$scoresX1.

使用 arima()

变量选择过程很简单.如果您决定k从总变量中取出第一个p变量,则通过检查plot(pc),然后提取矩阵的第一kpc$scores.每列形成z1, z2, ..., zk,并arima()通过参数传递给它们reg.


回到关于公式的问题

对于下面的pc对象,它是说"使用xVar1和xVar2来解释na.omit中的方差(dfData [,c("tVar","xVar1","xVar2")])"

经过我的解释,你应该知道答案是"不".不要混用响应变量tVar的回归步骤中使用,与预测变量xVar1,xVars......在PCA步骤中使用.

princomp() 允许三种方式传入参数:

  1. 按公式和数据;
  2. 按模型矩阵;
  3. 通过协方差矩阵.

你选择了第一种方式.该公式用于指示princomp()从中提取数据data,然后计算模型矩阵,协方差矩阵,相关矩阵,特征分解,直到我们最终得到PCA的结果.


跟进你的意见

因此,如果我理解正确,PCA主要用于减少变量的数量,我不应该tVar在公式或数据中包含响应变量.但我想知道为什么princomp(~xVar1+xVar2, data = na.omit(dfData[,c("tVar","xVar1","xVar2")]), cor=TRUE)princomp(na.omit(dfData[,c("xVar1","xVar2")]), cor=TRUE)基本相同?

该公式告诉我们如何从数据框中提取矩阵.由于您使用相同的公式~ xVar1 + xVar2,因此无论您是否tVars在数据框中包含要传递给princomp都没有区别,因为该列不会被触及princomp.

不要tVars在您的PCA配方中包含.正如我所说,回归和PCA是不同的问题,不应相互混淆.

需要明确的是,与PCA战术不是创建一个新的变量,它的组合xVar1xVar2,并解释了大部分的方差tVar,而是创建一个新的变量,它的组合xVar1xVar2,并解释了大部分的方差dfData[,c("xVar1","xVar2")]

是.回归(或arima()在你的设置)来设置你的反应之间的关系tVars,并预测变量x1, x2, ..., xpz1, z2, ..., zk.回归/ arima模型将根据预测因子解释响应的均值和方差.

PCA是一个不同的问题.它只选择原始预测变量的低秩(较少参数)表示xVar1, xVar2, ...,以便您可以在以后的回归/ ARIMA建模中使用较少的变量.

不过,您可能需要考虑是否应该针对您的问题进行PCA.

  1. 你有很多变数,比如10+吗?在统计建模中,通常会达到数十万个参数.如果我们使用所有这些计算,计算可能会变得很慢.在这种情况下,PCA非常有用,可以降低计算复杂度,同时给出原始协方差的合理表示.
  2. 你的变量高度相关吗?如果它们彼此线性相关,则PCA可能不会丢弃任何东西.例如,玩具数据xVar1xVar2你给仅仅是线性无关的,所以降维是不可能的.您可以按以下方式查看数据中的相关性pairs(mydata).更好的可视化可能是使用corrplotR包.有关如何使用它绘制协方差矩阵的示例,请参阅此答案.