我有一个大矩阵(1,000行和50,000列)。我知道有些列是相关的(排名只有100),我怀疑有些列甚至是成比例的。我怎样才能找到这样的比例列? (一种方法是循环corr(M(:,j),M(:,k))
),但是有什么更有效的吗?
答案 0 :(得分:6)
如果我正确理解您的问题,您希望确定矩阵中线性相关的那些列,这意味着一列是比例或另一列的标量倍数。这是一个基于QR Decomposition的非常基本的算法。对于QR分解,您可以使用任何矩阵并将其分解为两个矩阵的乘积:Q
和R
。换句话说:
A = Q*R
Q
是一个正交矩阵,每列都是一个单位向量,这样Q
乘以它的转置就可以得到单位矩阵(Q^{T}*Q = I
)。 R
是一个右三角形或上三角形矩阵。 Golub and Van Loan in their 1996 book: Matrix Computations的一个非常有用的理论是,如果R
的对角元素的所有值都不为零,则矩阵被视为满秩。由于计算机上的浮点精度,我们必须阈值并检查R
对角线中任何大于此容差的值。如果是,则该对应列是独立列。我们可以简单地找到所有对角线的绝对值,然后检查它们是否大于某个公差。
我们可以稍微修改一下,以便我们搜索 的值,而不是容差,这意味着列不是独立的。以这种方式调用QR分解的方式是:
[Q,R] = qr(A, 0);
Q
和R
是我刚才谈到的,您指定矩阵A
作为输入。第二个参数0
代表生成Q
和R
的经济规模版本,如果此矩阵是矩形的(就像您的情况一样),会返回一个方形矩阵,其中尺寸是两种尺寸中最大的。换句话说,如果我有一个像5 x 8
这样的矩阵,那么生成一个经济规模的矩阵会给你一个5 x 8
的输出,而不指定0
会给你一个8 x 8
1}}矩阵。
现在,我们真正需要的是这种调用方式:
[Q,R,E] = qr(A, 0);
在这种情况下,E
将是一个置换向量,例如:
A(:,E) = Q*R;
这很有用的原因是它以Q
和R
的列排序,使得重新排序的版本的第一列是最可能的列是独立的,后面是那些列的降序顺序为" strength"。因此,E
会告诉您每列的线性独立性以及"强度"按递减顺序排列。这个"力量"完全捕获在对应于此重新排序的R
的对角线中。实际上,强度与第一个元素成正比。您应该做的是检查重新排列版本中R
的对角线是否大于由公差缩放的第一个系数,并使用这些来确定哪些相应列是线性独立的。
但是,我要翻转它并确定最后可能的独立列所在的R
对角线中的点。此后的任何内容都将被视为线性依赖。这与检查是否有任何对角线小于阈值基本相同,但我们正在使用矩阵的重新排序对我们有利。
在任何情况下,假设您的矩阵存储在A
中
%// Step #1 - Define tolerance
tol = 1e-10;
%// Step #2 - Do QR Factorization
[Q, R, E] = qr(A,0);
diag_R = abs(diag(R)); %// Extract diagonals of R
%// Step #3 -
%// Find the LAST column in the re-arranged result that
%// satisfies the linearly independent property
r = find(diag_R >= tol*diag_R(1), 1, 'last');
%// Step #4
%// Anything after r means that the columns are
%// linearly dependent, so let's output those columns to the
%// user
idx = sort(E(r+1:end));
请注意,E
将是一个置换向量,我假设您希望对它们进行排序,以便我们在向量无法线性独立的点之后对它们进行排序的原因了。让我们测试一下这个理论。假设我有这个矩阵:
A =
1 1 2 0
2 2 4 9
3 3 6 7
4 4 8 3
您可以看到前两列是相同的,第三列是第一列或第二列的倍数。你只需要乘以2乘以得到结果。如果我们运行上面的代码,这就是我得到的:
idx =
1 2
如果你也看一下E
,这就是我得到的:
E =
4 3 2 1
这意味着第4列是最好的"线性独立列,后面是第3列。因为我们将[1,2]
作为线性相关列返回,这意味着列{1}}作为列的第1列和第2列是其他列的标量倍数。在这种情况下,这将是第3列,因为第1列和第2列是第3列的一半。
希望这有帮助!
如果您不想进行任何[1,2,3,4]
因子分解,那么我建议您将矩阵缩减为row-reduced Echelon form,并且可以确定构成列空间的基础向量你的矩阵QR
。实质上,如果要使用矩阵向量乘法应用此矩阵,则列空间为您提供可以生成输出向量的所有可能线性组合的最小列集。您可以使用rref
命令确定哪些列构成列空间。您将向A
提供第二个输出,为您提供一个元素向量,告诉您哪些列是线性独立的,或者构成该矩阵的列空间的基础。就这样:
rref
[B,RB] = rref(A);
会为您提供列空间的哪些列的位置,RB
将是矩阵B
的行减少的梯队形式。由于您希望找到线性依赖的列,因此您需要返回一组不包含这些位置的元素。因此,定义从A
到尽可能多的列的线性增加向量,然后使用1
删除此向量中的这些条目,结果将是您正在寻找的线性相关列。换句话说:
RB
通过使用上面的代码,这就是我们得到的:
[B,RB] = rref(A);
idx = 1 : size(A,2);
idx(RB) = [];
请记住,我们确定第2列和第3列是线性相关的,这是有道理的,因为它们都是第1列的倍数。与QR分解方法相比,哪些列线性相关的识别是不同的,因为QR顺序基于特定列线性独立的可能性的列。由于第1列到第3列彼此相关,因此返回哪一列并不重要。其中一个构成了另外两个的基础。
与QR方法相比,我还没有测试过使用idx =
2 3
的效率。我怀疑rref
执行高斯行消除,与进行QR分解相比,复杂性更差,因为该算法是高度优化和高效的。因为你的矩阵相当大,我会坚持使用QR方法,但无论如何都要使用rref
,看看你得到了什么!
答案 1 :(得分:4)
如果通过除以最大值来标准化每列,则比例变为相等。这使问题更容易。
现在,为了测试相等性,可以在列上使用单个(外部)循环;内部循环很容易用bsxfun
进行矢量化。要获得更高的速度,请仅将每列与右侧的列进行比较。
另外为节省时间,结果矩阵预先分配到大致的大小(你应该设置它)。如果大概的大小是错误的,唯一的惩罚是速度稍慢,但代码可以正常工作。
像往常一样,浮点值之间的相等性测试应包括容差。
结果以2列矩阵(S
)给出,其中每行包含两行成比例的索引。
A = [1 5 2 6 3 1
2 5 4 7 6 1
3 5 6 8 9 1]; %// example data matrix
tol = 1e-6; %// relative tolerance
A = bsxfun(@rdivide, A, max(A,[],1)); %// normalize A
C = size(A,2);
S = NaN(round(C^1.5),2); %// preallocate result to *approximate* size
used = 0; %// number of rows of S already used
for c = 1:C
ind = c+find(all(abs(bsxfun(@rdivide, A(:,c), A(:,c+1:end))-1)<tol));
u = numel(ind); %// number of columns proportional to column c
S(used+1:used+u,1) = c; %// fill in result
S(used+1:used+u,2) = ind; %// fill in result
used = used + u; %// update number of results
end
S = S(1:used,:); %// remove unused rows of S
在此示例中,结果为
S =
1 3
1 5
2 6
3 5
意思是第1列与第3列成比例;第1列与第5列等成比例。
答案 2 :(得分:0)
如果矩阵的行列式为零,则列是成比例的。
有50,000列,或2 25,000列。
最简单的解决2乘2矩阵的行列式。
因此:找到比例矩阵,解决方案的最长时间是 在电子表格上定义大矩阵。
将行列式公式应用于从左侧第1个方格开始的正方形。 复制每一行&amp;列,以便在下一个电子表格中找到答案。
找到决定因素为零的列。
这是非常基本的,不是非常耗时,应该是结果导向的。 手动或Excel SpreadSheet(高效)