深度学习基础之线性回归

1理解线性回归

线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法,运用十分广泛。其表达形式为y = w’x+e,e为误差服从均值为0的正态分布。

回归分析中,只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。

1.1基本含义

在统计学中,线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。只有一个自变量的情况称为简单回归,大于一个自变量情况的叫做多元回归。(这反过来又应当由多个相关的因变量预测的多元线性回归区别,而不是一个单一的标量变量。)

1.2拟合方程

1.2.1最小二乘法

一般来说,线性回归都可以通过最小二乘法求出其方程,可以计算出对于y=bx+a的直线。

最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达。

以最简单的一元线性模型来解释最小二乘法。什么是一元线性模型呢?监督学习中,如果预测的变量是离散的,我们称其为分类(如决策树,支持向量机等),如果预测的变量是连续的,我们称其为回归。回归分析中,如果只包括一个自变量和一个因变量,且二者的关系可用一条直线近似表示,这种回归分析称为一元线性回归分析。如果回归分析中包括两个或两个以上的自变量,且因变量和自变量之间是线性关系,则称为多元线性回归分析。对于二维空间线性是一条直线;对于三维空间线性是一个平面,对于多维空间线性是一个超平面。 [4]

对于一元线性回归模型, 假设从总体中获取了n组观察值(X1,Y1),(X2,Y2), …,(Xn,Yn)。对于平面中的这n个点,可以使用无数条曲线来拟合。要求样本回归函数尽可能好地拟合这组值。综合起来看,这条直线处于样本数据的中心位置最合理。 选择最佳拟合曲线的标准可以确定为:使总的拟合误差(即总残差)达到最小。有以下三个标准可以选择: [4]

(1)用“残差和最小”确定直线位置是一个途径。但很快发现计算“残差和”存在相互抵消的问题。
(2)用“残差绝对值和最小”确定直线位置也是一个途径。但绝对值的计算比较麻烦。
(3)最小二乘法的原则是以“残差平方和最小”确定直线位置。用最小二乘法除了计算比较方便外,得到的估计量还具有优良特性。这种方法对异常值非常敏感。 [4]

最常用的是普通最小二乘法( Ordinary Least Square,OLS):所选择的回归模型应该使所有观察值的残差平方和达到最小。(Q为残差平方和)- 即采用平方损失函数。 [4]

在这里插入图片描述
在这里插入图片描述

1.3应用

1.3.1数学

线性回归有很多实际用途。分为以下两大类: [3]
如果目标是预测或者映射,线性回归可以用来对观测数据集的和X的值拟合出一个预测模型。当完成这样一个模型以后,对于一个新增的X值,在没有给定与它相配对的y的情况下,可以用这个拟合过的模型预测出一个y值。

给定一个变量y和一些变量X1,…,Xp,这些变量有可能与y相关,线性回归分析可以用来量化y与Xj之间相关性的强度,评估出与y不相关的Xj,并识别出哪些Xj的子集包含了关于y的冗余信息。

1.3.2趋势线

一条趋势线代表着时间序列数据的长期走势。它告诉我们一组特定数据(如GDP、石油价格和股票价格)是否在一段时期内增长或下降。虽然我们可以用肉眼观察数据点在坐标系的位置大体画出趋势线,更恰当的方法是利用线性回归计算出趋势线的位置和斜率。

1.3.3流行病学

有关吸烟对死亡率和发病率影响的早期证据来自采用了回归分析的观察性研究。为了在分析观测数据时减少伪相关,除最感兴趣的变量之外,通常研究人员还会在他们的回归模型里包括一些额外变量。例如,假设我们有一个回归模型,在这个回归模型中吸烟行为是我们最感兴趣的独立变量,其相关变量是经数年观察得到的吸烟者寿命。研究人员可能将社会经济地位当成一个额外的独立变量,已确保任何经观察所得的吸烟对寿命的影响不是由于教育或收入差异引起的。然而,我们不可能把所有可能混淆结果的变量都加入到实证分析中。例如,某种不存在的基因可能会增加人死亡的几率,还会让人的吸烟量增加。因此,比起采用观察数据的回归分析得出的结论,随机对照试验常能产生更令人信服的因果关系证据。当可控实验不可行时,回归分析的衍生,如工具变量回归,可尝试用来估计观测数据的因果关系。

1.3.4金融

资本资产定价模型利用线性回归以及Beta系数的概念分析和计算投资的系统风险。这是从联系投资回报和所有风险性资产回报的模型Beta系数直接得出的。

1.3.5经济学

线性回归是经济学的主要实证工具。例如,它是用来预测消费支出,固定投资支出,存货投资,一国出口产品的购买,进口支出,要求持有流动性资产,劳动力需求、劳动力供给。

2使用线性回归解决实际问题

2.1案例说明

使用tensorflow编写一个方法:随机生成1000个数据点。
对于横坐标坐标的要求为,进行随机高斯处理化,以0为均值,以0.55为标准差;
对于纵坐标,数据点在y1=x1*0.1+0.3上小范围浮动。
代码如下:

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt	

num_points=1000    
vectors_set=[]

def inputs():
	for i in range(num_points):
		x1=np.random.normal(0.0,0.55)   #横坐标,进行随机高斯处理化,以0为均值,以0.55为标准差
    	y1=x1*0.1+0.3+np.random.normal(0.0,0.03)   #纵坐标,数据点在y1=x1*0.1+0.3上小范围浮动
    	vectors_set.append([x1,y1])
 	x_data=[v[0] for v in vectors_set]
	y_data=[v[1] for v in vectors_set]
	return x_data, y_data

x_vals, y_vals = inputs()

plt.plot(x_vals, y_vals, 'b.')
plt.show()

生成的数据如下图所示:
在这里插入图片描述

2.2使用线性回归进行计算

使用线性回归进行计算,计算一条直线,使其尽可能地穿过1000个数据点的中心。

一条线的方程为y=kx+b,其中k为斜率,b为截距。只要确定斜率和截距线的方程就可以求出。因此就转变为如何计算出一个最符合的 斜率 和 截距,来让这条线过这些数据的中心。

但于此同时我们也应该考虑一个问题,过这些数据中心的线也会有很好条,如何确定那一条是最优的?

此时我们就可以采用“每个点到直线的距离远近关系” 来判断这条直线是否为最优。

这种情况下:我们可以把点的 “y坐标值 - 点在直线上所对应的y坐标值” 称为 “残差”。

因此:
1.可以根据所有点到直线的“残差和最小”计算斜率和截距。但有一个问题,计算“残差和”存在相互抵消的问题。
2.可以根据所有点到直线的“残差绝对值和最小”来确定直线位置。但绝对值的计算比较麻烦。
3.可以根据所有点到直线的“残差平方和最小”来确定直线位置。即使用最小二乘法计算最优直线。

2.3公式推导

2.3.1假设

已知:1000个数据点的坐标
未知:一元线性方程的斜率k以及截距b

从已知内容可以得出两部分数据:分别是1000个点的 x坐标值 以及y坐标值。

对于某一点s的坐标为(x1,y1),根据线性方程y=kx+b,可以计算出s点对应到直线上的y值为kx1+b。
即残差a=y1-(kx1+b)。

现在使用矩阵进行计算:

假设:
1000个点的所有x坐标值我们用一个列向量X表示。
1000个点的所有y坐标值我们用一个列向量Y表示。
斜率k,截距b:用一个2行的列向量W表示。即后期使用w1代替k,W0代替b。

W表示为:


Sample


系数W向量

则:
Y预测=W1*x+W0
也可以将此式子看成Y预测=W1*x+W0*1。
因此:
将列向量X进行转化,为每一行添加一列新的值,且值皆为1。
即此时X变为了一个1000*2的矩阵。(注意此时只针对于一元的情况)。
矩阵X表示为:

Sample

矩阵X

Y的预测值为:Y预测=X*W

Sample

Y预测列向量

2.3.2推导

1.残差的平方和为:


Sample


残差的平方和

2.求解残差的平方和最小:
如何调整w以使得L(w)取得最小值有很多方法,其中有最小二乘法(min square),是一种完全是数学描述的方法,和梯度下降法。
梯度下降

在选定线性回归模型后,只需要确定参数w,就可以将模型用来预测。然而w需要在L(w)最小的情况下才能确定。因此问题归结为求极小值问题,使用梯度下降法。梯度下降法最大的问题是求得有可能是全局极小值,这与初始点的选取有关。

 梯度下降法是按下面的流程进行的:

 1)首先对w赋值,这个值可以是随机的,也可以让w是一个全零的向量。

 2)改变w的值,使得L(w)按梯度下降的方向进行减少。

 梯度方向由L(w)对w的偏导数确定,由于求的是极小值,因此梯度方向是偏导数的反方向。结果为:

迭代更新的方式有两种,一种是批梯度下降,也就是对全部的训练数据求得误差后再对θ进行更新,另外一种是增量梯度下降,每扫描一步都要对θ进行更新。前一种方法能够不断收敛,后一种方法结果可能不断在收敛处徘徊。

一般来说,梯度下降法收敛速度还是比较慢的。

另一种直接计算结果的方法是最小二乘法。

最小二乘法

将训练特征表示为X矩阵,结果表示成y向量,仍然是线性回归模型,误差函数不变。那么w可以直接由下面公式得出:

Sample

但此方法要求X是列满秩的,而且求矩阵的逆比较慢。

最小二乘法通过数学推导出标准方程的过程其实非常简单,知乎上有一篇博客https://zhuanlan.zhihu.com/p/22474562写得很详细,大家可参照这个进行推导。

Sample

2.4编码实现

最小二乘法的编码实现:

x_data = tf.placeholder(tf.float32, shape=(None, 2))
y_data = tf.placeholder(tf.float32, shape=(None, 1))

#construct graph
#转置
xt = tf.transpose(x_data)
#矩阵相乘
xt_x = tf.matmul(xt, x_data)
#求逆
xt_inv = tf.matrix_inverse(xt_x)
#矩阵相乘
xt_y = tf.matmul(xt, y_data)

#计算相关系数W
w = tf.matmul(xt_inv, xt_y)
#推断输出即预测y值  根据直线方程由x坐标点计算出y点
y_pred = tf.matmul(x_data, w)


with tf.Session() as sess:
	#将一些列x值转换为一个列向量
	x_vals_column = np.transpose(np.matrix(x_vals))
	#构建一个皆为1的列向量 用来与截距进行乘
    ones_column = np.transpose(np.matrix(np.repeat(1, num_points)))
	#将x值列与1列构建成一个矩阵
	A = np.column_stack((x_vals_column, ones_column))
	#y的真实值
    b = np.transpose(np.matrix(y_vals))
    
    #运行计算
    y,w1 = sess.run([y_pred,w], feed_dict={x_data:A, y_data:b})
	#打印系数
    print(w1)
    
#红色的线
plt.plot(x_vals, y, 'r-')
#蓝色的点
plt.plot(x_vals, y_vals, 'b.')
#绘图
plt.show()

结果为:
在这里插入图片描述
全局梯度下降的编码实现:

x_vals, y_vals = inputs()

x_data = tf.placeholder(tf.float32, shape=(None, 2))
y_data = tf.placeholder(tf.float32, shape=(None, 1))

w_data = tf.placeholder(tf.float32, shape=(2, 1))
b_data = tf.placeholder(tf.float32, shape=())

#预测结果
y_pred = tf.add(tf.matmul(x_data, w_data), b_data)
#残差
diff = y_pred - y_data
#损失函数
loss = tf.reduce_mean(tf.reduce_sum(diff ** 2, axis=1))

#梯度的w,b
grad_w, grad_b = tf.gradients(loss, [w_data, b_data])

with tf.Session() as sess:
	values = {x_data: x_vals, w_data: np.random.randn(2, 1), 
          	b_data: np.random.random(), y_data: y_vals}
    #学习率/步长
	learning_rate = 1e-5
    loss_vec = []
	#循环50次
	for t in range(50):
    	#执行计算
        out = sess.run([loss, grad_w, grad_b], feed_dict=values)
	    #损失值,梯度的w,梯度的b
    	loss_val, grad_w_val, grad_b_val = out
        #修正w,b
	    values[w_data] -= learning_rate * grad_w_val
    	values[b_data] -= learning_rate * grad_b_val
    
   	 	#将损失值添加到数组中
    	loss_vec.append(loss_val)
	#运行获取y的预测值
	y_pred_vals = sess.run(y_pred, feed_dict=values)

	print(values[w_data])
	print(values[b_data])

plt.plot(loss_vec, 'r.')
plt.show()
  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值