回归是一种统计学上分析数据的一种方法。它分为两种:线性回归和逻辑回归。它取决于最后回归出来的值是连续的还是离散的。线性回归最终回归出来的值是连续的,比如说用线性回归预测股票的时候回归出来的就应该是连续值,逻辑回归与预测结果是离散值,一般用来做分类,回归的结果用来表示某一个事物的类别。

下面用一个简单的例子来介绍一下线性回归的概念,通过会介绍如何使用深度学习框架TensorFlow进行线性回归。

一、线性回归的基本概念

线性回归的定义:给定数据集,我们试图从D中学习得到一个线性模型,该模型尽可能准确的反映,我们试图从D中学习得到一个线性模型,该模型尽可能准确的反映x(i)与y(i)之间的对应关系。这里的线性模型,就是属性x的线性组合的函数f(x).




线性回归结果展示 线性回归的结果_线性回归

数据集D




线性回归结果展示 线性回归的结果_线性回归结果展示_02

f(x的表达式)



用向量可以表示为:




线性回归结果展示 线性回归的结果_权重_03


上面的向量w表示weight,,就是权重的意思,表示对应的属性对预测结果的影响的大小。所以,通常的线性回归的问题,就变成了如何求得上面的模型参数w、b。

下面通过一个真实的案例来学习如何求解线性回归的问题。

应用案例:预测一只超级宝贝进化后的cp值。(cp值是什么意思?我也不知道,你可以认为也就是y值)

提示:微信公众号的编辑窗口不支持latex公式输入,也不支持别的公式输入方式,想放入公式只能贴图,过于麻烦了。下面的x_w原本应该表示的是x下标w,现在没找到好的公式输入的办法,只能先这样了。

目标:找到一个函数,输入是一个超级宝贝的各种信息,用x表示这一只超级宝贝,x_w表示它的重量,x_h表示它的高度···,输出的是这一只超级宝贝进化后的cp值。用下图表示:


线性回归结果展示 线性回归的结果_线性回归结果展示_04


第一步:

建立模型,实际上就是如何形式化的表达出这个模型,你找到的应该是一个函数的集合。在这个问题中,对应的模型如下:


线性回归结果展示 线性回归的结果_线性模型_05


这是一个线性函数,如何模型的参数w、b都没有确定,因此它表示的是一个函数集。

说明:

  • x_i是输入x的各种属性,也被称为x的特征(比如说超级宝贝进化前的信息:高度、重量等等)
  • w_i表示权重
  • b表示偏置

第二步:

在上面的的函数集中找到最合适的函数。这个过程就是俗称的训练的过程。

(1) 准备训练数据,比如说:10个超级宝贝进化前的信息和进化后的cp值,如下所示:


线性回归结果展示 线性回归的结果_线性模型_06


如果将它画在散点图中如下所示:


线性回归结果展示 线性回归的结果_线性回归_07


(2) 定义损失函数:用来评价我们当前找到的模型的好坏,一般用预测值和真实值的误差来评价。


线性回归结果展示 线性回归的结果_机器学习线性回归_08


(3) 找到最合适的w、b使得误差平方和最小

如何找到这个wb呢?--- 就是传说中的梯度下降法了。

下面假设上面的问题中w只有一项, b=0,这样问题就简化很多了。

梯度下降的过程如下:

  1. 随机选择一个初始值w0
  2. 计算L(W)在w0处的微分值L'(W0)

如下所示:


线性回归结果展示 线性回归的结果_线性模型_09


计算的微分值就表示L(w)在w0处的斜率。由图可知:

  • 若L'(W0)<0,则应该增加w的值
  • 若L'(W0)>0,则应该减小w的值

那么具体应该增加或者减少多少呢?

w的更新公式:


线性回归结果展示 线性回归的结果_线性回归结果展示_10

权重的更新公式


重复上面的步骤,误差L(w)不断的下降到最小值(也有可能是局部最小值),此时对应的w就是要找的w。

梯度下降的一个令人担忧的地方:如果初始值给的不好的话,可能会陷入局部最小值,如下图所示:


线性回归结果展示 线性回归的结果_线性回归结果展示_11


最后,还要说一句:

线性回归当中,损失函数是凸面的,所以不会出现陷入局部最优解的情况。

一、Tensorflow实战线性回归

真实线性模型为:y=0.2x+0.1。在程序中生成两个数据集,训练集和测试集。然后用训练集训练回归模型,拟合出最合适的w和b,然后对测试集中的数据进行预测。

基于tensorflow的代码实现如下:

# -*- coding: utf-8 -*-import tensorflow as tfimport numpy as npimport matplotlib.pyplot as pltrng = np.random# 模型参数learning_rate = 0.01training_epochs = 1000display_step = 50# 真实的参数w、b,也就是真实的模型为y = 0.2x + 0.1truth_w = 0.2truth_b = 0.1# 准备训练数据train_X = np.asarray([3.3, 4.4, 5.5, 6.71, 6.93,  4.168, 9.779, 6.182, 7.59, 2.167,  7.042, 10.791, 5.313, 7.997, 5.654,  9.27, 3.1])train_Y = truth_w * train_X + truth_bn_samples = train_X.shape[0]# 创建两个展占位符X = tf.placeholder(tf.float32)Y = tf.placeholder(tf.float32)# 随机设置模型的初始的权重W = tf.Variable(rng.randn(), name="weight")b = tf.Variable(rng.randn(), name="bias")# 构建线性模型pred = tf.add(tf.multiply(X, W), b)# 定义损失函数cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(n_samples - 1)# 定义梯度下降优化器optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)# tensorflow变量初始化器init = tf.global_variables_initializer()# 开始训练with tf.Session() as sess: #变量初始化 sess.run(init) #梯度下降训练模型 for epoch in range(training_epochs): for (x, y) in zip(train_X, train_Y): sess.run(optimizer, feed_dict={X: x, Y: y}) #每训练50次在控制台中输出当前模型的loss以及权重大小 if (epoch+1) % display_step == 0: c = sess.run(cost, feed_dict={X: train_X, Y:train_Y}) print("Epoch: