简单线性回归(Simple Linear Regression)(附代码)

浏览: 2119

简单线性回归是最基础的一种回归模型,自变量只有一个,函数曲线为直线,因变量为连续型,自变量可以是连续的或者是离散的。函数表示如下:

其中 y 是因变量, x是自变量, β0 和 β1 属于起始值和系数,ε 为偏移量,为了使得到的函数模型更加准确,最后会加上偏移量。

Image

线性回归一般使用最小二乘法来求解函数模型级求解 β0 和 β1 。 方法如下:最小二乘法

Image

如图中四个点为数据(x,y):(1,6)(2,5)(3,7)(4,10)。我们需要根据红色的数据来求蓝色的曲线。目前我们已知这四个点匹配直线y= β1 + β2x 。所以我们要找到符合这条直线的最佳情况,即最合适的β0 和 β1。

Image

最小二乘法就是尽量取两边方差的最小值,这样可以找到最拟合的曲线。

Image

然后我们我们同时对β0和β1求其偏导数

Image

这样我们很容易就解除方程组的解

Image

所以我们就得到了直线 y=3.5 + 1.4x

用Python和Java代码表示如下:

# -*- coding: utf-8 -*-

"""

Created on Thu Dec 01 00:02:49 2016

@author: steve

"""

def SLR(x,y):

intercept = 0.0

slope = 0.0

n = len(x)

sumx = 0.0

sumy = 0.0

sumx2 = 0.0



# 第一次循环,得到平均值

for i in range(n):

sumx += x[i]

sumy += y[i]

sumx2 += x[i]*x[i]

xbar = sumx/n

ybar = sumy/n

xxbar = 0.0

yybar = 0.0

xybar = 0.0



# 第二次循环,得到方差

for i in range(n):

xxbar += (x[i] - xbar) * (x[i] - xbar);

yybar += (y[i] - ybar) * (y[i] - ybar);

xybar += (x[i] - xbar) * (y[i] - ybar);

# 计算斜率和intercept

slope = xybar / xxbar

intercept = ybar - slope * xbar

print "slope is {}, intercept is {}".format(slope, intercept)

## 其他统计变量我就不写了。



x=[1,2,3,4]

y=[6,5,7,10]

SLR(x,y)



public class SLR {

// 这是用二分法做的简单线性回归

private final double intercept, slope;
private final double r2;
private final double svar0, svar1;

public SLR(double[] x, double[] y) {

if (x.length != y.length) {
throw new IllegalArgumentException("lengths doesn't match!!!");
}

int n = x.length;

// 第一次循环,找到 所有x和y的平均值

double sumx = 0.0;
double sumy = 0.0;
double sumx2 = 0.0;

for (int i=0; i<n; i++) {
sumx += x[i];
sumy += y[i];
sumx2 += x[i]*x[i];
}

double xbar = sumx / n;
double ybar = sumy / n;

// 第二次计算,求出方差
double xxbar = 0.0;
double yybar = 0.0;
double xybar = 0.0;
for (int i = 0; i < n; i++) {
xxbar += (x[i] - xbar) * (x[i] - xbar);
yybar += (y[i] - ybar) * (y[i] - ybar);
xybar += (x[i] - xbar) * (y[i] - ybar);
}
System.out.println(xxbar);
System.out.println(yybar);
System.out.println(xybar);
slope = xybar / xxbar; //求偏导数的过程
intercept = ybar - slope * xbar;

// 其他的统计数据
double rss = 0.0; // residual sum of squares
double ssr = 0.0; // regression sum of squares
for (int i = 0; i < n; i++) {
double fit = slope*x[i] + intercept;
rss += (fit - y[i]) * (fit - y[i]);
ssr += (fit - ybar) * (fit - ybar);
}

int degreesOfFreedom = n-2;
r2 = ssr / yybar;
double svar = rss / degreesOfFreedom;
svar1 = svar / xxbar;
svar0 = svar/n + xbar*xbar*svar1;

}

public double intercept() {
return intercept;

}

public double slope() {
return slope;

}

public double R2() {
return r2;
}

public double slopeStdErr() {
return Math.sqrt(svar1);
}

public double interceptStdErr() {
return Math.sqrt(svar0);
}

//这是预测方法,在机器学习中的函数
public double predict(double x) {
return slope*x + intercept;
}

public String toString() {
StringBuilder s = new StringBuilder();
s.append(String.format("%.2f n + %.2f", slope(), intercept()));
s.append(" (R^2 = " + String.format("%.3f", R2()) + ")");
return s.toString();
}

}

这是一个回归总结的系列,每一篇我都会加上代码。参考了几篇论文,先开个头,后面我会一点点完善。我这渣渣编程水平也太差了~~Python给我写成这个鬼样子····人老了果然不适合写代码了~

推荐 4
本文由 dykin 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

1 个评论

欢迎鹏鹏经常来玩。

要回复文章请先登录注册