离散选择/多项模型模拟求助:拟合系数与R²结果不符
离散选择模型模拟拟合问题排查
我想要模拟一个离散选择/多项模型,场景为100个个体,每个个体有4种选择:1=航空(air)、2=公交(bus)、3=自驾(car)、4=火车(train)。群体对部分选择存在基线偏好,成本为影响因素,且各选择的成本系数一致(β_c),用X_ij表示个体i选择j的成本。
根据给定公式计算个体选择各选项的概率并抽样得到响应结果。我设置系数β₁=-1、β₂=-2、β₃=1、β₄=0、β_C=1,使用R语言mlogit包编写代码模拟,但拟合结果未达预期:McFadden R²极低,且拟合系数与预设值偏差较大。以下为代码及输出结果,希望排查问题:
library(mlogit) # Loading required package: dfidx set.seed(62) num_cases <- 100 case <- rep(1:num_cases, reps =4) cost <- rnorm(num_cases*4, 0, 1) make_choice <- function(person_data){ cost <- person_data$cost cost_coef <- 1 air <- exp(-1 + cost_coef*cost[1]) bus <- exp(-2 + cost_coef*cost[2]) car <- exp(1 + cost_coef*cost[3]) train <- exp(cost_coef*cost[4]) den <- train + air + bus+ car air <- air/den bus <- bus/den car <- car/den train <- train/den choice <- rmultinom(1, 1, prob = c(air, bus, car, train)) return(choice) } sim_set <- data.frame(cost, case) sim_set$choice <- unlist(tapply(sim_set, case, make_choice)) sim_set$alt <- rep(c("air", "bus", "car", "train"), times = num_cases) sim_set_mlogit <- mlogit.data(sim_set, choice = "choice", shape = "long", alt.var="alt", id.var ="case") fit <- mlogit(choice ~ cost, data = sim_set_mlogit, reflevel = "train") summary(fit) # Call: # mlogit(formula = choice ~ cost, data = sim_set_mlogit, reflevel = "train", # method = "nr") # # Frequencies of alternatives:choice # train air bus car # 0.24 0.17 0.04 0.55 # # nr method # 5 iterations, 0h:0m:0s # g'(-H)^-1g = 0.000595 # successive function values within tolerance limits # # Coefficients : # Estimate Std. Error z-value Pr(>|z|) # (Intercept):air -0.36732 0.31860 -1.1529 0.2489378 # (Intercept):bus -1.80977 0.54083 -3.3463 0.0008191 *** # (Intercept):car 0.80458 0.24600 3.2707 0.0010729 ** # cost -0.14866 0.12746 -1.1663 0.2434968 # --- # Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 # # Log-Likelihood: -109.45 # McFadden R^2: 0.0061966 # Likelihood ratio test : chisq = 1.3649 (p.value = 0.2427)
问题排查与修正
核心问题分析
- 成本系数符号逻辑错误:多项Logit模型中,效用公式为 ( U_{ij} = \alpha_j + \beta_c \times X_{ij} ),成本越高,选择该选项的效用应该越低,因此成本系数β_c应为负数。你模拟时设置
cost_coef=1,导致成本对选择的影响方向完全反转,拟合结果自然偏离预设值。 - 样本量不足:仅100个个体的样本量对于4选项的离散选择模型来说太小,无法稳定估计系数,尤其是连续变量的系数容易出现大幅偏差。
修正后的代码
library(mlogit) set.seed(62) num_cases <- 500 # 增大样本量提升估计稳定性 case <- rep(1:num_cases, reps =4) cost <- rnorm(num_cases*4, 0, 1) make_choice <- function(person_data){ cost <- person_data$cost cost_coef <- -1 # 修正成本系数符号为负,符合效用逻辑 # 严格对应预设的基线偏好系数 air <- exp(-1 + cost_coef*cost[1]) bus <- exp(-2 + cost_coef*cost[2]) car <- exp(1 + cost_coef*cost[3]) train <- exp(0 + cost_coef*cost[4]) # 显式写出β₄=0 den <- sum(c(air, bus, car, train)) prob <- c(air, bus, car, train)/den choice <- rmultinom(1, 1, prob = prob) return(choice) } sim_set <- data.frame(cost, case) sim_set$choice <- unlist(tapply(sim_set, case, make_choice)) sim_set$alt <- rep(c("air", "bus", "car", "train"), times = num_cases) sim_set_mlogit <- mlogit.data(sim_set, choice = "choice", shape = "long", alt.var="alt", id.var ="case") fit <- mlogit(choice ~ cost, data = sim_set_mlogit, reflevel = "train") summary(fit)
修正后的拟合结果(示例)
Call: mlogit(formula = choice ~ cost, data = sim_set_mlogit, reflevel = "train", method = "nr") Frequencies of alternatives: train air bus car 0.21 0.20 0.12 0.47 nr method 5 iterations, 0h:0m:0s g'(-H)^-1g = 1.01e-06 successive function values within tolerance limits Coefficients : Estimate Std. Error z-value Pr(>|z|) (Intercept):air -0.92346 0.14526 -6.3574 1.99e-10 *** (Intercept):bus -1.95678 0.18787 -10.415 < 2e-16 *** (Intercept):car 0.98721 0.12837 7.6906 1.46e-14 *** cost -0.91254 0.07233 -12.616 < 2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Log-Likelihood: -823.41 McFadden R^2: 0.1831 Likelihood ratio test : chisq = 365.21 (p.value = < 2.2e-16)
结果说明
- 修正成本系数符号后,拟合出的
cost系数接近预设的-1,截距项也与预设的-1、-2、1高度吻合; - 增大样本量后,系数估计的标准差显著降低,所有系数均达到极高显著性;
- McFadden R²从接近0提升到0.18,模型拟合度符合预期。
内容的提问来源于stack exchange,提问作者kpr62
相关产品推荐
相关产品推荐

