高斯判别基本原理#
虽然逻辑回归在机器学习任务中的效果非常好,但在样本呈现特殊分布的情况下,我们可以使用其他更好的算法。高斯判别分析(Gaussian Discriminant Analysis,简称 GDA)就是其中的一个。这篇博客的主要内容,就是介绍高斯判别分析算法的主要原理以及公式的推导。

基本先验假设#
与逻辑回归不同,高斯判别分析需要两个先验假设,分别为:
-
类别标签 y 服从伯努利分布
P(y)=⎩⎨⎧ϕy(1−ϕ)1−y0y=0,1y=0,1
-
正负样本均符合正态分布
P(x∣y=0)=(2π)2n∣Σ∣211exp(−21(x−μ0)TΣ−1(x−μ0))
P(x∣y=1)=(2π)2n∣Σ∣211exp(−21(x−μ1)TΣ−1(x−μ1))
正因为在模型中我们需要预先假设样本服从正态分布,这也是 “高斯判别分析” 名字的由来。
有了以上的假设之后,我们就能进行下一步的推导。
对数似然函数#
在前面的先验假设中,我们需要用到 ϕ 、Σ 、μ0 和 μ1 等参数,所以我们先要给出这些参数的参数估计。
首先我们要求出对数似然函数。对于整个数据集,似然函数是:
i=1∏mP(x(i),y(i)∣ϕ,Σ,μ0,μ1)=i=1∏mP(x(i)∣y(i))P(y(i))取对数后,得到的对数似然函数:
L(ϕ,Σ,μ0,μ1)=i=1∑m[logP(x(i)∣y(i))+logP(y(i))]分解条件概率#
为了便于处理不同类别的数据,我们将条件概率项 logP(x(i)∣y(i)) 根据 y(i) 的值进行分解。由于 y(i) 是二值的,我们可以使用 y(i) 作为指示函数:
- 当 y(i)=1 时,logP(x(i)∣y(i))=logP(x(i)∣y(i)=1)
- 当 y(i)=0 时,logP(x(i)∣y(i))=logP(x(i)∣y(i)=0)
因此,求和项可以重写为:
i=1∑mlogP(x(i)∣y(i))=i=1∑m[y(i)logP(x(i)∣y=1)+(1−y(i))logP(x(i)∣y=0)]带入对数似然函数可得:
L(ϕ,Σ,μ0,μ1)=i=1∑m[y(i)logP(x(i)∣y=1)+(1−y(i))logP(x(i)∣y=0)]+i=1∑mlogP(y(i))
高斯判别代码讲解#
不同于前面两个模型,高斯判别模型是 闭式解 的分类器,无需梯度下降之类的梯度迭代。因此高斯判别分析的代码非常简单,下面是完整代码:
from sklearn.datasets import make_classification
X, y = make_classification(
self.mu0 = np.mean(X[y == 0], axis=0)
self.mu1 = np.mean(X[y == 1], axis=0)
diff0 = X[y == 0] - self.mu0
diff1 = X[y == 1] - self.mu1
self.sigma = (diff0.T @ diff0 + diff1.T @ diff1) / m
def predict_proba(self, X):
inv_sigma = np.linalg.inv(self.sigma)
w = inv_sigma @ (self.mu1 - self.mu0)
np.log(self.phi / (1 - self.phi))
+ 0.5 * self.mu0.T @ inv_sigma @ self.mu0
- 0.5 * self.mu1.T @ inv_sigma @ self.mu1
return 1 / (1 + np.exp(-(X @ w + b)))
return (self.predict_proba(X) >= 0.5).astype(int)
if __name__ == "__main__":
y_pred = model.predict(X)
print("准确率:", np.mean(y_pred == y))
1. 先验参数求解#
接上面所说,我们要想满足先验,首先就要求解出四个关键参数。根据极大似然估计的原理,我们要想使得模型最优,就要让似然函数取到最大值,这等价于让对数似然函数取到最大值。因此我们可以对四个关键参数求偏导来得到四个参数的具体值:
self.mu0 = np.mean(X[y == 0], axis=0)
self.mu1 = np.mean(X[y == 1], axis=0)
diff0 = X[y == 0] - self.mu0
diff1 = X[y == 1] - self.mu1
self.sigma = (diff0.T @ diff0 + diff1.T @ diff1) / m
根据最大似然估计(MLE)的原理,我们对每个参数求偏导,并令其等于零即可解出参数的估计值。
-
参数 ϕ 的估计
参数 ϕ=P(y=1) 是类别标签 y 的伯努利分布的参数。由于 ϕ 只存在于 i=1∑mlogP(y(i)) 一项中,我们可以单独对这一项求导:
∂ϕ∂L(ϕ,Σ,μ0,μ1)=∂ϕ∂∑i=1mlogP(y(i))=∂ϕ∂∑i=1mlogϕy(i)(1−ϕ)1−y(i)=∂ϕ∂∑i=1my(i)logϕ+(1−y(i))log(1−ϕ)=i=1∑my(i)ϕ1−(1−y(i))1−ϕ1
令导数等于零,解得:
ϕ=m1i=1∑my(i)+(1−y(i))y(i)=m1i=1∑my(i)
这正是 正样本在总样本中的比例 ,符合我们对先验概率 ϕ 的直观理解。
-
均值向量 μk 的估计
我们假设 μ0 和 μ1 分别是 y=0 和 y=1 时的条件均值向量。
以 μ1 为例,它只出现在条件概率 P(x∣y=1) 项中,因此有:
∂μ1∂L(ϕ,Σ,μ0,μ1)=∂μ1∂∑i=1my(i)logP(x(i)∣y(i)=1)=∂μ1∂∑i=1my(i)log(2π)2n∣Σ∣211exp(−21(x−μ1)TΣ−1(x−μ1))=i=1∑my(i)Σ−1(x(i)−μ1)
令导数为零解得:
μ1=∑i=1my(i)∑i=1my(i)x(i)
同理可得:
μ0=∑i=1m(1−y(i))∑i=1m(1−y(i))x(i)
这两个结果分别表示 正样本和负样本的样本均值 。
-
协方差矩阵 Σ 的估计
相对于上面三个参数,求解 Σ 则更要复杂一些:
∂Σ∂L(ϕ,Σ,μ0,μ1)=∂Σ∂∑i=1my(i)logP(x(i)∣y(i)=1)+∑i=1m(1−y(i))logP(x(i)∣y(i)=0)=∂Σ∂∑i=1mlog(2π)2n∣Σ∣211−21∑i=1m(x(i)−μy(i))TΣ−1(x(i)−μy(i))=∂Σ∂−2m(nlog2π+log∣Σ∣)−21∑i=1m(x(i)−μy(i))TΣ−1(x(i)−μy(i))=−2mΣ−1−21i=1∑m(x(i)−μy(i))(x(i)−μy(i))T(Σ−1)2
令等式为零并右乘 Σ2 解得:
Σ=m1i=1∑m(x(i)−μy(i))(x(i)−μy(i))T
其中 μy(i) 表示 x(i) 所属类别的均值(即 μ0 或 μ1 )。
这个结果正是 基于类别均值的总体协方差矩阵的无偏估计 。
由此我们就得到了所有参数的似然估计结果。
2. 模型参数求解#
下面我们就来证明一下为什么 GDA 是 线性 判别模型,以及具体的模型参数该如何求解。
def predict_proba(self, X):
inv_sigma = np.linalg.inv(self.sigma)
w = inv_sigma @ (self.mu1 - self.mu0)
np.log(self.phi / (1 - self.phi))
+ 0.5 * self.mu0.T @ inv_sigma @ self.mu0
- 0.5 * self.mu1.T @ inv_sigma @ self.mu1
return 1 / (1 + np.exp(-(X @ w + b)))
GDA 的核心是计算后验概率,它可以通过贝叶斯定理得到:
P(y=1∣x)=P(x∣y=0)P(y=0)+P(x∣y=1)P(y=1)P(x∣y=1)P(y=1)为了方便分类,我们用对数几率作为判别函数来求解:
δ(x)=logP(y=0∣x)P(y=1∣x)=logP(x∣y=0)P(y=0)P(x∣y=1)P(y=1)=logP(y=0)P(y=1)+logP(x∣y=0)P(x∣y=1)线性模型推导#
仔细观察上面的先验条件,我们假设了正例跟负例的协方差矩阵相同,因此条件概率密度公式可以写成:
P(x∣y=k)=(2π)2n∣Σ∣211exp(−21(x−μk)TΣ−1(x−μk))代入 δ(x) 的尾项后,展开平方化简可得:
logP(x∣y=0)P(x∣y=1)=−21(x−μ1)TΣ−1(x−μ1)+21(x−μ0)TΣ−1(x−μ0)δ(x)=(Σ−1(μ1−μ0))Tx+(log1−ϕϕ−21(μ1TΣ−1μ1−μ0TΣ−1μ0))对比线性判别函数的形式自然可以得到:
w=Σ−1(μ1−μ0)b=log1−ϕϕ−21(μ1TΣ−1μ1−μ0TΣ−1μ0)根据这两个公式我们可以轻松求解高斯判别模型参数。
深层问题探究#
-
高斯判别分析要求正例和负例满足一定的条件,其中一个便是协方差要求相同,这是为什么?
标准的 GDA(也是最常见的一种形式)假设:
Σ0=Σ1=Σ
这意味着:
不同类别的样本具有 相同 的协方差矩阵,只是均值不同。
这个假设非常重要,因为它会带来下面的结果:
-
线性判别分析(Linear Discriminant Analysis,简称 LDA):当我们假设 Σ0=Σ1=Σ 时,对数几率 δ(x) 中的二次项(如 xTΣ−1x )会被抵消,判别边界 wTx+b=0 是一条直线(或超平面)。此时 GDA 的决策边界与逻辑回归(Logistic Regression)类似,因此在决策边界层面 GDA 与 LDA 高度相关。
-
二次判别分析(Quadratic Discriminant Analysis,简称 QDA):如果我们 不强制 协方差相等,即假设 Σ0=Σ1 ,那么对数几率 δ(x) 中涉及 x 的二次项将 不会被抵消 。此时 δ(x) 会出现 xTAx 形式的二次项,导致决策边界是一条 二次曲线/曲面 。这种模型被称为二次判别分析。
-
高斯判别分析与逻辑回归的区别是什么?
由上面证明 “为什么 GDA 是线性判别模型” 的结果我们可以知道,高斯判别模型的对数几率函数只不过是一个复杂的线性函数罢了,因此高斯判别模型本质上就是逻辑回归。无需迭代但需要一定的先验 便是高斯判别模型跟逻辑回归的区别,局限(需要先验)但高效(无需迭代)。