线性回归模型和最小二乘法
最小二乘法极小化残差的平方和,该准则度量平均拟合偏离。
将残差平方和写成如下形式
RSS(θ)=(y−Xβ)T(y−Xβ)
这是
p+1
个参数的二次函数。
关于
β
微分,得到
∂RSS∂β=−2XT(y−XTβ)
假定
X
是列满秩的,从而
令
XT(y−XTβ)=0
得到唯一解:
β^=(XTX)−1XTy
在训练输入上的拟合值为
y^=Xβ^=X(XTX)−1y
从几何上来看,这个拟合向量是y向X的列空间的投影,矩阵
P=X(XTX)XT
也称为投影矩阵,同时也是一个幂等矩阵,即满足
Pn=P
为了确定
β^
的性质,假定观测
yi
是不相关的,具有常数方差
σ2
,而
xi
是固定的,非随机的。
即y满足
y=xβ+ϵ,ϵ
为观测误差服从正态分布
N(0,σ2)
由此可以得到
β^
的方差-协方差矩阵
Var(β^)=Var((XTX)−1XTy)=(XTX)−1σ2
现在来求
σ2
的估计
σ2
等于误差e的平方期望值,我们想使用残差的平方和来估计方差
σ2
,
残差向量为
e^=y−y^=y−X(XTX)−1XTy
将投影矩阵用P表示,P有如下性质
P=PT=Pn
(I−P)=(I−P)T=(I−P)n
从几何上来理解,将一个向量在一个线性空间内投影多次等同于投影一次。
残差的平方和为
||y−Py||2=||(I−P)y||2=yT(I−P)(I−P)y=yT(I−P)y
这里用到了一个定理:
x是n维随机变量,具有均值
u
和协方差矩阵
E(xTAx)=tr(AΣ)+uTAu
那么我们可以得到:
E(yT(I−P)y)=σ2tr(I−P)+E(yT)∗(I−P)∗E(y)
因为
E(y)=Xβ
,所以
(I−P)∗E(y)=Xβ−X(XTX)−1XTXβ=0
此外
tr(P)=tr(X(XTX)−1XT)
,
利用迹的交换律,得到
tr(P)=tr(XTX(XTX)−1)=tr(I(p+1)∗(p+1))=p+1
tr(I−P)=tr(IN∗N)−tr(P)=n−p−1
,
所以
E(||y−Py||2)=E(yT(I−P)y)=σ2(n−p)
所以可以得到方差的无偏估计
σ^2=||y−Py||2/(n−p+1)
然后可以得到以下性质(证明略)
β^
服从高斯分布
N(β,(XTX)−1σ2)
(N−p−1)σ^2σ2
服从自由度为N-p-1的卡方分布
β^
和
σ^2
是统计独立的
利用这些分布性质,可以形成参数
βj
的假设检验和置信区间
为检验特定系数
βj=0
的假设,形成Z得分
zj=β^σvj√
其中
vj
是
(XTX)−1
的第j个对角线元素。在原假设
βj=0
下,
zj
服从分布
tn−p−1
(具有自由度为
N−p−1
的t分布),
因此绝对值大的
zj
将导致拒绝该假设
当想要检验一组变量能否从一个模型里排除的时候,可以使用F统计量
F=(RSS0−RSS1)/(p1−p0)RSS1/(N−p1−1)
其中
RSS1
是具有
p1+1
个参数的较大模型的残差,
RSS0
是具有
p0+1
的变量的残差和。
F统计量具有分布
Fp1−p0,N−p1−1
,可以证明当删除一个系数时,F统计量相当于Z得分的平方。
另外也可以通过类似的方法得到
β
的置信区间。
高斯-马尔科夫定理
高斯马尔科夫定理:在所有的线性无偏估计中,参数
β
的最小二乘方估计
β^
具有最小方差。
也就是说假设输入为
α
,如果有
αTβ
的其他无偏估计
cy
,即
E(cy)=αTβ
那么
Var(αTβ^)≤Var(cy)
现在简单的证明一下高斯-马尔科夫定理。
c
可以写成
然后根据
E(cy)=cE(y)=(αT(XTX)−1XT+d)Xβ
=\alpha\beta+dX\beta=\alpha^T\beta
=αβ+dXβ=αTβ
对于任意的\beta
β
,有
dx\beta=0
dxβ=0
,所以得到
dx=0
dx=0
首先求出最小二乘法估计的方差
Var(\alpha^T\hat \beta)=\alpha^TVar(\hat \beta)\alpha
Var(αTβ^)=αTVar(β^)α
=σ2αT(XTX)−1α
然后是其余估计的方差
Var(cy)=cVar(y)cT=σ2(αT(XTX)−1α+ddT)
而dd^T是一个非负整数,所以得到
Var(αTβ^)≤Var(cy)
代码实现
from numpy import *
# 预处理数据
def loadData(filename):
dataSet = []
labels = []
fr = open(filename)
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = list(map(float, curLine))
dataSet.append(fltLine[:-1])
labels.append(fltLine[-1])
return dataSet, labels
# 普通最小二乘法
def ols(xArr, yArr):
xMat = mat(xArr); yMat = mat(yArr).T
xTx = xMat.T*xMat
if linalg.det(xTx) == 0.0:
print("xTx is not invertible")
return
return xTx.I * (xMat.T) * yMat