基于多项回归估计Dirichlet参数:纳入标准误的方法咨询
我尝试用R语言nnet包的multinom函数做多项回归,用预测概率估计Dirichlet分布的参数,同时想纳入模型的标准误。以下是我的实现过程:
数据准备
有两组分类数据,类别比例相同,但第二组样本量是第一组的10倍:
df1 <- data.frame(x=c(rep("A", 100), rep("B", 200), rep("C", 300))) df2 <- data.frame(x=c(rep("A", 1000), rep("B", 2000), rep("C", 3000)))
多项回归建模
仅用截距项做简单多项回归:
library(nnet) mn1 <- multinom(x~1, data = df1) mn2 <- multinom(x~1, data = df2) summary(mn1) summary(mn2)
计算预测概率
通过softmax函数从回归系数计算预测概率(虽然仅用截距时可直接算数据分布,但希望利用模型标准误):
softmax <- function(x) { exp(x) / sum(exp(x)) } pb1 <- softmax(c(0, coef(mn1)[,1])) pb2 <- softmax(c(0, coef(mn2)[,1])) pb1; pb2
Dirichlet分布模拟
用dirmult包的rdirichlet函数,以预测概率作为alpha参数模拟:
library(dirmult) set.seed(9999) dir1 <- as.data.frame(dirmult::rdirichlet(1000, alpha = c(pb1))) dir2 <- as.data.frame(dirmult::rdirichlet(1000, alpha = c(pb2))) colnames(dir1) <- c("A", "B", "C") colnames(dir2) <- c("A", "B", "C") dir1 <- melt(dir1) dir2 <- melt(dir2)
可视化结果
用ggplot2绘制密度图,发现两组Dirichlet分布基本一致:
library(ggplot2) ggplot(dir1, aes(value, color = variable)) + geom_density() ggplot(dir2, aes(value, color = variable)) + geom_density()
(配图:df1的Dirichlet分布密度图、df2的Dirichlet分布密度图)
核心疑问
当前方法未纳入多项回归的标准误。理论上样本量越大标准误越小,对应的Dirichlet分布alpha参数应该越大。请问:
- 如何将多项回归的标准误融入Dirichlet分布的alpha参数?
- 有没有更优的方法基于简单分类分布估计Dirichlet参数?
- 我的目标是通过模拟分类分布来估计高阶指标的置信区间,是否有其他可行方法?
一、将多项回归标准误融入Dirichlet参数的方法
Dirichlet分布的α参数可理解为伪计数,α_k = n * p_k(n为总伪计数,p_k为类别概率)。样本量越大,概率估计的不确定性越低,α的总和应越大(分布更集中在估计概率附近)。
1. 基于系数协方差矩阵的概率抽样法
从多项回归系数的多元正态分布中抽样,转换为概率后结合样本量构造α参数,以此纳入标准误的影响:
library(MASS) # 提取模型系数与协方差矩阵 coef_mn1 <- coef(mn1)[,1] vcov_mn1 <- vcov(mn1) # 从系数的多元正态分布中抽样 set.seed(123) n_samples <- 1000 coef_samples <- mvrnorm(n_samples, coef_mn1, vcov_mn1) # 转换为类别概率(加入基准类别0) prob_samples <- t(apply(coef_samples, 1, function(x) softmax(c(0, x)))) # 用样本量缩放概率得到α参数:样本量越大,α总和越大,分布越集中 alpha_samples1 <- prob_samples * nrow(df1) alpha_samples2 <- prob_samples * nrow(df2) # 基于每个抽样的α做Dirichlet模拟 dir_sim1 <- lapply(1:n_samples, function(i) dirmult::rdirichlet(1, alpha_samples1[i,])) dir_sim2 <- lapply(1:n_samples, function(i) dirmult::rdirichlet(1, alpha_samples2[i,]))
2. 贝叶斯共轭先验法(更简洁)
仅含截距的多项回归本质等价于多项分布的贝叶斯估计,Dirichlet是多项分布的共轭先验。此时后验Dirichlet参数为α = 观测计数 + 先验伪计数:
# 用观测计数+平滑项(避免0计数)作为α参数 alpha_df1 <- table(df1$x) + 1 alpha_df2 <- table(df2$x) + 1 # 模拟Dirichlet分布 set.seed(9999) dir1_bayes <- as.data.frame(dirmult::rdirichlet(1000, alpha = alpha_df1)) dir2_bayes <- as.data.frame(dirmult::rdirichlet(1000, alpha = alpha_df2))
这种方法天然体现了样本量的影响:样本量越大,α总和越大,分布越集中,完美匹配标准误随样本量减小的逻辑。
二、更优的Dirichlet参数估计方法
对于简单分类分布的参数估计,最优方法是贝叶斯共轭先验估计:
- 无信息先验:设置
先验伪计数 = (1,1,...,1)(Jeffreys先验,适用于无领域知识的场景) - 有信息先验:若已知类别概率的大致范围,可设置对应先验伪计数(比如已知A类占比约1/6,可设先验伪计数为(1,2,3))
此外,也可使用DirichletReg包拟合Dirichlet回归,但对于仅估计总体类别概率的场景,共轭先验法足够简洁高效。
三、估计高阶指标置信区间的替代方法
若目标是估计熵、Gini系数等高阶指标的置信区间,除Dirichlet模拟外,还有以下两种实用方法:
1. 非参数自助法
直接对原始样本有放回抽样,每次抽样后计算高阶指标,用抽样结果的分位数作为置信区间:
set.seed(123) n_boot <- 1000 boot_stats <- replicate(n_boot, { boot_sample <- sample(df1$x, replace = TRUE) # 示例:计算熵 p <- prop.table(table(boot_sample)) -sum(p * log(p)) }) # 输出95%置信区间 quantile(boot_stats, c(0.025, 0.975))
该方法无需依赖分布假设,完全基于原始数据,鲁棒性强。
2. 参数化自助法
基于多项回归的概率估计,从多项分布中抽样后计算高阶指标:
set.seed(123) param_boot_stats <- replicate(n_boot, { # 从估计的多项分布中抽样 sim_sample <- sample(c("A","B","C"), size = nrow(df1), replace = TRUE, prob = pb1) # 示例:计算熵 p <- prop.table(table(sim_sample)) -sum(p * log(p)) }) # 输出95%置信区间 quantile(param_boot_stats, c(0.025, 0.975))
该方法假设数据服从多项分布,计算效率比非参数自助法更高。
内容的提问来源于stack exchange,提问作者Marco Pastor Mayo

