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

使用R拟合广义有序概率模型时遇LINPACK矩阵过大报错求助

解决R中拟合广义有序模型时的内存/矩阵过大问题

问题背景

我正在处理一个约500万条观测值的大型数据集,需要在R中拟合广义有序概率(probit)或对数(logit)模型,当前运行的代码如下:

library(dplyr)
library(ordinal)

# Set working directory and load data
setwd("...Hostels/R")
data <- read.csv(".../data_full.csv")

options(qr.LAPACK = TRUE)

# Convert character columns to factors
data$guest_country_name <- as.factor(data$guest_country_name)
data$unique_booking_id <- as.factor(data$unique_booking_id)

# Compute the number of reviews by guest_country_code
data <- data %>%
  group_by(guest_country_code) %>%
  mutate(nreviews = n()) %>%
  ungroup()

# Compute the number of different nationalities staying in a room
data <- data %>%
  group_by(unique_booking_id, guest_country_name) %>%
  mutate(unique_tag = row_number() == 1) %>%
  ungroup() %>%
  group_by(unique_booking_id) %>%
  mutate(num_nationalities = sum(unique_tag)) %>%
  ungroup()

# Apply combined filter condition
min_nreviews = 50
min_nationalities = 70
data <- data %>% filter(nreviews >= min_nreviews & num_nationalities >= min_nationalities)

# Define the countries and reference country
countries_all <- c("Algeria", "Argentina", "Australia", ..., "Ukraine", "United_Arab_Emirates", "United_Kingdom")

# Create dummy variables for each country
for (c in countries_all) {
  data[[c]] <- as.numeric(data$guest_country_name == c)
}

# Convert unique_booking_id to a factor
data$unique_booking_id <- as.factor(data$unique_booking_id)

# Ensure that the 'score' variable is an ordered factor
data$score <- as.ordered(data$score)

# Construct the formula for the model
formula <- as.formula(paste("score ~", paste(c(countries_all, "unique_booking_id"), collapse = " + ")))

# Fit the cumulative link model with nominal effects for countries
model <- clm(formula, nominal = as.formula(paste("~", paste(countries_all, collapse = " + "))), data = data)

# Print the model summary
summary(model)

运行代码时出现如下错误:

Error in qr.default(X, tol = tol, LAPACK = FALSE): 
  too large a matrix for LINPACK.

我的计算机配备了128GB内存,因此对出现该内存限制问题感到意外。请问是否有办法在保留模型结构的前提下绕过或解决此错误?

补充信息

  • score变量为有序因子(ordered factor);
  • 数据集包含大量国家虚拟变量;
  • 错误提示表明设计矩阵可能过大无法处理。

恳请提供优化模型拟合流程、使用替代方法或包等方面的建议!


解决方案

1. 强制使用LAPACK处理QR分解

你已经设置了options(qr.LAPACK = TRUE),但clm内部可能强制调用了LINPACK。可以通过clm.control()明确指定用LAPACK,它处理大矩阵的能力远优于LINPACK:

model <- clm(formula, nominal = as.formula(paste("~", paste(countries_all, collapse = " + "))), 
             data = data, control = clm.control(qr = "LAPACK"))

2. 取消手动创建虚拟变量,直接用因子变量

手动循环生成国家哑变量会大幅增加数据列数,浪费内存。clm可以直接处理因子变量,自动完成编码,无需手动生成哑变量:

# 删除手动创建虚拟变量的循环代码
# 直接用guest_country_name因子构建公式
formula <- as.formula("score ~ guest_country_name + unique_booking_id")
# 名义效应部分同样直接使用因子
model <- clm(formula, nominal = ~ guest_country_name, 
             data = data, control = clm.control(qr = "LAPACK"))

这种方式会大幅缩减设计矩阵的大小,因为因子编码是紧凑存储的,而非每个国家对应一列。

3. 换用更高效的建模包

如果ordinal包的clm仍无法处理,可尝试以下替代方案:

使用rms包的lrm函数(针对有序回归优化)

library(rms)
# 构建数据环境
dd <- datadist(data)
options(datadist = "dd")
# 拟合有序logit模型
model <- lrm(score ~ guest_country_name + unique_booking_id, data = data)
summary(model)

使用brms包(贝叶斯框架,支持稀疏矩阵)

library(brms)
# 启用稀疏矩阵优化,大幅节省内存
model <- brm(
  formula = score ~ guest_country_name + unique_booking_id,
  family = cumulative("logit"),
  data = data,
  sparse = TRUE,
  chains = 2,  # 根据内存调整链数
  cores = 4    # 利用多核加速
)
summary(model)

4. 预处理阶段优化内存

  • 用data.table的fread代替read.csv读取数据,效率更高、内存占用更少:
library(data.table)
data <- fread(".../data_full.csv")
  • 过滤后删除不再需要的中间变量:
data <- data %>% select(-c(nreviews, unique_tag, num_nationalities))
  • 若unique_booking_id为数字型,转为整数因子减少内存占用:
data$unique_booking_id <- as.factor(as.integer(data$unique_booking_id))

5. 提前检查设计矩阵大小

可以先计算设计矩阵的内存占用,确认是否真的超出承载:

model_matrix <- model.matrix(formula, data = data)
print(object.size(model_matrix), units = "GB")

如果矩阵确实过大,可考虑进一步合并样本量极小的分组(不过你已过滤nreviews >=50,这一步可能无需操作)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:24:58