?? 新建 文本文檔 (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()
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 + -