Sklearn LDA无法生成指定维度:二分类3特征数据集问题咨询
为什么我的LinearDiscriminantAnalysis只输出一维结果?
嘿,我来帮你拆解这个问题——你遇到的情况其实是LDA(线性判别分析)的固有特性,完全不是代码写错啦!
核心原因:二分类任务中LDA的上限就是1维
LDA的目标是找到能让类间差异最大、类内差异最小的投影方向。对于二分类问题来说,只需要一个最优的投影方向就足够把两类数据分开了。所以不管你把n_components参数设成2、3还是其他数值,它最终只会返回1维的结果。
而你之前测试的示例数据集,应该是多分类任务(比如3类及以上),这时候LDA最多可以输出min(类别数-1, 特征数)维的结果,所以当时能正常得到多维输出。
如果你想可视化3个特征的二分类数据集,试试这些方法
既然LDA在二分类场景下帮不上忙,推荐你用这几个方案:
1. 直接画3D散点图
最直观的方式,直接把三个特征作为坐标轴,用颜色区分类别:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import pandas as pd # 读取你的数据集 Data = pd.read_csv("DataFrame.csv", sep=";") x = Data[['特征1', '特征2', '特征3']].values # 替换成你实际的特征列名 y = Data['目标列'].values # 替换成你的分类标签列名 # 创建3D绘图窗口 fig = plt.figure(figsize=(10,7)) ax = fig.add_subplot(111, projection='3d') # 按类别绘制散点 for class_label in pd.unique(y): mask = y == class_label ax.scatter(x[mask, 0], x[mask, 1], x[mask, 2], label=f'类别 {class_label}', alpha=0.7) # 设置坐标轴标签和图例 ax.set_xlabel('特征1') ax.set_ylabel('特征2') ax.set_zlabel('特征3') ax.legend() plt.show()
2. 用PCA做线性降维
PCA不考虑类别信息,能保留数据的主要方差,适合快速看数据的整体分布:
from sklearn.decomposition import PCA import matplotlib.pyplot as plt import pandas as pd Data = pd.read_csv("DataFrame.csv", sep=";") x = Data[['特征1', '特征2', '特征3']].values y = Data['目标列'].values # 降维到2维 pca = PCA(n_components=2) x_pca = pca.fit_transform(x) # 绘制散点图 plt.figure(figsize=(8,6)) plt.scatter(x_pca[y==0, 0], x_pca[y==0, 1], label='类别0', alpha=0.7) plt.scatter(x_pca[y==1, 0], x_pca[y==1, 1], label='类别1', alpha=0.7) plt.xlabel('PCA主成分1') plt.ylabel('PCA主成分2') plt.legend() plt.show()
3. 用t-SNE做非线性降维
如果你的数据是非线性分布的,t-SNE能更好地保留局部结构,可视化效果更清晰:
from sklearn.manifold import TSNE import matplotlib.pyplot as plt import pandas as pd Data = pd.read_csv("DataFrame.csv", sep=";") x = Data[['特征1', '特征2', '特征3']].values y = Data['目标列'].values # 降维到2维 tsne = TSNE(n_components=2, random_state=42) x_tsne = tsne.fit_transform(x) # 绘制散点图 plt.figure(figsize=(8,6)) plt.scatter(x_tsne[y==0, 0], x_tsne[y==0, 1], label='类别0', alpha=0.7) plt.scatter(x_tsne[y==1, 0], x_tsne[y==1, 1], label='类别1', alpha=0.7) plt.xlabel('t-SNE维度1') plt.ylabel('t-SNE维度2') plt.legend() plt.show()
总结
不是你的代码有问题,而是LDA在二分类任务中的设计就是如此——它最多只能输出1维结果。选择上面的任意一种方法,都能帮你可视化3个特征的二分类数据集~
内容的提问来源于stack exchange,提问作者Daniel Slätt
相关产品推荐
相关产品推荐

