☰
数理统计习题解答的R语言复现:从最大似然到假设检验
2026/9/25 1:06:04 网站建设 项目流程

简介:《约翰·赖斯数理统计和数据分析》(第三版)配套的完整解决方案集,面向需要系统掌握统计学理论与应用的学生、自学者和教师,覆盖概率论、假设检验、回归分析、方差分析、非参数检验、贝叶斯统计、实验设计及时间序列等核心章节的习题解答。压缩包共二十一个文件,大小约一点零五MB,主要包含R语言代码、R Markdown笔记、HTML渲染页面、PDF题解、封面图片以及XML、GIT等配置文件,便于对照代码与推导过程进行学习。读者可借助这些材料深入理解每道题的统计思想,掌握用R实现数据清洗、建模、检验与可视化的具体方法,并获得可复现代码与分层笔记,按章节快速复习巩固,提升解决实际统计问题的能力。目前已有三百人学习下载,适合正在使用该教材入门或备考的读者辅助参考。

1. 数理统计和数据分析的习题解答:先弄清这份方案能帮你省下多少时间

《约翰·赖斯的数理统计和数据分析》(第3版)的习题解答,经常以 Mathematical_Statistic_Data_Analysis_Solutions 这类项目名出现在 GitHub 和各类学习资源站上。很多同学下载后就丢进收藏夹,等到考前两周才翻出来对答案,结果发现自己连标准答案是“怎么算出来”的都看不懂。问题不在于答案本身,而在于这本书的习题偏偏大量依赖数值计算与图形验证,光看纸面推导根本推不到最后一步。真正值得投入精力的,是想清楚:这份解决方案覆盖哪些章节,每类习题背后的计算套路是什么,以及如何用 R 或 Python 把每一道题的结论重新跑出来。适合的人群很明确:正在啃第 3 版教材的统计系学生、转行做数据分析想补理论底子的从业者,以及准备面试前需要快速回顾假设检验和回归的人。下文我按自己的复现经验,把这一整套方案拆成可执行的操作流程。

2. 按概率、估计、检验、回归拆解习题:每类题的解法套路与工具选型

拿到一份习题解答,第一件事不是从头看到尾,而是先按章节建索引,弄清楚这本书在考察哪几类问题。赖斯这本书的章节安排,从概率论一路推进到抽样调查、参数估计、假设检验、方差分析与回归,每一章习题的计算密度完全不同。我习惯把习题先分成四类:概率与随机变量计算、参数估计与似然优化、假设检验与拟合优度、回归与方差分析。分好类之后,就能给每一类题配上相对固定的计算工具,避免反复试错。

2.1 概率与随机变量的习题:穷举样本空间还是直接套分布函数

这类题集中在教材前半部分,通常要求计算事件的概率、随机变量的期望、方差,或者两个随机变量的协方差。常见做法是先判断样本空间大小:如果是离散且规模有限的场景,直接穷举比套公式更不容易出错;如果遇到连续分布,则转为积分或调用分布函数。

# 离散概率:抛三枚均匀硬币,求出现正面次数的分布 outcomes <- expand.grid(rep(list(c("H", "T")), 3)) head(outcomes) count_heads <- apply(outcomes, 1, function(x) sum(x == "H")) table(count_heads) / nrow(outcomes)

这段代码先用expand.grid生成全部 8 种结果,再用apply统计每个组合中正面出现的次数,最后除以总样本数得到概率质量函数。参数上需要注意nrow(outcomes)在样本空间不对称时会直接给出分母,不用手工数。对于连续分布,比如指数分布的均值与方差,直接用解析式算更快,但如果题目要求验证数值结果,可以用integrate做数值积分对照。这里最容易踩的坑是把“分布函数”和“概率质量函数”混为一谈,画图前先用?ecdf看帮助文档确认输入输出。

2.2 参数估计习题:矩估计、最大似然与数值优化

参数估计是这本书习题的难点集中地。矩估计通常手工解方程就够,但最大似然估计一旦涉及两个参数联立求解,或者似然函数没有闭式解,就必须交给数值优化器。常见做法是先写出对数似然函数,再用optim或者nlm求解。我一般会建议先试optim,因为它的返回结果里直接带hessian,可以顺手算标准误。

# 以正态分布两个参数(mu, sigma2)的MLE为例 set.seed(42) x <- rnorm(100, mean = 5, sd = 2) neg_loglik <- function(theta) { mu <- theta[1] sigma2 <- theta[2] if (sigma2 <= 0) return(Inf) n <- length(x) n * log(sqrt(sigma2)) + sum((x - mu)^2) / (2 * sigma2) } fit <- optim(c(0, 1), neg_loglik, method = "L-BFGS-B", lower = c(-Inf, 1e-6), hessian = TRUE) fit$par

neg_loglik里把方差参数单独抽出,并通过if (sigma2 <= 0) return(Inf)防止优化器把方差带进负数区域,这是数值优化的关键约束。lower下界限制了方差的搜索空间,hessian = TRUE则让optim返回二阶导数矩阵。参数说明上,L-BFGS-B适合边界约束问题,如果你的似然函数很平滑,也可以换成默认的Nelder-Mead,但边界约束场景下前者更可靠。这里最容易翻车的点,是初始化值c(0, 1)离真实值太远导致收敛到局部极值。把初值设为样本均值和样本方差,通常能避免大多数迭代失败。

2.3 假设检验与拟合优度:算 p 值和说人话之间要有桥梁

假设检验题在习题解答里往往看起来很短:给出检验统计量、p 值、结论。但这恰恰是读者最容易照抄而没有真正理解的部分。赖斯这本书里的假设检验习题,经常要求你从零开始构造检验统计量,而不是直接调用t.test或chisq.test。我的建议是:先用 R 自带函数拿到结果,再手推一遍关键量作为验证。

# 卡方拟合优度检验:观测频数与理论概率 observed <- c(18, 24, 28, 30) probs <- c(0.2, 0.3, 0.3, 0.2) chisq_res <- chisq.test(observed, p = probs) chisq_res$statistic chisq_res$p.value # 手算:sum((observed - expected)^2 / expected) expected <- sum(observed) * probs sum((observed - expected)^2 / expected)

chisq.test的两个参数分别传入观测频数和理论概率向量,R 会自动计算期望频数并输出统计量与自由度。手算部分则用sum((observed - expected)^2 / expected)验证结果一致性。参数说明上,p向量必须归一化为总和 1,否则 R 会报错或者强制归一化,最常见的错误是把百分比写成整数。此外,期望频数小于 5 的单元格会让卡方近似失效,这时需要用chisq.test(..., simulate.p.value = TRUE)做蒙特卡洛模拟得到更可靠的 p 值。真实场景中,我见过不少人直接把答案里的 p 值抄进报告,却没发现自由度因为合并类别而少算了一格,这类低级失误只能靠重跑检验统计量来拦截。

2.4 回归与方差分析习题:把 ANOVA 表和回归系数表读透

回归和方差分析的习题,答案通常是一张表:系数估计、标准误、t 值、F 值、R 平方。抄答案的人只会看最后显著性星号,但做数据分析的人必须能解释每一个数字怎么来。R 的lm输出里藏着几乎所有需要的信息,关键是知道去哪一行取哪个数。

# 单因素方差分析:比较三个组的均值 group <- factor(rep(1:3, each = 10)) y <- c(rnorm(10, 0, 1), rnorm(10, 1, 1), rnorm(10, 1.5, 1)) aov_fit <- aov(y ~ group) summary(aov_fit) # 手动对照:组间平方和 / 组内平方和 group_means <- tapply(y, group, mean) grand_mean <- mean(y) ss_between <- sum(10 * (group_means - grand_mean)^2) ss_within <- sum((y - rep(group_means, each = 10))^2)

aov的 summary 输出里,第一行给出组间自由度、平方和、均方、F 值和 p 值,第二行是残差项。手动对照部分用tapply计算各组均值,用grand_mean计算总均值,再分别求组间平方和与组内平方和。注意rep(group_means, each = 10)这一步很容易写错成每组的均值没有对齐原始数据顺序,导致组内平方和偏差。更复杂一点的回归题,涉及多元共线性时,我会额外查看vif函数输出,但它不在基础包里,需要加载car包。对于教材后面的多元回归章节,习题答案往往会让你做变量筛选,这时务必理解summary(lm_fit)$adj.r.squared与普通 R 平方的差别,避免只看未调整的数值而高估模型的解释力。


下表是我在复现这套习题时常用的题型-工具对照,方便快速定位。

习题类型推荐R函数需要人工核对的关键点
离散概率计算expand.grid+apply样本空间是否穷举完整
连续分布概率integrate/pnorm积分上下限是否与事件对应
矩估计mean/var/ 解方程方程是否按一二阶矩联立
最大似然估计optim+hessian参数边界约束与初值选择
假设检验t.test/chisq.test单双侧方向与自由度
方差分析aov/summary组内平方和的残差对齐
线性回归lm/summary系数符号与共线性影响

3. 复现一道习题的完整流程:R 环境、数据样例与三步走

前面做了分类,这一章落到具体操作:从搭建环境开始,到在本地把三道典型习题完整跑通。我用 R 4.3 作为运行时,代码只在基础包和MASS、boot两个包之间切换,这样能最大程度降低环境差异带来的“答案对不上”问题。

3.1 环境准备:固定 R 版本、安装包与项目目录组织

复现任何统计习题前,先把版本和依赖锁死。不同 R 版本之间optim的默认终止条件略有差异,rnorm生成的随机数虽然在相同种子下各版本一致,但依赖包版本的升级仍可能改变函数的默认行为。我的做法是在项目根目录写一个session-info.txt,同时用renv锁定包版本。

R --version Rscript -e 'install.packages(c("MASS", "boot", "car"), repos = "https://cloud.r-project.org")' Rscript -e 'packageVersion("MASS"); packageVersion("boot")'

第一行确认 R 版本,第二行安装后续代码需要的扩展包,第三行打印包版本用于记录。参数说明上,repos指定了国内可访问的镜像地址,如果不指定,R 会按默认源安装。这里我建议不要用install.packages的默认repos = NULL,因为某些公司的内网环境会卡在下载环节。实际执行时把这些命令放在setup.R里,之后每次换电脑重跑一遍即可,算是一个简单有效的后悔药。

3.2 单个样本推断题的复现:t 检验、置信区间与手工核对

教材里关于单样本均值推断的习题非常多,常见的问法是“给定一组数据,检验均值是否等于某个常数,并给出 95% 置信区间”。拿到这种题,我通常先输出描述统计,然后同时跑t.test和手工计算,两边对不上就说明哪个环节写错了。

# 一组来自正态总体的样本数据(通常习题会直接给出) x <- c(4.8, 5.2, 5.0, 5.4, 4.9, 5.1, 4.7, 5.3, 5.0, 4.9) test_res <- t.test(x, mu = 5, conf.level = 0.95) test_res$statistic test_res$p.value test_res$conf.int # 手工计算:t = (xbar - mu) / (sd / sqrt(n)) n <- length(x) xbar <- mean(x) s <- sd(x) t_stat <- (xbar - 5) / (s / sqrt(n)) lower <- xbar - qt(0.975, df = n - 1) * s / sqrt(n) upper <- xbar + qt(0.975, df = n - 1) * s / sqrt(n)

t.test的第一个参数传入样本向量,mu指定原假设下的均值,默认是 0,conf.level决定置信区间的置信水平。手工计算里最需要注意的是sd(x)是样本标准差,分母是自由度 n-1,不是总体标准差。qt(0.975, df = n-1)取 t 分布的双侧 0.05 临界值,对应 95% 置信区间。这里常见的翻车点是混淆了qnorm和qt:当样本量小于 30 时,用正态临界值替代 t 临界值会低估区间宽度,答案也自然和书上的对不上。如果遇到习题给出的是汇总统计量而不是原始数据,就把x替换成手工构造的样本向量,或者直接套公式计算,两种路径的结果应该完全一致。

3.3 最大似然估计的复现:写对数似然函数,用 optim 带参数走一遍

第 2 章提过 MLE 的一般流程,这里给一个更完整的操作模板,特别关注两件事:边界约束和标准误。习题答案里给的 MLE 往往是一个精确数值,如果优化结果在小数点后第三位都对不上,优先检查你的似然函数是否写错了密度表达式。

# 习题示例:Gamma 分布的形状与尺度参数估计(随机生成数据便于复现) set.seed(123) y <- rgamma(200, shape = 3, rate = 2) gamma_negloglik <- function(param) { shape <- param[1] rate <- param[2] if (shape <= 0 || rate <= 0) return(Inf) -sum(dgamma(y, shape = shape, rate = rate, log = TRUE)) } fit_gamma <- optim(c(1, 1), gamma_negloglik, method = "L-BFGS-B", lower = c(1e-4, 1e-4)) fit_gamma$par

dgamma(..., log = TRUE)直接返回对数密度,求和后加负号就变成负对数似然。optim的lower参数分别限定 shape 和 rate 必须大于 0,这是 Gamma 分布参数的自然约束,不加边界时优化器偶尔会把参数试探到负数区域,导致似然返回NaN。初值c(1, 1)比较粗糙,正常数据量下也能收敛,但如果你发现收敛慢,可以先用fitdistr里的矩估计初值替换。执行后fit_gamma$par应该接近c(3, 2),和生成数据的真实参数一致,但任何一组随机样本的 MLE 都不可能精确等于真实参数,差异在 0.1 以内都算正常。习题答案如果是一个明确的小数,而你的结果偏差较大,先复查dgamma的rate参数是不是被误写成scale,这两个是倒数关系。

3.4 检验功效的模拟复现:用蒙特卡洛代替书末答案表

赖斯书里有一类习题会问到“在某个效应量下检验的功效是多少”,需要查功效表或计算正态近似。既然手头有 R,我一般直接跑模拟,既验证答案表格的数值,也能画功效曲线。这个思路也适用于任何区间估计或检验特性类题目。

set.seed(2024) B <- 5000 pvals <- replicate(B, { g1 <- rnorm(12, mean = 0, sd = 1) g2 <- rnorm(12, mean = 0.8, sd = 1) t.test(g1, g2, var.equal = TRUE)$p.value }) power <- mean(pvals < 0.05) power

replicate重复执行t.test5000 次,var.equal = TRUE对应两独立样本 t 检验的经典版本。每次模拟生成两个样本,效应量为均值差 0.8,最后统计 p 值小于 0.05 的比例即为功效。原则上B取得越大,功效的蒙特卡洛标准误越小,5000 次通常能把功效估计误差控制在 0.01 上下。习题答案给 0.67,模拟得到 0.66 或者 0.68 都是正常的,这种波动恰好说明解析解算的是“渐近”功效,而模拟结果带有抽样误差。如果两者差异超过三个标准误,再回头检查第二组的均值是不是写成了 0.8 的累积效应,而不是单次抽样均值。

4. 数理统计习题答案的常见翻车现场:5 个统计计算坑的排查清单

习题解答写得再详细,也不能保证你落到自己手上时一次跑通。以下五个坑是我在学生作业和复现过程中遇到最多的,每一条都按现象、原因、解决的顺序排查。

4.1 坑一:R 里正态分布函数的参数名是 sd,不是方差

现象:执行rnorm(100, mean = 0, var = 4)直接报错,或者换成dnorm(x, mean = 0, var = 4)返回的所有值都相同。

原因:R 的rnorm、dnorm、pnorm、qnorm系列函数,第二个分布参数统一命名为sd,也就是标准差,而不是方差。教材里习惯用 σ² 表示方差,照搬到 R 时就把sd位置填成了 4,导致分布的离散程度翻倍。

解决:写分布函数前先记忆一组等价关系:正态分布填sd = sqrt(var),Gamma 分布用rate还是scale取决于密度公式,Poisson 和二项分布则不需要这个转换。快速验证方法是对一个固定分布抽样并输出var(x),如果计算出的样本方差和你设想的参数差一个量级,那就是参数名的映射错了。

4.2 坑二:置信区间的解释被写成“95% 概率包含真值”

现象:习题答案里写出“我们有 95% 的概率认为总体均值落在该区间内”,老师批注“频率学派表述错误”。

原因:教材上的置信区间是在频率学派框架下定义的,置信水平描述的是“重复抽样下区间覆盖真值的比例”,而不是某一次特定抽样的后验概率。把参数当作随机变量来理解,就混入了贝叶斯概念。

解决:统一改成标准表述:在 95% 的置信水平下,该区间覆盖总体均值的比例是 95%,对于某一次具体抽样得到的区间,只能说“在给定数据下计算出的区间”,不说“该均值的概率”。这份解决方案里如果遇到此类判断题,直接按频率学派口径写结论,扣分概率最低。

4.3 坑三:p 值算对了但单双侧检验的边界没乘 2

现象:习题中的原假设是 μ = 5,备择假设是 μ ≠ 5,手工计算 Z 统计量为 2.31,直接用1 - pnorm(2.31)得到单侧 0.0104,但答案给的是 0.0208。

原因:双侧检验的 p 值是在两尾区域都算进去的概率,只算一侧就漏掉对称的尾部面积,结果正好少一半。

解决:明确备择假设的方向。双侧检验写2 * (1 - pnorm(abs(z))),左侧检验写pnorm(z),右侧检验写1 - pnorm(z)。R 里t.test会自动处理,但手算对照答案时一定要在代码旁注释是哪一种检验边界,防止事后忘记为什么乘了 2。

4.4 坑四:模拟没固定种子,两次运行结果对不上

现象:同一份习题的模拟答案,第一次跑功效是 0.668,过几天重跑变成 0.652,于是怀疑自己代码哪里有 bug。

原因:rnorm在未设置随机种子时每次启动都会重新生成伪随机数序列,样本的两次模拟波动是正常的,但对照“标准答案”时会被认为是操作不稳定。

解决:在代码最前面统一加上set.seed(123),并且把种子值作为参数定义成脚本顶部的一个变量。这样无论换机器还是换会话,只要种子相同、代码相同,输出就完全一致。正式的习题解答里如果包含模拟结果,明文标注种子值也是一种负责任的表现。

4.5 坑五:书中计算符号与 R 输出符号映射错位

现象:习题解答中写“估计量为 θ̂ = 2.31”,你在 R 里找summary(lm_fit)输出,发现estimate列的值是 2.31,但自己对照回归方程时把截距和斜率弄反,导致解释结论完全不对。

原因:教材和 R 使用不同的符号体系,lm输出的(Intercept)对应公式中的 β₀,后面的变量系数对应 β₁、β₂ 等,新手容易看错行。

解决:先打印names(coef(lm_fit))确认系数向量的排列顺序,再与题目公式的变量顺序逐一比对。另一个更隐蔽的错位出现在aov输出中,Residuals行的平方和对应组内误差,而不是误差项的某个系数。解这类题时我习惯在代码旁写一行注释,标明“题目里的 α_j 对应输出中的 group2 行”,能极大减少对表时的困惑。

5. 用自助法和置换检验验证任何一版答案的正确性

习题解答不管来自哪里,最终要交给你自己验证:答案里的这个置信区间宽度、那个功效数值,到底是不是合理。我最常用的验证手段不是重新读推导过程,而是直接用模拟把结论“重新生成”一遍。这里给一个通用模板,对区间估计、检验功效、回归系数的显著性都可以套用。

set.seed(7) library(boot) # 以一组原始样本的均值置信区间为例 sample_data <- rnorm(50, mean = 3, sd = 1.5) boot_mean <- function(data, i) mean(data[i]) boot_out <- boot(sample_data, statistic = boot_mean, R = 2000) boot.ci(boot_out, type = c("norm", "perc", "bca"))

boot函数三要素分别是原始数据、统计量函数和迭代次数R。统计量函数必须接收两个参数:完整数据集和重抽样索引向量i,mean(data[i])就是第 i 次自助样本的均值。boot.ci输出三种置信区间:norm用的是正态近似,perc是分位数法,bca是偏差校正加速区间。当样本分布明显不对称时,bca比前两者更可靠,否则以perc结果作为基准。如果习题答案给出的置信区间与三种区间都差异很大,先确认样本量是否是 50,再看原假设的分布假设是否合理。除了检验答案,这个模板还可以反向使用:你自己写好一段推断代码,把模拟数据和重复次数传入,输出结果就会变成你做分析时的核查工具。

对我来说,最后真正受益的是养成了一个习惯:任何一版习题解答到手,先抽三道不同类型的题跑一遍模拟——一道概率计算、一道估计、一道检验——三处都对上,才敢在后续复习中把这份方案当作参考。反过来说,我也遇到过某版答案推导正确但数值表抄错的情况,靠模拟才发现那个小差异不是抽样误差而是一处明显的印刷错误。希望这篇文章的流程能帮你少走一遍我走过的弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询