使用class包实现KNN时出现NA/NaN/Inf错误的排查求助
解决class包knn函数的NA相关错误与警告
核心排查方向
class包的knn函数有两个硬性要求:
- 训练集(
train)和测试集(test)的所有特征必须是数值型 - 数据集不能存在
NA/NaN/Inf值
结合你的报错和操作,以下是具体排查与解决步骤:
检查所有字段的类型与缺失值
- 运行
str(who_training)和str(who_validation),确认除了分类标签Status外,其他特征不能是字符型或未处理的因子(比如Country转成因子后仍无法被knn直接处理)。 - 用以下代码检查全量NA情况,确认有没有遗漏的缺失字段:
# 检查训练集各列的NA数量 sapply(who_training, function(x) sum(is.na(x))) # 检查测试集各列的NA数量 sapply(who_validation, function(x) sum(is.na(x))) - "NAs introduced by coercion"警告大概率是某列被强制转数值时失败,比如字符型列里混了非数字内容,可以用以下代码排查:
# 检查字符型列中的非数字内容 lapply(who_training, function(x) { if(is.character(x)) x[!grepl("^-?\\d+(\\.\\d+)?$", x)] else NULL })
- 运行
处理因子型特征
knn不支持直接输入因子类型特征,必须转换成数值型:- 对于无序因子(比如
Country):生成哑变量是最稳妥的方式,同时要保证训练集和测试集的因子水平完全一致,避免列数不匹配:# 统一训练/测试集的Country因子水平 common_levels <- unique(c(who_training$Country, who_validation$Country)) who_training$Country <- factor(who_training$Country, levels = common_levels) who_validation$Country <- factor(who_validation$Country, levels = common_levels) # 生成Country的哑变量并替换原列 train_dummies <- model.matrix(~ Country - 1, data = who_training) who_training <- cbind(who_training[, !names(who_training) == "Country"], train_dummies) test_dummies <- model.matrix(~ Country - 1, data = who_validation) who_validation <- cbind(who_validation[, !names(who_validation) == "Country"], test_dummies) - 对于有序因子:可以直接用
as.integer(your_factor)转成数值,但同样要保证训练/测试集的水平一致。
- 对于无序因子(比如
排查数值型字段的异常值
运行以下代码检查是否存在Inf值(knn完全不允许这类值):# 检查训练集数值列的Inf情况 sapply(who_training[, sapply(who_training, is.numeric)], function(x) sum(is.infinite(x))) # 检查测试集数值列的Inf情况 sapply(who_validation[, sapply(who_validation, is.numeric)], function(x) sum(is.infinite(x)))
调整后的示例代码
完成上述处理后,再运行knn:
# 确保所有特征都是数值型 train_features <- who_training[, !names(who_training) == "Status"] train_features <- as.data.frame(sapply(train_features, as.numeric)) test_features <- who_validation test_features <- as.data.frame(sapply(test_features, as.numeric)) # 最终检查 any(is.na(train_features)) # 必须返回FALSE any(is.na(test_features)) # 必须返回FALSE KNN_build <- knn(train = train_features, test = test_features, cl = who_training$Status, k = 5)
内容的提问来源于stack exchange,提问作者kompprograms
相关产品推荐
相关产品推荐

