Datawhale组队学习第27期:集成学习
本次学习的指导老师萌弟教学视频
本贴为学习记录帖,有任何问题欢迎随时交流~
部分内容可能还不完整,后期随着知识积累逐步完善。
开始时间:2021年7月19日
最新更新:2021年7月20日(Task4分类问题)

一、度量分类模型的性能指标

1. 混淆矩阵

  • 假阴性和假阳性都是分类错误,在现实生活中这两种分类错误的代价有所不同,需要分开讨论。
  • 这里有点类似最小错误率决策和最小风险决策。

2.分类模型的指标

准确率Accuracy

  • 含义:真阳性和真阴性的占总样本比例

  • 调用函数:sklearn.metrics.accuracy_score

  • 计算公式:
    A c c u r a c y ( 二 分 类 ) = T P + T N T P + T N + F P + F N Accuracy(二分类) = \frac{TP+TN}{TP+TN+FP+FN} Accuracy()=TP+TN+FP+FNTP+TN

精度Precision

  • 含义:真阳性占预测阳性比例,又称为:查准率

  • 调用函数:sklearn.metrics.average_precision_score

  • 计算公式:
    P r e c i s i o n ( 二 分 类 ) = T P T P + F P P r e c i s i o n ( 多 分 类 − M i c r o ) = ∑ i = 1 n T P i ∑ i = 1 n ( T P i + F P i ) P r e c i s i o n ( 多 分 类 − M a c r o ) = 1 n ∑ i = 1 n T P i T P i + F P i \begin{aligned} Precision(二分类) &= \frac{TP}{TP+FP} \\ Precision(多分类-Micro) &= \frac{\sum\limits_{i=1}^{n}TP_i}{\sum\limits_{i=1}^{n}(TP_i+FP_i)} \\ Precision(多分类-Macro) &= \frac{1}{n} \sum\limits_{i=1}^{n}\frac{TP_i}{TP_i+FP_i} \end{aligned} Precision()Precision(Micro)Precision(Macro)=TP+FPTP=i=1n(TPi+FPi)i=1nTPi=n1i=1nTPi+FPiTPi

召回率Recall

  • 含义:真阳性占实际阳性比例,又称为真阳性率TPR,敏感性Sensitive,查全率

  • 调用函数:sklearn.metrics.recall_score

  • 计算公式:
    R e c a l l ( 二 分 类 ) = T P T P + F N R e c a l l ( 多 分 类 − M i c r o ) = ∑ i = 1 n T P i ∑ i = 1 n ( T P i + F N i ) R e c a l l ( 多 分 类 − M a c r o ) = 1 n ∑ i = 1 n T P i T P i + F N i \begin{aligned} Recall(二分类) &= \frac{TP}{TP+FN} \\ Recall(多分类-Micro) &= \frac{\sum\limits_{i=1}^{n}TP_i}{\sum\limits_{i=1}^{n}(TP_i+FN_i)} \\ Recall(多分类-Macro) &= \frac{1}{n} \sum\limits_{i=1}^{n}\frac{TP_i}{TP_i+FN_i} \end{aligned} Recall()Recall(Micro)Recall(Macro)=TP+FNTP=i=1n(TPi+FNi)i=1nTPi=n1i=1nTPi+FNiTPi

假阳性率FPR

  • 含义:假阳性占实际阴性的比例,常用于ROC曲线中,等于1 - 特异性Specificity
  • 计算公式:
    F P R = F N T N + F P FPR = \frac{FN}{TN+FP} FPR=TN+FPFN

F1值

  • 含义::综合精度和召回率(注意:在多分类下也有MicroMarco)。

  • 调用函数:sklearn.metrics.f1_score

  • 计算公式:
    F 1 = 2 × P r e c i s i o n × R e c a l l P r e c i s i o n + R e c a l l F1 = 2 \times \frac{Precision \times Recall}{Precision + Recall} \\ F1=2×Precision+RecallPrecision×Recall

ROC

  • 含义:纵轴为真阳率、横轴为假阳性率的曲线图。
  • 调用函数:sklearn.metrics.roc_curve
  • 例子:

AUC

  • 含义:ROC曲线与X轴之间的面积
  • 调用函数:sklearn.metrics.roc_auc_score

二、常见的分类模型

1. 感知机

  • 常用库:sklearn.sklearn.neural_network.MLPClassifier

2. Logistic回归

  • 常用库:sklearn.linear_model.LogisticRegression

3. 支持向量机

  • 线性可分问题
    • 最大间隔
    • sign函数
  • 非线性可分问题
    • 核函数:低维度映射到高维度
    • 多项式核函数
    • 高斯核函数
    • Sigmoid核函数
    • 余弦相似度核函数
  • 常用库:sklearn.svm.LinearSVC

4. 决策树

  • 关键是分割节点的标准(回归树中使用的是均方误差)
  • 常见的分割节点标准:
    • 错误率
    • 基尼系数
    • 交叉熵
  • 常用库:sklearn.tree.DecisionTreeClassifier

5. K近邻

  • 常用库:sklearn.neighbors.KNeighborsClassifier

三、Logistic回归

1. 线性回归模型及其假定回顾

线性回归模型

y = w T x + ϵ y = w^Tx + \epsilon y=wTx+ϵ

线性回归模型的假定

  • 线性假定: y = w T x + ϵ y = w^T x + \epsilon y=wTx+ϵ,其中w的元素均为常数

  • 严格外生性假定: E ( ϵ ∣ x ) = 0 E(\epsilon|x) = 0 E(ϵx)=0,即扰动项独立于观测数据

  • 数值矩阵 x x x 是列满秩,不存在严格的多重共线性

  • 球形扰动项假定: V a r ( ϵ ∣ x ) = σ 2 Var(\epsilon|x) = \sigma^2 Var(ϵx)=σ2,即扰动项条件同方差和无自相关

  • 正态性假定: ϵ ∣ x ∼ N ( 0 , σ 2 ) \epsilon|x \sim N(0, \sigma^2) ϵxN(0,σ2)

离散型变量下的线性回归

  • 在普通线性回归中, y y y是一个连续型随机变量,那么 ϵ = y − w T x \epsilon = y - w^Tx ϵ=ywTx显然也是连续性变量,这时的 c o v ( ϵ , x ) = 0 cov(\epsilon, x) = 0 cov(ϵ,x)=0,满足严格外生性和正态性假定。

  • y y y是一个离散型随机变量时(假设是二值离散),那么 ϵ = 1 − w T x \epsilon=1-w^Tx ϵ=1wTx ϵ = − w T x \epsilon = -w^Tx ϵ=wTx,这时 c o v ( ϵ , x ) ≠ 0 cov(\epsilon, x) \ne 0 cov(ϵ,x)=0,意味着扰动项依赖于观测数据,也表明了扰动项存在异方差;同时 ϵ ∣ x ∼ B ( 0 , 1 ) \epsilon|x \sim B(0,1) ϵxB(0,1),不满足原有的正态性假定。

线性回归、感知机与Logistic回归的联系

  • y y y是一个离散型随机变量时(假设是二值离散),依旧使用原有的线性回归模型, w T x w^Tx wTx的取值范围有可能是 ( − ∞ , + ∞ ) (-\infty, +\infty) (,+)。从分类角度看,存在一个超平面将其划分成两个类别所属的空间,这里的划分一般是采用 s i g n sign sign函数(阶跃函数),将 w T x w^Tx wTx直接转化成二分类的类别,而 s i g n sign sign函数称为连接函数。这里的通过 s i g n sign sign函数进行中间转化的线性模型,称为感知机
  • 上面的模型直接预测成类别,而现实或许更关注某个类别发生的概率。因此,从概率的角度思考, w T x w^Tx wTx需要映射到 [ 0 , 1 ] [0, 1] [0,1]上,即:存在一个连接函数,使得y的预测值介于 [ 0 , 1 ] [0, 1] [0,1]之间。显然,上述使用的 s i g n sign sign函数不适合作为这类模型的连接函数。这时 s i g m o i d sigmoid sigmoid函数作为连接函数,形成的模型称为逻辑斯蒂回归模型
  • 对比之后可以发现,该三类模型依旧是依赖于线性模型,主要区别在于各自选取的连接函数。普通线性回归可以视连接函数为: h ( w T x ) h(w^Tx) h(wTx) = w^Tx,感知机的连接函数为: h ( w T x ) = s i g n ( w T x ) h(w^Tx) = sign(w^Tx) h(wTx)=sign(wTx) L o g i s t i c Logistic Logistic回归的连接函数为: h ( w T x ) = s i g m o i d ( w T x ) h(w^Tx) = sigmoid(w^Tx) h(wTx)=sigmoid(wTx)
  • 下面是三者的对比图,图片选自《机器学习的思考故事》

2. Sigmoid函数引入

  • 定义(一般记为 σ \sigma σ
    σ ( x ) = F ( x ) = 1 1 + e − x \sigma(x) = F(x) = \frac{1}{1+e^{-x}} σ(x)=F(x)=1+ex1

  • 特点:

    • x x x映射到 [ 0 , 1 ] [0, 1] [0,1]
    • 平滑且易求导
  • 导数:
    σ ′ ( x ) = F ′ ( x ) = e − x ( 1 + e − x ) 2 = F ( x ) ( 1 − F ( x ) ) \sigma'(x) = F'(x) = \frac{e^{-x}}{(1+e^{-x})^2} = F(x)(1-F(x)) σ(x)=F(x)=(1+ex)2ex=F(x)(1F(x))

  • 函数图像:

  • 实现代码:

    import numpy as np
    import matplotlib.pyplot as plt
    
    
    # 定义sigmoid函数
    def sigmoid(x_):
        return 1 / (1 + np.exp(-x_))
    
    
    x = np.linspace(-10, 10, 100)
    y = sigmoid(x)
    
    # 画出函数图像
    plt.plot(x, y, 'r')
    plt.title(r'$F(x) = \frac{1}{1+e^{-x}}$')
    plt.xlabel('x')
    plt.ylabel('F(x)')
    plt.show()
    

3. Logistic回归模型推导

模型设定

  • 对于给定的 x x x,有y为类别标签(只为0或1),设定某件事发生的概率为 P ( y = 1 ∣ x ; w ) P(y=1|x;w) P(y=1x;w),则有:
    P ( y = 1 ∣ x ; w ) = σ ( w T x ) P ( y = 0 ∣ x ; w ) = 1 − σ ( w T x ) P(y=1|x;w) = \sigma(w^Tx) \\ P(y=0|x;w) = 1 - \sigma(w^Tx) P(y=1x;w)=σ(wTx)P(y=0x;w)=1σ(wTx)

  • 从随机试验角度看,箱子中有N个球(只有黑色和白色),抽取一次为白色的球记为事件A,而事件 X X X服从 b ( 1 , P ) b(1,P) b(1,P),即有:
    P ( A ) = P ( Y = y ∣ x ; w ) = P ( Y = 1 ∣ x ; w ) y [ 1 − P ( Y = 1 ∣ x ; w ) ] 1 − y , 其 中 y = 0 , 1 P(A) = P(Y=y|x;w) = P(Y=1|x;w)^y[1-P(Y=1|x;w)]^{1-y},其中y=0,1 P(A)=P(Y=yx;w)=P(Y=1x;w)y[1P(Y=1x;w)]1yy=0,1

参数估计

  • 显然,我们最关注的是每个类别对应的概率(这里只需知道一个类别P,便可知道另一个类别的概率)。因此需要估计 b ( 1 , P ) b(1, P) b(1,P)中的 P P P,可以考虑采用极大似然估计法。

  • P ( y = 1 ∣ x ; w ) = π ( x ) P(y=1|x;w) = \pi(x) P(y=1x;w)=π(x),则 P ( Y = y ∣ x ; w ) = [ π ( x ) ] y [ 1 − π ( x ) ] 1 − y P(Y=y|x;w) = [\pi(x)]^y[1-\pi(x)]^{1-y} P(Y=yx;w)=[π(x)]y[1π(x)]1y

  • 假设给定样本 x = { x 1 , x 2 , . . . x n } x = \{x_1, x_2, ... x_n\} x={ x1,x2,...xn},对应的标签 y = { y 1 , y 2 , . . . , y n } y = \{y_1, y_2,..., y_n\} y={ y1,y2,...,yn},有样本联合概率分布(似然函数)为:
    L ( w ) = ∏ i = 1 n P ( Y i = y i ∣ x i ; w ) = ∏ i = 1 n [ π ( x i ) ] y i [ 1 − π ( x i ) ] 1 − y i = ∏ i = 1 n [ 1 1 + e x p { − w T x i } ] y i [ 1 − 1 1 + e x p { − w T x i } ] 1 − y i \begin{aligned} L(w) &= \prod\limits_{i=1}^{n}P(Y_i=y_i|x_i;w) \\ &= \prod\limits_{i=1}^{n}[\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i} \\ &= \prod\limits_{i=1}^{n} [\frac{1}{1+exp\{-w^Tx_i\}}]^{y_i}[1 -\frac{1}{1+exp\{-w^Tx_i\}}]^{1-y_i} \end{aligned} L(w)=i=1nP(Yi=yixi;w)=i=1n[π(xi)]yi[1π(xi)]1yi=i=1n[1+exp{ wTxi}1]yi[11+exp{ wTxi}1]1yi

  • 对似然函数取对数,得到:
    log ⁡ L ( w ) = ∑ i = 1 n [ y i ⋅ log ⁡ π ( x i ) + ( 1 − y i ) ⋅ log ⁡ ( 1 − π ( x i ) ) ] = ∑ i = 1 n [ y i ⋅ log ⁡ π ( x i ) 1 − π ( x i ) + log ⁡ ( 1 − π ( x i ) ] = ∑ i = 1 n [ y i ( w T x i ) + l o g ( 1 − π ( x i ) ) ] \begin{aligned} \log L(w) &= \sum\limits_{i=1}^{n} [y_i \cdot \log \pi(x_i)+(1-y_i) \cdot \log(1-\pi(x_i))] \\ &= \sum\limits_{i=1}^{n} [y_i \cdot \log\frac{\pi(x_i)}{1-\pi(x_i)}+ \log(1-\pi(x_i) ] \\ &= \sum\limits_{i=1}^{n} [y_i(w^Tx_i) + log(1-\pi(x_i))] \end{aligned} logL(w)=i=1n[yilogπ(xi)+(1yi)log(1π(xi))]=i=1n[yilog1π(xi)π(xi)+log(1π(xi)]=i=1n[yi(wTxi)+log(1π(xi))]

优化问题

  • 目标函数:
    J ( w ) = − 1 n ∑ i = 1 n [ y i ⋅ ( w T x i ) + log ⁡ ( 1 − π ( x i ) ) ] = − 1 n [ ( Y T X ⋅ w + ∑ i = 1 n log ⁡ ( 1 − π ( x i ) ) ] \begin{aligned} J(w) &= -\frac{1}{n}\sum\limits_{i=1}^{n} [y_i \cdot (w^Tx_i) +\log(1-\pi(x_i))] \\ &= -\frac{1}{n}[(Y^TX\cdot w + \sum_{i=1}^{n}\log(1-\pi(x_i))] \end{aligned} J(w)=n1i=1n[yi(wTxi)+log(1π(xi))]=n1[(YTXw+i=1nlog(1π(xi))]

  • 优化任务:
    w = argmin w J ( w ) w = \mathop{\text{argmin}}_{w} J(w) w=argminwJ(w)

优化算法(梯度下降法)

  • 定义 s i g m o i d sigmoid sigmoid函数

  • 初始化参数 w ( 0 ) = [ w 0 ( 0 ) , w 1 ( 0 ) , . . . , w m ( 0 ) ] w^{(0)} = [w_0^{(0)}, w_1^{(0)},..., w_m^{(0)}] w(0)=[w0(0),w1(0),...,wm(0)]

  • 设定学习率 α \alpha α,最大迭代次数 l o o p s loops loops,可接受误差 ϵ \epsilon ϵ

  • 计算当前梯度(使用链式法则):
    ∂ J ( w ) ∂ w j = − 1 n ∑ i = 1 n [ y i ∂ w T x i ∂ w j − 1 1 − π ( x i , w ) ∂ π ( x i , w ) ∂ w j ] = − 1 n ∑ i = 1 n [ y i x i j − 1 1 − π ( x i , w ) π ( x i , w ) ( 1 − π ( x i , w ) ) ∂ w T x i ∂ w j ] = − 1 n ∑ i = 1 n [ y i x i j − 1 1 − π ( x i , w ) π ( x i , w ) ( 1 − π ( x i , w ) ) x i j ] = − 1 n ∑ i = 1 n { [ y i − π ( x i , w ) ] x i j } = − 1 n ∑ i = 1 n [ ( y i − y ^ i ) x i j ] = 1 n ∑ i = 1 n [ ( y ^ i − y i ) x i j ] \begin{aligned} \frac{\partial J(w)}{\partial w_j} &= -\frac{1}{n} \sum\limits_{i=1}^{n} [y_i\frac{\partial w^Tx_i}{\partial w_j} - \frac{1}{1-\pi(x_i,w)} \frac{\partial \pi(x_i,w)}{\partial w_j}] \\ &= -\frac{1}{n} \sum\limits_{i=1}^{n} [y_ix^j_i - \frac{1}{1-\pi(x_i,w)} \pi(x_i, w)(1 - \pi(x_i,w))\frac{\partial w^Tx_i}{\partial w_j}] \\ &= -\frac{1}{n} \sum\limits_{i=1}^{n} [y_ix^j_i - \frac{1}{1-\pi(x_i,w)} \pi(x_i, w)(1 - \pi(x_i,w))x_i^j] \\ &= -\frac{1}{n} \sum\limits_{i=1}^{n} \{[y_i - \pi(x_i, w)]x_i^j\} \\ &= -\frac{1}{n} \sum\limits_{i=1}^{n} [(y_i - \hat y_i)x_i^j] \\ &= \frac{1}{n} \sum\limits_{i=1}^{n} [(\hat y_i - y_i)x_i^j] \\ \end{aligned} wjJ(w)=n1i=1n[yiwjwTxi1π(xi,w)1wjπ(xi,w)]=n1i=1n[yixij1π(xi,w)1π(xi,w)(1π(xi,w))wjwTxi]=n1i=1n[yixij1π(xi,w)1π(xi,w)(1π(xi,w))xij]=n1i=1n{ [yiπ(xi,w)]xij}=n1i=1n[(yiy^i)xij]=n1i=1n[(y^iyi)xij]

    • 转换成矩阵运算( X X X n × m n\times m n×m的数值矩阵,有m个特征):

    ∂ J ( w ) ∂ w = [ 1 n ∑ i = 1 n x i j ( y ^ i − y i ) ] m × 1 = 1 n X T ( Y ^ − Y ) \begin{aligned} \frac{\partial J(w)}{\partial w} &= [\frac{1}{n} \sum\limits_{i=1}^{n} x_i^j(\hat y_i - y_i)]_{m\times1} \\ &=\frac{1}{n} X^T(\hat Y - Y) \end{aligned} wJ(w)=[n1i=1nxij(y^iyi)]m×1=n1XT(Y^Y)

  • ∂ J ( w ) ∂ w ≥ ϵ \frac{\partial J(w)}{\partial w} \ge \epsilon wJ(w)ϵ,则更新参数,再按上述计算方式更新梯度:
    w ( k + 1 ) : = w ( k ) − α ⋅ ∂ J ( w ) ∂ w w^{(k+1)} := w^{(k)} - \alpha \cdot \frac{\partial J(w)}{\partial w} w(k+1):=w(k)αwJ(w)

  • ∂ L ( w ) ∂ w < ϵ \frac{\partial L(w)}{\partial w} < \epsilon wL(w)<ϵ 或超过最大迭代次数时,返回最新更新的参数 w ( k ) w^{(k)} w(k)

4. Logisitic回归的实现

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split


# 定义sigmoid函数
def sigmoid(x_):
    return 1.0 / (1.0 + np.exp(-x_))


def grad(x_, y_, w_):
    y_hat = sigmoid(np.dot(x_, w_))
    return np.dot(x_.T, y_hat - y_) / len(y_)


def loss(w_, x_, y_):
    n = len(x_)
    h = sigmoid(np.dot(x_, w_))
    j = -np.dot(np.transpose(y_), np.dot(x_, w_)) + sum(np.log(1 - h)) / n
    return j


def sgd(x_, y_, w_, alpha_=0.01, loops_=100, err=0.001):
    num = 0
    g = grad(x_, y_, w_)
    while num < loops_:
        theta_ = w_ - alpha_ * g
        g = grad(x_, y_, theta_)
        if np.all(np.abs(g) < err):
            print('已找到最优参数!\n总共迭代的次数为{}'.format(num))
            print('最优参数为:{}'.format(np.round(w_, 3)))
            break
        w_ = theta_
        num += 1
    if num == loops_:
        print('以达到最大迭代次数!\n最终参数为:{}'.format(np.round(w_, 3)))
    return w_


if __name__ == '__main__':
    # 加载数据集
    data = load_iris()

    data.keys()

    # 选定变量
    x = data['data']  # 返回的是ndarray类型,150个样本、4个特征
    y = data['target']

    # 分割样本(注意:这里是为了二分类)
    x_train, x_test, y_train, y_test = train_test_split(x[:100], y[:100], 
    													test_size=0.2, random_state=2021)

    # 初始化参数
    w = np.zeros((len(x[0]), ))

    # 标准化
    x_train = (x_train - np.mean(x, axis=0)) / np.std(x_train, axis=0)

    # 设定参数
    alpha = 0.01
    loops = 100000
    epsilon = 0.0001

    # 梯度下降求解
    best_w = sgd(x_train, y_train, w, alpha, loops, epsilon)

    # 预测
    y_pred = np.zeros(len(x_test))
    y_pred[sigmoid(np.dot(x_test, best_w)) > 0.5] = 1

    # 精度
    print(sum(y_pred == y_test) / len(y_pred))

四、参考资料

  1. https://github.com/datawhalechina/ensemble-learning
  2. https://www.bilibili.com/video/BV1Mb4y1o7ck?t=470