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$的先验概率。
代码修复关键点
- 丢弃二维矩阵参数:不要再传递
Qxx这类二维矩阵给隐函数,一维场景只需要上述的$a, b, c$三个标量参数 - 重新定义隐函数:针对一维场景,隐函数应接收$a, b, c$,返回$ax^2 + bx + c$,而不是复用二维的矩阵计算逻辑
- 边界绘制逻辑:一维的二次决策边界是二次方程的根(最多两个点),可以用
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
相关产品推荐
相关产品推荐

