假设有一系列数据点
(
x
i
,
y
i
)
(
i
=
1
,
.
.
.
,
m
)
(x_i, y_i)(i=1,...,m)
(xi,yi)(i=1,...,m),线性回归就是要找到一个拟合函数,使之尽可能地逼近这些数据点。假设拟合函数为
h
(
x
)
=
k
x
+
b
h(x)=kx+b
h(x)=kx+b,那么每个样本的估计量就是
h
(
x
i
)
h(x_i)
h(xi),进而实际值和估计量的残差为:
r
i
=
h
(
x
i
)
−
y
i
r_i=h(x_i)-y_i
ri=h(xi)−yi
对于残差
r
i
r_i
ri,有三种相关的范数:
-
∞
infin
∞-范数:残差绝对值的最大值:
max
1
≤
i
≤
m
∣
r
i
∣
maxlimits_{1 leq i le m}|r_i|
1≤i≤mmax∣ri∣1-范数:绝对残差和:
∑
i
=
1
m
∣
r
i
∣
sum_{i=1}^m|r_i|
∑i=1m∣ri∣2-范数:残差平方和:
∑
i
=
1
m
r
i
2
sum_{i=1}^mr_i^2
∑i=1mri2
一般来说,采用2-范数来衡量拟合函数与实际函数的相似性,主要原因是它方便求导。2-范数越小,相似度就越高啦。
由此,就能写出最小二乘的定义了:
min
k
,
b
∑
i
=
1
m
(
y
i
−
(
k
x
i
+
b
)
)
2
.
minlimits_{k,b}sum_{i=1}^m(y_i-(kx_i+b))^2.
k,bmin∑i=1m(yi−(kxi+b))2.
显然,这是一个无约束的优化问题,分别对
k
,
b
k,b
k,b求导,然后令偏导为0,就能得到极值点:
k
=
m
∑
i
=
1
m
x
i
y
i
−
(
∑
i
=
1
m
x
i
)
(
∑
i
=
1
m
y
i
)
m
∑
i
=
1
m
(
x
i
)
2
−
(
∑
i
=
1
m
x
i
)
2
k=frac{msum_{i=1}^mx_iy_i-(sum_{i=1}^mx_i)(sum_{i=1}^my_i)}{msum_{i=1}^m(x_i)^2-(sum_{i=1}^mx_i)^2}
k=m∑i=1m(xi)2−(∑i=1mxi)2m∑i=1mxiyi−(∑i=1mxi)(∑i=1myi)
b
=
∑
i
=
1
m
y
i
m
−
k
∑
i
=
1
m
x
i
m
b=frac{sum_{i=1}^my_i}{m}-kfrac{sum_{i=1}^mx_i}{m}
b=m∑i=1myi−km∑i=1mxi
(建议自行推导一遍)
因此已知数据点的值就可以根据公式直接得出拟合函数的斜率和截距。
代码也很简单:
import pandas as pd
sales=pd.read_csv('train_data.csv',engine='python') #读取CSV
X=sales['X'].values #存csv的第一列
Y=sales['Y'].values #存csv的第二列
#初始化赋值
s1 = 0
s2 = 0
s3 = 0
s4 = 0
n = 4 ####需要根据的数据量进行修改
#循环累加
for i in range(n):
s1 = s1 + X[i]*Y[i] #X*Y,求和
s2 = s2 + X[i] #X的和
s3 = s3 + Y[i] #Y的和
s4 = s4 + X[i]*X[i] #X**2,求和
#计算斜率和截距
k = (s2*s3-n*s1)/(s2*s2-s4*n)
b = (s3 - k*s2)/n
print("Coeff: {} Intercept: {}".format(k, b))
#y=1.4x+3.5
其中train_data.csv的数据如下:



