R语言如何利用训练集极值对测试集正确执行min-max归一化
问题原因
你对sweep函数的margin参数理解有误:
- 该参数指定统计量(这里是训练集极值向量)对应的操作维度:
margin = 1代表按行操作,要求统计量长度和数据集行数一致,会将统计量的每个值对应应用到某一行的所有元素;margin = 2代表按列操作,要求统计量长度和数据集列数一致,会将统计量的每个值对应应用到某一列的所有元素。 - 你当前需要对每一列减去该列对应的训练集最小值,4个最小值刚好对应测试集的4个数值列,应该设置
margin = 2。你误设为margin = 1,R会触发向量循环机制,把最小值向量按行循环应用,导致运算逻辑完全错误,得到不符合预期的结果。
修正方案
方法1:修改sweep参数
直接把第二个参数改为2即可,后续归一化可以再除以训练集的极值差:
# 减训练集最小值 first_step <- sweep(iris_test[,1:4], 2, iris_train_mins, FUN = "-") # 除以训练集最大值与最小值的差,得到最终归一化结果 iris_test_norm <- sweep(first_step, 2, iris_train_maxs - iris_train_mins, FUN = "/")
方法2:用tidyverse风格实现(和训练集处理逻辑统一)
如果习惯用dplyr的写法,可以直接调用训练集的极值做跨列运算,代码可读性更高:
iris_test_norm <- iris_test %>% select(-id) %>% mutate(across(where(is.numeric), .fns = function(x) (x - min(iris_train[[cur_column()]]))/(max(iris_train[[cur_column()]]) - min(iris_train[[cur_column()]]))))
内容的提问来源于stack exchange,提问作者Alexis
相关产品推荐
相关产品推荐

