📄 新建 文本文档 (2).txt
字号:
LI Yu
Academy of Management Science,Henan University,Kaifeng 475001,Henan,China
Abstract:The present paper studies the basic method of nonlinear regression analysis by computer,gives a program of curve fitting,analyzes the forecasting results and relative information by the best fitting curve model.
Key words:nonlinear regression analysis;curve fitting;curve model;standard error
在非线性回归分析时,将以往观测值描点并连接起来的手工绘图拟合方法有时是十分直观和有效的,但这种方法含有一定的主观性,且不能形成数学形式的回归方程,因而不能完全满足预测的需要.为非线性回归模型寻找一个回归方程,即通过对以往观测值进行曲线拟合求出最优拟合度的数学模型,是非线性回归分析中最重要的方法.一元非线性回归分析的曲线拟合方法,在自变量为时间因素的预测中经常遇到和使用.多元非线性回归分析也可采用曲线拟合的方法,但多元回归在研究非线性关系时,具有诸多限制和较大局限性,不是一种常用和有效的方法.在一元非线性回归分析时,曲线模型的种类很多,本文就以最常用的6种曲线为例,探讨利用计算机进行非线性回归分析的基本方法.
(1)线性模型.线性模型是曲线模型中最简单的一种,其数学公式为y=a+bx.
(2)逆线性模型.其数学公式为y=a+b/x.
(3)指数模型.也叫复比增长模型,其数学公式为y=k+abx.
(4)修正指数曲线模型.其数学公式为y=k+axb.
(5)逻辑斯谛曲线模型.呈S形,是生长曲线的一种,又称为皮尔曲线模型,其数学公式为y=1/(k+abx).
(6)二次曲线模型.是多项式回归模型中最简单、最常用的一种,其数学公式为y=a+bx+cx2.
1 曲线模型的线性变换
引入曲线模型后,就要采用曲线拟合的方法来确定哪种曲线能够最恰当地描述所采集的观测数据,这时可利用计算机对各种可能的曲线方程进行计算,求出各曲线的回归系数和拟合优度,从而选取最佳曲线模型进行预测.
为了通过回归分析求出各曲线模型的系数,需要将一些曲线方程变换为线性形式.其中:
y=a+b/x→y=a+b.(1/x);
y=k+abx→ln(y-k)=lna+(lnb).x;
y=k+axb→ln(y-k)=lna+b.(lnx);
y=1/(k+abx)→ln(1/y-k)=lna+(lnb).x.
2 曲线拟合程序
一元非线性回归曲线拟合程序根据自变量和因变量的观测数据,用最小二乘法对6种常见曲线进行拟合,推导出相应的回归常数、回归系数和标准误差,然后根据标准误差的大小选取曲线模型,并依此进行预测.由于对某些曲线方程进行线性变换时,采用了对数的方法,因此在拟合处理时,将略去对负数或0取对数的曲线类型.曲线拟合程序如下:
#include <math.h>
#include <stdio.h>
#define N 100
main()
{int i,j,e;
float Xc,Yc,X1,Y1,X2,XY,X2Y,X4,T,c,k,k2,k3,k4,x ;
float x[N],y[N],a[6],b[6];
static char *curve[]={″y=a+b*x″,″y=a+b/x″,″y=k+a*pow(b,x)″,″y=k+a*pow(x,b)″,″y=1/(k+a*pow(b,x)″,″y=a+b*x+c*x*x″};
for (i=0;i<N;++i){
printf(″\n请输入自变量观测值x和因变量观测值y:\n″);
printf(″x=″);
scanf(″%f″,&x[i]);
printf(″y=″);
scanf(″%f″,&y[i]);
}
for (j=0;j<6;++j){
printf(″\n\n\正在对曲线%d——%s进行拟合处理…\n″,j,curve[j]);
if(j==2||j==3||j==4){
printf(″请输入k的估计值:″);
scanf(″%f″,&k);
}
if(j==2)k2=k;
if(j==3)k3=k;
if(j==4)k4=k;
X1=Y1=X2=XY=X2Y=X4=T=0;
for(i=0;i<N;++i){
if((j==2||j==3)&&y[i]-k<=0||j==4&&1/y[i]-k<=0){
printf(″k的估计值不合理!\n″);
goto cend;
if(j==1 && x[i]==0‖j==3 && x[i]<=0){
printf(“观测值地乐趣用本曲线进行拟合!\n”);
goto cend;
}
switch(j){
case 1:
Xc=1/x[i];
Yc=y[i];
break;
case 2:
Xc=x[i];
Yc=log(y[i]-k);
break;
case 3:
Xc=log(x[i]);
Yc=log(y[i]-k);
break;
case 4:
Xc=x[i];
Yc=log(1/y[i]-k);
break;
default:
Xc=x[i];
Yc=y[i];
break;
}
X1+=Xc;
Y1+=Yc;
X2+=Xc*Xc;
XY+=Xc*Yc;
if(j==5){
X2Y+=Xc*Xc*Yc;
X4+=pow(Xc,4);
}
}
if(j<5){
b[j]=(N*XY-X1*Y1)/(N*X2-X1*X1);
a[j]=Y1/N-b[j]*X1/N;
if(j>1)a[j]=exp(a[j]);
if(j==2‖j==4)b[j]=exp(b[j]);
}
else{
a[j]=(Y1*X4-X2*X2Y)/(N*X4-X2*X2);
b[j]=XY/X2;
c=(N*X2Y-X2*Y1)/(N*X4-X2*X2);
}
for(i=0;i<N;++i){
if(j==0)T+=pow(y[i]-a[j]-b[j]*x[i],2);
if(j==1)T+=pow(y[i]-a[j]-b[j]/x[i],2);
if(j==2)T+=pow(y[i]-k-a[j]*pow(b[j],x[i]),2);
if(j==3)T+=pow(y[i]-k-a[j]*pow(x[i],b[j]),2);
if(j==4)T+=pow(y[i]-1/(k+a[j]*pow(b[j],x[i])),2);
if(j==5)T+=pow(y[i]-a[j]-b[j]*x[i]-c*x[i]*x[i],2);
}
prinf(″回归系数:\n″);
if(j<5)
printf(″a=%f,b=%f\n″,a[j],b[j]);
else
printf(″a=%f,b=%f,c=%f\n″,a[j],b[j],c);
printf(″标准误差:%f\n″,sqrt(T/N);
cend:continue;
}
for(;;){
printf(″是否进行预测(Y/N)?″);
if(e=getchar())=='N'‖e=='n')
break;
if(e=='Y'‖e=='y'){
printf(″请输入用于预测的曲线模型代码:″);
scanf(″%d″,&j);
printf(″请输入预测自变量X=″);
scanf(″%f″,&x
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -