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

kNN数据归一化时触发undefined columns selected错误求助

kNN归一化报错问题分析与解决

错误核心原因

你遇到的Error in [.data.frame(newdata, , object$method$center, drop = FALSE) : undefined columns selected错误,本质是归一化模型norm.values训练时用的列,和new.df的列不匹配,具体问题出在两处:

  1. 用硬编码的数字索引排除列(-c(1,8)),误把非响应变量当成要排除的对象,导致归一化模型包含了new.df没有的列,同时漏掉了new.df有的列。
  2. 划分数据集时,采样的是原数据集bank.df的行名,却用在处理后的bank.dummies.df上,存在潜在行名不匹配风险。

解决步骤

1. 用列名代替数字索引(彻底避免列顺序坑)

永远不要用固定数字索引选择列,改用列名定位,不管列顺序怎么变都不会出错:

# 明确指定要排除的列(ID + 响应变量,这里假设响应变量是Personal.Loan,可根据实际调整)
exclude_cols <- c("ID", "Personal.Loan")
# 提取需要归一化的列
train_norm_cols <- train.df[, !names(train.df) %in% exclude_cols]
# 创建归一化模型
norm.values <- preProcess(train_norm_cols, method=c("center", "scale"))

2. 确保new.df与训练列完全匹配

在执行预测前,先验证列的一致性:

# 检查训练归一化列和new.df的列差异
setdiff(names(train_norm_cols), names(new.df))  # 训练有但new.df缺失的列
setdiff(names(new.df), names(train_norm_cols))  # new.df有但训练没有的列

如果两个结果都为空,说明列完全匹配。如果有差异,要么给new.df补全缺失列,要么在预测时只传入匹配的列:

new.norm.df <- predict(norm.values, new.df[, names(train_norm_cols)])

3. 修正数据集划分的小错误

之前采样的是bank.df的行名,应该改用处理后的bank.dummies.df行名,避免行名不匹配:

set.seed(111)
train.index <- sample(row.names(bank.dummies.df), 0.6*dim(bank.dummies.df)[1])  
valid.index <- setdiff(row.names(bank.dummies.df), train.index)  
train.df <- bank.dummies.df[train.index, ]
valid.df <- bank.dummies.df[valid.index, ]

修正后的完整代码

bank.df <- UniversalBank
# 移除ZIP code变量
bank.df <- bank.df[,-5]

# 处理Education哑变量
bank.df$Education <- as.factor(bank.df$Education)
library(fastDummies)
bank.dummies.df <- dummy_cols(bank.df, select_columns = c("Education"), 
                          remove_first_dummy = FALSE, remove_selected_columns = TRUE)

# 划分训练集/验证集(修正行名采样对象)
set.seed(111)
train.index <- sample(row.names(bank.dummies.df), 0.6*dim(bank.dummies.df)[1])  
valid.index <- setdiff(row.names(bank.dummies.df), train.index)  
train.df <- bank.dummies.df[train.index, ]
valid.df <- bank.dummies.df[valid.index, ]

# 构造新客户数据
new.df <- data.frame(Age = 40, Experience = 10, Income = 84, Family = 2, CCAvg = 2, 
                     Mortgage = 0, Securities.Account = 0, CD.Account = 0, Online = 1, 
                     CreditCard = 1, Education_1 = 0, Education_2 = 1, Education_3 = 0)

# 初始化归一化数据集
train.norm.df <- train.df
valid.norm.df <- valid.df

# 用列名方式做归一化
library(caret)
exclude_cols <- c("ID", "Personal.Loan")
train_norm_cols <- train.df[, !names(train.df) %in% exclude_cols]

norm.values <- preProcess(train_norm_cols, method=c("center", "scale"))
train.norm.df[, !names(train.norm.df) %in% exclude_cols] <- predict(norm.values, train_norm_cols)
valid.norm.df[, !names(valid.norm.df) %in% exclude_cols] <- predict(norm.values, valid.df[, !names(valid.df) %in% exclude_cols])

# 执行新客户数据归一化(确保列匹配)
new.norm.df <- predict(norm.values, new.df[, names(train_norm_cols)])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:05:32