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

使用sklearn在Python中绘制两类线性判别分析(LDA)结果失败的技术问询

嘿,这个问题我碰到过!核心原因是LDA在二分类和多分类时输出的维度逻辑不一样,我来给你拆解清楚并解决~

首先得明确LDA的核心逻辑:对于K类分类问题,LDA最多会生成K-1个线性判别式(LD)。所以当你做二分类(T类/非T类)时,只会得到1个LD维度,也就是X_lda_sklearn是一维数组(形状为(n_samples,)),而不是三分类时的二维数组((n_samples,2))。这就是你访问X[:,1]时会触发“索引越界”错误的根本原因。

下面给你两种解决方案,按需选择:


方案1:适配一维LDA结果的可视化(推荐,更贴合实际意义)

既然二分类只有1个LD维度,我们可以直接用这个维度作为x轴,把类别作为y轴区分数据,这样能直观展示LDA在唯一判别维度上的分类效果。修改后的代码如下:

import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

# 替换成你的实际数据处理逻辑
X = PODall.drop('标签列名', axis=1)  # 把'标签列名'改成你存储0/1标签的列名
y = PODall['标签列名']

# 训练LDA并转换数据
sklearn_lda = LinearDiscriminantAnalysis()
X_lda_sklearn = sklearn_lda.fit_transform(X, y)

def plot_scikit_lda_binary(X, y, title):
    ax = plt.subplot(111)
    # 针对二分类的标签(0=非T类,1=T类)设置样式
    for label, marker, color, label_name in zip(
        [0, 1], ('o', 's'), ('blue', 'red'), ['非T类', 'T类']):
        plt.scatter(
            x=X[y == label],
            y=[label]*len(X[y == label]),  # 用标签值作为y轴,将两类数据垂直分开
            marker=marker,
            color=color,
            alpha=0.5,
            label=label_name
        )
    
    plt.xlabel('LD1')
    plt.ylabel('类别')
    leg = plt.legend(loc='upper right', fancybox=True)
    leg.get_frame().set_alpha(0.5)
    plt.title(title)
    
    # 美化图表细节
    plt.tick_params(axis="both", which="both", bottom="on", top="off", 
                    left="on", right="off")
    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    plt.grid(axis='x')
    plt.tight_layout()
    plt.show()

# 调用绘图函数
plot_scikit_lda_binary(X_lda_sklearn, y, title='二分类LDA结果可视化 (scikit-learn)')

方案2:手动添加维度,模拟二维绘图(适合和三分类可视化风格统一)

如果你希望保持和三分类时完全一致的二维图布局,可以手动给一维的LDA结果添加一列全0的“伪LD2”,这样就能直接复用你原有代码的结构:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

# 同样替换成你的实际数据处理逻辑
X = PODall.drop('标签列名', axis=1)
y = PODall['标签列名']

sklearn_lda = LinearDiscriminantAnalysis()
X_lda_sklearn = sklearn_lda.fit_transform(X, y)

# 把一维数组转换成二维,添加全0的第二列作为伪LD2
X_lda_2d = np.column_stack((X_lda_sklearn, np.zeros_like(X_lda_sklearn)))

def plot_scikit_lda(X, y, title):
    ax = plt.subplot(111)
    for label, marker, color, label_name in zip(
        [0, 1], ('o', 's'), ('blue', 'red'), ['非T类', 'T类']):
        plt.scatter(
            x=X[:,0][y == label],
            y=X[:,1][y == label] * -1,  # 乘-1不影响,因为第二列全是0
            marker=marker,
            color=color,
            alpha=0.5,
            label=label_name
        )
    plt.xlabel('LD1')
    plt.ylabel('LD2')
    leg = plt.legend(loc='upper right', fancybox=True)
    leg.get_frame().set_alpha(0.5)
    plt.title(title)
    
    # 保留你原来的图表美化逻辑
    plt.tick_params(axis="both", which="both", bottom="on", top="off", labelbottom="on",
                    left="off", right="off", labelleft="on")
    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.spines["bottom"].set_visible(False)
    ax.spines["left"].set_visible(False)
    plt.grid()
    plt.tight_layout()
    plt.show()

# 调用绘图函数
plot_scikit_lda(X_lda_2d, y, title='二分类LDA结果可视化(模拟二维)')

注意:方案2中的LD2没有实际意义,只是为了适配原有代码结构,如果是做分析推荐用方案1哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 03:27:34