一元多项式回归

设拟合多项式为φm(x)

在这里插入图片描述

残差平方和

用最小二乘来确定系数a0,a1,…,am,设残差平方和
在这里插入图片描述
Q对ak求偏导数,并令其等于零,有
在这里插入图片描述
写成矩阵形式为:
在这里插入图片描述
在这里插入图片描述
(上面的方程是解别人的图,原址奉上:https://www.cnblogs.com/144823836yj/p/5524610.html
接下来就是解线性方程组

增广矩阵法

由于需要构造系数为1,将进行大量浮点运算,况且矩阵的元素肯能很大,会出现大吃小的可能,会引入大量误差

在数据量少,阶数较小时适用

x=c(1,2,3,4,5)
y = c(1,1.5,3,4.5,5)
二次多项式拟合增广矩阵

5.0 15.0 55.0 | 15
15.0 55.0 225.0 | 56
55.0 225.0 979.0 | 231
解为 -0.3 ,1.1 ,0.0
x矩阵为非正定矩阵,秩为2,拟合为一次项

逆矩阵法

在这里插入图片描述
依旧计算量相当大,浮点运算误差影响更大

R代码

三次多项式拟合

x=matrix(c(5.0,	15.0,	55.0,	225.0	,
           15.0,	55.0,	225.0,	979.0	,
           55.0,	225.0,	979.0,	4425.0,	
           225.0,	979.0,	4425.0,	20515.0	),
         nr=4,nc=4)
b=matrix(c(15.0,	56.0,	231.0	,1007.0	),nr=4,nc=1)
c=solve(x)%*%b
a=matrix(c(1.5,-1,0.5),nr=3,nc=1)

> c
           [,1]
[1,]  2.5000000
[2,] -2.8333333
[3,]  1.5000000
[4,] -0.1666667

solve(x)为求x的逆矩阵
solve(x,b)可直接求解xa=b

针对对称矩阵有LDLT分解法(LT为L的转置)

在这里插入图片描述

java代码

public class CurveFit {
	public static void main(String[] args) {
		double[] x=new double[] {1,2,3,4,5};
		double[] y=new double[] {1,1.5,3,4.5,5};
		
		show(curveFit(x,y,3));
	}
	public static double [] curveFit(double[] x,double[] y,int pow) {
		double[][] matrix=createMatrix(x,y,pow);
		LDLTDCMP(matrix);
		double [] xy=iteration(y,x,pow+1);
		LDLTBKSB(matrix,xy);
		return xy;
	}
	public static double[][] createMatrix(double[] x,double[] y,int pow) {
		double [] xx=iteration(x,x,2*pow);
		double[][] matrix=new double[pow+1][pow+1];
		matrix[0][0]=x.length;
		for(int i=0;i<pow+1;i++) {
			for(int k=0;k<pow+1;k++) {
				if(i+k>0) {
					matrix[i][k]=xx[i+k-1];
				}
			}
		}
	
		return matrix;
		
	}
	public static double[] iteration(double[] start,double [] value,int count) {
		double[] itr = null;
		double[] ret = new double [count];
		for(int i=0;i<count;i++) {
			if(i==0) {
				itr=start.clone();
			}else {
				itr=mul(itr,value);
			}
			ret[i]=sum(itr);
		}
		return ret;
	}
	public static double[] mul(double[] a,double[] b) {
		double[] c=a.clone();
		if(a.length==b.length) {
			for(int i=0;i<a.length;i++) {
				c[i]*=b[i];
			}
		}
		return c;
	}
	public static double sum(double[] a) {
		double ret=0;
		for(int i=0;i<a.length;i++) {
			ret+=a[i];
		}
		return ret;
	}
	
	public static void LDLTDCMP ( double [][]a)
	{
	    int k=0,m=0,i=0,n=a.length;
	    for (k = 0; k < n; k++)
	    {
	        for (m = 0; m < k; m++) {
	        	a[k][k] = a[k][k] - a[m][k] * a[k][m];
	        }  
	        if (a[k][k] == 0)
	        {
	            return;
	        }
	        for (i = k + 1; i < n; i++)
	        {
	            for (m = 0; m < k; m++)
	                a[k][i] = a[k][i] - a[m][i] * a[k][m];
	            a[i][k] = a[k][i] / a[k][k];
	        }
	    }
	}

	public static void LDLTBKSB ( double[][]a, double []b)
	{
	    int i;
	    int k;
	    int n=a.length;
	    for (i = 0; i < n; i++){
	        for (k = 0; k < i; k++)
	            b[i] = b[i] - a[i][k] * b[k];
	    }
	    for (i = n - 1; i >= 0; i--){	       
	        b[i] = b[i] / a[i][i];
	        for (k = i + 1; k < n; k++)
	            b[i] = b[i] - a[k][i] * b[k];
	    }
	}
	
    public static void show(double[][] array) {
    	for(int i=0;i<array.length;i++) {
    		double[] itme=array[i];
    		for(double out:itme) {
    			System.out.print(out+"\t");
    		}
    		System.out.println();
    	}System.out.println();
    };
    public static void show(double[] array) {
    	for(double out:array) {
    		System.out.print(out+"\t");
    	}
    	System.out.println();
    	System.out.println();
    }
}

LDLTDCMP为矩阵分解 ,LDLTBKSB为求解,两个方法是网上看见的,非常精炼,自愧不如,拿来就用
运行结果:

2.500000000000047 -2.833333333333396 1.5000000000000235 -0.1666666666666693

R语言多项式回归

x=c(1,2,3,4,5)
y = c(1,1.5,3,4.5,5)
xy=data.frame(x=x,y=y) 
#model <- lm(xy$y ~ poly(x,3))
model <- lm(xy$y ~  x + I(x^2) + I(x^3))

回归模型

> model

Call:
lm(formula = xy$y ~ x + I(x^2) + I(x^3))

Coefficients:
(Intercept)            x       I(x^2)       I(x^3)  
     2.5000      -2.8333       1.5000      -0.1667   

模型摘要

> summary(model)

Call:
lm(formula = xy$y ~ x + I(x^2) + I(x^3))

Residuals:
         1          2          3          4          5 
 3.052e-16 -1.221e-15  1.831e-15 -1.221e-15  3.052e-16 
Coefficients:
              Estimate Std. Error    t value Pr(>|t|)    
(Intercept)  2.500e+00  1.256e-14  1.990e+14 3.20e-15 ***
x           -2.833e+00  1.642e-14 -1.726e+14 3.69e-15 ***
I(x^2)       1.500e+00  6.094e-15  2.461e+14 2.59e-15 ***
I(x^3)      -1.667e-01  6.729e-16 -2.477e+14 2.57e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2.554e-15 on 1 degrees of freedom
Multiple R-squared:      1,	Adjusted R-squared:      1 
F-statistic: 6.39e+29 on 3 and 1 DF,  p-value: 9.196e-16

p值9.196e-16接近于0说明完美拟合。

拟合图像

x=c(1,2,3,4,5)
y = c(1,1.5,3,4.5,5)

f1=function(x){
  -0.3+1.1*x
}
f3=function(x){
  2.5-2.83*x+1.5*x^2-0.167*x^3
}
plot(x,y)
curve(f1,from=0,to=6,col="blue",add=T)
curve(f3,from=0,to=6,col="red",add=T)

text(4,3.5, "y = -0.3+1.1*x",col="blue")
text(3,1.5, "y = 2.5-2.83x+1.5x^2-0.167X^3",col="red")

在这里插入图片描述

过拟合问题

1.拟合度高并不代表模型最优
在这里插入图片描述
2.拟合度低并不代表模型很差
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值