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

使用dplyr反归一化标准化聚类中心遇错误,求解决方案

解决标准化聚类中心的反归一化问题

问题原因

你原代码的核心问题有两个:

  1. 直接使用unlist(sds)和unlist(means)会生成长度为4的向量,与每列3行的数值进行循环回收,无法实现按列对应的反标准化(即Sepal.Length列只能用sds和means中对应的Sepal.Length值)。
  2. 错误使用where(Sepal.Length:Petal.Width),where()需要接收判断函数(比如is.numeric),而非列名范围。

解决方案

方法一:使用cur_column()匹配对应列的均值和标准差(最简洁)

利用dplyr的cur_column()获取当前处理的列名,精准匹配means和sds中对应的数值:

library(dplyr)

centroids_original_scale <- centroids_standardized %>%
  mutate(across(-.cluster, ~ .x * sds[[cur_column()]] + means[[cur_column()]]))

方法二:长格式转换后计算(更直观,适合复杂场景)

将所有数据转换为长格式,合并后计算再转回宽格式,避免列名匹配错误:

library(dplyr)
library(tidyr)

# 将均值和标准差转为长格式
means_long <- means %>% pivot_longer(everything(), names_to = "variable", values_to = "mean")
sds_long <- sds %>% pivot_longer(everything(), names_to = "variable", values_to = "sd")

# 反标准化计算
centroids_original_scale <- centroids_standardized %>%
  pivot_longer(-.cluster, names_to = "variable", values_to = "standardized") %>%
  left_join(means_long, by = "variable") %>%
  left_join(sds_long, by = "variable") %>%
  mutate(original = standardized * sd + mean) %>%
  select(.cluster, variable, original) %>%
  pivot_wider(names_from = "variable", values_from = "original")

方法三:用purrr遍历列处理

适合习惯函数式编程的场景,明确对每一列单独计算:

library(dplyr)
library(purrr)

# 提取数值列名
num_cols <- setdiff(names(centroids_standardized), ".cluster")

centroids_original_scale <- centroids_standardized %>%
  bind_cols(
    map2_dfc(
      .x = select(., all_of(num_cols)),
      .y = map2(means[num_cols], sds[num_cols], ~ list(mean = .x, sd = .y)),
      ~ .x * .y$sd + .y$mean
    ) %>% set_names(num_cols)
  ) %>%
  select(.cluster, all_of(num_cols))

验证结果

以Cluster_1的Sepal.Length为例,手动计算:
-1.01 * 0.828 + 5.84 = 5.00372
运行上述代码后,centroids_original_scale中对应值与手动计算一致,说明反标准化正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:25:14