我有一个行列式为零的安全收益相关矩阵。(这有点令人惊讶,因为样本相关矩阵和相应的协方差矩阵在理论上应该是正定的。)
我的假设是,至少一种证券线性依赖于其他证券。R中是否有一个函数可以按顺序测试每个列的线性相关性?
例如,一种方法是一次建立一个安全性的相关矩阵,并在每个步骤计算行列式。当行列式= 0时,请停止运行,因为您已确定证券是其他证券的线性组合。
识别在这样的矩阵中的线性相关性的任何其他技术是可以理解的。
我有一个行列式为零的安全收益相关矩阵。(这有点令人惊讶,因为样本相关矩阵和相应的协方差矩阵在理论上应该是正定的。)
我的假设是,至少一种证券线性依赖于其他证券。R中是否有一个函数可以按顺序测试每个列的线性相关性?
例如,一种方法是一次建立一个安全性的相关矩阵,并在每个步骤计算行列式。当行列式= 0时,请停止运行,因为您已确定证券是其他证券的线性组合。
识别在这样的矩阵中的线性相关性的任何其他技术是可以理解的。
Answers:
您似乎在问一个真正令人发人深省的问题:在给定单个相关性(或协方差或平方和与叉积和)的情况下,如何检测哪个列与哪个列线性相关。我暂时认为清除操作可能会有所帮助。这是我在SPSS(不是R)中的探针进行说明。
让我们生成一些数据:
v1 v2 v3 v4 v5
-1.64454 .35119 -.06384 -1.05188 .25192
-1.78520 -.21598 1.20315 .40267 1.14790
1.36357 -.96107 -.46651 .92889 -1.38072
-.31455 -.74937 1.17505 1.27623 -1.04640
-.31795 .85860 .10061 .00145 .39644
-.97010 .19129 2.43890 -.83642 -.13250
-.66439 .29267 1.20405 .90068 -1.78066
.87025 -.89018 -.99386 -1.80001 .42768
-1.96219 -.27535 .58754 .34556 .12587
-1.03638 -.24645 -.11083 .07013 -.84446
让我们在V2,V4和V5之间创建一些线性相关性:
compute V4 = .4*V2+1.2*V5.
execute.
因此,我们修改了列V4。
matrix.
get X. /*take the data*/
compute M = sscp(X). /*SSCP matrix, X'X; it is singular*/
print rank(M). /*with rank 5-1=4, because there's 1 group of interdependent columns*/
loop i= 1 to 5. /*Start iterative sweep operation on M from column 1 to column 5*/
-compute M = sweep(M,i).
-print M. /*That's printout we want to trace*/
end loop.
end matrix.
5次迭代中M的打印输出:
M
.06660028 -.12645565 -.54275426 -.19692972 -.12195621
.12645565 3.20350385 -.08946808 2.84946215 1.30671718
.54275426 -.08946808 7.38023317 -3.51467361 -2.89907198
.19692972 2.84946215 -3.51467361 13.88671851 10.62244471
.12195621 1.30671718 -2.89907198 10.62244471 8.41646486
M
.07159201 .03947417 -.54628594 -.08444957 -.07037464
.03947417 .31215820 -.02792819 .88948298 .40790248
.54628594 .02792819 7.37773449 -3.43509328 -2.86257773
.08444957 -.88948298 -3.43509328 11.35217042 9.46014202
.07037464 -.40790248 -2.86257773 9.46014202 7.88345168
M
.112041875 .041542117 .074045215 -.338801789 -.282334825
.041542117 .312263922 .003785470 .876479537 .397066281
.074045215 .003785470 .135542964 -.465602725 -.388002270
.338801789 -.876479537 .465602725 9.752781632 8.127318027
.282334825 -.397066281 .388002270 8.127318027 6.772765022
M
.1238115070 .0110941027 .0902197842 .0347389906 .0000000000
.0110941027 .3910328733 -.0380581058 -.0898696977 -.3333333333
.0902197842 -.0380581058 .1577710733 .0477405054 .0000000000
.0347389906 -.0898696977 .0477405054 .1025348498 .8333333333
.0000000000 .3333333333 .0000000000 -.8333333333 .0000000000
M
.1238115070 .0110941027 .0902197842 .0347389906 .0000000000
.0110941027 .3910328733 -.0380581058 -.0898696977 .0000000000
.0902197842 -.0380581058 .1577710733 .0477405054 .0000000000
.0347389906 -.0898696977 .0477405054 .1025348498 .0000000000
.0000000000 .0000000000 .0000000000 .0000000000 .0000000000
请注意,第5列最终充满了零。(据我了解),这意味着V5与前面的某些列线性关联。哪几列?看一下第5列最后不为零的迭代-迭代4。我们看到V5与V2和V4绑定在一起,系数为-.3333和.8333:V5 = -.3333 * V2 + .8333 * V4,对应到我们对数据所做的处理:V4 = .4 * V2 + 1.2 * V5。
这就是我们知道哪一列与另一列线性关联的方式。我没有检查上述方法在更一般的情况下对数据中许多相互依赖的组有多大帮助。在上面的示例中,它似乎很有帮助。
这是一种简单的方法:计算由于删除每一列而产生的矩阵的秩。删除后导致最高等级的列是线性相关的列(因为删除那些不会降低等级,而删除线性独立的列却会降低)。
在R中:
rankifremoved <- sapply(1:ncol(your.matrix), function (x) qr(your.matrix[,-x])$rank)
which(rankifremoved == max(rankifremoved))
system is exactly singular: U[5,5] = 0
有问题的列时,这非常有用的答案,我现在知道这意味着第5列是问题所在(事后看来很明显,因为它是零列!)
your.matrix = matrix(1:4, 2)
吗?
该问题询问有关“识别变量之间的潜在[线性]关系”的问题。
快速简便的关系检测方法是使用您喜欢的软件对其他变量(使用常数,甚至使用偶数)进行回归:任何良好的回归过程均可检测和诊断共线性。(您甚至不必费心查看回归结果:我们仅依赖于建立和分析回归矩阵的有用副作用。)
但是,假设检测到共线性,下一步怎么办? 主成分分析(PCA)正是需要的:其最小的成分对应于近乎线性的关系。这些关系可以直接从“负荷”中读取,“负荷”是原始变量的线性组合。小载荷(即与小特征值相关的载荷)对应于近似共线性。特征值对应于理想的线性关系。仍然比最大值小得多的稍大的特征值将对应于近似线性关系。
(确定什么是“小”负载是一门艺术和大量文献。对于建模因变量,我建议将其包括在PCA的自变量中,以识别组件,无论如何它们的大小-在其中因变量起着重要的作用。从这个角度来看,“小”表示比任何此类组件都小得多。)
让我们看一些例子。 (这些R
用于计算和绘图。)从执行PCA的功能开始,寻找小零件,对其进行绘图,然后返回它们之间的线性关系。
pca <- function(x, threshold, ...) {
fit <- princomp(x)
#
# Compute the relations among "small" components.
#
if(missing(threshold)) threshold <- max(fit$sdev) / ncol(x)
i <- which(fit$sdev < threshold)
relations <- fit$loadings[, i, drop=FALSE]
relations <- round(t(t(relations) / apply(relations, 2, max)), digits=2)
#
# Plot the loadings, highlighting those for the small components.
#
matplot(x, pch=1, cex=.8, col="Gray", xlab="Observation", ylab="Value", ...)
suppressWarnings(matplot(x %*% relations, pch=19, col="#e0404080", add=TRUE))
return(t(relations))
}
让我们将其应用于一些随机数据。这些建立在四个变量(问题的和)的基础上。这是一个将计算为其他给定线性组合的小函数。然后,它将iid正态分布的值添加到所有五个变量中(以查看当多重共线性仅是近似值而不是精确值时,过程执行得如何)。
process <- function(z, beta, sd, ...) {
x <- z %*% beta; colnames(x) <- "A"
pca(cbind(x, z + rnorm(length(x), sd=sd)), ...)
}
我们都准备好了:仅保留生成并应用这些过程。我使用问题中描述的两种情况:(每个都有一些错误)和(每个都有一些错误)。但是,首先请注意,PCA几乎总是应用于居中数据,因此使用可以将这些模拟数据居中(但不能重新缩放)。sweep
n.obs <- 80 # Number of cases
n.vars <- 4 # Number of independent variables
set.seed(17)
z <- matrix(rnorm(n.obs*(n.vars)), ncol=n.vars)
z.mean <- apply(z, 2, mean)
z <- sweep(z, 2, z.mean)
colnames(z) <- c("B","C","D","E") # Optional; modify to match `n.vars` in length
在这里,我们讨论了两种情况和三种错误级别。原始变量始终保留不变:只有和错误项有所不同。
与左上方面板相关的输出是
A B C D E
Comp.5 1 -1 -1 -1 -1
这表示一排红点-始终为,表示完美的多重共线性-由组合:正好是所指定的。
上中间面板的输出是
A B C D E
Comp.5 1 -0.95 -1.03 -0.98 -1.02
系数仍然接近我们的预期,但是由于引入的误差,它们并不完全相同。它在所隐含的五维空间内加厚了四维超平面,并使估计方向稍微倾斜了一点。随着更多的误差,增厚变得可与点的原始散布相媲美,从而使超平面几乎无法估计。现在(在右上方的面板中)系数为
A B C D E
Comp.5 1 -1.33 -0.77 -0.74 -1.07
它们已经改变了很多,但是仍然反映了基本的基本关系,其中的质数表示已消除(未知)错误的值。
底行的解释方式相同,其输出类似地反映系数。
在实践中,通常不会出现将一个变量选为其他变量的明显组合的情况:所有系数的大小都可能相当,符号也不同。此外,当关系有多个维度时,没有唯一的方式来指定它们:需要进一步分析(例如行减少)来确定这些关系的有用基础。这就是世界的运作方式:您只能说PCA输出的这些特定组合几乎不对应数据变化。 为了解决这个问题,某些人可以直接使用最大(“主要”)成分作为回归或后续分析中的自变量,无论采用哪种形式。如果这样做,请不要忘记首先从变量集中删除因变量并重做PCA!
这是复制此图的代码:
par(mfrow=c(2,3))
beta <- c(1,1,1,1) # Also can be a matrix with `n.obs` rows: try it!
process(z, beta, sd=0, main="A=B+C+D+E; No error")
process(z, beta, sd=1/10, main="A=B+C+D+E; Small error")
process(z, beta, sd=1/3, threshold=2/3, main="A=B+C+D+E; Large error")
beta <- c(1,1/2,1/2,1)
process(z, beta, sd=0, main="A=B+(C+D)/2+E; No error")
process(z, beta, sd=1/10, main="A=B+(C+D)/2+E; Small error")
process(z, beta, sd=1/3, threshold=2/3, main="A=B+(C+D)/2+E; Large error")
(在大错误情况下,我不得不摆弄阈值,以便仅显示单个组件:这就是将这个值作为参数提供给的原因process
。)
"loadings," which are linear combinations of the original variables
这句话看起来不准确。荷载是预测变量中各个分量的线性组合的系数。那么,您是说吗?A − 1
princomp
大约两周前,我遇到了这个问题,并决定需要重新审视它,因为在处理海量数据集时,不可能手动执行这些操作。
我创建了一个for()循环,该循环一次计算矩阵的秩。因此,对于第一个迭代,等级将为1。第二个等级将为2。直到等级比您使用的列数少时才发生。
非常简单:
for (i in 1:47) {
print(qr(data.frame[1:i])$rank)
print(i)
print(colnames(data.frame)[i])
print("###")
}
for()循环故障
我确信您可以添加一个if语句,因为我只处理50ish列,所以我现在还不需要它。
希望这可以帮助!