&引用;“内存不足”;matlab中mv回归的误差分析

&引用;“内存不足”;matlab中mv回归的误差分析,matlab,linear-regression,multivariate-testing,Matlab,Linear Regression,Multivariate Testing,我正在尝试使用mvregress和我拥有的数百个维度的数据。(3~4). 使用32 gb的ram,我无法计算beta版,并收到“内存不足”消息。我找不到MVRegression的任何使用限制来阻止我将其应用于具有这种维度的向量,我做错了什么吗?有没有办法通过我的数据使用多元线性回归 下面是一个出错的例子: dim=400; nsamp=1000; dataVariance = .10; noiseVariance = .05; mixtureCenters=randn(dim,1); X=ran

我正在尝试使用mvregress和我拥有的数百个维度的数据。(3~4). 使用32 gb的ram,我无法计算beta版,并收到“内存不足”消息。我找不到MVRegression的任何使用限制来阻止我将其应用于具有这种维度的向量,我做错了什么吗?有没有办法通过我的数据使用多元线性回归

下面是一个出错的例子:

dim=400;
nsamp=1000;
dataVariance = .10;
noiseVariance = .05;
mixtureCenters=randn(dim,1);
X=randn(dim, nsamp)*sqrt(dataVariance ) + repmat(mixtureCenters,1,nsamp);
N=randn(dim, nsamp)*sqrt(noiseVariance ) + repmat(mixtureCenters,1,nsamp);
A=2*eye(dim);
Y=A*X+N;
%without residual term:
A_hat=mvregress(X',Y');
%wit residual term:
[B, y_hat]=mlrtrain(X,Y)
在哪里


错误是:

Error using bsxfun
Out of memory. Type HELP MEMORY for your options.

Error in kron (line 36)
   K = reshape(bsxfun(@times,A,B),[ma*mb na*nb]);

Error in mvregress (line 319)
            c{j} = kron(eye(NumSeries),Design(j,:));
这是WHO命令的结果:

whos
  Name                  Size                Bytes  Class     Attributes

  A                   400x400             1280000  double              
  N                   400x1000            3200000  double              
  X                   400x1000            3200000  double              
  Y                   400x1000            3200000  double              
  dataVariance          1x1                     8  double              
  dim                   1x1                     8  double              
  mixtureCenters      400x1                  3200  double              
  noiseVariance         1x1                     8  double              
  nsamp                 1x1                     8  double   

好的,我想我有一个解决方案给你,首先是简短版本:

dim=400;
nsamp=1000;
dataVariance = .10;
noiseVariance = .05;
mixtureCenters=randn(dim,1);
X=randn(dim, nsamp)*sqrt(dataVariance ) + repmat(mixtureCenters,1,nsamp);
N=randn(dim, nsamp)*sqrt(noiseVariance ) + repmat(mixtureCenters,1,nsamp);
A=2*eye(dim);
Y=A*X+N;

[n,d] = size(Y);
Xmat = [ones(n,1) X];
Xmat_sz=size(Xmat);
Xcell = cell(1,n);
for i = 1:n
    Xcell{i} = kron(Xmat(i,:),speye(d));
end
[beta,sigma,E,V] = mvregress(Xcell,Y);
B = reshape(beta,d,Xmat_sz(2))';
y_hat=Xmat * B ;
奇怪的是,我无法访问函数的工作区,它没有出现在调用堆栈中。这就是为什么我把函数放在脚本后面的原因

下面的解释也可能对您将来有所帮助: 查看
kron
定义,插入m×n和p×q矩阵时的结果是大小为mxp×nxq,在您的示例中为400×1001和1000×1000,这构成了一个400000×1001000矩阵,其中包含4×10^11个元素。现在有400个,每个元素占用8个字节以获得双精度,即总大小约为1.281 PB的内存(或者1.138 PB,如果您愿意的话),即使使用32 GB的大内存,也无法实现

看到你的一个矩阵,眼睛一号,大部分包含零,结果矩阵包含所有可能的元素乘积组合,它们中的大部分也将是零。对于这种情况,MATLAB提供了稀疏矩阵格式,它仅存储非零元素,从而根据矩阵中零元素的数量节省大量内存。您可以使用
sparse(X)
将完整矩阵转换为稀疏表示,或者使用
speye(n)
直接获得眼睛矩阵,这就是我上面所做的。稀疏属性传播到结果,您现在应该有足够的内存(我有1/4的可用内存,它可以工作)

然而,马修·冈恩在评论中提到的问题仍然存在。我得到一个错误,说:

使用mvregress时出错(第260行) 数据不足,无法估计完全或最小二乘模型。

前言 如果每个回归方程的回归系数都相同,并且您对OLS估计值感兴趣,则可以用对
\
的简单调用替换对mvregress的调用

它出现在对
mlrtrain
的调用中,您有一个矩阵转置错误(自更正后)。在mvregress语言中,n是观察值的数量,d是结果变量的数量。生成一个矩阵Y,它是d乘以n。但是,当您应该调用mlrtrain(X',Y')而不是mlrtrain(X,Y)时

如果下面没有具体说明你在寻找什么,我建议你准确地定义你想要估计的内容

如果我是你,我会写什么 这里所说的太多都是毫无根据的,所以我现在发布的代码就是如果我是你的话我会写的。我已经降低了维度,以显示在您的特殊情况下与只调用
\
等价。我还以更标准的方式写了一些东西(例如,让观察沿着行进行,并且不产生矩阵转换错误)

如果你想做一些不同于此的事情,你需要清楚地说明你想做什么

要在
X
上回归
Y
,可以执行以下操作:

[beta_mvr, sigma_mvr, resid_mvr] = mvregress(X, Y);
这似乎非常缓慢。对于每个回归使用相同的数据矩阵的情况,以下内容应与MVRegression相匹配

beta_hat  = X \ Y;            % estimate beta using least squares
resid     = Y - X * beta_hat;     % calculate residual
如果要使用1的向量构造新的数据矩阵,请执行以下操作:

X_withones = [ones(nsamp, 1), X];
对一些困惑的问题作进一步澄清 假设我们要运行回归

y_i = \sum_j x_{ij} + e_i  i=1...n, j=1...k
我们可以用k数据矩阵X构造数据矩阵n,用1结果向量y构造n。OLS估计值为
bhat=pinv(X'*X)*X'*y
,也可以在MATLAB中使用
bhat=X\y
进行计算

如果要多次执行此操作(即在同一数据矩阵X上运行多元回归),可以构造一个结果矩阵Y,其中每列表示一个单独的结果变量。Y=[ya,yb,yc,…]。简单地说,OLS解决方案是
B=pinv(X'*X)*X'*Y
,可以计算为
B=X\Y
。B的第一列是对X的Y(:,1)进行回归的结果。B的第二列是对X的Y(:,2)进行回归的结果,以此类推。。。在这些条件下,这相当于调用B=mvregress(X,Y)

更多的测试代码 如果回归系数相同,且采用简单的最小二乘法进行估计,则多元回归和方程组最小二乘法之间存在等价性

d = 10;
k = 15;
n = 100;

C = RandomCorr(d + k, 1);  %Use any method you like to generate a random correlation matrix
s = randn(d+k , 1) * 10;
S = (s * s') .* C;         % generate covariance matrix

mu = randn(d+k,1);

data = mvnrnd(ones(n, 1) * mu', S);

Y = data(:,1:d);
X = data(:,d+1:end);

[b1, sigma] = mvregress(X, Y);
b2 = X \ Y;

norm(b1 - b2)

您会注意到b1和b2在数值上是等效的。即使sigma与零非常不同,它们也是等效的。

为了确保您的matlab安装或系统没有问题,您正在运行64位版本的matlab,并且
内存
打印至少可以使用大部分内存的信息?@Daniel这是正确的。我可以看到,我的内存和交换都达到了32GB(总计64GB),然后代码就失败了。我还没有仔细阅读以了解
kron([Xmat(I,:)],eye(d))
试图做什么,但每次调用都会生成一个1000×1001000大小的矩阵,即8GB的数据结构。然后,您对mvregress的调用最终尝试从400个观测值中估计1001000个回归系数(这是不可能的)。这可能不是你想要的?线性回归模型的一个经典假设是严格的外生性,即E[E | X]=0。考虑到(假设为误差项?)N具有非零均值的设置,除非将问题重新定义为满足严格外生性的问题(例如,通过为每种混合物添加一个指示变量来捕获混合物的特定均值),否则无法一致地估计a。
X_withones = [ones(nsamp, 1), X];
y_i = \sum_j x_{ij} + e_i  i=1...n, j=1...k
d = 10;
k = 15;
n = 100;

C = RandomCorr(d + k, 1);  %Use any method you like to generate a random correlation matrix
s = randn(d+k , 1) * 10;
S = (s * s') .* C;         % generate covariance matrix

mu = randn(d+k,1);

data = mvnrnd(ones(n, 1) * mu', S);

Y = data(:,1:d);
X = data(:,d+1:end);

[b1, sigma] = mvregress(X, Y);
b2 = X \ Y;

norm(b1 - b2)