#计量基础-统计学R语言初步使用手册
本手册为本人统计学复习时随意整理,旨在为不熟悉统计学和R语言的同学做简单科普。
它默认你:
- 不熟悉 R
- 不熟悉统计学术语
- 看到公式会紧张
- 希望先“看懂”、再“会用”、最后“会解释”
所以这份手册的写法不是“默认你已经懂”,而是尽量按下面这个顺序展开:
- 先说这是什么
- 再说为什么要学它
- 再说它和前面学过的内容有什么关系
- 最后才给公式和代码
[!tip]
这门课最重要的不是背一堆定义,而是养成一个固定问法:
- 这个方法想解决什么问题?
- 它的输入是什么?
- 它的输出是什么?
- 图和数字该怎么解释?
0. 先建立全局地图
0.1 这门课到底在学什么
这门课不是在学“很多互不相关的统计方法”。
它其实一直在围绕一个核心问题打转:
当我们同时观察很多变量时,怎样理解它们之间的联合结构?
例如,你现在不再只看一个人的身高,而是同时看:
- 身高
- 体重
- 腰围
- 血压
- 肌肉量
- 脂肪量
这时问题就不再是“某一个变量是多少”,而是:
- 这些变量之间是不是有共同变化规律?
- 能不能把很多变量压缩成少数几个“方向”?
- 如果有分组,哪些方向最能区分组?
- 如果分成两大类变量,这两类变量之间有没有整体关系?
这就是多元统计multivariate statistics的核心。
0.2 这门课的方法之间是什么关系
0.3 你真正需要达到的水平
对期中来说,你不需要做到:
- 能手推所有证明
- 能背出特别复杂的推导
- 能写出很长的 R 程序
你需要做到的是:
- 知道每种方法在干什么
- 能读懂基础输出
- 能解释简单图形
- 能比较相近方法的区别
- 能在题目里选对方法
1. R 语言最少必要入门
这一章只讲本课立即会用到的 R。
1.1 什么是 R
R 是一种专门用于数据分析和统计的编程语言。
你可以把它理解成:
- 一个计算器
- 一个会画图的工具
- 一个能做统计分析的软件语言
对这门课来说,R 的主要作用是:
- 组织数据
- 调用统计函数
- 画图帮助理解
1.2 什么是“对象”
在 R 里,你做出的东西通常都可以存进一个名字里,这个名字就叫对象object。
x<-1:5y<-c(2,4,6,8,10)z<-x+y z这里:
x是一个对象y是一个对象z也是一个对象
<-的意思可以读成:
- “把右边的结果放进左边这个名字里”
1.3 什么是向量vector
向量就是一串同类型的数据。
例如:
- 一组身高
- 一组分数
- 一组年龄
x<-c(3,5,7,9)mean(x)sd(x)length(x)解释:
c(...)表示把数字合并成一个向量mean(x)求均值sd(x)求标准差length(x)求长度,也就是里面有几个数
1.4 什么是矩阵matrix
矩阵就是一个长方形数字表。
本课里你应该把矩阵理解成:
- 行 = 样本
observations - 列 = 变量
variables
X<-matrix(c(160,55,165,60,170,68,175,74),nrow=4,byrow=TRUE)colnames(X)<-c("height","weight")X dim(X)这段代码的意思:
- 有 4 个人
- 每个人测了 2 个变量
- 第 1 列是身高,第 2 列是体重
dim(X)会告诉你矩阵大小,比如4 x 2。
1.5 什么是数据框data.frame
数据框比矩阵更灵活。
矩阵通常要求所有列是同一种类型,最常见是数值。
数据框允许:
- 一列是数值
- 一列是文字
- 一列是类别标签
df<-data.frame(height=c(160,165,170,175),weight=c(55,60,68,74),group=c("A","A","B","B"))df这里:
height、weight是数值变量group是类别变量
1.6 怎么取数据
这一点很重要,因为你后面几乎一直在做这个动作。
df$height# 取名为 height 的这一列df[1,]# 第 1 行df[,2]# 第 2 列X[2,1]# 第 2 行第 1 列记忆方式:
[行, 列]- 前面空着 = 所有行
- 后面空着 = 所有列
1.7 本课最常用的基础函数
mean(df$height)var(df$height)sd(df$height)cov(df$height,df$weight)cor(df$height,df$weight)scale(df[,c("height","weight")])这几个函数一定要看懂:
| 函数 | 它在算什么 | 你应该怎么理解 |
|---|---|---|
mean() | 均值 | 数据的平均水平 |
var() | 方差 | 数据波动有多大 |
sd() | 标准差 | 方差的平方根,和原变量单位一致 |
cov() | 协方差 | 两个变量是不是一起变化 |
cor() | 相关系数 | 标准化后的协方差,范围固定在 -1 到 1 |
scale() | 标准化 | 把变量转成可比较的统一尺度 |
1.8 什么是apply()
当你想对矩阵每一行或者每一列做同样的操作时,apply()很方便。
X<-matrix(1:12,nrow=3,byrow=TRUE)apply(X,1,mean)# 每一行求均值apply(X,2,mean)# 每一列求均值这里的1和2很值得记住:
1= rows2= columns
1.9 第一幅图:散点图
x<-c(1,2,3,4,5)y<-c(2,4,5,4,6)plot(x,y,pch=19,col="steelblue",main="Simple scatterplot",xlab="x",ylab="y")这张图里每个点代表:
- 一个观测对象
你要养成的读图习惯:
- 点大致沿一条斜线排列吗?
- 点是聚成几团吗?
- 有没有特别远的点?
后面 PCA、LDA、CCA 的很多图,本质上都是“散点图升级版”。
1.10 图示:为什么标准化前后会长得不一样
df<-data.frame(income=c(40,50,55,60,70),height=c(155,160,165,170,175))par(mfrow=c(1,2))plot(df$income,df$height,pch=19,col="tomato",main="Raw scale",xlab="income",ylab="height")z<-scale(df)plot(z[,1],z[,2],pch=19,col="steelblue",main="Standardized scale",xlab="income (z)",ylab="height (z)")par(mfrow=c(1,1))左图和右图的区别不是“关系变了”,而是“坐标尺度统一了”。
这句话很重要:
标准化主要是为了让不同单位的变量能放在同一个公平的比较框架里。
1.11 这一章结束后你应该会说什么
- 什么是对象、向量、矩阵、数据框
- 什么叫“行是样本,列是变量”
cov()和cor()都是在研究两个变量的关系scale()是把变量变到统一尺度上
2. 最少必要统计基础
这一章是后面所有方法的地基。
如果这里没看懂,后面的 PCA、CCA、FA 会显得像很多新名词;如果这里看懂了,你会发现后面大部分方法只是“换一种方式研究变量如何一起变化”。
2.1 先分清几个最常见的统计对象
变量variable
变量就是你测量的某一项。
例如:
- 身高
- 体重
- 年龄
- 肌肉量
观测observation
观测就是一个样本、一位受试者、一条记录。
例如:
- 第 1 个学生
- 第 1 个病人
- 第 1 个城市
连续变量和分类变量
连续变量:
- 可以取很多数值,例如身高、体重、收入
分类变量:
- 表示类别,例如性别、物种、组别
为什么这很重要?
因为方法选择会受变量类型影响:
- 连续变量常配 PCA、FA、CCA、PLS
- 已知分类标签时常配 LDA、QDA、PLS-DA
2.2 均值、方差、标准差
均值是什么
均值mean就是平均数。
如果一组数是:
2, 4, 6
那它们的均值就是:
(2 + 4 + 6) / 3 = 4
均值回答的问题是:
- 这一组数据大概在什么位置
方差是什么
方差variance回答的问题是:
- 这些数离平均值有多分散
如果所有数都非常接近均值,方差就小。
如果数值很分散,方差就大。
样本方差公式:
s 2 = ∑ ( x i − x ˉ ) 2 n − 1 s^2 = \frac{\sum (x_i - \bar{x})^2}{n - 1}s2=n−1∑(xi−xˉ)2
这公式你不需要一上来死背,但你要知道每一部分在干什么:
x_i - xbar:每个数离平均值有多远- 平方:避免正负抵消
- 求和:把所有偏离加起来
- 除以
n - 1:得到样本方差
标准差是什么
标准差standard deviation就是方差的平方根。
它比方差更常被直观理解,因为:
- 标准差和原数据单位一致
例如:
- 身高的标准差还是“厘米”
- 收入的标准差还是“元”
最小例子
x<-c(2,4,6)mean(x)var(x)sd(x)2.3 协方差:两个变量是否一起变化
先别看公式,先看意思
协方差covariance想回答的是:
- 当变量 X 变大时,变量 Y 会不会也跟着变大?
如果是,就倾向于正协方差。
如果 X 变大时 Y 倾向于变小,就倾向于负协方差。
公式长什么样
cov ( X , Y ) = ∑ ( x i − x ˉ ) ( y i − y ˉ ) n − 1 \operatorname{cov}(X, Y) = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{n - 1}cov(X,Y)=n−1∑(xi−xˉ)(yi−yˉ)
不要被公式吓到,它本质上仍然是在看:
- X 离自己均值的偏差
- Y 离自己均值的偏差
- 这两个偏差是不是经常同号
如果常常同号:
- 一个高于平均时另一个也高于平均
- 协方差倾向于正
如果常常异号:
- 一个高于平均时另一个低于平均
- 协方差倾向于负
例子
x<-c(1,2,3,4)y<-c(2,4,6,8)z<-c(8,6,4,2)cov(x,y)cov(x,z)解释:
cov(x, y)应该是正的,因为它们一起增大cov(x, z)应该是负的,因为一个变大时另一个变小
2.4 相关:更容易解释的关系强度
为什么还需要相关
因为协方差有一个问题:
- 它会受单位影响
例如:
- 你的收入用“元”记录
- 另一个人用“万元”记录
同样的关系,协方差数值可能完全不同。
所以我们引入相关系数correlation。
相关的好处
相关系数的范围固定在:
-1到1
这样解释就容易得多:
1:完全正线性关系-1:完全负线性关系0:没有明显线性关系
最小例子
cor(x,y)cor(x,z)2.5 图示:高相关和低相关看起来有什么不同
set.seed(767)x<-rnorm(100)y1<-0.9*x+rnorm(100,sd=0.2)y2<-rnorm(100)par(mfrow=c(1,2))plot(x,y1,pch=19,col="steelblue",main="Strong linear relation")plot(x,y2,pch=19,col="tomato",main="Weak linear relation")par(mfrow=c(1,1))cor(x,y1)cor(x,y2)这段代码最应该帮你建立的是“图形直觉”:
- 左图里点大致沿斜线分布,相关高
- 右图里点更像随机一团,相关低
这件事很重要,因为后面很多方法其实都在研究这种“联合变化的形状”。
2.6 标准化为什么重要
这是很多初学者第一次真正卡住的地方,所以这里讲慢一点。
第一步:先理解“标准化”这个词
标准化standardization的意思不是“让数据变得标准答案一样”。
它真正做的事情是:
把不同单位、不同量纲的变量,转换到同一个可比较的尺度上。
标准化公式是:
z = x − x ˉ s d ( x ) z = \frac{x - \bar{x}}{sd(x)}z=sd(x)x−xˉ
你可以把这条公式拆成两步理解:
x - xbar
先看这个值离平均值有多远再除以
sd(x)
把“远多少”转成“相对于本变量自己的波动来说远多少”
第二步:标准化后会发生什么
标准化之后:
- 均值会变成 0
- 标准差会变成 1
这不代表数据“失真”了,而是代表:
- 它们被放进了同一种单位体系里
第三步:为什么 PCA 特别在意这件事
先想一个最直观的例子。
你现在有两个变量:
income:收入,数值大概是40, 50, 60height:身高,数值大概是155, 165, 175
如果你直接把它们放进 PCA,不标准化会怎样?
答案是:
- 数值范围更大的变量更容易主导分析
这时候 PCA 很可能更关注“数字大不大”,而不是“变量结构是否重要”。
也就是说,不标准化时:
- 结果可能更多反映变量单位
- 而不是变量之间真正的关系
第四步:最小代码例子
df<-data.frame(income=c(40,50,55,60,70),height=c(155,160,165,170,175))scale(df)你运行后会看到:
- 原来的
income和height数值都变了 - 但它们都被改造成“均值 0、标准差 1”的尺度
第五步:图形理解
df<-data.frame(income=c(40,50,55,60,70),height=c(155,160,165,170,175))par(mfrow=c(1,2))plot(df$income,df$height,pch=19,col="tomato",main="Before standardization",xlab="income",ylab="height")z<-scale(df)plot(z[,1],z[,2],pch=19,col="steelblue",main="After standardization",xlab="income (z)",ylab="height (z)")par(mfrow=c(1,1))这段图的重点不是让你看“点云完全变形了没有”,而是让你明白:
- 标准化以后,两列变量终于可以在同一个公平框架里比较
第六步:什么时候特别要考虑标准化
这些场景通常应该优先考虑:
- 变量单位不同
- 变量数值范围差很多
- 你不希望“大数字变量”天然拥有更大话语权
第七步:你现在应该会怎么说
标准化就是把变量转换到同一个可比较的尺度上。它特别重要,因为像 PCA 这类方法会受变量尺度影响;如果不同变量的单位差很多,不标准化时,大量纲变量可能主导结果。
2.7p-value的最小正确理解
这一小节也常卡人,因为很多教材上来就讲得很抽象。
我们先只抓最小正确含义。
第一步:先理解零假设H0
零假设H0可以先粗略理解为:
- “没有差异”
- “没有关系”
- “没有效应”
比如:
- 两组均值没有差异
- 两个变量没有关系
这不一定是现实真相,而是检验开始时先假设它成立。
第二步:p-value到底在说什么
p-value可以理解为:
如果零假设真的成立,那么像现在这么极端的结果,出现的概率有多大。
注意,它说的是:
- “假设 H0 成立时,数据有多极端”
它没有说:
H0为真的概率是多少
这两句话完全不是一回事。
第三步:一个硬币的直觉例子
假设你怀疑一枚硬币不公平。
零假设:
- 这枚硬币是公平的
你抛了 20 次,结果出现了 19 次正面。
这时你会想:
- 如果硬币真是公平的,出现这么偏的结果是不是太夸张了?
这时对应的p-value就是在回答:
- 在“硬币公平”的前提下,像这么极端的结果有多罕见
第四步:p-value小意味着什么
如果p-value很小,通常说明:
- 在
H0为真的前提下,这个结果不太常见
因此我们会倾向于:
- 怀疑
H0
但不要说成:
- “H0 有 3% 的概率是真的”
这是错误说法。
第五步:不要把p-value当成什么
不要把它理解为:
- 零假设为真的概率
- 效应大小
- 结果是否重要的全部标准
例如:
- 很小的效应,如果样本非常大,也可能有很小的
p-value - 很大的效应,如果样本很小,也不一定有很小的
p-value
第六步:你现在应该会怎么说
p-value表示:如果零假设为真,那么观察到当前这么极端或更极端结果的概率有多大。它不是零假设为真的概率,也不是效应大小。
2.8 为什么会有多重检验问题
这件事如果不靠例子讲,会很容易抽象。
第一步:先看单个检验
假设你做 1 次检验,并规定:
p < 0.05就算显著
这大致意味着:
- 即使零假设为真,也有 5% 左右概率因为随机波动而误报“显著”
这个错误就叫假阳性false positive。
第二步:如果你做很多很多次检验
现在不是做 1 次,而是做 1000 次。
就算这 1000 个检验全都没有真实效应,也会发生什么?
答案是:
- 你仍然可能看到很多“显著”
为什么?
因为每次检验都有机会因为随机波动误报。
第三步:最直观的数字感觉
如果每次检验的误报概率大约是 5%,那做 1000 次检验时:
- 你大概可能看到几十个看起来“显著”的结果
虽然它们其实只是随机误报。
这就是为什么:
- 检验做得越多
- 只看原始
p-value - 就越危险
第四步:为什么这在高维数据里特别严重
在多元统计和现代数据分析里,经常会出现:
- 几百个变量
- 几千个基因
- 很多后续单变量检验
这时如果你还按“每个检验都单独看0.05”的方式判断,就很容易把噪声当成信号。
第五步:这就是 FDR 为什么重要
FDRFalse Discovery Rate想控制的是:
- 你判为显著的一堆结果里,有多少比例可能是假阳性
它不是在说“完全不许犯错”,而是在说:
- 我们要控制错误发现的比例,不要让假阳性泛滥
第六步:最小模拟例子
set.seed(767)pvals<-runif(1000)sum(pvals<0.05)这里runif(1000)生成了 1000 个 0 到 1 之间的随机数。
你可以把它粗略看成:
- 在零假设都成立时,很多检验产生的一组原始
p-value
sum(pvals < 0.05)统计的是:
- 其中有多少个“看起来显著”
你通常会发现:
- 明明没有真实信号,仍然会冒出一些“显著”
这就是多重检验问题最直观的样子。
第七步:你现在应该会怎么说
当同时进行很多检验时,即使每个检验都没有真实效应,也可能因为随机波动出现不少看似显著的结果,所以不能只看单个原始p-value,这就是 FDR 等多重检验控制方法存在的原因。
2.9 这一章结束后你应该会说什么
- 方差描述一个变量的波动大小
- 协方差描述两个变量是否一起变化
- 相关是更容易解释的标准化关系强度
- 标准化是把变量放到同一个可比较尺度上
p-value不是零假设为真的概率- 检验做很多次时,会自然冒出假阳性,所以要控制多重检验错误