使用R语言Plotly绘制带LDA判别边界的3D图时的问题
LDA判别平面绘制不匹配问题的解决
问题核心
用R的MASS包做线性判别分析(LDA)后,使用Plotly绘制3D数据和判别平面,发现平面无法穿过数据,数据“漂浮”在平面上方。手动使用lda系数和参考方法生成的常数项仍无法解决问题。
关键错误点
- 硬编码系数易出错:手动输入
SB.lda等系数,容易和模型实际输出的scaling值产生偏差,应该直接从model$scaling提取。 - 常数项计算逻辑偏差:判别平面的本质是两组数据在判别空间中的分割面,正确的常数项需要基于两组均值的判别函数值的中点计算,而非仅用先验加权均值推导。
修正后的代码
library(plotly) library(MASS) # 加载数据 train <- data.frame(read.table("https://raw.githubusercontent.com/gunsnfloyd/algorithmdata/main/train.tsv", header = TRUE)) # 训练LDA模型 model <- lda(WS ~ SB + OPS + tSho, data = train) # 提取LDA系数(直接从模型获取,避免手动输入错误) lda_coef <- model$scaling[,1] # 二分类任务仅存在1个判别维度 SB.lda <- lda_coef["SB"] OPS.lda <- lda_coef["OPS"] tSho.lda <- lda_coef["tSho"] # 计算正确的常数项:两组均值的判别函数值的中点的相反数 group_discriminant <- model$means %*% lda_coef constant <- -mean(group_discriminant) # 生成判别平面的网格数据(基于数据实际范围,避免手动设定偏差) x.lda <- seq(min(train$SB), max(train$SB), length.out = 100) y.lda <- seq(min(train$OPS), max(train$OPS), length.out = 100) z.lda <- outer(x.lda, y.lda, function(x, y) { (-SB.lda * x - OPS.lda * y - constant) / tSho.lda }) # 绘制3D散点和判别平面 fig <- plot_ly(train, x = ~SB, y = ~OPS, z = ~tSho, color = ~WS, colors = c('#BF382A', '#0C4B8E')) %>% add_markers() %>% add_surface(x = x.lda, y = y.lda, z = z.lda, colors = "#0C4B8E", opacity = 0.5) %>% layout(scene = list( xaxis = list(title = 'SB'), yaxis = list(title = 'OPS'), zaxis = list(title = 'tSho') )) fig
原理说明
- LDA的判别平面满足方程:
x %*% lda_coef + constant = 0,其中constant取两组均值对应的判别函数值的平均值的相反数,确保平面能穿过两组数据的中心区域。 - 基于数据实际最值生成平面网格,避免手动设定范围导致平面与数据空间不匹配。
内容的提问来源于stack exchange,提问作者gunsnfloyd
相关产品推荐
相关产品推荐

