线性回归
线性回归, 是回归分析中的一种, 其表示自变量 x 与因变量 y 之间存在线性关系.
回归分析是从数据出发, 考察变量之间的数量关系, 并通过一定的数学关系式将这种关系描述出来, 再通过关系式来估计某个变量的取值, 同时给出该估计的可靠程度.
一元线性回归
在回归分析中只涉及一个自变量,一个因变量 称为一元线性回归
多元线性回归
在回归分析中涉及多个自变量,一个因变量 称为多元线性回归
注意 多元线性回归一般会用到 归一化公式 : (x-平均值)/标准差 将数据缩放到[-1,1] 之间.
data2 = (data2 - data2.mean()) / data2.std()
代价函数
由于我们构建模型的最终目的是用来预测, 因此好参数构建的模型应该具备很好的预测能力, 也就是说预测值和实际值差异很小, 我们把预测值h(x)与实际值y之间的差异称为误差. 对于某个值来说 误差就是 h(x)-y 对于整个模型而言就是将每个误差求和.因为误差也有正负之分,所以需要求每个误差的平方和然后对平方和求平均值 即为 代价函数
首先,我们将创建一个以参数θ为特征函数的代价函数
J
(
θ
)
=
1
2
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
J(\theta)=\frac{1}{2m}\sum\limits_{i=1}^{m}( h_\theta ( x^{(i)})-y^{(i)})^2
J(θ)=2m1i=1∑m(hθ(x(i))−y(i))2
其中 m 代表总样本数,
h
(
x
(
i
)
)
h(x^{(i)})
h(x(i)) 代表第i个值的预测结果,
y
(
i
)
y^{(i)}
y(i) 代表第i个值的实际值
h
θ
(
x
)
=
θ
T
X
=
θ
0
x
0
+
θ
1
x
1
+
θ
2
x
2
+
.
.
.
+
θ
n
x
n
{{h}{\theta }}\left( x \right)={{\theta }^{T}}X={{\theta }{0}}{{x}{0}}+{{\theta }{1}}{{x}{1}}+{{\theta }{2}}{{x}{2}}+...+{{\theta }{n}}{{x}_{n}}
hθ(x)=θTX=θ0x0+θ1x1+θ2x2+...+θnxn
python 代码实现 :
def computeCost(x, y, theta):
inner = np.power(((x*theta.T) - y),2)
return np.sum(inner) / (2 * len(x))
梯度下降
什么是梯度下降?
梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)
在单个自变量函数曲线中, 梯度也就是曲线上某点处的斜率, 而对于我们的损失函数来说, 其有两个自变量
θ
0
\theta_0
θ0 和
θ
1
\theta_1
θ1 , 故这两个自变量与损失函数将构成三维曲面.
可以将这三维曲面想象成一座山, 我们现在的目标是山底, 我们要想最快下山, 就需要走最陡峭的方向, 而最陡峭的方向可以看成是当前方向(下山方向)中变化最大的反方向. (其中, 变化最大的方向是指从下山改为上山, 与目标不符, 故取其反方向, 即最大的反方向).
梯度下降法与下山过程类似, 我们的目标是求出使得损失函数数值最小的最优解. 具体过程就是给定一个初始位置, 沿着梯度的反方向(也就是负的梯度)走一个步长的距离, 更新当前位置, 如此反复, 直至找到使得损失函数最小的最优解,
θ j : = θ j − α ∂ ∂ θ j J ( θ ) {{\theta }_{j}}:={{\theta }_{j}}-\alpha \frac{\partial }{\partial {{\theta }_{j}}}J\left( \theta \right) θj:=θj−α∂θj∂J(θ)
其中, a 为学习效率, 也称为步长, 等号右边的
θ
j
\theta_j
θj 为每次更新之前的模型参数(j=0,1), 即每走负梯度个步长, 更新一次
θ
0
\theta_0
θ0 和
θ
1
\theta_1
θ1, 而且这两者是同步更新.
python 实现 :
def gradientDescent(x, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)
for i in range(iters):
error = (x * theta.T) - y
for j in range(parameters):
# multiply 矩阵相乘
term = np.multiply(error, x[:,j])
temp[0,j] = theta[0,j] - ((alpha / len(x)) * np.sum(term))
# ??? 为什么这里就可以是ax + b 的两个系数
# y = ax0 + bx1 (x0=1)
# 竖着求和 解得 a b
theta = temp
cost[i] = computeCost(x, y, theta)
return theta, cost
正则方程
正规方程是通过求解下面的方程来找出使得代价函数最小的参数的: ∂ ∂ θ j J ( θ j ) = 0 \frac{\partial }{\partial {{\theta }_{j}}}J\left( {{\theta }_{j}} \right)=0 ∂θj∂J(θj)=0 。 假设我们的训练集特征矩阵为 X(包含了 x 0 = 1 {{x}_{0}}=1 x0=1)并且我们的训练集结果为向量 y,则利用正规方程解出向量 θ = ( X T X ) − 1 X T y \theta ={{\left( {{X}^{T}}X \right)}^{-1}}{{X}^{T}}y θ=(XTX)−1XTy 。 上标T代表矩阵转置,上标-1 代表矩阵的逆。设矩阵 A = X T X A={{X}^{T}}X A=XTX,则: ( X T X ) − 1 = A − 1 {{\left( {{X}^{T}}X \right)}^{-1}}={{A}^{-1}} (XTX)−1=A−1
梯度下降与正规方程的比较:
梯度下降:需要选择学习率α,需要多次迭代,当特征数量n大时也能较好适用,适用于各种类型的模型
正规方程:不需要选择学习率α,一次计算得出,需要计算 ( X T X ) − 1 {{\left( {{X}^{T}}X \right)}^{-1}} (XTX)−1,如果特征数量n较大则运算代价大,因为矩阵逆的计算时间复杂度为 O ( n 3 ) O(n3) O(n3),通常来说当 n n n小于10000 时还是可以接受的,只适用于线性模型,不适合逻辑回归模型等其他模型
python 实现:
# 正规方程
def normalEqn(x,y):
#X.T@X等价于X.T.dot(X)
theta = np.linalg.inv(x.T@x)@x.T@y
return theta
使用 :
sklearn中已经继承了线性回归函数:
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(x,y)
y_pred = model.predict(x_test)
线性回归两大算法的优缺点:
梯度下降:
优点:
- 在特征变量多的情况下,能够有效的运行
缺点:
- 依赖于步长a 和起始位置的选择, 因此需要多次尝试寻找合适的补偿和起始位置
- 每次更新当前位置需要计算全部的训练数据, 迭代速度较慢
最小二乘估计:
优点:
- 直接使用计算公式,简单高效
缺点:
- 训练数据拟合的函数如果不是线性的时候 不能使用
- 需要矩阵可逆
- 当样本特征数量很大时,计算会非常耗时,甚至是无法计算的情况
应用总结:
-
当训练数据特征数量较少时, 且拟合函数为线性, 则可以直接采用最小二乘法, 如果拟合函数非线性, 可以先对其进行对数转换再运用最小二乘法;
-
当训练数据特征数量较多时, 由于其对拟合函数无要求, 若数据量不大, 则可选用批量梯度下降, 若数据量很大, 则可以选用小批量梯度下降.
资料地址 : https://www.cnblogs.com/star-zhao/p/10543368.html