【机器学习】050--判别 or ⽣成:从逻辑回 归说起

Posted by ShawnD on September 26, 2020

线性回归与线性分类

线性回归:就是 $w^Tx+b$,得到的结果 $y=w^Tx+b$,它是一个属于 $(-\infty,\infty)$ 的实数 $R$,而线性分类问题(我们以二分类为例),则是进一步需要将 $w^Tx+b$ 进行映射,这里分为两类:

  • 第一类是硬分类,映射的结果是一个二值集合 ${0,1}$ 中的一个值,硬分类不是我们介绍的重点;
  • 第二类是软分类,映射的结果是 $[0,1]$ 区间上的一个值,软分类的“软”就体现在这,它不是硬生生的告诉你到底是类别 0 还是类别 1,而是得到一个概率值,表示取得分类的概率,哪个分类的概率大,我们就取哪一个。

软分类模型:判别与生成

我们接下来几节中要介绍线性分类模型:逻辑回归、高斯判别分析和朴素贝叶斯分类器,都属于软分类。

软分类又分为判别式模型和生成式模型,这两类又有什么不同呢?

逻辑回归属于判别式模型,直接对条件概率 $p(Y X)$ 进行建模、学习和求解;而后面两个模型:高斯判别分析和朴素贝叶斯则是生成式模型,它是对联合概率$p(X,Y)$ 进行建模。
那么,什么称之为对条件概率 $p(Y X)$ 建模,什么又叫作对联合概率 $p(X,Y)$ 建模?我们通过式子来看。

逻辑回归的基本建模

我们以二分类问题为例,在逻辑回归当中,我们关注的是给定一个样本 $x$,如何去求得 $p(y=1 x)$ 的概率?

这里我们利用的就是一个称之为 sigmoid 的激活函数 $\sigma(z)=\frac{1}{1+e^{-z}}$,其中 $z=w^Tx$。通过它完成了位于 $(-\infty,+\infty)$ 范围内的 $w^Tx$ 到一个位于 $[0,1]$ 之间概率值的转换。

我们看看 $\sigma(z)=\frac{1}{1+e^{-z}}$ 的函数图像就明白了。

代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
    import matplotlib.pyplot as plt
    import numpy as np
    import seaborn
    seaborn.set()
    
    def sigmoid(z):
        return 1/(1+np.e**(-z))
    
    z = np.linspace(-7.5, 7.5, 1000)
    plt.plot(z, sigmoid(z), color='r', label='sigmoid(z)')
    plt.ylim(-0.2, 1.2)
    plt.legend()
    plt.show()

运行结果:

图 1 sigmoid函数示意图

我们发现:函数的定义域是 $(-\infty,+\infty)$,也就是位于整个实数域上的 $z=w^Tx$ 被映射到了 $[0,1]$ 范围内,也就可以对 $p(y=1|x)$ 的概率值进行表示。

最终,我们来明确一下逻辑回归中的二分类条件概率表达式:

\[p_1=p(y=1|x)=\sigma(w^Tx)=\frac{1}{1+e^{-w^Tx}}=\varphi(x;w)\] \[p_0=p(y=0|x)=1-p(y=1|x)=\frac{e^{-w^Tx}}{1+e^{-w^Tx}}=1-\varphi(x;w)\]

那么,综合起来,把这两个分类的条件概率统一到一个表达式中,我们就可以写作是:

\[p(y|x)=p_1^{y}p_0^{1-y}\]

其实这个式子没有太多深刻特殊的含义,纯粹就是一种统一的数学表达,我们可以简单带入验证一下:

当 $y=1$ 时,$p(y=1 x)=p_1^1p_0^0=p_1$,而当 $y=0$ 时,$p(y=0 x)=p_1^0p_0^1=p_0$。

这也就是所谓的直接对条件概率建模。而逻辑回归当中的待估计参数,就是向量 $w$。

逻辑回归参数估计与代码试验

拿到了条件概率模型之后,当我们手上有了一组样本 $(X,Y)$,样本数量为 $N$。同样是通过极大似然估计的方法,去把参数 $w$ 给估计出来:

\[\begin{aligned} w_{mle} & =argmax_{w}=log~p(Y|X)\\ & =argmax_w~log\prod_{i=1}^{N}p(y_i|x_i)\\ & =argmax_w\sum_{i=1}^{N}log~p(y_i|x_i)\\ & =argmax_w\sum_{i=1}^N(y_ilogp_1+(1-y_i)logp_0)\\ & =argmax_w\sum_{i=1}^N(y_ilog\varphi(x;w)+(1-y_i)log(1-\varphi(x;w))) \end{aligned}\]

得到了这个最终的目标式子之后,在这里我们可以采用梯度下降法,就可以逐步逼近到我们所需要的 $w$ 估计值,这里我们就不继续展开了。

在 sklearn 中,处理逻辑回归的问题也是非常容易的,我们举一个实际的例子来看一下。

sklearn 的数据集中有一个乳腺癌的样本数据集,样本大小 569,每一个样本包含 30 维的特征,而最终的分类结果表示为 1(是乳腺癌)或者 0(不是乳腺癌)。

代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    from sklearn.datasets import load_breast_cancer
    from sklearn.model_selection import train_test_split
    from sklearn.linear_model import LogisticRegression
    
    cancer = load_breast_cancer()
    X = cancer.data
    y = cancer.target
    print(X.shape)
    print(y.shape)
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=33)
    
    model = LogisticRegression()
    model.fit(X_train, y_train)
    
    print(model.coef_)
    print(model.score(X_test, y_test))

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
    (569, 30)
    (569,)
    
    [[ 2.30207141e+00  1.00795794e-01 -1.44196343e-01  1.96927419e-03
      -1.40603606e-01 -4.46827777e-01 -6.74062968e-01 -3.18178491e-01
      -1.93828047e-01 -3.26951226e-02 -1.93941475e-02  1.12220752e+00
       4.35401705e-01 -7.51584848e-02 -2.33847494e-02 -7.08485728e-02
      -1.24172626e-01 -4.55451605e-02 -7.40278164e-02 -6.08239626e-03
       1.54572437e+00 -3.09298213e-01 -1.41401755e-01 -2.83776618e-02
      -2.52314145e-01 -1.11551295e+00 -1.43317636e+00 -5.85379297e-01
      -6.14937820e-01 -1.10622292e-01]]
    0.9473684210526315

我们同样地,80% 的样本作为训练数据,而剩下的 20% 的数据作为测试数据,经过训练,我们得到了一个 $w$ 的估计值,它正是 30 维的参数向量,而最终我们也获得了这个训练模型的评分。