线性回归的原理
线性回归的一般形式
有数据集,其中,
其中n表示变量的数量,d表示每个变量的维度。
可以用以下函数来描述y和x之间的关系:
如何来确定的值,使得
尽可能接近y的值呢?均方误差是回归中常用的性能度量,即:
我们可以选择,试图让均方误差最小化:
极大似然估计(概率角度的诠释)
下面我们用极大似然估计,来解释为什么要用均方误差作为性能度量
我们可以把目标值和变量写成如下等式:
ϵ表示我们未观测到的变量的印象,即随机噪音。我们假定𝜖ϵ是独立同分布,服从高斯分布。(根据中心极限定理)
因此,
我们建立极大似然函数,即描述数据遵从当前样本分布的概率分布函数。由于样本的数据集独立同分布,因此可以写成
选择θ,使得似然函数最大化,这就是极大似然估计的思想。
为了方便计算,我们计算时通常对对数似然函数求最大值:
显然,最大化即最小化
2、线性回归损失函数、代价函数、目标函数
损失函数(Loss Function):度量单样本预测的错误程度,损失函数值越小,模型就越好。
代价函数(Cost Function):度量全部样本集的平均误差。
目标函数(Object Function):代价函数和正则化函数,最终要优化的函数
3、线性回归的优化方法
1、梯度下降法
设定初始参数,不断迭代,使得
最小化:
即:
将所有的参数以向量形式表示,可得:
由于这个方法中,参数在每一个数据点上同时进行了移动,因此称为批梯度下降法,对应的,我们可以每一次让参数只针对一个数据点进行移动,即
2、最小二乘法矩阵求解
为了最小化J,求导:
评价指标
常用R2,可避免量纲不一致的问题,
5、sklearn.linear_model参数详解:
fit_intercept : 默认为True,是否计算该模型的截距。如果使用中心化的数据,可以考虑设置为False,不考虑截距。注意这里是考虑,一般还是要考虑截距
normalize: 默认为false. 当fit_intercept设置为false的时候,这个参数会被自动忽略。如果为True,回归器会标准化输入参数:减去平均值,并且除以相应的二范数。当然啦,在这里还是建议将标准化的工作放在训练模型之前。通过设置sklearn.preprocessing.StandardScaler来实现,而在此处设置为false
copy_X : 默认为True, 否则X会被改写
n_jobs: int 默认为1. 当-1时默认使用全部CPUs ??(这个参数有待尝试)
可用属性:
coef_:训练后的输入端模型系数,如果label有两个,即y值有两列。那么是一个2D的array
intercept_: 截距
可用的methods:
fit(X,y,sample_weight=None):
X: array, 稀疏矩阵 [n_samples,n_features]
y: array [n_samples, n_targets]
sample_weight: 权重 array [n_samples]
在版本0.17后添加了sample_weight
get_params(deep=True): 返回对regressor 的设置值
predict(X): 预测 基于 R^2值
score: 评估
import numpy as np #建立随机数 np.random.seed(1234) x = np.random.rand(500,3) #建立y与x的映射关系 y = 4.2+5.7X1+10.8X2 y = x.dot(np.array([4.2,5.7,10.8])) #np.dot()返回数组的点积
#sklearn求解 import numpy as np from sklearn.linear_model import LinearRegression import matplotlib.pyplot as plt #调用模型 lr = LinearRegression(fit_intercept = True) #训练模型 lr.fit(x,y) print("估计参数值:%s"%(lr.coef_)) #计算R平方 print("R2:%s"%(lr.score(x,y))) #设定任意变量,预测目标函数 x_test = np.array([2,4,5]).reshape(1,-1) y_hat = lr.predict(x_test) print("预测值:%s"%(y_hat))
#最小二乘法 class LR_LS(): def _init_(self): self.w = None def fit(self,X,y): temp0 = np.dot(X.T,X) temp = np.dot(np.linalg.inv(temp0),X.T) self.w = np.dot(temp,y) def predict(self,X): y_pred = np.dot(X,self.w) return y_pred if __name__ == "__main__": lr_ls = LR_LS() lr_ls.fit(x,y) print("估计的参数值:%s"%(lr_ls.w)) x_test = np.array([2,4,5]).reshape(1,-1) print("预测值为:%s"%(lr_ls.predict(x_test)))
#梯度下降法 class LR_GD(): def _init_(self): self.w = None def fit(self,X,y,alpha = 0.02,loss = 1e-10): y = y.reshape(-1,1) [m,d] = np.shape(X) self.w = np.zeros((d)) tol = 1e5 if tol >loss: told= y-np.dot(X,self.w) self.w = self.w - 1/m *alpha * (np.dot(told , X)) tol = np.abs(np.sum(told)) def predict(self,X): y_pred = np.dot(X,self.w) return y_pred if __name__ == "__main__": lr_gd = LR_GD() lr_gd.fit(x,y) print("估计参数值为:%s"%(lr_gd.w)) x_test = np.array([2,4,5]).reshape(1,-1) print("预测值:%s"%(lr_gd.predict(x_test)))