如何在R中用极大似然估计(MLE)为数据框中每个词估计负二项分布参数?
好的,我来帮你解决这个问题——在R里用极大似然估计(MLE)拟合负二项分布的参数(r,p),不管是单个向量还是数据框里每个词对应的向量都能搞定。
单个向量的参数估计(以word_a为例)
首先得明确负二项分布的参数定义:这里我们用的是**(r, p)**形式,其中r是形状参数(正实数),p是每次试验的成功概率(0 < p < 1),对应的概率质量函数为:
P(X = k) = \binom{k + r - 1}{k} p^r (1-p)^k ,k = 0,1,2,...
方法1:用MASS包的fitdistr函数(快速便捷)
fitdistr是R里做MLE拟合的常用工具,已经封装好了负二项分布的拟合逻辑,调用起来很省心:
# 1. 定义你的数据向量 word_a <- c(141,97,103,158,71,101) # 2. 加载MASS包(R自带的推荐包,无需额外安装) library(MASS) # 3. 拟合负二项分布 nb_fit <- fitdistr(word_a, distr = "negative binomial") # 查看结果 print(nb_fit)
运行结果里的estimate部分:
size对应的就是我们要的r参数prob对应的就是p参数
同时结果还会给出参数的标准误,方便你做后续的统计推断。
方法2:手动写对数似然函数+optim优化(理解原理)
如果你想搞懂MLE的底层逻辑,可以自己定义对数似然函数,再用optim来最大化它(注意optim默认是最小化,所以我们要把对数似然取负):
# 定义负二项分布的负对数似然函数(适配optim的最小化逻辑) neg_log_likelihood <- function(par, x) { r <- par[1] p <- par[2] # 参数合法性检查:r必须>0,p必须在(0,1)之间 if (r <= 0 || p <= 0 || p >= 1) { return(Inf) } # 计算对数似然总和后取负 ll <- sum(dnbinom(x, size = r, prob = p, log = TRUE)) return(-ll) } # 生成初始参数猜测(用样本均值和方差推导) mu <- mean(word_a) var_x <- var(word_a) # 负二项分布中,方差var = mu + mu²/r → 解出r的初始值 r_init <- mu^2 / (var_x - mu) p_init <- mu / (mu + r_init) initial_par <- c(r_init, p_init) # 用optim做优化 optim_result <- optim(par = initial_par, fn = neg_log_likelihood, x = word_a) # 提取MLE估计的参数 r_mle <- optim_result$par[1] p_mle <- optim_result$par[2] cat("手动拟合的r参数:", round(r_mle, 4), "\n") cat("手动拟合的p参数:", round(p_mle, 4), "\n")
这个方法的好处是你可以自定义参数约束或调整优化逻辑,适合更复杂的场景。
数据框中每个词批量估计参数
假设你的数据框是类似这样的结构:
| word | count |
|---|---|
| word_a | 141 |
| word_a | 97 |
| word_b | 50 |
| word_b | 62 |
你可以用dplyr按词分组,批量拟合每个组的参数:
library(dplyr) # 构造示例数据框 word_counts <- tibble( word = rep(c("word_a", "word_b"), each = 6), count = c(141,97,103,158,71,101, 50,62,45,58,42,55) ) # 批量拟合每个词的负二项参数 nb_params <- word_counts %>% group_by(word) %>% summarise( r = fitdistr(count, "negative binomial")$estimate["size"], p = fitdistr(count, "negative binomial")$estimate["prob"], .groups = "drop" ) print(nb_params)
这样就能快速得到每个词对应的(r,p)参数估计值了。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

