图像缩略图

Polyfitn.

版本1.3(56.7KB)由 John d'Errico.
1维或n维多项式建模

252下载

更新2016年4月27日

查看许可证

Polyfitn是polyfit的扩展,允许用户使用多个自变量创建模型。它还允许用户指定一个通用模型,例如,一个二次模型,有常数和二次项,但没有线性项。
例如,为了拟合一个多项式模型到余弦曲线上选择的点,我们只需要偶数有序项。
x = -2:.1:2;
y = cos (x);
P = polyfitn(x,y,'常数x^2 x^4 x^6');
p.cofficients.
ans =.
[0.99996 -0.49968 0.041242 -0.0012079]
当然,系数不会被精确,因为我只使用了基本上是截断的泰勒系列的有限术语,并且我只有有限量的点来构建模型。余弦系列的确切的第一个4系数将是:
>> [1 -1/2 1/24 -1/720]
ans =.
1 -0.5 0.041667 -0.0013889

所以我们得到了预期的结果。

当然,Polyfitn在更高的尺寸上工作,就像这个问题真的很旨在解决。

x =兰德(100 1);
y = rand(100,1);
Z = exp(x+y) + randn(100,1)/100;
p = polyfitn (x, y, z, 3);

结果可以转换为符号形式,以更简单地查看模型。这里我将使用我的sympoly工具箱,但也提供了一个polyn2sym函数。

polyn2sympoly(p)
ans =.
* x1 ^2 + 1.4919* x1 ^2* x2 + 0.041084* x1 ^2 + 1.4615* x1 * x2 ^2 - 0.095977* x1 * x2 + 1.2799* x1 + 0.56912* x2 ^3 - 0.15306* x2 ^2 + 1.361* x2 + 0.94819

当然,对于那些希望确定所生成的术语的重要性的人来说,生成参数错误估计。

我还提供了用于评估这些模型的工具,并分辨模型。

一个警告-小心使用高阶多项式来拟合你的数据。仅仅因为低阶模型有效,高阶模型并不一定更好。高阶多项式常常在数据点之间产生严重的环。总是绘制你的数据。想想你将要构建的模型。然后绘制结果模型。使用您的眼睛来验证结果,而不是简单地查看r平方系数(尽管我也返回了该参数)。

如果您确实发现高阶多项式模式是必要的,因为您的曲线太复杂了,考虑使用回归或平滑样条模型代替。

引用

John d'Errico(2020年)。Polyfitn.(//www.tianjin-qmedu.com/matlabcentral/fileexchange/34765-polyfitn), MATLAB中央文件交换。检索

意见及评分(123

分享得很好,约翰·德雷科。但有一点疑问,大多数情况下,当我们使用高阶多项式对大型数据集建模时,自变量矩阵的列变得线性相关,矩阵变得奇异。
一世。我们可以在正常运行中使用伪反转:232-241的Polyfitn?
二,。但是,这导致一些系数的方差变为零,t统计量变为NaN,如何克服这一问题?

y汉张

看起来很棒,似乎非常准确(比较我手动计算的几个)。但这简单地包裹起来,你可以点击一下你所需要的一切!做得好!

Heehang Kim

亲爱的,约翰D 'Errico
感谢您分享您的惠益代码
你能解释一下你用来求项数的方程吗。其实我是根据下面的公式计算二次模型的项数(系数)的

no =(n + 2)(n + 1)/ 2%n是变量的数量
目前,如果我使用3度或更多,我面临着计算系数数量的问题。请你帮助我好吗 ?

问候

任何人都知道如何在GPU上运行此功能,或者重大加速计算?

感谢您的工作。您是否知道如何使用多项式作为可接受优化的函数(例如fminimax)?多齿性的输入必须在此处向变化。

这只是工作正常。拇指向上。

术语[1 1 10 0]是一个三阶项,至少就polyfitn如何看待它而言。这是一个三方互动的术语。如果你想在你的模型中使用这个术语,你总是可以指定那个模型。

做得好!我只有一个问题。当我查看如何生成型号时,对于令我们说:
订单= 2;
p = 4;
我们得到:
modelterms =
2 0 0 0
1 1 0 0
1 0 1 0
1 0 0 1
1 0 0 0
0 2 0 0
0 1 1 0
0 1 0 1
0 1 0 0
0 0 2 0
0 0 1 1
0 0 1 0
0 0 0 2
0 0 0 1
0 0 0 0
varlist = {'x1'} {'x2'} {'x3'} {'x4'}
我的问题是,为什么有些组合缺失了,比如:
1 1 1 0
1 0 1 1

仍然是这个包的忠实粉丝!

嗨,约翰!令人惊叹的工作!我是Matlab的初学者,我正在尝试使用你的工具来获得曲线的等式。我有两组点,x和y,其中命令曲线(x,y)产生所需的曲线(https://imgur.com/a/nq7pqxa.)。我想要的是这个曲线的等式。是否有可能使用您的工具或者我得到了所有错误吗?非常感谢 :)

请在下面的地址上找到纠正版本的函数,该函数采用Massimo CIACCI解决方案,并在确定系统时修复贝纳因素错误(ndata == nterms)。
http://ecco-qua.modexpeng.com/?fi=ivap1ne6ir&fn=polyfitn.m.

希望它有助于他人

在第419行中找到了一个简单的错误:
-------------
如果没有这种修复,它会用一个术语像'y ^ 2 * x ^ 2'一起射击解析错误
K > > pTot = polyfitn ([YY (:), XX (:)), Zfunc (:), Y Y ^ 2 Y * X ^ 2 Y ^ 2 * X ^ 2”)
使用Polyfitn> ParseModel(第379行)错误
变量不是一个有效的名称:'2'
-------------
解决办法:
项=项(1 + k1:结束);修复解析错误
%术语(k1(1))='';

-------------

使用此修复,指数部分也从术语字符串中消耗,而不会留下类似的内容
'x ^ 2 * x ^ 2'
“^ 2 * X ^ 2”
'2 x ^ 2'<---错了
“X ^ 2”<,对吧

这太棒了!它像魅力一样工作。对于那些有1D Vector X,Y和矩阵Z的人来说,这样做可能会有所帮助
[X,Y]=ndgrid(X,Y);
p = polyfitn ([X (:), Y(:))、Z(:),“恒X1 X1 ^ 2 X2 ^ X1 * X2”)%
谢谢这个伟大的工具!

loi dang.

桑托什

Zuzkat.

请,如何解决“贝卡因”错误?

一直在找到这个工具非常有用!
这也适用于电力法拟合吗?如果是的话,那是什么语法?提前致谢!

Catsui.

对不起,在发布消息后,我终于找到了“下载”...... - '非常感谢你

在这里,在文件交换,我发现了工具“permn”。
permn (0:2, 2)
给出完整二次模型的所有9项。

伟大的工具!
但是,我注意到,如果我使用polyfitn([x1 x2],y,2),则模型项不包含混合项[21]和[12]。仅使用混合术语[1]。这是有意的吗?还是虫子?

@Jacob如果您的数据在10x10网格中组织,x,y和z向量都将每个值都有100个值。x和y将重复10次不同的网格值。这与您使用的散射3绘图功能相同。这样做是更有用的,因为它没有*要求*您的x和y值要组织为网格。

@Chad:
谢谢乍得!是的,我最终算出来了,但我还是不明白为什么z是x - y平面上的数据分布当它的大小不是n_x x n_y?

@雅各布:
polyfitn的语法要求x,y,和z在polyfitn(x,y,z…是列向量或行向量,而不是网格。

嘿约翰,
谢谢你这个功能!我有一个问题:由于我在matlab中绝对缺乏知识,我无法围绕下面迈出我的头:我有一个(x,y)的飞机/网格 - 让我们说10x10 - 以及z = f的测量数据点(x,y)。所以z是一个10x10矩阵,100个条目。每当我尝试polyfitn([x,y],z,3)matlab告诉我,z必须是向量,而不是矩阵。您的“手动”表示,Z必须具有尺寸NX1,其中n是x或y的大小。但我没有得到z如何只有10个条目而不是10 ^ 2。如果你能帮助我,那就太好了。欢呼雅各

秦旭

嗨,约翰,
谢谢你的Polyfitn工具箱,这是一个很好的帮助!

我正在处理一个4-5个输入参数(从excel文件导入,一个列向量)和一个参数的问题,其他参数依赖于这个参数。
我用CF工具箱和两个参数验证了我的函数。
当我用第三个输入参数尝试时,我收到警告:

警告:矩阵接近奇异或严重缩放。结果可能是不准确的。rcond = 1.794064e-17。

此外,我检查了R2(=0.9495),我认为结果调整得太好了。

你能想出一个可能的方法来解决这个问题吗?还是我遗漏了什么?
我认为尤其是使用多维问题的工具箱。

如果你能想到任何可以帮助我的事情,我将非常感激!

非常感谢,
为托拜厄斯干杯

这是我的编码。

x = durchmesser3;
y = plattendicke3;
w=情绪3;
z = Kraft3;

p = polyfit ([w] x, y,, z, 2);

如果存在('sympoly')==2
polyn2sympoly(p)
结尾
如果存在('sym')== 2
polyn2sym(p)
结尾

@拉蒙:

a + b * sqrt(x):
Polyfitn(x,y,[0; 1/2])

a + b / x:
Polyfitn(x,y,[0; -1])

Jaime

约翰! !谢谢。不用多说了,我要给它编程。谢谢!;)

它是polyfit,能够适合以下功能:

a + b * sqrt(x)或a + b / x

还是

非常感谢这个工具箱,很棒的帮助!

它是否能够替代统计工具箱中的stepwiseglm功能?

有没有具体的会议论文来解释polyfit的整个过程?
它真的有助于挖掘算法,而不是试图了解编码。
谢谢

Suzie阿曼

有没有人有一个例子是如何在3D中使用它?

谢谢!

我正在寻找一种使用多项式适应3D字段的方法。此功能完全快速地解决了任务。

谢谢分享!

嗨,约翰!我是Matlab的初学者。我需要找到一个曲面的多项式拟合,它有两个向量x和y。

X是1x191, y是1x51。

然后我有飞机z,哪个尺寸为51x191。

我可以用:
表面(x,y,z)

但我不明白我怎么能用你的文件来找到我的方程式。

谢谢你的回答!

安培

我克服了新的新秀并设法现在成功使用它。完全巫术!谢谢。

嗨,约翰,
我可以首先说我是一个严重的matlab新秀。我有三套录制的数据,我使用了散点interpolant和meshgrid来创建一个表面图。我现在想要找到这个表面的公式。但是在输入三个数据集时,我会得到“使用betainc错误
Z必须是实数
非负面。

Polyfitn错误(线条
266)
polymodel。P =
Betainc(polymodel.dof ./(t。^ 2
+
polymodel.dof),polyodel.dof / 2,1 / 2);“

Z变量都是25到26之间的正数。我不确定这是否是使用三个特定的数据集而不是从函数中获取数据的问题。

非常感谢。

Mimo-我不知道你在问什么。

你问的是,是否只有一个变量x,但有多个y向量?Polyfitn不是用来解决这种形式的问题,但它将只是Polyfitn内部的一个循环。我想我可以写polyfitn来循环y的列。这是我下次发布的一个想法。:)

问题是您使用Polyfitn来简单地计算回归系数,或者如果您想要整个九个码,即标准错误,R ^ 2等。

例如,如果你的问题就像你描述的那样简单……

假设X是数据的NX1列向量,独立变量向量,修复了所有问题。Y是NXP阵列,因此您需要解决P分开问题。然后可以轻松找到回归系数:

ab = [(n, 1), x (:)] \ y;

数组AB将是2xP阵列,其中每列AB是一组回归系数。所以第一行AB将是每个问题的常量术语。

a = ab(1,:);
b = ab(2,:);

同样,这并不提供任何统计数据,R ^ 2等,但这是一个简单的解决问题,我认为你已经提出了。

mimo.

嗨,约翰,
这个功能很棒。我刚刚遇到这个问题,如果可以以“y(i)= a(i)+ b(i).x”的形式找到多线性回归,只有单个变量“x”,通过找到向量A(i)和b(i)?

假设和是变量,那么就这样做:

mdl = polyfitn([phi(:),theta(:)],z(:),2);

您可能需要使用meshgrid或ndgrid(根据需要)来生成phi和theta。

嗨,伙计们!我一直在做一个三维图,(从- /3到/3的点)和都是一样的,每个点都有一个值z,所以最后我得到了和的每个可能组合的矩阵。我想多项式地近似矩阵中的点在和的函数中。我已经看了polyfit但是你必须放的点(z)不可能是一个矩阵。Polyfit也不行因为它只适用于2D (,z)或(,z)

不错的工作!

除了基本的东西,什么都没有。(我承认旁观者清。)就是经典的多元线性回归。参见Draper和Smith关于回归分析的任何文本。所以任何来自统计工具箱的工具都可以做同样的事,只要你为你的模型准备了适当的设计矩阵。

亲爱的约翰

谢谢你的好工具。我积极使用它,它的工作量很好。我想学习你正在使用的方法。我想知道你是否知道在哪里可以找到相关理论。

欢呼,

塞巴斯蒂安

Netorha.

你好约翰,
非常感谢您的伟大脚本。它非常好!

但是,我有一个关于一个问题的问题,这有点困难......实际上我通过使用以下代码(其中Arr_node_coords_y,_x和Arr_temperuiteField是33x5矩阵的Matlab Fit()执行数据拟合:

[xData, yData, zData] = prepareSurfaceData(arr_node_coords_y, arr_node_coords_x, arr_temperaturefield);

%设置安装类型和选项。
ft = fittype('poly24');
opts=fitoptions(英尺);

%适合数据的模型。
[fitresult, gof] = fit([xData, yData], zData, ft, opts);

%的阴谋
子图(2,2,2);
h = plot(fitresult, [xData, yData], zData);
轴([0 2.5 0 8 20 60]);
Xlabel('宽[m]');
ylabel('高度[m]');
zlabel('温度[°C]');
标题('Fit'的温度);
网格;
用([8 8 60]);
彩色杆;

......有可能,用polyfitn()执行相同的东西吗?... - 我以几种方式尝试了,但不幸的是我没有找到工作解决方案。

也许有人可以帮助我......?

rihab.

你好,约翰
我将100x1,100x1的数据作为一个独立的变量和依赖变量作为100x100,也是它的复杂号码。您可以帮助我解决多项式适合吗?
当我一直试图为一个因变量的对角线元素做polyfit,它显示'错误使用betainc
输入必须是真实的,完整的,双或
单身的'。
它意味着什么,我如何克服这个问题?

@sagar - 但这不是多项式模型。因此,您无法使用工具进行多项式模型来适合任何一般非线性模型。使用非线性回归工具。曲线拟合工具箱是最简单的选择,但是有许多其他人,在统计或初始化工具箱中为启动器。或者使用像fminsearch或fminbod这样的优化器,但您需要最小化残差的平方和。

Sagar.

嗨,优秀的功能。我知道我们可以做到:poly_fit = polyfitn(x,y,3);用于测试输入变量的所有组合(例如x1和x2)。但是,如果我想构建自定义输入指数,我该怎么办,我想适合这样的东西:
poly_fit = 2.3x1 ^ 3 + 1.5e ^ -x2

我该怎么做呢?

阿卡什

修复了南问题。对于那个很抱歉。

约翰·德埃里科(John D’errico)提交的众多优秀作品之一。

如果因变量包含任何nan,就会产生令人困惑的betainc错误。我建议在代码的早期添加这个错误检查:

assert(sum(isnan(depvar))==0,“因变量不能包含任何nan”。)

j

难以置信的谢谢你的贡献!

Akshay.

工作伟大,应该包括在标准包

Christoph.

嗨,约翰,

我使用“Polyfitn”找到基于三个输入变量的非线性系统的不同参数的多项式。在三个方程中插入这些多项式,然后我试图“向其定位”,但通过插入不同订单的多项式,我无法收敛到一个解决方案。

我一直在通过文件交换列表查找其他相关代码。我想知道我是否应该尝试使用一些样条方法而不是'polyfitn',但我不确定如何在方程式中插入它并解决它们。同时求解三个非线性方程的任何其他方法。

谢谢

约翰

我很抱歉,但我只能假设像米奇一样的豪华,正在使用一个相当旧的matlab释放。

如果你真的想解决这个问题,你应该提供足够的信息让我知道是不是这样。既然你描述的测试用例工作得很好,正如我在这里展示的,我的建议是使用一个合理的最近的版本,既然Mitch说他使用的是一个7年前的版本,并且得到了同样的错误,我认为这就是情况。

如果您确实在使用一个最近的版本,并且仍然有问题,那么我只能假设您使用不当,或者您安装了导致问题的其他东西。例如,当我执行这个测试时,它运行得很完美,但我没有一个7年前的MATLAB版本,我甚至不能运行那么旧的东西。

indvar =兰德(12,2);
depvar=rand(12,1);
m = [0 0;1 0;0 1;2 0;1 1;0 2;3 0;2 1;1 2;0 3];
P = Polyfitn(Idvar,depvar,m)
P =

ModelTerms (10 x2双):
系数:[-0.0610 -4.6966 5.5355 27.4400 -24.9658 -0.4228 -32.4825 42.3187 -18.4250 5.9917]
ParameterVar: [12.5177 249.5518 129.5089 850.2142 511.0641 282.0906 504.6530 953.0042 477.2848 209.7347]
Parameterstd:[3.5380 15.7972 11.3802 29.1584 22.6067 16.7956 22.4645 30.8708 21.8468 14.4822]
DOF:2
p:[0.9878 0.7943 0.6748 0.4460 0.3845 0.9822 0.2851 0.3040 0.4878 0.7192]
R2:0.6497
调整后的D2:-0.9265
RMSE: 0.1327
varnames:{'''}

没有你的有用信息,我无法猜出问题是什么。我在此上下文中引用的信息将涉及告诉我您拥有的Matlab版本。它将涉及告诉我完整的错误消息,而不仅仅是一个错误消息的片段。

顺便说一句,尝试用一个有10个术语的模型拟合一个只有12个数据点的数据集将产生一个几乎毫无意义的结果。我认为这是一个严重过度拟合数据的案例。

Gautam

D'Errico先生,非常感谢您的提交。它看起来非常有用,除了我给出12 x 2矩阵作为独立变量矩阵和从属变量的12 x 1列矩阵时,它会显示以下结果:
未定义的功能或变量“Varlist”。

Polyfitn错误(第233行)
polymodel.varnames = Varlist;

我使用的模型是这样的:
m = [0 0;1 0;0 1;2 0;1 1;0 2;3 0;2 1;1 2;0 3];

有关如何为我工作工作的任何建议将非常有帮助和极大地赞赏。非常感谢你。
Gautam。

米奇,

它与你认为它在你的测试中被正确定义无关。我只是不知道它的定义是什么,因为你给了我除了这个变量以外的所有东西。所以除非你能给我一个可建构的失败的例子,否则我不知道你在做什么。我使用了一个不同的变量名是完全不相干的。我可以把传入的变量命名为Fred和Barney,它就会运行。

我也不知道这个旧的MATLAB版本是否有问题。这个网站告诉我,我用R2007b编写了这个工具,所以它应该对你有用,但也可以想象,多年来对它做的一个mod现在在旧版本中失败了。这是我无法测试的东西,因为我不能使用那个旧的MATLAB版本。

所以我的第一个建议是运行我给出的测试。验证它是否正确运行。如果它没有运行,那么您需要查看您拥有的测试中的输入参数有什么不同。或者您可以向我发送您拥有的数据,如果您不想在线发布。

如果问题是您的旧版本确实是问题,那么您将需要学习使用反斜杠(并不是那么困难)来解决问题,或者也许可以获得统计工具箱的副本。

嗨,约翰,
谢谢你的快速回复。
很抱歉,我的问题中缺少数据,但我的变量err_func是您的输出,它是定义的。
我检查所有变量尺寸,它们是正确的。
然后我尝试复制并浏览您的榜样并显示相同的错误:

??? 未定义的函数或变量“varlist”。

在==> polyfit232出错
polymodel.varnames = Varlist;

与我的Matlab版本(R2007b)相关的问题是否存在?

提前致谢
米奇

米奇,

我不知道你在做什么。我的初步猜测是你试图从编辑器或类似的东西“运行”函数。你没有这样的函数,虽然很多人都试图这样做。

我确实看到您没有在示例中定义变量err_func,所以我甚至不能真正猜出您的错误是什么。

inpar =兰特(20,2);
outpar =兰特(20,1);
model_exp = [1 0; 2 0; 0 1; 1 1; 0 2];
p = polyfitn (inpar outpar model_exp);

这个测试用例运行得很好。

嗨,约翰,
感谢您的大提交。
我试着在我自己的数据上使用它。但是我不能正确设置modelterms参数:

IE。

in_par = [zeta theta];
model_exp = [1 0; 2 0; 0 1; 1 1; 0 2];
p = polyfitn(in_par,err_func,model_exp)

运行后出现以下错误:

??? 未定义的函数或变量“varlist”。

在==> polyfit232出错
polymodel.varnames = Varlist;

==> launch_regr in 14的错误
p = polyfitn(in_par,err_func,model_exp)

你能帮帮我吗?

我想仍然乞求这个问题,polyfitn需要具备适合多个右手侧面的能力,即,相同的模型,但对于多个依赖变量?

就我个人而言,我发现这几乎不需要,当我在前世支持一大群色彩科学家时,我们确实使用了这种能力,它实际上只对构建监控模型有用。从那时起,监视器变得更加复杂,因此线性度降低。我猜想,使用更复杂的模型可以更好地处理较新的显示器。对于打印机等,这当然万博1manbetx是正确的,最好使用三维查找表进行处理,通过像我自己的gridfit这样的工具进行调整。

但事实是,我经常惊讶地发现别人以我没想到的方式使用这些工具。

因此,如果我看到至少有一些要求这种能力的人,我会考虑添加它。在此之前,我的偏好是为了简化代码在这方面。(嘿,我应该退休!)

我完全同意约翰的观点;我轻率地提出了那个建议,没有全盘考虑。对不起,我把你引入歧途了。谢谢约翰的建议和卓越的数学工具-它们是无价的!

我很抱歉,但我完全不同意马克给安德森的建议。

具有多个输出变量的系统不再需要Polyfitn的简单环路。该循环的成本根本不足以提高代码的复杂性和接口的复杂性。

相反,建议使用迭代方案,如高斯-牛顿,lsqnonlin,或lsqcurvefit,等等,这些都是荒谬的方法。你仍然需要循环,或者你需要产生一个很大的问题,本质上是一个块对角雅可比矩阵。这一切都是为了避免一个简单的循环?或者你会写一个循环,只是为了避免循环?注意,在Mark的建议中,您只需要编写一些代码来评估模型。如果你使用像lsqnonlin或lsqcurvefit这样的工具,那么你要么需要提供雅可比矩阵,要么需要让这个工具多次调用你的目标函数来计算有限差分来生成雅可比矩阵。

不要为了避免一个简单的循环而把迭代工具扔到一个问题上,在一个真正能用基本线性代数解决的问题上。请注意,即使迭代工具会迅速收敛,这些工具也会尝试进行多余的迭代,直到它有效地意识到它确实收敛了为止。这将需要一个备用的雅可比矩阵求值。

安德森

这个工具看起来很有用。但我是否正确地理解了它不适合具有多个输出变量的系统?如果是这样的话,有人知道有一种工具可以对具有多个输出变量的系统进行多项式拟合吗?

eran - 它可能是有趣的,但我认为它会鼓励人们适应太高的阶段,这是我不断被迫警告人们不做的事情。

由于您的想法需要在代码中添加更多选项,这将使代码更加复杂。同样,使用工具也不那么简单,因为如果生成并返回许多模型,那么像polyvaln和polyn2sym这样的工具将不能直接工作,或者还需要修改。

就效率的显着增长而言,请记住,只要代码中有更多选项,就会对基本用户变得效率较低。复杂的代码也更有可能有意外的错误。

所以我自己不会去做这种改进。你自己能做到吗?是的,理论上是可以的。为了提高效率,需要在建模过程中封装一个循环,可能使用qrupdate函数从模型中添加或删除术语。我不确定这与围绕整个代码的简单循环相比是否值得,只是重复调用polyfitn,除非您广泛使用该工具。

伊兰

你好再次,

非常感谢你的最后一个答案!
当然这是一个愚蠢的问题:)

我有另一个问题,这可能有点棘手 -
假设有一个n个点的集合。
我想检查每个k 当然,我可以做一个“for”循环,得到我的答案。。。但这是非常低效的。

有没有办法修改代码拆分,以便这将是工作?

我认为主要问题是您定义“Design Matrix”的部分。

再次感谢您的快速帮助!

作为一个延续,让我这样解释一下,因为这是回归中的常见问题。

当创建一个y = x/2的数据集时,数据位于一个不填充(x,y)平面区域的区域。相反,它完全位于y = x/2这条线上。实际上,x和y是完全相互依赖的,已知x,我们知道y的值。

问题是,当您的点脱落该线路时,我们没有关于z发生的事情的信息,因此没有估计完整模型的系数可能是令人满意的。

为了帮助说服您发生了什么,让您从您创建的原始函数z开始。

z = 4 + x + x。^ 2 + x。* y;

将y的已知关系代入z,使其仅作为x的函数。那么我们就可以:

Z = 4 + x + 1.5*x^2

我们可以把z仅仅看成是x的函数。

Out = Polyfitn(X,Z,2)
出=
Modelterms:[3x1双]
系数:[1.5 1 4]
参数var: [1.5362e-32 1.6407e-28 7.6808e-26]
Parameterstd:[1.2394E-16 1.2809E-14 2.7714E-13]
R2: 1
调整趋势:1
RMSE: 9.327 e-13
varnames:{'x1'}

这里没有提出警告,合适的基本完美,产生了我们预期的系数的值。我可以很容易地完成适合Z作为y的函数。

嗨,伊兰,

但想想你在做什么。

乍一看,我认为x比较大,因此这只是一个缩放问题。然后我看了看你的问题。这就是问题所在!

y = x / 2

你的模型是x和y的二次函数,因为它有x ^2 x *y和y ^2。当然,您希望polyfit会告诉您x.^2的系数为零,就像您创建数据时所隐含的那样。

但是你创建了y作为x的简单倍数。你应该看到x。* y == 2 * y。^ 2 == x。^ 2/2。

世界上没有一个线性代数方案可以智能地恢复这些项的系数,并知道从哪一组系数开始。解决方案并不是唯一的。这就是为什么你会收到关于奇点的警告。你会得到一个答案,但不是唯一的答案。

这里的故事是垃圾,垃圾出来。您的数据无法充分支持估计您希望适合的型号。万博1manbetx

伊兰

嗨jhon,

非常感谢您提供了这个必要的功能。很遗憾matlab不支持这个…万博1manbetx

我尝试使用这个函数,但遇到了一个小问题。
我使用:
x = 0:100;
y = x / 2;
z = 4 + x + x。^ 2 + x.y;
在= [x'y'];

Out = Polyfitn(Z,2);

我得到的是关于函数“QR”产生的矩阵“R”的单个的警告。当然,当我使用“\”实际上使用“r”的倒数。
在使用函数“qr”后,这在行中发生了两次。

您是否有任何建议如何解决此问题?

当然,我问这个问题,因为我得到了“Polyfitn”产生的系心与你所期望的那些......

非常感谢!

嗨,亚历克斯,

我想你想要Ezsurf,而不是Ezplot。例如,这对我有用:

xy =兰德(100 2);
Z = 3 + 2 * SUM(XY,2)+ SUM(XY。^ 2,2)+ 4 * PROD(XY,2)+ RANDN(100,1)/ 10;
模型=聚合体(xy,z,2);
有趣= polyn2sym(型号);
ezsurf(乐趣)

生态队伍

嗨,约翰,

这些功能很棒!

我用它来模拟两个垂直圆锥体的相交,这为我提供了一个三维空间中的抛物线。我想知道,有没有一种内在的方法来绘制合适尺寸的拟合曲线?我试着使用你的Polyni2Sym工具,然后使用ezplot,但它无法在3D中正确显示曲线。

谢谢,
亚历克斯
生态队伍

嗨雷蒙德,

这些参数的推导是为了适用于有噪声的模型。例如,假设我在一个点上得到了一个给定过程的10个度量值。常数模型的最小二乘最佳估计,因此y=c,由样本的均值给出。与此同时,我们可以计算均值估计值中的不确定性估计值,用它来计算参数周围的近似置信区间。我们可以用更复杂的回归模型做类似的事情,根据数据中感知到的噪声,对模型中的参数和这些参数周围的不确定性进行估计。噪声被认为是模型估计后剩下的东西。再一次,这将给出标准差的估价值我们可以把它放到参数上。(将提供的标准差乘以学生的t统计量,得到一个近似的置信区间。使用大约+/- 2或3 σ是得到置信区间的常用方法)

事实上,大多数时候你有更多的数据点比参数适合模型,我们也可以在这些参数中形成我们不确定性的估计。您拥有的数据越多,当然越好,因为它允许我们更好地估计参数。一件好事是我们甚至不需要纯粹的复制来形成对参数中不确定性的估计。不确定性基于模型无法在数据中预测的内容。

传统上,对于多项式模型,这些标准差估计是决定在模型中删除项的一种方法。如果置信区间包含0作为一种可能性,那么我们可以得出结论,我们不能将给定参数的估计与零区分开来。

至少这在传统模型中是真的,我们正在尝试将正确的模型适应我们的数据,并且所有阻碍这种过程的所有内容都是随机(高斯)噪声的存在。上述近似也假设参数是独立的,因此根据数据,x和x ^ 2通常不会是正交变量。缺乏正交性的缺乏在回归估计中引入了相关性,这是在用于报告的参数标准偏差的近似值中忽略了这一点。

当模型中缺乏适合时,这种方法存在额外的问题。在这里,我们正试图将一个模型适合数据,但实际上,该过程不是真正基于该模型的。我们选择的模型可能只是现实的近似,或者它可能是错误的。假设您有一个曲面,并且您尝试估计线性模型。在这种情况下,将有缺乏契合,因为该数据不受模型表示的很好。

当然,线性代数并不理解缺乏拟合不仅仅是纯粹的噪声。数学在这方面有点笨。它不能像我们一样看到残差的规律。它只相信残差是纯粹的噪声,并利用这些噪声用标准的统计技术估算参数的不确定性。

最后,我想说的是,这些标准偏差是软件根据您提供的数据、几种近似值以及您的模型对这些数据的有效性,对参数估计的粗略衡量。

嗨,约翰,

这是一个很棒的工具!我正在使用它来适应三维晶片上的磁场的二次函数。

我对适合参数的不确定性感兴趣。解释“parametersts”是正确的,因为这种不确定性?(如果不是,那是什么?),关于我如何确定如何鉴于我没有向代码提供测量不确定性的“parameterstsd”是有点困惑。你能解释一下这个“parameterstd”是如何计算的?

谢谢!
雷蒙德

yonatan - 系数的绑定约束不是选项之一。您可以使用像LSQNONNEG这样的工具用于基本的基本非负性约束。例如,如果x和y是列向量,则将A和B的非负系数作为向量,您将执行此操作:

ab = lsqnonneg([x,x。^ 2],y);

对于对系数的更复杂的约束,您通常希望从优化工具箱中等更换LSQLIN等工具。例如,如果您只想约束其中一个系数或者需要对系数的总和上的约束,则LSQLIN将是有用的。缺少该工具箱,还有其他工具,就像我自己的lee等文件交换,可以沿着这些行为您做一些东西,并且随着一些努力,您可以始终将许多常规问题转换为LSQNONNEG可以处理的那样。

yonatan

这很棒!
是否有方法仅限于仅限于正系数的功能?
例如,f(x)= a * x + b * x ^ 2用于正A和B?
提前感谢。

安德鲁

这太棒了!

Syeda.

潘晨云

你需要在模型中列出术语。例如,要指定一个总顺序不高于3,但y中没有立方项的模型,您可以指定modelterms参数为

modelterms = [3 0
2 1;
2 0;
1 2;
1 1;
1 0;
0 2;
0 1;
0 0]

或者,您可以通过为同一模型提供作为字符串的字符串列表来进行:

modelterms ='x ^ 3,x ^ 2 * y,x ^ 2,x * y ^ 2,x * y,x,y ^ 2,y,常数'

马丁

嗨,约翰,首先,干得好!
我的问题是,有可能对多项式使用两种不同的阶吗?因为我用一个6阶(n=6)的多项式来拟合我的函数(3D)。但是如果我的函数有一个多项式,比如在一个方向上是5,在另一个方向上是6 (m和n),那就太好了。
z(x,y)=a(n)*x^n+b(m)*y^m+a(n-1)*x^(n-1)+b(m-1)*y^(m-1)。。。

杰夫 - Polyfitn返回结构的原因是因为模型可能有些复杂,用户在多个变量中指定的一般术语。1-D多项式更容易描述为系数列表,因为1-D Polyfit总是假设一个非常特定的模型形式。

然而,从返回的结构中提取系数完全没有问题。例如,考虑这个简单的模型z(x,y)。

一些简单的数据…
x =兰德(10,1);
y = rand(10,1);
Z = x + 2*y + 3 + randn(size(x))/10;

%生成模型
mdl = polyfitn([x,y],z,{'x','y','常量'})
mdl=
Modelterms:[3x2双]
系数:[0.9706 2.0162 3.0302]
参数变量:[0.0214 0.0266 0.0093]
parameterstd:[0.1462 0.1631 0.0966]
R2: 0.9787
AdjustedR2: 0.9726
RMSE: 0.1180
varnames:{'x'y'}

当然,系数只是结构字段中的数字。所以我们可以将系数提取为向量:

格式长
c = mdl.cofficients.
C =
0.970599545975740 2.016179608143575 3.030225230230983

它们不是我所投入的内容,而是随机噪声对数据损坏了一点。

或者我们甚至可以把这个结构转换成一个符号多项式,一个符号,或者我自己的符号形式。

Polyn2sympoly(MDL)
ans =.
0.97059954597574 * x + 2.01617960814358 * y + 3.03022523023098

我们可以自己计算多项式不需要polyvaln,只要你知道模型是什么。(由于每个术语的指数都存储在结构中,这也很容易。)

C(1)*。5 + C(2)*。25 + C(3)
ans =.
4.019569905254746

进行比较:
polyvaln (mdl [5, .25])
ans =.
4.019569905254746

杰夫

约翰-干得好。问:我想我读到过用polyfitn解决的系数只能用polyvaln来解释。那是正确的吗?如果我想使用polyfitn来寻找数据拟合练习的系数,然后将它们应用到matlab之外的未来数据集(因此没有polyvaln),这是不可能的吗?或者,我误解了什么?

丹尼斯韦特,
感谢提供这个修复。它的工作原理!

约翰,很好的工作。
我遇到了一个小故障。
当将modelterms指定为指数数组时,变量“varlist”没有被赋值。
我通过在第160行插入以下代码来解决这个问题:
Else varlist = repmat({"},1,p);

尽管我写过polyfitn,高阶多项式(尤其是多维)很少能很好地替代选择具有适当行为的非线性模型。也就是说,如果您有这样一个模型。这些多项式会给你带来麻烦,尤其是在推断的时候。除非您有足够的数据,否则即使在您的数据中,模型也可能表现奇怪。我称之为内插问题。

基本上,您需要非常小心,高阶多项式适合。

顺便说一下,nlinfit DOES处理多个独立变量。你说没有,但没有限制。问题是在多个维度中选择一个智能模型。这在一般情况下是非常困难的。一个很好的原因是,像w = f(x,y,z)这样的函数形式很难形象化。

就我个人而言,我一直倾向于使用样条模型来解决这些问题。我经常不能凭空建立一个模型,我宁愿避免高阶多项式。我自己的网格匹配是一个简单的例子,有两个独立变量。

卡兰

你好约翰,

谢谢你的意见。我真的很感激。从我所理解的是,数据不足以使用这种高阶多项式拟合。我实际上正在看着数据拟合到我自己的自定义方程,但没有找到它的型号,而且类似于Nlin Fit,但是具有多个独立变量。如果您有任何建议,请告诉我。

谢谢你。

卡兰

嗨Karan,

你已经陷入了回归建模中的常见谬论。它如下:“如果n是好的,那么n + 1更好,n + 2必须真的很精彩。”

这个谬论很容易开始。我们在数据上尝试了一个线性模型。它可以工作,但不是很好。毕竟,must问题只是局部线性的。所以我们尝试一个二次模型。它更适合。缺乏配合的情况减少了。但这一模式仍存在问题。它不适合我们数据的形状。

既然我们在二次方程上做得很好,那就试试三阶模型。是的,它做得更好。哇。继续推进,直到我们有第6个订单,或者第10个订单。多项式模型就像泰勒级数近似,所以更多的项一定会给出更好的结果。但最终,这一切都变成了我们眼前的数字垃圾。那么发生了什么?

在这里,您有3个变量。第一阶模型具有常数项,以及x,y和z术语。那种模型中的4个术语。您有74个数据点,肯定没有问题估计相应的系数。

一个二次模型再加上6个项,x^2,y^2,z^2,还有交叉积项x*y,x*z和y*z,因此总共需要估计10个系数。

我们谬论的诅咒是,当我们按顺序向上移动时,项的数量增长得越来越快。在3阶,我们有20项需要估计,35项在4阶,56项在5阶,84项在6阶。第10个订单的型号将有286个条款。

你的数据怎么样?您只有74个数据点。(在我做一些统计咨询的早期时,我的客户总是问他们需要多少数据。我的答案几乎总是“比你更多。”

每个不同的数据点都是大多数其他信息。(复制点不算在这里。他们所做的一切都会减少您的估计中的不确定性。所以复制很好,但在某些方面不太有价值。)

更糟糕的是,新的数据点并不总是提供新的信息。例如,两个点决定一条线。直线上的第三个点对直线的斜率和截距没有增加新的信息。同样,就像一个复制,它所做的就是减少你对系数估计的不确定性。

那么当你试图估计只有74个数据点的第六阶模型时发生了什么?您的数据信息太少,以支持这么大型模型。万博1manbetx回来的消息来自Matlab,告诉您,您的矩阵是数值单数(排名缺陷。)

有了这一切,事情可能会变得更糟,使问题变得更加困难。一些数据比其他数据更糟糕。例如,如果将1E6添加到所有自动变量,则某些给定顺序的多项式仍将在数学上进行估计(理论上),但它可能导致数字单数的矩阵。这是因为使用双精度浮点算术编写线性代数。这些数字可以简单地躺在太宽范围内的动态范围,以便代数成功。(当你提出1E6的顺序到连续更高的力量时会发生什么?)

因此,当您有更多的系数来估计数据点时,您将始终具有级别缺陷矩阵,但根据数据本身,您仍可能仍有排名不足问题。

如果您的中心和缩放变量,某些多项式模型将变得更加易于估计。因此,使每个变量使其具有零的平均值,并且大致在间隔[-1,1]中。请参阅升高为+/- 1到更高权力的募集数字不会创建动态范围问题。这将迫使您改变问题,但它通常允许您获得其他难以解决的问题的可行估计。(使用正交多项式是另一种经常有帮助的方法。)

我希望这有帮助。真的,这是一门我见过的一个学期的课程,所以我只触及了表面。

约翰

卡兰

非常感谢你做的这些。我正在得到这个警告 -
警告:Rank deficient, Rank = 64, tol = 5.8216e-010。
我用了3个自变量,74个数据点,用了6度。您能帮我理解一下这是什么意思吗?谢谢你。

约翰,

像往常一样伟大的代码!

只有一个数据点时似乎失败了。

n = 1;
x =兰德(n, 2);
Y = EXP(SUM(X,2))+ RANDN(N,1)/ 100;
p = polyfitn (x, y, 3);

虽然失败在某些情况下可能是可取的,但它实际上应该抛出一个错误。您的代码确实为n-1个输入提供了n-param输出,因此处理这种情况并不矛盾。

我认为这是在第120行之后的逻辑中——检查输入的大小并相应地进行转置。

谢谢!

约翰 - 这里有两种可能的问题。首先,如果您遇到了已知多个右侧侧面的问题,那么是的,它是非常可矢量的。由此,我的意思是与相同的独立变量集的问题,但不同的依赖变量集。然后反斜杠是去的方式,允许您为大量节省提供一次次要方程式。您需要建立设计矩阵当然,但这不是一件难点。

但是,如果您有多个问题,每个问题都有不同的独立变量,然后矢量化将要求您构建稀疏块对角线设计矩阵。因此,您可以在这项努力中获得一点,但并不像第一种情况一样重要。您需要将设计矩阵构建为稀疏矩阵。这里的诀窍是将块提供给Blkdiage作为单独稀疏的矩阵。因此,在单元格数组中创建单个(稀疏)设计矩阵,然后将其传递给Blkdiag作为逗号分隔的列表。您能否就能实现这一点,使反斜杠比呼叫周围的循环更高效率?是的,但正如我所说,这将需要一些努力。

您可能会从我的回复中收集,以至于将结果从此代码中的结果传染措施不会是一个琐碎的动作,但您可以在投资的某个时间更有效地进行事物。

约翰

很棒的功能!

您能否建议任何方式向用户矢量化?我有一个标量函数,它取决于它在空间f(x,y,z)中的位置,并且我计算围绕n尸体的这个函数。目前,我为每个身体运行循环,但有没有办法修改代码,以便反斜杠运算符一次在它们中都在跨越所有,返回n个系数?

这应该这样做......

看看下面这两行:

[Q, R E] = qr (M, 0);

多元模型系数(E)=R\(Q'*depvar);

假设作为W的列向量,为每个数据点。更改上述行以阅读:

[q,r,e] = qr(bsxfun(@ times,w(:),m),0);

polymodel.coffients(e)= r \(q'*(w(:)。* depvar));

这应该为您提供参数的加权估计。我认为参数的统计数据也将工作,以及R ^ 2等。当然,您需要在体重向量中作为一个参数传递。

上面的更改假设您使用具有BSXFUN的版本。它已经存在了一段时间,所以不应该是一个问题。即使没有,对Repmat的呼叫也会替换它。

伟大的功能!谢谢你。是否会有一种简单的方法来将其转换为减重最小二乘法。我想自己自己做,也许你有一些见解或警告?

线性回归(polyfitn)在其核心使用反斜杠。例如,假设一个人希望使用polyfit估计一个变量的二次模型。模型是

Y = A1 * x ^ 2 + a2 * x + a3(+噪声)

Polyfit能够通过以最小化残差的平方和的方式求解线性(但过度的)方程式的线性(但过度的)系统来估计三个未知系数[A1,A2,A3]。同样,反斜杠是这里下面的发动机。

现在,假设有人想要估计一个更复杂的模型,它有两个独立变量z(x,y)。我把它写成一个完整的两变量二次模型,有6个未知数系数。

Z = a1*x^2 + a2*x*y + a3*y^2 + a4*x + a5*y + a6 +噪声

只要您有足够的数据来估计六个未知系数,问题基本相同。看到他们以与我们之前看的一个变量问题相同的方式线性进入问题。反斜杠再次可以解决过剩的问题以估计系数。

实际上,Polyfit和Polyfitn都使用设计矩阵的QR分解来实现其目标。这是因为它们都设计成在参数上生成协方差矩阵估计。QR分解是服务两个目的的最简单方法,但它只是线性代数。

德先生

谢谢..你的功能解决了我的问题,但老实说,我很好奇2D表面线性回归的概念。我们是否必须在每一行上做Polyfit(第一个订单)以获得最佳的表面拟合平面?

谢谢。

更新

1.3

为p和DoF添加了文档,在帮助中也添加了一个示例。

1.2.0.0

删除适合数据的NANS

1.1.0.0

在系数上加一个p值。

MATLAB版本兼容性
使用R2007B创建
与任何版本兼容
平台兼容性
视窗 苹果系统 Linux.

polyfitntools / demo / html /