You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab中一维二次判别分析边界绘图故障排查

一维二次判别分析(QDA)二次决策边界绘制问题解决思路

核心问题定位

你遇到的问题本质是一维QDA的决策边界推导与参数传递逻辑和二维/3D场景完全不同,之前3D场景的参数传递逻辑不适用于一维,而你观察到的Qxx(1,2) = -1*Qxx(2,1)是误用二维矩阵参数的直接表现——一维QDA根本不存在交叉项,这个反对称矩阵本身就是错误的。

一维QDA决策边界的本质

一维两类QDA的决策边界是解二次方程:$a x^2 + b x + c = 0$,推导自两类判别函数的相等条件:

  • 类$i$的判别函数:$g_i(x) = -\frac{1}{2}\ln(\sigma_i^2) - \frac{(x-\mu_i)2}{2\sigma_i2} + \ln(P_i)$
  • 令$g_1(x) = g_2(x)$,整理后得到二次方程系数:
    $$
    \begin{align*}
    a &= \frac{1}{2\sigma_2^2} - \frac{1}{2\sigma_1^2} \
    b &= \frac{\mu_1}{\sigma_1^2} - \frac{\mu_2}{\sigma_2^2} \
    c &= \left(-\frac{\mu_12}{2\sigma_12} + \frac{\mu_22}{2\sigma_22}\right) - \ln\left(\frac{\sigma_2}{\sigma_1}\right) + \ln\left(\frac{P_2}{P_1}\right)
    \end{align*}
    $$
    其中$\mu_i$是类$i$的均值,$\sigma_i^2$是类$i$的方差,$P_i$是类$i$的先验概率。

代码修复关键点

  1. 丢弃二维矩阵参数:不要再传递Qxx这类二维矩阵给隐函数,一维场景只需要上述的$a, b, c$三个标量参数
  2. 重新定义隐函数:针对一维场景,隐函数应接收$a, b, c$,返回$ax^2 + bx + c$,而不是复用二维的矩阵计算逻辑
  3. 边界绘制逻辑:一维的二次决策边界是二次方程的根(最多两个点),可以用np.roots([a,b,c])求解后,用竖线(axvline)绘制;如果要展示判别函数的趋势,可以绘制整个二次曲线

可运行代码示例

import numpy as np
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
from sklearn.datasets import make_blobs

# 生成一维两类数据(两类方差不同,才会出现二次边界)
X, y = make_blobs(n_samples=200, centers=2, n_features=1, cluster_std=[1, 3], random_state=42)

# 拟合QDA模型
qda = QuadraticDiscriminantAnalysis()
qda.fit(X, y)

# 提取QDA核心参数
mu1, mu2 = qda.means_[0][0], qda.means_[1][0]
var1, var2 = qda.covariance_[0][0][0], qda.covariance_[1][0][0]
p1, p2 = qda.priors_[0], qda.priors_[1]

# 计算二次方程系数
a = 1/(2*var2) - 1/(2*var1)
b = mu1/var1 - mu2/var2
c = (-mu1**2/(2*var1) + mu2**2/(2*var2)) - np.log(np.sqrt(var2/var1)) + np.log(p2/p1)

# 求解决策边界的根
x_roots = np.roots([a, b, c])

# 可视化
plt.scatter(X[y==0], np.zeros_like(X[y==0]), label='Class 0', alpha=0.6)
plt.scatter(X[y==1], np.zeros_like(X[y==1]), label='Class 1', alpha=0.6)

# 绘制判别函数差值曲线(展示二次趋势)
x_range = np.linspace(X.min()-2, X.max()+2, 100)
g_diff = a * x_range**2 + b * x_range + c
plt.plot(x_range, g_diff, color='gray', linestyle='--', label='QDA Discriminant Difference')

# 绘制决策边界
for root in x_roots:
    plt.axvline(x=root, color='red', linewidth=2, label='Decision Boundary')

plt.legend()
plt.xlabel('Feature X')
plt.yticks([])
plt.show()

关键注意事项

  • 如果你的数据两类方差相同,QDA会退化为LDA,此时二次项系数$a=0$,边界变为线性,这是正常现象
  • 检查你之前的代码是否错误地将一维数据包装成二维,导致协方差矩阵被生成为2D,进而出现无意义的交叉项(即你看到的Qxx(1,2))

内容的提问来源于stack exchange,提问作者user2587726

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 12:58:19