Matlab寻找合适的系数
我有如下所述的x向量和y向量:Matlab寻找合适的系数,matlab,regression,Matlab,Regression,我有如下所述的x向量和y向量: x = [0 5 8 15 18 25 30 38 42 45 50]; y = [81.94 75.94 70.06 60.94 57.00 50.83 46.83 42.83 40.94 39.00 38.06]; 有了这些值,我如何才能找到系数y=a*(b^x) 我尝试过这段代码,但它在y=a*e^(b*x) 我知道插值技术,但我无法将其应用到我的解决方案中 非常感谢 因为y=a*b^x与log(y)=log(a)+x log(b)相同,所以您可以 >
x = [0 5 8 15 18 25 30 38 42 45 50];
y = [81.94 75.94 70.06 60.94 57.00 50.83 46.83 42.83 40.94 39.00 38.06];
有了这些值,我如何才能找到系数y=a*(b^x)
我尝试过这段代码,但它在y=a*e^(b*x)
我知道插值技术,但我无法将其应用到我的解决方案中
非常感谢 因为y=a*b^x与log(y)=log(a)+x log(b)相同,所以您可以
>> y = y(:);
>> x = x(:);
>> logy = log(y);
>> beta = regress(logy, [ones(size(x)), x]);
>> loga = beta(1);
>> logb = beta(2);
>> a = exp(loga);
>> b = exp(logb);
所以a和b的值是
绘制拟合曲线
>> plot(x, y, '.', x, a * b .^ x, '-')
给你这个-
注意回归
函数来自统计工具箱,但是您可以定义一个非常简单的版本,它可以满足您的需要
function beta = regress(y, x)
beta = (x' * x) \ (x' * y);
end
因为y=a*b^x与log(y)=log(a)+x log(b)相同,所以您可以
>> y = y(:);
>> x = x(:);
>> logy = log(y);
>> beta = regress(logy, [ones(size(x)), x]);
>> loga = beta(1);
>> logb = beta(2);
>> a = exp(loga);
>> b = exp(logb);
所以a和b的值是
绘制拟合曲线
>> plot(x, y, '.', x, a * b .^ x, '-')
给你这个-
注意回归
函数来自统计工具箱,但是您可以定义一个非常简单的版本,它可以满足您的需要
function beta = regress(y, x)
beta = (x' * x) \ (x' * y);
end
作为Chris Taylor给出的答案的扩展,该答案在对数变换域中提供了最佳线性拟合,您可以通过直接解决非线性问题,在原始域中找到更好的拟合,例如 例如,使用Chris给出的解决方案作为起点:
x = [0 5 8 15 18 25 30 38 42 45 50];
y = [81.94 75.94 70.06 60.94 57.00 50.83 46.83 42.83 40.94 39.00 38.06];
regress = @(y, x) (x' * x) \ (x' * y);
y = y(:);
x = x(:);
logy = log(y);
beta = regress(logy, [ones(size(x)), x]);
loga = beta(1);
logb = beta(2);
a = exp(loga)
b = exp(logb)
error = sum((a*b.^x - y).^2)
其中:
>> a, b, error
a =
78.862758878038164
b =
0.984328823937827
error =
42.275290442577422
您可以进一步迭代以找到更好的解决方案
beta = [a; b];
iter = 20
for k = 1:iter
fi = beta(1)*beta(2).^x;
ri = y - fi;
J = [ beta(2).^x, beta(1)*beta(2).^(x-1).*x ]';
JJ = J * J';
Jr = J * ri;
delta = JJ \ Jr;
beta = beta + delta;
end
a = beta(1)
b = beta(2)
error = sum((a*b.^x - y).^2)
给予:
>> a, b, error
a =
80.332725222265623
b =
0.983480686478288
error =
35.978195088265906
作为Chris Taylor给出的答案的扩展,该答案在对数变换域中提供了最佳线性拟合,您可以通过直接解决非线性问题,在原始域中找到更好的拟合,例如 例如,使用Chris给出的解决方案作为起点:
x = [0 5 8 15 18 25 30 38 42 45 50];
y = [81.94 75.94 70.06 60.94 57.00 50.83 46.83 42.83 40.94 39.00 38.06];
regress = @(y, x) (x' * x) \ (x' * y);
y = y(:);
x = x(:);
logy = log(y);
beta = regress(logy, [ones(size(x)), x]);
loga = beta(1);
logb = beta(2);
a = exp(loga)
b = exp(logb)
error = sum((a*b.^x - y).^2)
其中:
>> a, b, error
a =
78.862758878038164
b =
0.984328823937827
error =
42.275290442577422
您可以进一步迭代以找到更好的解决方案
beta = [a; b];
iter = 20
for k = 1:iter
fi = beta(1)*beta(2).^x;
ri = y - fi;
J = [ beta(2).^x, beta(1)*beta(2).^(x-1).*x ]';
JJ = J * J';
Jr = J * ri;
delta = JJ \ Jr;
beta = beta + delta;
end
a = beta(1)
b = beta(2)
error = sum((a*b.^x - y).^2)
给予:
>> a, b, error
a =
80.332725222265623
b =
0.983480686478288
error =
35.978195088265906
另一个选择是使用MATLAB,它允许您以交互方式生成拟合,还可以发出运行拟合所需的MATLAB代码
另一个选择是使用MATLAB,它可以让您以交互方式生成拟合,还可以发出运行拟合所需的MATLAB代码
我喜欢这一点,虽然这实际上是一个数学问题,而不是一个编程问题,但它很快就解决了。我要说我是一个数学家,而不是一个程序员,所以这个问题显然非常适合我!为什么我不能像你提到的那样实现log(y)=log(a)+x log(b)?如果没有回归或测试版,可能我正在使用这段代码,但实际上我没有得到解决方案。你能再描述一下吗?@Hayra我不明白你的问题是什么-你能再说一遍你的问题吗?我喜欢这样,虽然这实际上是一个数学问题,而不是一个编程问题,但它很快就解决了。我要说我是一个数学家,而不是一个程序员,所以这个问题显然非常适合我!为什么我不能像你提到的那样实现log(y)=log(a)+x log(b)?如果没有回归或测试版,可能我正在使用这段代码,但实际上我没有得到解决方案。你能再描述一下吗?@Hayra我不明白你的问题是什么-你能再说一遍你的问题吗?谢谢。看起来你的循环做了20次梯度下降迭代-对吗?这是高斯-牛顿的例子。它具有更快的收敛速度,并且不需要hessian函数。我们可以实现梯度下降,甚至是纯牛顿,因为海森函数很容易计算。谢谢。看起来你的循环做了20次梯度下降迭代-对吗?这是高斯-牛顿的例子。它具有更快的收敛速度,并且不需要hessian函数。我们可以实现梯度下降,甚至是纯牛顿,因为海森函数很容易计算。