學習重點:使用R複習並練習操作「機率」的基本觀念
pacman::p_load(dplyr)
為了方便討論,通常我們用一個類別或數量向量(factor or numeric vector)來代表某一個族群,向量之中的每一個值,代表族群之中的某一個研究對象。
Skin
:用類別向量代表族群之中的類別變數產生一個長度為10的類別向量:Skin
,用它來代表某一個10個人的族群當中每一個人的膚色
Skin = rep(c("White","Yellow","Black","Others"), 1:4) %>% factor
Skin
[1] White Yellow Yellow Black Black Black Others Others Others Others
Levels: Black Others White Yellow
用table()
計算各分類(level)的數量
table(Skin)
Skin
Black Others White Yellow
3 4 1 2
用直條圖觀察各分類的數量
table(Skin) %>%
barplot(main="Dist. of Skin Color",xlab="Skin Color", ylab="Count")
Weight
:用數值向量代表族群之中的數值變數產生一個長度為100的數值向量:Weight,,用它來代表某一個100個人的族群當中每一個人的體重
set.seed(2) # set.seed for randomization
Weight = rnorm(100,mean=60,sd=5) # 100 random samples
Weight
[1] 55.515 60.924 67.939 54.348 59.599 60.662 63.540 58.802 69.922 59.306
[11] 62.088 64.909 58.037 54.802 68.911 48.445 64.393 60.179 65.064 62.161
[21] 70.454 54.000 67.948 69.773 60.025 47.741 62.386 57.017 63.961 61.448
[31] 63.695 61.595 65.381 58.579 56.117 57.022 51.370 55.487 57.205 58.767
[41] 58.082 50.204 55.791 69.518 63.112 69.955 58.473 59.546 59.079 54.006
[51] 55.809 70.332 57.189 66.379 54.762 50.171 58.385 64.679 65.696 68.358
[61] 51.059 70.156 56.484 60.791 62.531 55.900 50.006 57.604 60.421 55.523
[71] 55.394 61.652 59.292 62.174 59.731 55.464 66.518 63.859 65.263 52.950
[81] 64.980 51.521 57.333 53.139 48.960 69.111 56.733 58.577 58.065 61.933
[91] 68.002 68.406 54.082 53.208 52.437 53.734 69.797 60.038 55.787 56.994
用直方圖觀察它的數值分布,比較一下直條圖和直方圖有什麼異同
par(mfrow=c(1,2), cex=0.8)
hist(Weight, main="體重的分布")
barplot(table(Skin), main="膚色的分布", xlab="", las=2)
🗿 問題討論:
■ 直條圖和直方圖有什麼異同?
■ 「分布」是什麼?
■ 類別變數和數值變數的分布有什麼異同?
💡 學習重點:
■ 分佈一般是指變數可能出現的值所出現的次數
■ 類別變數可能出現的值是有限的,所以各分類出現的次數可以清楚的被計算出來
■ 連續變數可能出現的值是無限的,所以我們需要指定數值區間,才能夠計算出現次數
■ 該數值區間就是直方圖的「欄寬(binwidth)」
如果我們改變直方圖的binwdith
par(mfrow=c(2,3), cex=0.75, mar=c(2,4,3,2))
for(bw in 1:6)
hist(Weight, seq(45,75,bw), main=paste("bw =",bw),xlab="")
🗿: binwidth
代表什麼? 它會如何改變直方圖的形狀? 為甚麼?
如果我們將族群增大為10,000人
set.seed(4); W10K = rnorm(10000,60,5)
for(bw in 1:6) {
hist(W10K, breaks=seq(40,85,bw), main=paste("bw =",bw),xlab="")
}
將Y軸從「次數(Frequency)」改為「密度(Density)」, 並且標上我們原先用來產生族群向量的「機率密度函數」
for(bw in 1:6) {
hist(W10K,breaks=seq(40,85,bw),freq=F,ylim=c(0,0.08),main=paste("bw =",bw),ylab="density")
curve(dnorm(x,60,5),40,85,col='red',add=T)
}
💡 學習重點:
■ 族群太小時,太窄或太寬的binwidth都很容易扭曲數值分佈的形狀
■ 族群夠大時,我們就可以用較窄的binwidth,讓直方圖逼近真實的數值分布
■ binwidth趨近於零時,不連續的「直方圖」就會逼近連續的「數值分布函數」
■ 等比例改變分布函數的高度,讓它下方的面積等於1,它就會變成「機率密度函數」
■ 數值分布函數下方的面積代表族群中的數值落在某一區間的次數
■ 機率密度函數下方的面積代表族群中的數值會落在某一區間的機率
🗿 問題討論:
■ 直方圖和數量分布之間有什麼關係?
■ 數量分布和機率函數之間有何異同?
■ 機率函數下方的總面積是多大呢?
W = 100
par(mfrow=c(1,1),cex=0.7)
curve(dbeta(x/W,2,2)/W,0,W,col='seagreen',lwd=3,main="Beta(2,2)",xlab="",y="Density")
abline(v=seq(0,W,W/10),h=seq(0,1.5,0.1)/W,col='lightgray',lty=3)
🗿 問題討論:
■ 從以上機率密度函數抽出80,000個樣本點,大約有多少點會落在40跟60之間?
■ 如果以上機率密度函數的底(support)變為[0, 1]
,它的最高點會變成多少?
■ 如果它的底變為[0.95, 1.05]
,它的最高點會變成多少?
我們將隨機變數定義為隨機實驗的結果(值),由於這些實驗帶有隨機的成份(也就是說每一次實驗都可能跑出不同的結果),所以隨機變數的值是不確定的。
最簡單的隨機變數就是隨機從目標族群之中選取一點,直接就把這一點當作隨機變數的值。
使用sample()
做個別隨機抽樣時,將樣本大小設為1 (size=1
)
sample(Skin, size=1) # sample size = 1
[1] Yellow
Levels: Black Others White Yellow
我們使用replicate()
重複(隨機個別抽樣)實驗十次,將結果放在skin1_10
這個類別向量裡面,由於sample()
是從目標族群之中隨機抽樣,所以我們每一次執行這一段程式,所得到的類別向量都不會相同。
skin1_10 = replicate(n=10, expr=sample(Skin, size=1))
skin1_10
[1] Others Others Black Black White Black Others Others Yellow Black
Levels: Black Others White Yellow
比較Skin
和skin1_10
之中各分類的比例
Skin %>% table %>% prop.table
.
Black Others White Yellow
0.3 0.4 0.1 0.2
skin1_10 %>% table %>% prop.table
.
Black Others White Yellow
0.4 0.4 0.1 0.1
🗿 問題討論:
在這個例子裡面 …
■ 我們的研究對象(分析單位)是?
■ 目標族群?
■ 目標變數?
■ 隨機變數?
當我們用一個類別向量來代表我們的目標族群時 …
■ Skin
代表什麼?
■ Skin[3:5]
代表什麼?
這個例子我們討論『類別變數」的『個別抽樣』隨機變數,在這裡 …
■ 我們如何定義我們的隨機變數?
■ 我們如何產生隨機變數的值?
當我將重複實驗的結果(值)存在skin1_10
這個(類別的)『結果向量』裡面 …
■ skin1_10
代表什麼?
■ skin1_10[10]
代表什麼?
■ Skin
和skin1_10
的長度各是多少?它們的長度是一樣的嗎?
■ Skin
和skin1_10
之中各分類的比例是一樣的嗎?
最後 …
■ 「目標族群的大小」和「重複實驗的次數」一定要相同嗎?
■ 目標族群和重複實驗的結果向量、兩者之中各分類的比例應該要相同(類似)嗎?
重複實驗10,100、1,000、10,000、100,000、1,000,000次,將結果放在Trials
這個序列(list)物件裡面
t0 = Sys.time()
Trials = list(
skin1_10 = replicate(10, sample(Skin, size=1)),
skin1_100 = replicate(100, sample(Skin, size=1)),
skin1_1K = replicate(1000, sample(Skin, size=1)),
skin1_10K = replicate(10000, sample(Skin, size=1)),
skin1_100K = replicate(100000, sample(Skin, size=1))
)
Sys.time() - t0
Time difference of 4.7524 secs
Trials
的子物件長度
sapply(Trials, length)
skin1_10 skin1_100 skin1_1K skin1_10K skin1_100K
10 100 1000 10000 100000
重複個別抽樣的結果之之中各分類的比例
sapply(Trials, function(v) {
prop.table(table(v))
})
skin1_10 skin1_100 skin1_1K skin1_10K skin1_100K
Black 0.2 0.23 0.290 0.3005 0.29749
Others 0.6 0.46 0.404 0.3943 0.40222
White 0.0 0.12 0.118 0.0987 0.09976
Yellow 0.2 0.19 0.188 0.2065 0.20053
接下來我們將隨機變數定義在數值變數(如Weight
)之上,我們同樣可以用重複抽樣產生一系列的結果向量
Trials = list(
weight1_10 = replicate(10, sample(Weight, size=1)),
weight1_100 = replicate(100, sample(Weight, size=1)),
weight1_1K = replicate(1000, sample(Weight, size=1)),
weight1_10K = replicate(10000, sample(Weight, size=1)),
weight1_100K = replicate(100000, sample(Weight, size=1))
)
par(cex=0.75, mfrow=c(2,3), mar=c(4,5,5,1))
for(v in Trials) {
hist(v,breaks=seq(40,80,2.5),main=paste(length(v),"repeats"),xlab="Weight")
}
hist(Weight, breaks=seq(40,80,2.5), col='gray', border='lightgray' )
💡 學習重點:
關於『隨機變數』 …
■ 隨機變數是定義在隨機實驗上面, 隨機實驗的結果就是隨機變數的值
■ 我們透過實驗來產生隨機變數的值,由於實驗的結果是隨機的, 所以隨機變數的值也是不確定的
■ 一般我們將重複實驗(N次)的結果存放在一個向量裡面,稱它為(重複N次的)『結果向量』
■ 由於隨機變數的值不確定,所以通常我們關心的是它的『分布(Distribution)』
■ 所謂『分布』就是結果向量之中各類別(或數值區間)出現的頻率
隨機變數可以分為『類別』與『數值』兩大類 …
■ 類別隨機變數的分布:各類別的比例,通常以直條圖表示
■ 數值隨機變數的分布:變數在數值空間之中的分布頻率(或機率), 通常以直方圖(或密度函數)表示
『個別抽樣』可以說是最簡單的隨機變數 …
■ 定義:從某一族群之中隨機選取一點, 直接以其值作為隨機變數的值
■ 我們用sample()
做隨機抽樣,個別抽樣實驗的樣本大小:size = 1
■ 我們用replicate(n,sample(.))
來重複實驗, 重複實驗的次數(n
)不必與目標族群的大小相同
對定義在『個別抽樣』實驗之上的類別(數值)隨機變數而言 …
■ 重複實驗的結果和族群之中各分類的比例(數值的分布)並不會完全一樣
■ 重複的次數越多,兩者之間的差異就會越來越小
■ 理論上,重複“無窮”多次時, 結果向量中各分類的比例(數值分布)就會趨近於族群之中的比例(分布)
%>%
和lapply()
善用%>%
和lapply()
可以降低程式的複雜度,也可以避免留下沒有用的(中間暫存)資料物件
lapply(10^(1:5), replicate, sample(Weight, 1)) %>% lapply(function(v) {
hist(v, breaks=seq(40,80,2.5), main=paste(length(v),"repeats"), xlab="")
}) -> z