Linear Regression模型简介

2018-07-09  本文已影响160人  南华coder

一、概述

1、背景
2、介绍
3、线性回归模型

主要介绍:回归方程、损失函数、损失函数求解方法、过拟合和欠拟合、多项式

二、回归方程

1、概述

在回归分析中,只包括一个自变量和一个因变量,且两种的关系可以使用一条直线近似表示,称为一元线性回归分析。如果有两个及以上的自变量,且自变量和因变量是线性关系,称为多元线性回归分析

2、建立回归方程

h_θ(x) = θ_0 + θ_1x_1+θ_2x_2+{\cdots}+θ_nx_n = \vec{θ}^T\vec{X}

其中\vec{θ} = \begin{bmatrix} θ_0 \\ θ_1 \\ θ_2 \\ {\cdots} \\ θ_n \end{bmatrix} \,\,\,\,\,\,\vec{X} = \begin{bmatrix} 1 \\ x_1 \\ x_2 \\ {\cdots} \\ x_n \end{bmatrix}

说明θ_0 , θ_1,θ_2,{\cdots}θ_n 是回归系数,我们的目标是求解出它们,然后代入回归方程,来预测新数据的输出值。

二、损失函数 (Loss Function)

1、公式

确立了回归方程后,我们使用均方误差(Mean Square Error,MSE)来评估真实值 与预测值之间的差异,公式如下:

J(θ) = \frac {1}{2n} \sum_{i=1}^n(h_θ(x^i) - y^i)^2,\,\,\text{n为样本数}

其矩阵表达式为

J(θ) = \frac {1}{2n}(Xθ - Y)^T(Xθ - Y) ,\,\,\text{n为样本数}

说明:以上就是线性回归的损失函数。下面介绍公式的推导。

2、解释

y^{(i)} = θ^T x^{(i)} + \xi^{(i)}\,\,\,\,\,\,\,(1)

p(\xi^{(i)}) = \frac {1}{\sqrt{2\pi\sigma}} exp(-\frac{{\xi^{(i)}}^2}{2\sigma^2})\,\,\,\,\,\,\,(2)

p(y^{(i)} |x^{(i)};θ) = \frac {1}{\sqrt{2\pi} \sigma} exp(- \frac{(y^{(i)} - θ^T x^{(i)})^2}{2\sigma^2})\,\,\,\,\,\,\,(3)

L(θ) = \prod_{i=1}^np(y^{(i)} |x^{(i)};θ) = \prod_{i=1}^n\frac {1}{\sqrt{2\pi} \sigma} exp(- \frac{(y^{(i)} - θ^T x^{(i)})^2}{2\sigma^2})|x^{(i)};θ) \,\,\,\,\,\,\,(4)

\hat{θ} = \frac {1}{2} \sum_{i=1}^n(h_θ(x^i) - y^i)^2 \,\,\,\,\,\,\,(5)

说明:极大似然函数估计知道,在\hat{θ} = \frac {1}{2} \sum_{i=1}^n(h_θ(x^i) - y^i)^2时,误差最小;为了后面计算推导,引入归一化的系数n, 最终得到的损失函数为:

J(θ) = \frac {1}{2n} \sum_{i=1}^n(h_θ(x^i) - y^i)^2,\,\,\text{n为样本数}

三、损失函数求解法1:普通最小二乘法(OLS)

1、求解

\hat{θ} = (X^TX)^{-1}X^TY

 def standRegre(xMat, yMat):
  '''
  :param xMat: X矩阵
  :param yMat: y矩阵
  :return: 回归系数矩阵
  '''

  xTx = xMat.T * xMat
  # linalg.det(xTx)计算行列式,行列式值为0.矩阵不可逆
  if linalg.det(xTx) == 0.0:
      print("This matrix is singular,cannot do inverse")
      return

  # .I用作求矩阵的逆矩阵
  ws = xTx.I * dot(xMat.T,yMat)
  return ws
效果图.png

说明:要求矩阵X必须满足可逆条件,否则是不可以解的。

2、解释

我们知道,损失函数的矩阵表达式为

J(θ) = \frac {1}{2n}(Xθ - Y)^T(Xθ - Y)
扩展后得到:
J(θ) = \frac {1}{2n}(θ^TX^TXθ - 2θ^TX^TY + YY )
对θ求偏导,令导数为0,得:
\frac{\partial J(θ)}{\partial θ} = \frac {1}{2n}(2θ^TX^TX - 2X^TY) = 0
最后求解得到:
θ^T = (X^TX)^{-1}(X^TY)

四、损失函数求解法2:梯度下降(Gradient Descent)算法

1、 简介

梯度下降算法是一种求局部最优解的方法;在数学上,函数的梯度(导数)方向是函数值增长最快的方向,其相反方向就是下降最快的方向。

θ = θ - \alpha \frac{\partial J(θ)}{\partial θ}, \,\,\, \alpha\text{是学习率,步长}

   具体对θ的每个分量的求导公式如下:

\frac{\partial J(θ)}{\partial θ_j} = \frac{1}{n}\sum_{i=1}^n(h_θ(x^i) - y^i)x^i_j

说明:梯度下降(GD)是最小化损失函数的一种常用方法,主要有批量梯度下降随机梯度下降两种迭代求解思路。

2、 批量梯度下降 (Batch Gradient Descent)

repeat until convergence {
\,\,\,\,\,\,\,\,\,θ_j:= θ_j - \alpha \frac{1}{n}\sum_{i=1}^n(h_θ(x^i) - y^i)x^i_j
}

说明:每更新一个θ_j ,都要遍历一次样本集;如果样本的数量n很大,开销比较大;BGD可以得到一个全局最优解,使得损失函数的风险最小

代码实现:

def bgd(rate, maxLoop, epsilon, X, Y):
    '''
    批量梯度下降法
    :param rate:  学习率
    :param maxLoop:
    :param epsilon: 收敛精度
    :param X: 样本特征矩阵
    :param Y: 标签矩阵
    :return: (theta, errors, thetas), timeConsumed
    '''

    # m是样本数,n是特征个数
    m, n = X.shape
    # 初始化theta,n*1维的零向量
    theta = np.zeros((n, 1))
    count = 0
    # 是否收敛
    converged = False
    error = float('inf')
    errors = []
    thetas = {}

    for j in range(n):
        thetas[j] = [theta[j, 0]]

    while count <= maxLoop:
        if (converged):
            break
        count = count + 1
        # sum = 0
        for j in range(n):
            # deriv = (X * theta - y).T * X[:, j] / m
            # print(deriv)
            deriv = np.float128(0)
            for i in range(m):
                deriv += ((X[i] * theta - Y[i]) * X[i,j])[0,0]/ m
            theta[j, 0] = theta[j, 0] - rate * deriv
            thetas[j].append(theta[j, 0])

        #误差
        error = loss_function(theta, X, y)
        errors.append(error[0, 0])
        # 如果已经收敛
        if (error < epsilon):
            converged = True
    return theta, errors, thetas
批量梯度下降.png
3、随机梯度下降 (Stochastic Gradient Descent)

repeat until convergence {
   for i=1 to n {
\,\,\,\,\,\,\,\,θ_j:= θ_j - \alpha (h_θ(x^i) - y^i)x^i_j
   }
}

说明1:在随机梯度下降法中,每更新θ_j 只需要一个样本 (x^i,y^i);在样本数量巨大时,SGD的性能比较好,但是最终结果未必是全局最优解。

代码实现

def sgd(rate, maxLoop, epsilon, dataMat, labelMat):
  '''
  随机梯度下降法
  :param rate:  学习率
  :param maxLoop:
  :param epsilon: 收敛精度
  :param dataMat: 样本特征矩阵
  :param labelMat: 标签矩阵
  '''
  sampleCount, featureCount = dataMat.shape
  #初始化theta,featureCount * 1维的0向量
  theta = np.zeros((featureCount,1))
  count = 0
  converged = False
  error = float('inf')
  errors = []
  thetas = {}  #字典

  for j in range(featureCount):
      thetas[j] = [theta[j,0]]

  # 迭代到最大次数结束
  while count <= maxLoop:
      if (converged):
          break
      count = count + 1
      errors.append(float('inf'))
      # 获取样本
      for i in range(sampleCount):
          if (converged):
              break
          #计算实际和预测的误差
          diff = labelMat[i,0] - regression_function(theta,dataMat[i].T)
          # 通过第i个样本来优化theta
          for j in range(featureCount):
              theta[j, 0] = theta[j, 0] + rate * diff * dataMat[i,j]
              thetas[j].append(theta[j, 0])
          error = loss_function(theta, dataMat, labelMat)
          errors[-1] = error[0, 0]
          # 如果已经收敛
          if (error < epsilon):
              converged = True
   return theta, errors, thetas
随机梯度下降.png
4、其他

五、特征缩放

当样本的特征的数值之间差异比较大时,梯度下降的过程不仅曲折,而且耗时;这时候需要将各个特征归一化到统一的区间。常见的做法如下:

1、0均值标准化(Z-score normalization)

z=\frac {x - μ}{δ}

    其中,μσ分别为原始数据集均值标准差

    说明:该种归一化方式要求原始数据的分布可以近似为高斯分布,否则归一化的效果会变得很糟糕。

def standardize(xArr):
    '''
    特征标准化处理
    :param xArr: 样本特征集
    :return: 标准化后的样本特征集
    '''
    m, n = xArr.shape
    # 归一化每一个特征
    for j in range(n):
        meanVal = xArr[:, j].mean(axis=0)
        std = xArr[:, j].std(axis=0)
        if std != 0:
            xArr[:, j] = (xArr[:, j] - meanVal) / pow(std,2)
        else:
            xArr[:, j] = 0
    return xArr
2、线性函数归一化(Min-Max Scaling)

X_{normal} = \frac {X - X_{min}}{ X_{max} - X_{min}}

    其中X_{norm}为归一化后的数据,X为原始数据,X_{max}X_{min}分别为原始数据集的最大值和最小值。

def normalize(xArr):
  """特征归一化处理
  Args:
      X: 样本特征集
  Returns:
      归一化后的样本特征集矩阵
  """
  m, n = xArr.shape
  # 归一化每一个特征
  for j in range(n):
      minVal = xArr[:, j].min(axis=0)
      maxVal = xArr[:, j].max(axis=0)
      diff = maxVal - minVal
      if diff != 0:
        xArr[:, j] = (xArr[:, j] - minVal) / diff
      else:
        xArr[:, j] = 0
   return xArr
3、总结

六、多项式回归

1、多项式

多项式由称为不定元的变量和常数系数通过有限次加减法、乘法以及自然数幂次的乘方运算得到的代数表达式,可以分为一次一元多项式和多元多项式。我们主要讨论一元多项式,其形式如下:

y = a_0 + a_1 * x + a_2 * (x^2) + ... + a_n * (x^n) + e

2、多项式回归

七、拟合的问题

1、概念
欠拟合、拟合和过拟合.png
上一篇 下一篇

猜你喜欢

热点阅读