目录
线性回归:
线性关系是我们生活中最为普遍的关系类型之一。对于最简单的线性关系的数学表达 :
上述公式描述了函数f(x)与自变量x的关系,当有多个自变量的时候,每一个特征都会对f(x)的取值产生影响,所以我们的目标是找到每个也是找到一个公式能够描述自变量和因变量之间的关系,公式也就变成了。
y 是因变量,x₁, x₂, ..., xₙ 是自变量,β₀是截距, β₁, β₂, ..., βₙ 是回归系数,ε 是误差项。我们的目标是找到最优的回归系数,使得模型的预测值与实际观测值之间的误差最小化。在后面运算中,β₀, β₁, β₂, ..., βₙ会写成矩阵的方式公式简化为:
x为1,x₁, x₂, ..., xₙ的组成的矩阵,w为β₀, β₁, β₂, ..., βₙ组成的向量。
定义损失函数:
使用回归模型常用的损失函数MSE(Mean Squared Error,均方误差)作为手写模型的损失函数,其公式为:
y为实际值,为预测值,上述公式计算了预测值与实际观测值之间差异的平方的平均值。当该值越小,表示模型的预测结果与实际观测值之间的差异越小,则模型拟合效果越好。MSE 是一个非负的指标,其值为 0 表示模型完全拟合了数据。然而,MSE 也存在一个问题,即它对异常值比较敏感,因为误差的平方会放大异常值的影响。
定义优化函数:
这里选择牛顿法作为优化函数,来快速得到最优的w。牛顿法通过泰勒展开式的二阶来逼近目标函数(在这里为损失函数MSE)。
首先我们需要知道,优化函数具体怎么优化模型。以MSE为例,为了让MSE最小,我们需要调整的值,而根据线性回归的公式(参照上面多元线性的公式),我们需要调整的是w 的值来得到最优的回归系数和截距。优化函数则是通过求导,利用数学公式对参数进行迭代的运算操作,更新β₀ β₁, β₂, ..., βₙ 的值来得到最优解。
泰勒展开式是一种将一个函数在某个点附近进行无穷阶级数展开的方法。泰勒展开式可以用来近似表示一个函数在给定点的邻域内的取值
泰勒展开:
其中,f'(x0) 表示函数 f(x) 在点 x0 处的一阶导数,f''(x0) 表示函数 f(x) 在点 x0 处的二阶导数,依此类推。展开式中的每一项都是函数在 x0 处的导数乘以相应的幂次项。泰勒展开式的优点是可以用一系列简单的函数来逼近复杂的函数,从而简化计算。通常情况下,我们可以通过截取展开式的有限项来近似表示函数的取值。截取的项数越多,近似的精度就越高。
牛顿法:
在牛顿法中,我们截取泰勒展开的二阶:
对该函数进行求导:
同时令f'(x)=0,那么公式就会变成:
改变一下形式,也就成为了牛顿法的更新公式 :
将mse的公式带入,因为我们求的参数为w,所以设定在mse函数中的自变量为w,也就是说上述公式可以转变为:
利用函数的一阶导和二阶导(海森矩阵)对参数进行更新,重复多次即可让得到损失函数的收敛值。
代码展示:
import numpy as np
class Linear1_nowton:
def __init__(self,iter=800,tol=1e-6):
self.iter=iter
self.tol=tol#对w变化量的限制
def fit(self,x,y):
x=np.array(x)
y=np.array(y)
x=np.column_stack((np.ones(len(y)),x))#在x特征里加入一列1,是为了算截距
self.sample,self.featers=x.shape
self.w=np.random.normal(0,1,self.featers)
#随机生成一批正态分布的w作为初始参数,也可以换成0
for i in range(self.iter):
y_pre=np.dot(x,self.w)#预测y=w*x,dot为矩阵乘法
error=y_pre-y
dw=np.dot(x.T,error)/self.sample#导数
hs=np.dot(x.T,x)/self.sample#海森矩阵
delt=np.linalg.solve(hs,dw)#w变化量
self.w-=delt
if np.linalg.norm(delt)<self.tol:#w变化量太低则判断为收敛,跳出
break
def predict(self,x):
x=np.column_stack((np.ones(x.shape[0]),x))
return np.dot(x,self.w)
在代码中对mse的公式描述为
是因为我们在模型里实际上要求得的是预测值与实际值的差,在这里是以预测值为基准所以与上面数学公式有些许出入。并且由于一阶导数和二阶导数中都有2所以抵消了,其他地方没有抵消是因为让代码更易理解。
代码中的数学运算都将x和y看做一个整体,即x是一个矩阵,y为一组向量,dot则为矩阵运算,linalg.solve为线性方程求解。
效果展示:
以波士顿房价数据为例:
和sklearn的线性回归的得分几乎相同,手写模型成功。使用了牛顿法,会让该模型更快的收敛,得到最优w,以上图的波士顿数据为例,只需要迭代三次即可得到最优。但缺点比较明显由于是单纯的线性回归模型,并没有考虑到误差项的问题,这是该模型的一个局限性。
如有不足,还请各位大佬指出。博主会继续虚心学习。