본문 바로가기
데이터분석/R

[R 통계분석] 표본분포

by 버섯도리 2022. 8. 10.

Section 01. 표본분포

 

> ## 01) 표본평균 x의 분포

> m10 <- rep(NA, 1000)
> m40 <- rep(NA, 1000)
> set.seed(9)
> for (i in 1:1000) {
+   m10[i] <- mean(rnorm(10))
+   m40[i] <- mean(rnorm(40))
+ }

> options(digits = 4)
> c(mean(m10), sd(m10))
[1] -0.01214  0.30311
> c(mean(m40), sd(m40))
[1] 0.004212 0.160942
> # 표본 크기를 4배 늘려서 표준편차는 대략 1/2 수준으로 줄었다.

hist(m10, xlim = c(-1.5, 1.5), main = "", xlab = "x", ylab = "",
+      col = "cyan", border = "blue")

hist(m40, xlim = c(-1.5, 1.5), main = "", xlab = "x", ylab = "",
+      col = "cyan", border = "blue")

> # 표본 크기가 클수록 기대값(모집단 평균) 주변에 많이 몰려 있으며 자료가 분포하는 전체 폭이 줄어듦을 알 수 있다.

 

Section 02. 중심극한정리

 

> ## 02) 정규분포로부터 추출된 표본평균 x의 분포

> set.seed(9)
> n <- 1000
> r.1.mean <- rep(NA, n)
> r.2.mean <- rep(NA, n)
> for (i in 1:n) {
+   r.1.mean[i] <- mean(rnorm(4, mean = 3, sd = 1))
+   r.2.mean[i] <- mean(rnorm(4, mean = 170, sd = 6))
+ }

> options(digits = 4)
> c(mean(r.1.mean), sd(r.1.mean))
[1] 3.0214 0.5096
> c(mean(r.2.mean), sd(r.2.mean))
[1] 170.032   2.835

> # 표준정규분포로부터 추출한 표본평균의 분포는 그 평균이 모집단 평균에 가깝고,
> # 표준편차는 모집단 정규분포의 표준편차를 표본 크기의 제곱근으로 나눈 값(σ/sqrt(4))과 비슷하다.

hist(r.1.mean, probability = T, xlab = "표본평균", ylab = "밀도",

+      main = "", col = "orange", border = "red")
> x1 <- seq(min(r.1.mean), max(r.1.mean), length = 1000)
> y1 <- dnorm(x = x1, mean = 3, sd = 1/sqrt(4))
lines(x1, y1, lty = 2, lwd = 2, col = "blue")


hist(r.2.mean, probability = T, xlab = "표본평균", ylab = "밀도",
+      main = "", col = "orange", border = "red")
> x2 <- seq(min(r.2.mean), max(r.2.mean), length = 1000)
> y2 <- dnorm(x = x2, mean = 170, sd = 6/sqrt(4))
lines(x2, y2, lty = 2, lwd = 2, col = "blue")

> # B(10, 0.1)의 분포도
> t <- 10; p <- 0.1; x <- 0:10
> b.p <- dbinom(x, size=t, prob=p)
barplot(b.p, names=x, main="n=10, p=0.1인 이항분포",
+         col = "orange", border = "red")


> ## 03) 임의의 분포로부터 추출된 표본평균 x의 분포

> set.seed(9)
> n <- 1000
> b.2.mean <- rep(NA, n)
> b.4.mean <- rep(NA, n)
> b.32.mean <- rep(NA, n)

> for (i in 1:n) {
+   b.2.mean[i] <- mean(rbinom(2, size = t, prob = p))
+   b.4.mean[i] <- mean(rbinom(4, size = t, prob = p))
+   b.32.mean[i] <- mean(rbinom(32, size = t, prob = p))
+ }

> (ex = t * p)
[1] 1
> (sdx = sqrt(t * p * (1-p)))
[1] 0.9487

> options(digits = 4)

> c(mean(b.2.mean), sd(b.2.mean))
[1] 1.0090 0.6763
> c(mean(b.4.mean), sd(b.4.mean))
[1] 1.006 0.481
> c(mean(b.32.mean), sd(b.32.mean))
[1] 0.9989 0.1624

> # 이항분포로부터 추출한 표본평균의 분포는 그 평균이 모집단 평균 1에 가깝고,
> # 표준편차는 모집단 이항분포의 표준편차(sdx)를 표본 크기(2,4,32)의 제곱근으로 나눈 값(σ/sqrt(n))과 비슷하다.
> # 히스토그램에서는 모집단 표준편차를 0.9로 지정

hist(b.2.mean, probability = T, xlim = c(0, 4), main = "표본 크기 : 2",
+      col = "orange", border = "red")
> x1 <- seq(min(b.2.mean), max(b.2.mean), length = n)
> y1 <- dnorm(x = x1, mean = 1, sd = 0.9/sqrt(2))
lines(x1, y1, lty = 2, lwd = 2, col = "blue")

> # 표본 크기가 2일 때는 정규분포와 차이가 크다.

hist(b.4.mean, probability = T, xlim = c(0, 4), main = "표본 크기 : 4",
+      col = "orange", border = "red")
> x2 <- seq(min(b.4.mean), max(b.4.mean), length = n)
> y2 <- dnorm(x = x2, mean = 1, sd = 0.9/sqrt(4))
lines(x2, y2, lty = 2, lwd = 2, col = "blue")

# 표본 크기가 2일 때도 차이가 나지만, 2일 때보다는 그 차이가 적다.

hist(b.32.mean, probability = T, xlim = c(0, 4), main = "표본 크기 : 32",
+      col = "orange", border = "red")
> x3 <- seq(min(b.32.mean), max(b.32.mean), length = n)
> y3 <- dnorm(x = x3, mean = 1, sd = 0.9/sqrt(32))
lines(x3, y3, lty = 2, lwd = 2, col = "blue")

> # 표본 크기가 32일 때는 약간의 차이를 보이지만, 앞의 두 경우보다 정규분포에 훨씬 가깝다.
>

> # 중심극한정리 : 표본 크기가 커짐에 따라 표본평균의 분포가 정규분포와 가까워진다. 

 

Section 03. 다양한 표본분포

 

> # χ2 분포

> df <- c(1, 3, 5, 10)
> x <- seq(0, 20, by=0.01)
> chi2.1 <- dchisq(x, df[1])
> chi2.3 <- dchisq(x, df[2])
> chi2.5 <- dchisq(x, df[3])
> chi2.10 <- dchisq(x, df[4])

> plot(x, type="n", xlim=c(0, 20), ylim=c(0, 0.3), main="", xlab="x", ylab="", axes=F)
> axis(1)
> axis(2)
lines(x, chi2.1, lty=1, col = "red")
lines(x, chi2.3, lty=2, col = "green")
lines(x, chi2.5, lty=3, col = "orange")
lines(x, chi2.10, lty=4, col = "blue")
> legend("topright", paste("df :", df), lty=1:4, cex=0.7, col=c("red", "green", "orange", "blue"))


> # χ2 분포는 자유도가 낮을수록 꼬리가 오른쪽으로 치우친 형태의 분포 모양을 가지며,

> # 자유도가 증가할수록 점점 정규분포의 형태와 비슷하게 평균을 중심으로 좌우대칭의 모양을 보인다.

>

> # t 분포

> df <- c(1, 2, 8, 30)
> x <- seq(-3, 3, by=0.01)
> y <- dnorm(x)
> t.1 <- dt(x, df=df[1])
> t.2 <- dt(x, df=df[2])
> t.8 <- dt(x, df=df[3])
> t.30 <- dt(x, df=df[4])

> par(mar=c(4,2,2,2))
plot(x, y, type="l", lty=1, axes=F, xlab="x", ylab="", col="red")
> axis(1)
lines(x, t.1, lty=4, col = "blue")
lines(x, t.2, lty=3, col = "green")
lines(x, t.8, lty=2, col = "orange")
lines(x, t.30, lty=6, col = "orangered")
> legend("topright", paste("df :", df), lty=c(4, 3, 2, 6), cex=0.7, col=c("blue", "green", "orange", "orangered"))


> # t 분포는 정규분포와 비슷한 형태이지만, 평균 주변에서 상대적으로 밀도가 낮고 양 끝으로 갈수록 꼬리 부분이 두툼한 형태를 갖는다.
> # 또한 자유도가 증가할수록 표준정규분포를 닮아간다.

> # f 분포

> df1 <- c(3, 10)
> df2 <- c(5, 20)
> x <- seq(0, 2, by=0.01)

> f3.5 <- df(x, df1[1], df2[1])
> f3.20 <- df(x, df1[1], df2[2])
> f10.5 <- df(x, df1[2], df2[1])
> f10.20 <- df(x, df1[2], df2[2])

plot(x, f3.5, type="l", ylim=c(0, 0.9), axes=F, xlab="x", ylab="", col="red")
> axis(1)
lines(x, f3.20, lty=2, col="green")
lines(x, f10.5, lty=3, col="orange")
lines(x, f10.20, lty=4, col="blue")
> legend("topright", paste("df :", c("3, 5", "3, 20", "10, 5", "10, 20")), lty=1:4, cex=0.7,
+        col=c("red", "green", "orange", "blue"))

> # F 분포는 서로 다른 두 χ2 분포의 비로서 각 χ2 분포의 자유도를 모수로 사용하여 두 개의 자유도의 변화에 따라 모양이 결정된다.
> # F 분포는 꼬리가 오른쪽으로 길게 늘어진 형태를 하고 있다.
> # F 분포는 두 개의 독립인 χ2 분포의 비율을 이용하는 것으로 두 모집단의 분산 비율을 알고자 할 때 사용한다.

> ## 04) 모집단의 분산

> options(digits=5)
> cor <- c(0.4196, 0.4172, 0.4237, 0.4182, 0.4324, 0.4365, 0.4354, 0.4156, 0.4172, 0.4414)

> m <- mean(cor)
> dev <- cor - m
> num <- sum(dev^2)
> denom <- length(cor)
> denom2 <- length(cor) - 1

> # 모분산
> (var.p <- num / denom)
[1] 8.4608e-05
> # 표본분산
> (var.s <- num / denom2)
[1] 9.4008e-05
> # R 함수와 비교
> var(cor)
[1] 9.4008e-05

> ## 05) 사용자 정의 함수(모분산)

> options(digits=5)
> var.p <- function(x) {
+   n <- length(x)
+   m <- mean(x)
+   num <- sum((x - m)^2)
+   var <- num / n
+   return(var)
+ }

> radius <- c(234, 234, 234, 233, 233, 233, 233, 231, 232, 231)
> weight <- c(146.3, 146.4, 144.1, 146.7, 145.2, 144.1, 143.3, 147.3, 146.7, 147.3)

> # 모분산
> var.p(radius)
[1] 1.16
> # 표본분산
> var(radius)
[1] 1.2889

> # 모분산
> var.p(weight)
[1] 1.9084
> # 표본분산
> var(weight)
[1] 2.1204

> ## 06) 여러 개의 전달인자와 기본 전달인자

> options(digits=4)
> var.p2 <- function(x, na.rm = FALSE) {
+   if (na.rm == TRUE) {
+     x <- x[!is.na(x)]
+   }
+   n <- length(x)
+   m <- mean(x, na.rm = na.rm)
+   num <- sum((x - m)^2, na.rm = na.rm)
+   var <- num / n
+   return(var)
+ }

> radius <- c(234, 234, 234, 233, 233, 233, NA, 231, 232, 231)
> var.p2(radius)
[1] NA
> var.p2(radius, na.rm = TRUE)
[1] 1.284

 

 

 

 

 

출처 : 이윤환, ⌜제대로 알고 쓰는 R 통계분석⌟, 한빛아카데미, 2020