数学建模指南
1、热爱建模
2、好好生活
3、特别的人关注数学建模
4、你好,建模人
让我们一起来了解一下十大算法之一的
数据处理算法基础造型因素°据处理算法种类多样,今天我们主要讲解数据拟合和参数估计。
数据拟合接下来我们一起看一个小例子
今天的例子呢就是一个简单的一元线性函数的拟合。拟合呢,通俗地说,就是找到一条目标曲线(直线),使得所有样本点到该直线的指标的总和最优。这个指标,可以使用均方误差,这个总和呢,就是均方误差的累和。
对于样本,我们通过下面两条语句来产生
x = 0.1:0.1:10; %产生首项为0.1,末尾项为10,公差为0.1的数组
y=x + randn(1,100); %产生与变量x等长度的数据,其值是在每个x数组元素上加上一个满足标准正态分布的随机数
由于目标是一元线性函数,所以只需要确定两个参数即可,k,b,k为斜率,b为直线对y轴的截距。
这里需要产生一对初始参数,选用的方法是:
k=mean(y)/mean(x); %即初始斜率为期望输出y的均值与输入均值的商
b=min(y); %初始截距为最小的期望输出
我们的实际输出为y',我们希望最后我们得到的直线能够满足以下指标:
其中n为我们的样本数,在这里就是100
由于 ,所以我们的指标还可以化为如下:
再回忆一下我们高等数学中的偏导知识,我们利用梯度下降法来更新我们的斜率,使得我们的指标最优:
上述两式分别为指标对k和b的梯度,所谓梯度下降,就是让我们的指标中的参数沿着负梯度变化,也就是k和b分别沿着指标对各自的偏导的负值进行变化,于是得到
但同时我们不希望k,b变化过大,出现梯度爆炸的情况,所以我们希望有一个比较小的数,来缩小单次k和b的变化量,于是我们得到:
通过多次迭代,使得指标J能够满足我们的要求,或者是:当我们的两个梯度很小时,比如我们设定到小于0.001,这样可以认为我们的J将基本不变,于是得到J的极小值。
具体程序:
test_x = 0.1:0.1:10;test_y=test_x + randn(1,100);k=mean(test_y)/mean(test_x);b=min(test_y);alpha = 0.025ya=k*test_x+b;err_mat=ya-test_y;err=[];for i=1:1000
delta_k=2*k/100*sum(test_x.^2)-2*b/90*sum(test_x)-2/100*sum(test_x.*test_y);
delta_b=-2*k/100*sum(test_x)+2*sum(test_y)/100+2*b;
k=k-alpha*delta_k;
b=b-alpha*delta_b;
ya=k*test_x+b;
err_mat=ya-test_y;
sum_err=sum((err_mat).^2)/100;
err=[err sum_err];
if abs(delta_k)+abs(delta_b)<0.0001
break;
endendplot(1:i,err);title('误差-迭代次数');xlabel('迭代次数');ylabel('均方误差');figure(2);plot(test_x,k*test_x+b);hold onplot(test_x,test_y,'+');legend('Result','Samples')
运行结果:
从上图可知,所得直线基本处于样本中间,而误差,即我们的指标,最终稳定到1,这里,我们的指标是前述J的二倍 。
顺便和大家说一下有关于Matlab出图的一个小技巧。当我们要把运行结果图放到论文中时,我们希望figure窗口的边框部分不要出现,操作如下:
1.点击文件:
2.导出设置:
3.√上这里:
关于运行结果:
误差可能可以进一步降低,因为我们收敛到的是局部极小值,并非是全局最小,进一步地优化我们的J,可以通过粒子群算法、遗传算法等仿生智能算法。
你学会了吗?