回归,Regression,是一种归纳的思想——当看到大量的事实所呈现的样态,推断出原因是如的,当看到大量的数字对(pair)是某种样态,推断出它们之间蕴含的关系是如何。
线性回归
线性回归是利用数理统计学中的回归分析来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。其表达形式如下:
\(y=ax+b+e\)(e为误差服从均值为0的正态分布)
假设有多个x和y样本值,尝试用y=ax+b+e来拟合,可以得到:
\(\vert e\vert=\vert ax+b-y\vert\)误差大小其实是猜想的ax+b的值和观测到的y的值之间的差值。试着把所有的|e|都求和:
\(Q=\sum_{i=1}^n(ax_i+b-y_i)^2\)现在的问题是让a和b分别等于什么值时Q最小,即:
\(\frac{∂Q}{∂a}=0\)且\(\frac{∂Q}{∂b}=0\)
分别求导后:
\(\left\{
\begin{array}{c}
\frac{∂Q}{∂a}=2\sum_{i=1}^n[x_i(ax_i+b-y_i)]=0\\
\\
\\
\frac{∂Q}{∂b}=2\sum_{i=1}^n(ax_i+b-y_i)=0
\end{array}
\right.
\)
推导出:
\(\left\{
\begin{array}{c}
\sum_{i=1}^nx_i^2+b\sum_{i=1}^nx_i=\sum_{i=1}^ny_ix_i(1)\\
\\
\\
a\sum_{i=1}^nx_i+nb=\sum_{i=1}^ny_i(2)
\end{array}
\right.
\)
把(2)式做如下处理:
\((2)·\frac{\sum_{i=1}^nx_i}{n}-(1)\)得到下面的等式:
\(a\Biggl( \sum_{i=1}^nx_i·\frac{\sum_{i=1}^nx_i}{n}-\sum_{i=1}^nx_i^2\Biggr)=\sum_{i=1}^ny_i·\frac{\sum_{i=1}^nx_i}{n}-\sum_{i=1}^ny_ix_i\)推导出来a和b的表达式:
\(\left\{
\begin{array}{c}
a=\frac{\frac{\sum_{i=1}^ny_i·\sum_{i=1}^nx_i}{n}-\sum_{i=1}^ny_ix_i}{\frac{\sum_{i=1}^nx_i·\sum_{i=1}^nx_i}{n}-\sum_{i=1}^nx_i^2}\\
\\
\\
b=\frac{\sum_{i=1}^ny_i-a\sum_{i=1}^nx_i}{n}
\end{array}
\right.
\)
其中,a就是斜率,b是截距。
在Python中,可以直接使用最小二乘法进行线性拟合。例如:
[mdx_table]
x
1
2
3
4
5
6
7
8
9
—–
y
0.199
0.389
0.580
0.783
0.980
1.177
1.380
1.575
1.771
[/mdx_table]
import numpy as np
import matplotlib.pyplot as plt
x=[1,2,3,4,5,6,7,8,9]
y=[0.199,0.389,0.580,0.783,0.980,1.177,1.380,1.575,1.771]
t1=t2=t3=t4=0
n=len(x)
for i in range(n):
t1+=y[i]#\sum y
t2+=x[i]#\sum x
t3+=x[i]*y[i]#\sum xy
t4+=x[i]**2#\sum x^2
a=(t1*t2/n-t3)/(t2*t2/n-t4)
b=(t1-a*t2)/n
x=np.array(x)
y=np.array(y)
plt.plot(x,y,'o',label='Original data',markersize=10)
plt.plot(x,a*x+b,'r',label='Fitted line')
plt.show()
- 拟合的效果如图:
也可以直接用numpy包中的内置函数,效果与上图相同。
import numpy as np
import matplotlib.pyplot as plt
x=[1,2,3,4,5,6,7,8,9]
y=[0.199,0.389,0.580,0.783,0.980,1.177,1.380,1.575,1.771]
A=np.vstack([x,np.ones(len(x))]).T
#调用最小二乘法函数
a,b=np.linalg.lstsq(A,y)[0]
x=np.array(x)
y=np.array(y)
plt.plot(x,y,'o',label='Original data',markersize=10)
plt.plot(x,a*x+b,'r',label='Fitted line')
plt.show()
非线性回归
有些非线性回归模型,经过适当的数学变换,便能得到它的线性化表达形式,但对另外一些非线性回归模型,仅仅做变量变换根本无济于事。属于前一种情况的非线性回归模型一般称为内蕴的线性回归,而后者则称为内蕴的非线性回归。
这里只讨论前者这种简单的情况,例如:
- 表 20世纪60年代世界人口状况
[mdx_table header=”true”]
年份
世界人口(亿)
—–
1960
29.72
—–
1961
30.61
—–
1962
31.51
—–
1963
32.13
—–
1964
32.34
—–
1965
32.85
—–
1966
33.56
—–
1967
34.20
—–
1968
34.83
[/mdx_table]
根据马尔萨斯人口模型(其中s是人口,t是年份,e是自然常数):
\(s=α·e^{βt}\)对等式两边同时取ln
\(lns=βt+lnα\)这里实际上用的还是线性回归模型,相当于:
\(y=ax+b\)且
\(\left\{
\begin{array}{c}
lns=y\\
\\
β=a\\
\\
lnα=b
\end{array}
\right.
\)
直接调用最小二乘法拟合:
import numpy as np
import matplotlib.pyplot as plt
x=[1960,1961,1962,1963,1964,1965,1966,1967,1968]
y=[29.72,30.61,31.51,32.13,32.34,32.85,33.56,34.20,34.83]
logy=np.log(y)
A=np.vstack([x,np.ones(len(x))]).T
#调用最小二乘法函数
a,b=np.linalg.lstsq(A,logy)[0]
x=np.array(x)
plt.plot(x,logy,'o',label='Original data',markersize=10)
plt.plot(x,a*x+b,'r',label='Fitted line')
plt.show()
- 线性拟合的效果如图:
求出β和α
beta=a
alpha=pow(np.e,b)
y=np.array(y)
plt.plot(x,y,'o',label='Original data',markersize=10)
plt.plot(x,alpha*pow(np.e,beta*x),'r',label='Fitted line')
plt.show()
plt.axis([1960,2010,25,100])
plt.plot(x,y,'o',label='Original data',markersize=10)
x=np.arange(1960,2010)
plt.plot(x,alpha*pow(np.e,beta*x),'r',label='Fitted line')
plt.show()
- 非线性拟合的效果如图:
- 预测的效果如图:
想了解更多关于大数据和机器学习: