zoukankan      html  css  js  c++  java
  • 线性回归,逻辑回归,神经网络,SVM的总结

    线性回归,逻辑回归,神经网络,SVM的总结

    • 详细的学习笔记.
    • markdown的公式编辑手册.
    • 回归的含义: 回归就是指根据之前的数据预测一个准确的输出值.
    • 分类的含义: 分类就是预测离散的输出值, 比如男生为1, 女生为0(0/1离散输出问题).
    • 机器学习中往往会有一个假设(hypothesis), 本质上来讲(h)代表学习算法的解决方案或函数.
      • (h)可以理解为是我们预先选定的规则或者函数的形式,我们需要不停地得到对应的参数.
      • (h)是一个从(x)(y)的函数映射.

    单变量的线性回归(Linear Regression with One Variable)

    • 单变量的表达方式(hypothesis function):

      [h_{ heta(x)};=; heta_{0}+ heta_{1}x ]

      • 因为只含有一个特征(即输入变量), 因此这类问题叫作单变量线性回归问题.
    • 模型所预测的值与训练集中实际值之间的差距就是建模误差(modeling error).
    • 目标函数(代价函数Cost Function): 目标是选择出可以使得建模误差的平方和能够最小的模型参数.
      • 代价函数的数学公式的表达为:

      [J( heta_{0}, heta_{1})=frac{1}{2m}sum_{i=1}^{m}(h_ heta(x^{(i)}-y^{(i)}))^{2} ]

      • 这个公式的(frac{1}{2m})是为了求偏导好计算; 大致的意思就是求每个样本的均方误差.
      • Goal: (min limits_{ heta_{0}, heta_{1}}J( heta_{0}, heta_{1})), 让代价函数最小.
      • 需要一个有效的算法, 能够自动地找出使代价函数(J)取最小值的参数( heta_{0})( heta_{1}), 这个算法就是梯度下降.
    梯度下降(Gredient Descent)
    • 梯度下降是一个用来求函数最小的优化算法, 在线性回归的算法中, 用它来求代价函数(J( heta_{0}, heta_{1}))的最小值.
    • 梯度下降背后的思想: 开始随机选择一个参数组合(( heta_{0}, heta_{1},ldots, heta_{n})), 计算出代价函数对应的函数值, 然后寻找一个能让代价函数下降最多的参数组合; 持续这么做直到找到一个局部最小值(local minimum),因为没有尝试所有的参数组合, 所以不能确定得到的局部最小值是否为全局最小值(global minimum), 选择不同的初始参数组合可能会找到不同的局部最小值.
    • 批量梯度下降(batch gradient descent)算法的公式:

    [ heta_{j}:= heta_{j} - alphafrac{partial}{partial heta_{j}}J( heta_{0}, heta_{1})qquad(for\,j = 0\,\,and\,;j = 1) ]

    - 其中$alpha$是学习率(**learning rate**),它决定了我们沿着能让代价函数下降程度最大的方向向下迈出的步子有多大,在批量梯度下降中,我们每一次都同时让所有的参数减去学习速率乘以代价函数的导数。
    - 梯度下降的过程为:
        + 根据代价函数求出其偏导函数, 因为所谓的梯度就是一阶偏导, 也就是沿参数该方向的变化率.
        + 算出梯度的大小值(把上一次的$	heta_{0}$和$	heta_{1}$代入偏导函数求解).
        + 迭代算出可能更好的参数值(就是用原来的$	heta$值减去偏导值乘以学习率的积).
        + 不断更新$	heta_{0}$和$	heta_{1}$
    - $alpha$太大或太小会出现什么情况:
        + 如果$alpha$太小, 即学习速率太小, 需要迭代很多次才能达到局部最优.
        + 如果$alpha$太大, 梯度下降可能会越过最低点, 甚至无法收敛, 出现震荡或发散现象.
        + 即使学习率$alpha$保持不变时, 梯度下降也可以收敛到局部最优, 因为到最优点时偏导为零呀.
    - 批量梯度下降是指在梯度下降的每一步中, 都用到了所有的训练样本, 在梯度下降中, 在计算微分求导时, 需要对所有$m$个训练样本求和.
    - 有的梯度下降法不考虑整个训练集, 而是每次关注训练集中的一些小的子集.
    
    • 梯度下降算法, 可以用来最小化任何代价函数(J), 不只是线性回归中的代价函数, 只要是凸函数应该都可以使用梯度下降算法来求解局部最优.
    • 在数据量较大的情况下, 梯度下降法比正规方程(normal equations)要更适用一些.

    多变量的线性回归(Linear Regression with Multiple Variables)

    • (i)个训练实例, 就是特征矩阵中的第(i)行, 是一个向量(vector).
    • 多变量的hypothesis function(假设函数)的数学表达为:$$h_{ heta}(x) = heta_{0}x_{0}+ heta_{1}x_{1}+ heta_{2}x_{2}+ldots+ heta_{n}x_{n}$$
      • 此时模型有(n+1)维的特征向量, 特征矩阵的维度(m*(n+1)).
      • hypothesis function的向量的表达式为: (h_{ heta}(x) = heta^{T}X).
    • 多变量的代价函数(cost function)为所有建模误差的平方和, 数学表达为:

      [J( heta_{0}, heta_{1},ldots, heta_{n})=frac{1}{2m}sum_{i=1}^{m}(h_{ heta}(x^{(i)}-y^{(i)}))^{2} ]

      • 其中(h_{ heta}(x) = heta_{0}x_{0}+ heta_{1}x_{1}+ heta_{2}x_{2}+ldots+ heta_{n}x_{n}).
    • 目标函数还是要找出使得代价函数最小的一系列参数.
    • 多变量线性回归的批量梯度下降算法为:

      [Repeat{ heta_{j}:= heta_{j}-alphafrac{partial}{partial heta_{j}}J( heta_{0}, heta_{1},ldots, heta_{n}) }]

      • 求导计算为:

      [Repeat{ heta_{j}:= heta_{j}-alphafrac{1}{m}sum_{i=1}^{m}(h_{ heta}(x^{(i)})-y^{(i)})*x_{j}^{(i)} }]

      • python的代码实现为:
      def computeCost(X, Y, theta):
          inner = np.power(((X * theta.T) - y), 2) # 內积
          return np.sum(inner) / (2 * len(X)) # len(X)为行数
      
    • 特征缩放(即归一化处理): 在多维特征的情况下, 让这些特征具有相似的尺度, 将帮助梯度下降算法更快地收敛.
    • 正规方程(Normal Equation): 是相对于梯度下降算法的另一种方法.
      • 正规方程是为了求解偏导为0的点: (frac{partial}{partial heta_{j}}J( heta_{j})=0).

      • 用正规方程解出向量: ( heta=(X^{T}X)^{-1}X^{T}y).
      • 梯度下降与正规方程的比较:
        • 梯度下降需要选择学习率(alpha), 梯度下降需要多次迭代, 当特征数量(n)特别大时也比较适用, 并适用于各种类型的模型.
        • 正规方程不需要迭代, 一次计算即可得出结果, 但需要计算((X^{T}X)^{-1}), 计算矩阵的逆的时间复杂度为(O(n^{3})), 如果特征少还比较快, 特征特别多的话就不太能接受了.
        • 正规方程只适用于线性模型, 不适合逻辑回归等其他模型.
      • 只要特征数量小于一万, 通常适用标准方程(normal equation), 而不适用梯度下降法.
      • 梯度下降可以适用在有大量特征变量的线性回归问题上.
      • 正规方程的Python实现:
      import numpy as np
      def normalEqn(X, y):
          theta = np.linalg.inv(X.T@X)@X.T@y #X.T@X等价于X.T.dot(X)
          return theta
      
    • 正规方程及不可逆性:
      • 不可逆的矩阵称为奇异或退化矩阵.
      • 代价函数的向量形式为: (J( heta)=frac{1}{2}(X heta-y)^{2}).
      • 具体公式推导为:$$J( heta)=frac{1}{2}(X heta-y)^{T}(X heta-y)$$

      [=frac{1}{2}(X^{T} heta^{T}-y^{T})(X heta-y) ]

      [=frac{1}{2}(X^{T} heta^{T}X heta-X^{T} heta^{T}y-y^{T}X heta-y^{T}y) ]

      • 对代价函数进行求偏导:(frac{dAB}{dB}=A^{T}), (frac{dX^{T}AX}{dX} = (X^{T}A)^{T}).

      [frac{partial(J heta)}{partial heta}=frac{1}{2}(2X^{T}X heta-X^{T}y-(y^{T}X)^{T}-0) ]

      [frac{partial(J heta)}{partial heta}=frac{1}{2}(2X^{T}X heta-X^{T}y-X^{T}y) ]

      [frac{partial(J heta)}{partial heta}=X^{T}X heta-X^{T}y ]

      • 令偏导为0, 即(frac{partial J( heta)}{partial heta}=0), 则有( heta=(X^{T}X)^{-1}X^{T}y).

    逻辑回归(Logistic Regression)

    • 需要预测的变量(y)是离散的值, 将因变量(dependent variable)可能属于的两个类分别称为负向量(negative class)和正向类(positive class), (yin 0,1).
    • 逻辑回归是一个分类算法, 它的输出值永远在0和1之间.
    • Hypothesis Representation: (h_{ heta}(x)=g( heta^{T}X)).
      • (g)代表逻辑函数(logistic function)是一个常用的逻辑函数, S型函数(Sigmoid function), 具体的数学表达为: (g(z)=frac{1}{1+e^{-z}}).
      • Python的代码实现为:
      import numpy as np
      def sigmoid(z):
          return 1 / (1 + np.exp(-z))
      
      • 在逻辑回归中, 当(h_{theta}>=0.5)时, 预测(y=1); 当(h_{theta}<0.5)时, 预测(y=0).
    • 代价函数(cost function):
      • 在线性回归模型中, 我们定义的代价函数是所有模型误差的平方和; 在逻辑回归中, 重新定义了代价函数, 是对假设函数取了对数. 数学表达式为:

      [ Cost(h_{ heta}(x),y)= left{ egin{array}{**lr**} -log(h_{ heta}(x));;;;;if;;;y=1 & \ -log(1-h_{ heta}(x));;;;;if;;;y=0 end{array} ight. ]

      • 简化为:(Cost(h_{ heta}(x),y)=-y*log(h_{ heta}(x))-(1-y)*log(1-h_{ heta}(x))).
      • 求每个样本的平均值, 所以代价函数的数学表达为:

      [J( heta)=frac{1}{m}sum^{m}_{i=1}[-y^{(i)}*log(h_{ heta}(x^{(i)}))-(1-y^{(i)})*log(1-h_{ heta}(x^{(i)}))] ]

      • 把负号提出来, 即: $$J( heta)=-frac{1}{m}sum^{m}{i=1}[y^{(i)}*log(h{ heta}(x^{(i)}))+(1-y^{(i)})*log(1-h_{ heta}(x^{(i)}))]$$
    • python的代码实现为:
      import numpy as np
      def cost(theta, X, y):
          theta = np.matrix(theta)
          X = np.matrix(X)
          y = np.matrix(y)
          first = np.multiply(-y, np.log(sigmoid(X * theta.T)))
          second = np.multiply((1-y), np.log(1 - sigmoid(X * theta.T)))
          return np.sum(first - second) / (len(X))
      
    • 得到这个代价函数后, 就需要用梯度下降算法来求得能使代价函数最小的参数, 对代价函数求导后为:

      [ heta_{j}:= heta{j}-alphafrac{1}{m}sum_{i=1}^{m}(h_{ heta}(x^{(i)})-y^{(i)})*x_{j}^{(i)} ]

      • 然后不断的更新( heta_{j})值, simultaneously update all ( heta_{j}).
      • 虽然得到的梯度下降算法表面上和线性回归的梯度下降算法一样, 但是这里的(h_{ heta}=g( heta^{T}X))与线性回归本质上是不一样的.
    • 使用梯度下降法(gradient descent)最小化代价函数.
    • 线性回归的假设函数为:(h_{ heta}(x)= heta^{T}X= heta_{0}x_{0}+ heta_{1}x_{1}+dots+ heta_{n}x_{n}); 而现在逻辑回归的假设函数为: (h_{ heta}(x)=frac{1}{1+e^{- heta^{T}X}}), 更新规则虽然一样,但是假设的定义发生了变化.
      • 特征缩放(特征数据的归一化)同样适用于逻辑回归.
    高级优化
    • 在梯度下降的过程中, 需要计算两样东西: (J( heta))(J)等于(0, 1, dots, n)时的偏导数项.
    • 另一种角度看待这个问题的思路是: 写出代码来计算(J( heta))和这些偏导数, 然后把这些插入到梯度下降中.
    • 比梯度下降算法更好的优化算法:
      • 共轭梯度(Conjugate Gradient).
      • 局部优化算法(Broyden fletcher glodfarb shann, BFGS).
      • 有限内存局部优化算法(LBFGS).
      • 这三种算法有很多优点:
        • 不需要手动选择学习率(alpha), 因为内部有个内部循环(称为线性搜索line search), 尝试不同的学习速率(alpha), 并自动选择一个好的学习速率(alpha).
        • 往往最终收敛得远远快于梯度下降.
    正则化(Reguarization)
    • 正则化主要是用来解决过拟合问题(overfitting): 减少或改善过度拟合问题.
      • 正则化保留所有的特征, 但是减少参数的大小(magnitude).
      • 在代价函数中增加一个惩罚项.
    • 增加惩罚项后的数学表达为:

      [J( heta)=frac{1}{2m}[sum_{i=1}^{m}(h_{ heta}(x^{(i))}-y^{(i)})^{2}+lambdasum_{j=1}^{n} heta_{j}^{2}] ]

      • (lambda)称为正则化参数(Regularization Parameter).
      • 如果选择的正则化参数(lambda)过大, 则会把所有的参数都最小化了, 造成欠拟合.
    • 正则化线性回归的梯度下降算法的变化在于, 每次都在原有的算法更新规则基础上令( heta)值减少了一个额外的值.

      [ heta_{j}:= heta_{j}(1-alpha) ]

    • 正则化的逻辑回归模型: 代价函数(J( heta))增加一个惩罚项.

      [J( heta)=-frac{1}{m}sum^{m}_{i=1}[y^{(i)}*log(h_{ heta}(x^{(i)}))+(1-y^{(i)})*log(1-h_{ heta}(x^{(i)}))]+frac{lambda}{2m}sum_{j=1}^{n} heta_{j}^{2} ]

    神经网路(Neural Networks)

    • 神经网络是一个非线性假设的算法(non-linear hypotheses).
    • 无论是线性回归还是逻辑回归,都会有一个缺点: 当特征太多时, 计算负荷会非常大.
    • 神经网路模型建立在很多神经元之上, 每一个神经元又是一个小小学习模型, 这些神经元(也叫激活单元, activation unit), 有多个输入和一个输出; 神经网路中, 参数也被称作权重(weight).
    • Sigmoid(logistic) activation function(S激活函数).
    • 第一层为输入层(input layer), 最后一层为输出层(output layer), 中间的层为隐藏层(Hidden Layers), 我们为每一层增加一个偏差单位(bias unit).
      • 从左到右的算法称为前向传播算法(forward propagation)
      • 数学表达为: (z^{(2)}= heta^{(1)}*X^{T}), 激活为(a^{(2)}=g(z^{(2)})).
    • 其实神经网络就像是logistic regression, 只不过输入向量变成了中间层a.
    • 可以把a看成更高级的特征值, 也就是x的进化体, 因为他们是由x决定的, 因为是梯度下降的, 所以a是变化的, 并且越来越变化厉害, 所以这些更高级的特征值远比仅仅将x次方厉害,也能更好的预测新数据.
    • 从本质上讲, 神经网络能够通过学习得出其自身的一系列特征.逻辑回归中被限制使用原始特征. 可以认为隐藏层能输出新的特征.
    • 单层神经元(无中间层)的计算可用来表示逻辑运算, 逻辑与(AND), 逻辑或(OR).
    • 神经网络的代价函数: $$J(Theta)=-frac{1}{m}[sum_{i=1}^{m}sum_{k=1}^{k}y_{k}^{(i)}log(h_{Theta}(x^{(i)})){k}+(1-y{k}^{(i)})log(1-(h_{Theta}(x^{(i)})){k})]+frac{lambda}{2m}sum{l=1}^{L-1}sum_{i=1}^{s_{l}}sum_{j=1}^{s_{l}+1}(Theta_{ji}^{(l)})^{2}$$
      • 希望通过代价函数来观察算法预测的结果与真实情况的误差有多大, 神经网络对于每一行特征会给出K个预测.
      • 正则化的哪一项是排除了每一层( heta_{0})后, 每一层的( heta)矩阵的和.
    • 神经网络中比较重要的方向传播算法(Backpropagation algorithm):
      • 为了计算代价函数的偏导数(frac{partial}{partial heta_{ij}^{(l)}}), 需要采用一种反向传播算法.
      • 先计算最后一层误差, 然后再一层一层方向求出各层的误差, 直到倒数第二层.
      • (Delta_{ij}^{(l)})来表示误差矩阵.

      [D_{ij}^{(l)}:=frac{1}{m}Delta_{ij}^{(l)}+lambdaTheta_{ij}^{(l)} ]

    • 梯度的数值检验(Numerical Gradient Checking).
    • 训练神经网络的步骤:
      • 参数的随机初始化.
      • 利用正向传播方法计算所有的(h_{ heta}(x)).
      • 编写计算代价函数(J)的代码.
      • 利用方向传播方法计算所有偏导数.
      • 利用数值检验方法检验这些偏导数.
      • 使用优化算法来最小化代价函数.
    应用机器学习的建议
    • 获得更多的训练实例--通常是有效的, 但是代价较大, 可以先考虑一下的方法:
      • 尝试减少特征的数量.
      • 尝试获得更多的特征.
      • 尝试增加多项式特征.
      • 尝试减少正则化程度(lambda).
      • 尝试增加正则化程度(lambda).
    • 交叉验证: 70%的数据作为训练集, 30%的数据作为测试集.
      • 测试集和训练集都要含有各种类型的数据(数据洗牌).
    • 一个算法表现不理想, 多半是两种情况: 偏差比较大, 方差比较大.(要么是欠拟合, 要么是过拟合)
    • 学习曲线: 经常用学习曲线来判断某一个学习算法是否处于偏差/方差问题.
      • 学习曲线是学习算法的一个很好的合理检验(sanity check).
      • 获得更多的训练实例——解决高方差.
      • 尝试减少特征的数量——解决高方差.
      • 尝试获得更多的特征——解决高偏差.
      • 尝试增加多项式特征——解决高偏差.
      • 尝试减少正则化程度 λ——解决高偏差.
      • 尝试增加正则化程度 λ——解决高方差.
    • 使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,但计算代
      价较小使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算
      代价比较大,但是可以通过正则化手段来调整而更加适应数据.
      • 正则化对大型神经网络有很大的作用.
    • 学习算法的推荐方法:
      1. 从一个简单的能快速实现的算法开始,实现该算法并用交叉验证集数据测试这个算法.
      2. 绘制学习曲线,决定是增加更多数据,或者添加更多特征,还是其他选择.
      3. 进行误差分析:人工检查交叉验证集中我们算法中产生预测误差的实例,看看这些实例是否有某种系统化的趋势.
    • 查准率(Precision)和查全率(Recall),算法预测的结果分成四种情况:
      1. 正确肯定(True Positive,TP):预测为真,实际为真
      2. 正确否定(True Negative,TN):预测为假,实际为假
      3. 错误肯定(False Positive,FP):预测为真,实际为假
      4. 错误否定(False Negative,FN):预测为假,实际为真
    • 查准率(P)=TP/(TP+FP)--越高越好(预测有恶性肿瘤的病人中,实际上有恶性肿
      瘤的病人的百分比), 查全率(R)=TP/(TP+FN)--越高越好(在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的
      病人的百分比).
    • F1值(F1 score): (F1 = 2frac{PR}{P+R})

    支持向量机(Support Vector Machines)

    • SVM,在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。
    • SVM hypothesis的数学表达:

      [minlimits_{ heta}Csum_{i=1}^{m}[y^{(i)}cost_{1}( heta^{T}x^{(i)})+(1-y^{(i)}cost_{0}( heta^{T}x^{(i)}))]+frac{1}{2}sum^{n}_{i=1} heta_{j}^{2} ]

    • 将支持向量机看作是大间距分类器.
    • C的作用类似与(frac{1}{lambda}), C不是非常非常大的时候, 它可以忽略掉一些异常点的影响, 得到更好的决策界.
    • 高斯核函数(Gaussian Kernel), (f_{1}=e(-frac{||x-l^{(1)}||^{2}}{2sigma^{2}})), 这个函数与正态分布没有实际上的关系,只是看上去有点像而已.
    • 不使用核函数又称为线性核函数(linear kernel).
    • 多项式核函数(Polynomial Kernel).
    • 字符串核函数(String kernel).
    • 卡方核函数(chi-square kernel).
    • 直方图交集核函数(histogram intersection kernel).
      • 这些核函数的目标也都是根据训练集和地标之间的距离来构建新特征,这些核函数需要
        满足Mercer's定理.
      • 选择支持向量机的原因主要在于它的代价函数是凸函数,不存在局部最小值.
      • 逻辑回归和不带核函数的支持向量机它们都是非常相似的算法.
    • 对于许多这样的问题,神经网络训练起来可能会特别慢,但是如果你有一个非常好的 SVM 实现包,它可能会运行得比较快比神经网络快很多.
    • SVM 具有的优化问题,是一种凸优化问题.
    • 你有多少数据,你有多熟练是否擅长做误差分析和排除学习算法,指出如何设定新的特征变量和找出其他能决定你学习算法的变量等方面, 通常这些方面会比你使用逻辑回归还是SVM这方面更加重要。
  • 相关阅读:
    Android服务之bindService源代码分析
    [iOS 高级] iOS远程推送与本地推送大致流程
    redis集群
    面试你之前,我希望在简历上看到这些!
    解决安卓出现导入第三方包反复的错误
    【PA2012】【BZOJ4289】Tax
    Spark jdbc postgresql数据库连接和写入操作源代码解读
    Java中hashcode的理解
    CvArr、Mat、CvMat、IplImage、BYTE转换
    CSDN日报20170413 ——《天天写业务代码的那些年,我们是怎样成长过来的》
  • 原文地址:https://www.cnblogs.com/longjiang-uestc/p/10127393.html
Copyright © 2011-2022 走看看