我在MATLAB中以矩阵形式执行多因素线性回归,我遇到了以下警告:
警告:Matrix接近单一或严重缩放。结果可能不准确。 RCOND = smth。
我怀疑是因为我执行线性回归的方式,我遵循标准方法,其中系数向量是((X'X)^(-1))*(X'Y)
。我的矩阵X
具有以下格式:第一列只是所有1
,因此可以找到截距,在其他列中我使用{{1}的幂(所以多项式基础模型) } -coordinates,所以x
然后x
,x^2
等(列向量)。我认为错误的产生是由于更高的基数值非常小,并且它以某种方式将它们变成x^3
,因此警告。
我正在考虑使用另一种变量类型,但是double和它一样大?有没有办法强迫MATLAB不要将这些极小的值分配给NaN
?如果那当然是MATLAB的作用。
答案 0 :(得分:1)
几条评论。 (如果用符号混淆,最后检查定义。)
线性回归背后的假设之一是E [x_i * x_i']是满秩。当您使用样本均值X'*X / n
来近似总体均值E [x_i * x_i']时,您希望X'* X为满秩! 错误告诉您,由于机器精度,这个假设被违反了!
我猜你的一个列总是接近于0,或者当你提升到高功率时,两列在数值上相似(例如,在同一行中为0或HUGE)想象一下线性方程式:
y = b1 * x1 + b2 * x2 + e
如果x2总是为零,那么你永远不会正确估计b2,它可能是10,它可能是10 ^ 10。基本上同样的情况是,如果x2始终非常接近零,或者列的某些线性组合在数值上接近另一列:那么数据中微小的微小变化将导致估计中的巨大波动。在数学术语中,发生的是E [x_i * x_i']实际上小于满秩。
要尝试的东西,请检查cond(X'*X)
将x提升到1到3的功率,检查cond(X'*X)
是否将x提升为1到1,1到5等的权力......在某些时候,你的当X'*X
在数字上接近于排名不足时,条件数正在通过屋顶。
在收到此错误之前,您的估算值已经达到了总计。这个错误(“矩阵严重缩放等......”)告诉你,当你的X'X具有如此高的条件数时,e ^ -16的机器精度与这个病态条件矩阵结合将使你的估计不可靠。 但是你的数据中的错误几乎肯定比e ^ -16 的方式更大。出于估算目的,你的数据实际上是多线的WAY WAY。
你不能估计x这样高的幂的系数。你的数据还不够好。您需要回拨这个方式,直到条件号X'*X
合理。
也许你只能估计二阶多项式的系数!不要贪婪,并试着估计什么是不可能的。
使用b = X \ y
计算您的估算值。
对于任何线性方程,求解Ax = c,其中x = inv(A)* c 非最优。形成逆是不必要的。您可以使用A\c
直接求解线性系统。在这个问题中,您可以使用b
求解系数b = (X'*X) \ (X' * y);
并且因为\
运算符的工作方式(它解决了最小二乘意义上的超定系统),最简单的代码是:
b = X \ y; % USE THIS! (you can treat as a magical incantation to solve b = inv(X'*X) * X'y
最后一点不是问题的根源,但无论如何你应该修复它。
说明:
b
中估算k向量y_i = x_i' * b + e_i
。答案 1 :(得分:0)
MATLAB不会因为数字很小(甚至非常小)而引入NaN。如果您的输入x向量中没有NaN,那么MATLAB不会将它们放入x ^ 2或x ^ 3或x ^ n。
但是,如果你的X矩阵的一列或多列接近零,那么你就有一个病态矩阵,它不适合这种回归。您需要重新考虑您尝试使用的模型(即多项式的次数)。
BTW,对于这个特定问题,除非你需要编写自己的函数,否则你可以使用polyfit或统计工具箱中的众多回归函数之一。
如果您需要编写自己的函数,请确保使用反斜杠运算符而不是<Controls:MetroWindow.TitleTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, Converter={Converters:ToUpperConverter}}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center"
Margin="8 -1 8 0"
FontWeight="Light"
FontSize="{DynamicResource WindowTitleFontSize}"
FontFamily="{DynamicResource HeaderFontFamily}" />
</DataTemplate>
</Controls:MetroWindow.TitleTemplate>
函数,即使用inv
而不是(X'*X)\(X'*Y)
。