机器学习常见问题

1. 生成式模型与判别式模型

生成式模型

生成式模型会对 x 和 y 的联合分布 p(x, y) 进行建模,然后通过贝叶斯公式来求得 p(y|x) ,最后选取使得 p(y|x) 最大的 y. 比如朴素贝叶斯

生成式模型可以理解成生成数据分布的模型;

判别式模型

判别式模型直接对 P(y|x) 进行建模;比如 LR, SVM,把测试用例往里面一丢,label 就出来了

判别式模型可以理解成判别数据最后输出的模型

生成式模型与判别式模型对比

从结果角度来看,两种模型都能给我们最终的输出量(也就是 label),但是他们有很多不一样的地方:

  • 生成式模型的处理过程会告诉我们数据的一些统计信息,可以还原出联合概率分布 P(X, Y),但判别式不能
  • 一般来说,生成式模型会对数据的分布做一定的假设(比如朴素贝叶斯假设在给定 y 的情况下,各个特征之间是条件独立的),当满足这些假设时,生成式模型通常需要较少的数据就能取得不错的效果,但是当这些假设不成立时,判别式模型会取得更好的效果
  • 生成式模型最终得到的错误率会比判别式高,但生成式需要更少的样本就可以使错误率收敛
  • 生成式模型更容易拟合,而判别式要求解的问题通常比较复杂,都是凸优化问题
  • 当添加新的类别时,生成式模型不需要全部重新训练,只需要计算新的类别和 x 的联合概率分布,而判别式模型需要全部重新训练

常见的生成式模型

  • 朴素贝叶斯
  • KNN
  • 混合高斯模型
  • 隐马尔可夫模型 HMM
  • 深度信念网络 DBN

常见的判别式模型

  • 线性回归

  • 逻辑斯蒂回归 LR

  • 神经网络 NN

  • 支持向量机 SVM

2. 交叉验证

交叉验证的基本想法:重复地使用数据,把给定的数据切分为训练集和测试集,在此基础上反复的进行训练、测试、模型的选择

简单交叉验证

简单交叉验证的方法:

  1. 随机地将已给的数据分成两部分,一部分作为训练集,另一部分作为测试集;
  2. 用训练集在各种条件下训练模型,从而得到不同的模型;
  3. 在测试集上评测各个模型的测试误差,选出测试误差最小的模型

S 折交叉验证

S 折交叉验证方法如下:

  1. 随机地将已给的数据切分成 S 个互不相交的大小相同的子集;
  2. 利用 S-1 个子集的数据作为训练集来训练模型,利用余下的一个子集作为测试集来测试模型
  3. 将这一过程对可能的 S 中选择重复进行
  4. 最后选出 S 次评测中平均测试误差最小的模型

留一交叉验证

S 折交叉验证的特殊情形是 S=N,这个就是称为留一交叉验证

3. 有监督学习与无监督学习

有监督学习,从有标记的训练数据中推导出预测函数。有标记的训练数据是指:每个训练实例都包括输入和期望的输出。一句话:给定数据,预测标签

无监督学习,从无标记的训练数据中推断结论。最典型的无监督学习是聚类分析,他可以在探索性数据分析阶段用于发现隐藏的模式或者对数据进行分组。一句话:给定数据,寻找隐藏的结构

有监督学习

  • 有标签
  • 直接反馈
  • 预测未来结果

无监督学习

  • 无标签
  • 无反馈
  • 寻找隐藏的结构

4. 常见的损失函数

  • 0-1 损失函数

    用于分类问题,衡量误分类的数量。但是函数不可导,所以很少用

    预测值于目标值不相等,则为 1,否则为 0

    $$L(y, y’) =
    \begin{cases}
    1& \text{y = y’}\
    0& \text{y != y’}
    \end{cases}$$

    该损失函数的意思是:当预测错误的时候,损失函数为 1,预测正确的时候,损失函数值为 0. 该损失函数不考虑预测值和真实值的误差程度,也就是只要预测错误,预测错误和预测差很多是一样的。所以说这个定义太严格了,讲道理,如果真实值是 1,预测值是 0.9999 的话,可以认为是预测争取的,但是 0-1 损失函数会认为它是错的,所以对此进行改进,就有了 Preceptron Loss .

  • Preceptron Loss(感知损失)

    $$L(y, y’) = \begin{cases}
    1& \text{|y-y’| < t}\
    0& \text{|y-y’| \ge t}
    \end{cases}$$

    其中,t 是一个超参数.

  • Log Loss(对数损失函数 )

    在最大化似然函数时,是连乘的形式,但是为了便于处理,一般会套上 log,这样便可以将连乘转换为求和,由于 log 函数是单调递增函数,因此不会改变优化结果
    $$
    L(y, y’) = y \cdot \log y’ + (1-y) \cdot \log(1-y’), y \in {0,1}
    $$
    规定:
    $$
    0 \cdot \log 0 = 0
    $$

  • Square Loss(平方损失函数)

    常用于回归问题
    $$
    L(y, y’) = (y - y’)^2
    $$

  • Absolute Loss(绝对值损失函数)

    常用于回归问题
    $$
    L(y, y’) = |y - y’|
    $$

  • Exponential Loss(指数误差)

    常用于 boosting 算法中,如 AdaBoost
    $$
    L(y, y’) = \exp(-y \cdot y’), y \in {-1,1}
    $$

  • Hinge Loss(合页损失函数)

    可以用来解决间隔最大化问题,比如在 SVM 中解决几何间隔最大化问题
    $$
    L(y, y’) = \sum_{i=1}^N[1 - y_i’(w\cdot x_i + b)]_+ + \lambda ||w||^2
    $$

  • 交叉熵损失函数
    $$
    L(y, y’) = -\frac 1 n \sum _x [y \log y’ + (1-y) \log (1-y’)] ,y \in {0, 1}
    $$
    常见的二分类问题的损失函数

5. 常见的评价标准

分类问题

  1. 准确率(Accuracy)

    分类正确的个数除以总个数

  2. Precision,Recall,F1 score

    Precision 是预测为正类中,真实为正的概率

回归问题

  1. MAE(Mean Absolute Error,平均绝对误差)

    $\frac 1 n \sum _{i=1} ^n{|f_i - y_i|}$

  2. MSE(Mean Square Error,均方误差)

    $\frac 1 n \sum _{i=1} ^n{(f_i - y_i)^2}$

  3. RMSE(Root Mean Square Error,均方根误差),即为 MSE 开方

6. 正则化

正则化是为了防止过拟合,进而增强泛化能力,对参数做了一个限制。

主要有 L0 正则、L1 正则、L2 正则:

  1. L0 正则:非零参数的个数
  2. L1 正则:各个参数的绝对值之和
  3. L2 正则:各个参数的 L2 范数,也就是各个参数的平方和的开方值

参数稀疏有什么好处?

参数稀疏可以简化模型,避免过拟合。因为一个模型中真正重要的特征可能并不多,如果考虑所有所有的特征都起作用(也就是每个参数都不为 0),那么可能会出现过拟合的情况。

另一个好处就是,使模型的可解释性更强。

参数值越小模型越简单?

从复杂模型来倒推!

模型复杂 —> 会去拟合所有的点,包括异常点 —> 在某个小区间内,预测值会发现较大的波动 —> 较大的波动说明有较大的导数 —> 较大的导数说明对应的参数也较大 —> 模型参数值比较大

所以,参数值越小,模型越简单

L0 与 L1 正则

L0 与 L1 都能实现参数稀疏。但是 L0 很难优化求解,所以常用 L1.

L1 被称为 Lasso.

L2 正则

L2 可以使 W 的每个元素都很小,都接近于 0,但与 L1 不能,它不会让 w 等于 0,而是接近于 0. 越小的参数说明模型越简单,越简单的模型越不容易产生过拟合现象。

L2 被称为 Ridge.

L1 与 L2 的总结

  1. L1 会趋向于产生少量的特征,而其他的特征都是 0;而 L2 会选择更多的特征,这些特征都会接近于 0
  2. Lasso 在特征选择的时候很有用,而 Ridge 只是一种规则化
  3. 在所有特征只有少数特征起重要作用的情况下,选择 Lasso 比较合适,因为它能自动选择特征;而如果所有特征中,大部分特征都能起作用,而且起的作用很平均,那么 Ridge 更合适.

7. 过拟合与欠拟合

过拟合

指学习时选择的模型所包含的参数过多导致模型对训练数据过度拟合,以至于出现这一模型对已知数据预测得很好,但对未知数据预测得很差的现象。

过拟合时,通常是因为模型过于复杂,学习器把训练数据学的“太好了”,很可能把一些训练样本自身的特征当成所有潜在样本的共性了,这样一来模型的泛化性能就下降了。

如何判断?—— 在训练集误差很小,在测试集误差很大

过拟合高方差,低偏差

欠拟合

指模型使用的参数过少,以至于得到的模型很难拟合训练数据的现象。

欠拟合时,模型又过于简单,学习器没有很好地学到训练样本的一般性质,所以不论在训练数据还是测试数据中都表现得很差。

如何判断?—— 在训练集和测试集的误差均很大

解决过拟合的方法

  1. 交叉验证。通过交叉验证检验得到较优的模型参数

  2. 特征选择。减少特征数或使用较少的特征组合,对按区间离散化的特征,增大划分的区间

  3. 正则化。常用的有 L1、L2 正则,L1 正则还可以自动进行特征选择

  4. 增大正则化参数

  5. 增加训练数据(数据集扩增)

    数据集扩增也就是需要更多符合条件的数据,即和已有的数据是独立同分布的,一般有以下方法:

    • 从数据源头采集更多的数据
    • 复制原有数据并加上随机噪声
    • 重采样
    • 根据当前数据集,估计数据分布参数,使用该分布产生更多的数据
  6. Bagging,将多个弱分类器进行 Bagging,比如随机森林

深度学习中还有如下解决过拟合的方法:

  1. early stopping 早停策略

    具体做法:在训练的过程中,记录到目前为止最好的 validation accuracy,当连续 n 次 epoch 中,最好的 validation accuracy 不再提高时,就可以停止训练了

  2. Dropout

    随机删除一些隐藏层神经元,即认为这些神经元不存在,同时保持输入层与输出层神经元的个数不变。然后按照 BP 更新网络中的参数,这样一次迭代更新便完成了。下次迭代中,同样删除一些神经元,删除的神经元是随机选择的。直到训练结束

  3. shuffle:打乱数据集

  4. Batch Normalization

    BN 在训练某层时,会对每一个mini-batch数据进行标准(normalization) 处理,使输出规范到 N(0, 1)的正态分布,减少了内部神经元分布的改变;

    batch normalization是指在神经网络中激活函数的前面。这样做的好处:

    • 提高梯度在网络中的流动。Normalization能够使特征全部缩放到[0, 1],这样在反向传播时的梯度都在1左右,避免了梯度消失
    • 提升学习速率
    • 减少模型训练对初始化的依赖

解决欠拟合的方法

  1. 增加新特征。可以考虑加入特征组合等
  2. 尝试非线性模型。比如核 SVM、决策树、DNN 等
  3. 减小正则化参数
  4. Boosting。Boosting 往往有较小的偏差
  5. 深度学习中,可以增加网络的层数,神经元数目等等

8. 数据集切分方式

留出法

将数据集 D 切分为两个互斥的的集合,一个作为训练集一个作为测试集

为了保证类别比例,可以“分层采样”

交叉验证

自助法

每次有放回的随机抽样一个样本,抽出m个作为训练集;

自助采样会有0.368的数据没有被采样,可以用这部分的数据作为测试集,这叫做“包外估计” out-of-bag

9. AUC

AUC 的概率解释

AUC 可以看作,随机从正负样本中随机选一对正负样本,通过该模型对这两个样本分别计算一个 score,其中正样本的 score 大于负样本 score 的概率就是 AUC

AUC 对正负样本比例不敏感。AUC越大,表示模型区分正负样本的能力越强。

简单的二分类问题的 AUC 计算

先说简单的二分类的 AUC,是曲线 ROC 下面的面积。AUC 曲线,横轴是真正例率(正样本中预测为正的比例),纵轴是假正例率(负样本中预测为正的概率),绘制的过程是,对预测结果(为正的概率)进行降序排序,然后依次将每个样本划分为正例(该样本前面的也是正例),得到一个坐标点,依次这样,就画出 ROC 曲线。

让 AUC 做评价标准有什么好处?当测试集中正负样本的分布变换时(原来正负1:1,现在正负1:10),ROC 的曲线能保持一致。(因为横坐标时正样本中预测为正的概率,如果正样本成倍增加,但是这个比例是不变的,同理纵坐标也是)

多分类的问题的 AUC 计算

假设我们有 5 个样本,3 个类别,对这 5 个样本,都会计算出属于 类别1、类别2、类别3 的概率,用一个 5*3 的概率矩阵 P 表示。将概率转换成 0 和 1 的形式,也就是对于概率矩阵 P 的每一行,最大值为 1,其余为 0,得到标签矩阵 L。

我们有两种计算多分类 AUC 的方法:

  1. 对每个类别都画出一条 ROC 曲线,然后对 3 条 ROC 取平均,得到最后的 ROC 曲线,计算得到最后的 AUC 值:计算的过程是取的概率矩阵 P 和 标签矩阵 L的每一列,表示每个样本属于该类的概率以及他们是否真的属于这一类,利用这些数据来进行绘制。—— 对应sklearn.metrics.roc_auc_score函数中参数average值为’macro’
  2. 将多分类的 ACU 转换成二分类的 AUC 来进行计算:将概率矩阵 P 展开成一行(15个元素),将标签矩阵 L 展开成一行(15个元素),将这两行组成一个矩阵并转置,得到一个 15*2 的矩阵,每一行第一个元素表示为 1 的概率,第二个元素表示真实的标签(0 或 1),这样就转换成了二分类的 AUC 计算了。——对应sklearn.metrics.roc_auc_score函数中参数average值为’micro’

Reference

https://blog.csdn.net/u013630349/article/details/47146425 (生成式与判别式)

http://www.cnblogs.com/kemaswill/p/3427422.html (生成式与判别式)

https://zhuanlan.zhihu.com/p/26304729 (有监督与无监督)

http://liuchengxu.org/blog-cn/posts/bias-variance/ (偏差与方差)

https://cloud.tencent.com/developer/article/1047645 (损失函数)

https://lpq29743.github.io/redant/artificialintelligence/2018/02/25/Evaluation/ (评价标准)

https://zhuanlan.zhihu.com/p/29707029 (过拟合与欠拟合)

https://charlesliuyx.github.io/2017/10/03/%E3%80%90%E7%9B%B4%E8%A7%82%E8%AF%A6%E8%A7%A3%E3%80%91%E4%BB%80%E4%B9%88%E6%98%AF%E6%AD%A3%E5%88%99%E5%8C%96/ (正则化图示)

https://blog.csdn.net/YE1215172385/article/details/79443552 (多分类AUC)

https://tracholar.github.io/machine-learning/2018/01/26/auc.html (AUC概率解释)