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

多维尺度分析(MDS)内存超限求助:smacof包INDSCAL实现问题

解决INDSCAL分析中的内存溢出问题

问题背景

我有一个包含9位听众对语音对相似度评分的数据框,计划使用R的smacof包进行个体差异尺度分析(INDSCAL),以可视化语音间的多重关系。原实现代码如下:

# 获取唯一语音标识
voices <- unique(c(results$voice1, results$voice2))

# 语音数量
n_voices <- length(voices)

# 创建存储个体相异矩阵的列表
dissimilarity_list <- list()

# 为每位听众构建对称相异矩阵
for (subject_id in unique(results$subject)) {
  # 筛选当前听众的评分数据
  subject_responses <- results %>% filter(subject == subject_id)
  
  # 初始化空矩阵
  dissimilarity_matrix <- matrix(NA, nrow = n_voices, ncol = n_voices,
                                 dimnames = list(voices, voices))
  
  # 填充矩阵
  for (i in 1:nrow(subject_responses)) {
    voice1 <- subject_responses$voice1[i]
    voice2 <- subject_responses$voice2[i]
    response <- subject_responses$response[i]
    dissimilarity_matrix[voice1, voice2] <- response
    dissimilarity_matrix[voice2, voice1] <- response  # 假设评分对称
  }
  
  # 将矩阵加入列表
  dissimilarity_list[[subject_id]] <- dissimilarity_matrix
}

# 将矩阵列表转换为3D数组
dissimilarity_array <- array(NA, dim = c(n_voices, n_voices, length(dissimilarity_list)))
for (i in 1:length(dissimilarity_list)) {
  dissimilarity_array[,,i] <- dissimilarity_list[[i]]
}

# 替换数组中的NA为0
dissimilarity_array[is.na(dissimilarity_array)] <- 0

# 执行INDSCAL分析
indscal_result <- smacofIndDiff(dissimilarity_array, ndim = 2)

触发的错误

运行代码时,在转换为3D数组的步骤出现内存溢出错误:

Error: vector memory limit of 16.0 Gb reached, see mem.maxVSize()

注:存储矩阵的列表仅约0.09GB,设备为全新MBair,此前处理过更大数据集,且SPSS可正常运行该分析,需在不平均评分掩盖方差的前提下解决问题。

解决方案

1. 直接传入列表格式的相异矩阵(最优方案)

smacofIndDiff函数支持直接传入列表格式的相异矩阵,无需手动转换为3D数组,这能避免数组初始化阶段的内存浪费。修改后的代码可跳过数组转换步骤,直接传入列表:

# 保留原矩阵构建逻辑,跳过数组转换
# ...(原代码中构建dissimilarity_list的部分不变)

# 先为每个矩阵填充NA为0
dissimilarity_list <- lapply(dissimilarity_list, function(mat) {
  mat[is.na(mat)] <- 0
  mat
})

# 直接用列表作为输入执行INDSCAL分析
indscal_result <- smacofIndDiff(dissimilarity_list, ndim = 2)

2. 优化矩阵构建逻辑,减少内存冗余

原代码用双重循环构建矩阵效率较低,可改用tidyr的pivot_wider函数直接从长格式数据转换为对称矩阵,避免循环中的内存开销:

library(tidyr)
library(dplyr)

dissimilarity_list <- lapply(unique(results$subject), function(subj) {
  results %>%
    filter(subject == subj) %>%
    select(voice1, voice2, response) %>%
    # 补充对称行,确保矩阵对称
    bind_rows(rename(., voice1 = voice2, voice2 = voice1)) %>%
    # 转换为宽格式矩阵
    pivot_wider(names_from = voice2, values_from = response, values_fill = 0) %>%
    column_to_rownames("voice1") %>%
    # 补全缺失的语音行列,确保矩阵维度统一
    rowwise() %>%
    mutate(across(all_of(voices), ~ ifelse(is.na(.), 0, .))) %>%
    ungroup() %>%
    as.matrix()
})

# 执行INDSCAL分析
indscal_result <- smacofIndDiff(dissimilarity_list, ndim = 2)

3. 临时调整R的内存限制(备选方案)

如果上述方法仍有内存问题,可临时调高R的内存上限(根据设备内存调整):

# 设置内存上限为32GB
options(mem.maxVSize = 32e9)

此方法仅为临时 workaround,优先推荐前两种方法从根源优化内存使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:40:25