作图法求出直线的斜率a和截据b,可以确定这条直线所对应的经验公式,但用作图法拟合直线时,由于作图连线有较大的随意性,尤其在测量数据比较分散时,对同一组测量数据,不同的人去处理,所得结果有差异,因此是一种粗略的数据处理方法,求出的a和b误差较大。用最小二乘法拟合直线处理数据时,任何人去处理同一组数据,只要处理过程没有错误,得到的斜率a和截据b是唯一的。
最小二乘法就是将一组符合Y=a+bX关系的测量数据,用计算的方法求出最佳的a和b。显然,关键是如何求出最佳的a和b。
(1) 求回归直线
设直线方程的表达式为:
y=a+bx;
(2)然后后面一大部分bb的书上都有,我们要做的就是把数学公式转化成代码,仅此而已,说实话,我压根看不懂书上说杀玩意,毕竟数值老师也有点跟煞笔一样,记得刚开始几章一直讲天文地理的知识,什么九章算术里面的题目拿出来说,还让我们有兴趣去买,我有句妈卖批是一定要讲的,那么晦涩难懂的东西,你让我们看?跟个勺一样,后来就基本不去上课了..不过书上看不懂没关系,只需要转化成代码是能容易实现的:下面上自己的代码;
/********************************************
> File Name: spantwo.c
> Author:chendiyang
> School:WUST_CST_1501班
> Myblog:www.chendsir.com
> Mail:1441353519@qq.com
> Created Time: 2017年04月22日 星期六 22时29分41秒
************************************************************************/
#include <stdio.h>
#define MAX 30 //最多输入30个点进行线性拟和
typedef struct POINT//点的结构
{
double x;
double y;
}Point;
int main()
{
int m;//输入点的个数
int i;
Point points[MAX];//用来存储点
static double u11,u12,u21,u22,c1,c2;//用来构建法方程组的变量
double a,b,tmp;
printf("\n请输入点数:");
scanf("%d",&m);
if(m>MAX)
{
return 1;
}
if(m<=0)
{
return 1;
}
printf("\n请输入x点y点的坐标:\n");
for(i=0;i<m;i++)
{
scanf("%lf%lf",&points[i].x,&points[i].y);
}
//列出方程U(a,b)
for(i=0;i<m;i++)//即解法方程组
{
u21+=points[i].x;
u22+=points[i].x*points[i].x;
c1+=points[i].y;
c2+=points[i].x*points[i].y;
}
u12=u21;
u11=m;
//进行求解
a=(c1*u22-c2*u12)/(u11*u22-u12*u21);
b=(c1*u21-c2*u11)/(u21*u12-u22*u11);
//输出最小二乘解
printf("\n最小二乘解的线性方程为 :S(x)=%f+%fx\n",a,b);
return 0;
}
运行结果如图:
输入21个点进行线性拟合,输出最小二乘解.上面是在网上找的例题,结果是对的,不过为了试试书上的题目也是不是正确的,于是,在数值书的106面的例1,输入7个点,求出最小二乘解,结果如图:
结果显示:S(x)=0.842857+4.571429x ,107面书上的答案是:P(x)=0.843+4.57x,很明显,答案是正确的,而且我这个的精确度更高.此题目完毕!讲道理,这几天都在忙这个,压根不知道有什么意义。。