R语言中如何可视化30维非线性SVM模型的输出与决策边界
非线性SVM二分类可视化实现方案
现有代码的核心问题
- 未开启特征标准化:SVM基于距离计算,特征量纲差异会直接导致模型偏倚,可视化结果失真
- 随机选取两个原始特征绘图:高维核空间的决策边界硬投影到无关特征平面,没有可解释性
- 仅对支持向量做PCA:未纳入全量样本、未映射决策边界和分类结果,无法关联原始标签信息
- 语法错误:混淆矩阵计算时嵌套了两层
table(),会导致输出异常
第一步:筛选对分类最重要的2个特征
不要随机选特征,通过置换重要性计算每个特征对模型分类精度的贡献,取贡献最高的2个特征绘图,既保证可视化效果,还能量化特征重要性:
library(e1071) # 修正后的模型训练代码,记得开启标准化 classifierS = svm( formula = PH ~ ., data = training_set, type = 'C-classification', kernel = 'sigmoid', gamma = 0.5, cost = 0.5, scale = TRUE ) y_predS = predict(classifierS, newdata= test_set) cmS = table(test_set$PH, y_predS) # 删掉多余的table嵌套 # 置换重要性计算函数 calc_feat_imp <- function(model, data, target = "PH", perm_round = 50) { base_acc <- sum(predict(model, data) == data[[target]]) / nrow(data) imp_res <- sapply(setdiff(colnames(data), target), function(feat) { perm_acc <- replicate(perm_round, { perm_data <- data perm_data[[feat]] <- sample(perm_data[[feat]]) sum(predict(model, perm_data) == perm_data[[target]])/nrow(perm_data) }) mean(base_acc - perm_acc) }) sort(imp_res, decreasing = TRUE) } feat_importance <- calc_feat_imp(classifierS, training_set) top2_features <- names(feat_importance)[1:2]
第二步:绘制带决策边界的分类图
手动生成二维平面网格,预测每个网格点的分类结果作为背景填色,再叠加样本点、支持向量标记,就能得到清晰的分类可视化效果:
# 生成绘图网格 x1_lim <- range(training_set[[top2_features[1]]]) x2_lim <- range(training_set[[top2_features[2]]]) plot_grid <- expand.grid( v1 = seq(x1_lim[1], x1_lim[2], length.out = 200), v2 = seq(x2_lim[1], x2_lim[2], length.out = 200) ) colnames(plot_grid) <- top2_features # 其余特征填充训练集均值,保证预测输入维度和训练一致 rest_feats <- setdiff(colnames(training_set), c("PH", top2_features)) for (f in rest_feats) { plot_grid[[f]] <- mean(training_set[[f]]) } plot_grid$pred_label <- predict(classifierS, plot_grid) # 绘制决策区域背景 plot( plot_grid[[top2_features[1]]], plot_grid[[top2_features[2]]], col = ifelse(plot_grid$pred_label == 1, rgb(1,0.7,0.7,0.3), rgb(0.7,0.7,1,0.3)), pch = 15, cex = 0.5, xlab = top2_features[1], ylab = top2_features[2] ) # 叠加测试集样本:三角形为PH阳性、圆形为PH阴性,绿色为预测正确、红色为预测错误 test_pred <- predict(classifierS, test_set) points( test_set[[top2_features[1]]], test_set[[top2_features[2]]], pch = ifelse(test_set$PH == 1, 17, 16), col = ifelse(test_pred == test_set$PH, "darkgreen", "red"), cex = 1.2 ) # 标记支持向量(黑色空心方框) sv_points <- training_set[classifierS$index, ] points( sv_points[[top2_features[1]]], sv_points[[top2_features[2]]], pch = 0, cex = 2, lwd = 2 ) # 添加图例 legend("topright", legend = c("无PH决策区域", "PH决策区域", "无PH样本(预测正确)", "PH样本(预测正确)", "预测错误样本", "支持向量"), pch = c(15,15,16,17,16,0), col = c(rgb(0.7,0.7,1), rgb(1,0.7,0.7), "darkgreen", "darkgreen", "red", "black"), bty = "n" )
可选:全量特征PCA降维可视化
如果希望保留全量特征的信息做投影,不要只对支持向量做PCA,需要先对全量训练集做标准化降维,再映射决策边界:
# 提取全量特征做标准化+PCA train_feat_scaled <- scale(training_set[, !colnames(training_set) %in% "PH"]) pca_model <- prcomp(train_feat_scaled) pca_train <- as.data.frame(pca_model$x[,1:2]) pca_train$PH <- training_set$PH # PCA空间训练同参数SVM用于绘制边界 pca_svm <- svm(PH~., data = pca_train, type = "C-classification", kernel = "sigmoid", gamma = 0.5, cost = 0.5) # 测试集投影到PCA空间 test_feat_scaled <- scale( test_set[, !colnames(test_set) %in% "PH"], center = attr(train_feat_scaled, "scaled:center"), scale = attr(train_feat_scaled, "scaled:scale") ) pca_test <- as.data.frame(predict(pca_model, test_feat_scaled)[,1:2]) pca_test$PH <- test_set$PH pca_test$pred <- predict(classifierS, test_set) # 后续绘图逻辑和上述Top2特征绘图一致,将坐标轴替换为PC1、PC2即可
注意事项
- 小样本医疗场景下,RBF核(
kernel = "radial")的分类效果和决策边界平滑度通常优于sigmoid核,可以作为优先调参选项 - 基于Top2重要特征的绘图可解释性最强,能直接对应临床特征的分类阈值;PCA投影图保留了全量特征方差,但坐标轴为线性组合的主成分,无法直接对应单个特征的临床意义
- 若训练集样本量过小,网格预测时其余特征填充均值的方式可能带来偏差,可改用训练集抽样填充的方式提升稳定性
内容的提问来源于stack exchange,提问作者Ellie Desmond
相关产品推荐
相关产品推荐

