なぜ2つの自由度があるのか
2つの自由度はそれぞれ「分子の自由度」と「分母の自由度」と呼ばれることがあります。実は、これが上記の式に対応しており、分子の自由度は条件・グループの平均の自由度、分母の自由度はグループ内のデータのばらつきの自由度を示しています。以下では3つの条件を比較する1要因分散分析の場合で考えてみます。
条件・グループの平均の自由度
では、分子の自由度の意味を少し考えてみます。分子の自由度は
です。例えば3つのグループを比較するときの自由度は2になります。自由度というのは、値の取り方の自由度です。グループを考慮に入れない全体の平均値がわかっているとき、3つのうち2つのグループの平均値がわかると残り一つのグループの平均値は自然に決まります。
図式的に考えれば以下のようになります。

各グループの全てがグループの平均値と一致している状態です。データがたくさんあっても、データの値の取り方は限られており、全体平均がわかっているなら、あと2つの値は自由にとることができます。
条件内・グループ内のばらつきの自由度
次は、条件内・グループ内のデータのばらつきです。ここでも自由度の値の取り方は決まっています。グループの平均値がもとまっていれば、グループ内に含まれるデータの最後の1つは、他の値がわかると自然に決まります。

これを全てのグループについて足し合わせるので、以下のようになります。

図式的に考えれば、以下のように、各データのグループ平均からのズレを考えていることになります。

Rを使ってF値を求める
ではR言語でF値を計算してみます。基本的には以下のlm関数またはaov関数を利用すれば簡単に計算可能です。
lm関数/ aov関数の利用
特に1つの被験者間要因分散分析ならlm関数かaov関数かで計算結果が変わらないので、どちらでも好きな方を使ってください。
dat <- data.frame(dv = c(3.188957, 3.188957, 3.188957, 3.188957, 3.188957, 6.375809, 6.375809, 6.375809, 6.375809, 6.375809, -9.016713, -9.016713, -9.016713, -9.016713, -9.016713), iv = c("red", "red", "red", "red", "red", "orange", "orange", "orange", "orange", "orange", "blue", "blue", "blue", "blue", "blue"))
res_lm <- lm(dv ~ iv, data =dat)
anova(res_lm)
res_aov <- aov(dv ~ iv, data =dat)
summary(res_aov)
条件間・グループ間の平均値の差と条件内・グループ内のデータのばらつきを比較する
次に、条件間・グループ間の平均値の差をグループ内のデータのばらつきを比較するすることを具体的な数値計算とともに考えてみましょう。
仮想のデータセットをつくる
ここでは、本来全く差がない3つのグループを考えます。R言語のrnorm関数では、任意の平均値と分散のデータをランダムに作成できるので、これを利用しましょう。
dat <- data.frame(dv = c(rnorm(5),rnorm(5),rnorm(5)),iv = c("red", "red", "red", "red", "red", "orange", "orange", "orange", "orange", "orange", "blue", "blue", "blue", "blue", "blue"))
このデータにはred,orange,blueの3つのグループがあり、それぞれ平均0、分散1の分布から5つのデータがサンプルとして取られています*2。
条件間・グループ間の平均値のばらつきの分布
条件間・グループ間の平均値が、全体の平均に比べてどの程度ばらつくのかは、平方和という値で考えます。各データが、グループの平均値に一致しているとみなして、それが全体の平均からのズレを計算し、二乗します。それを足し合わせたものが平方和です。二乗は平方とも呼ばれるので、二乗したものの合計という意味で平方和という言い方をしています。
R言語を利用するなら例えば以下のように計算できます。
mean_dat <- mean(dat$dv)
mean_red <- mean(dat[dat[,"iv"]== "red","dv"])
mean_orange <- mean(dat[dat[,"iv"]== "orange","dv"])
mean_blue <- mean(dat[dat[,"iv"]== "blue","dv"])
MSS_group <- ((mean_red - mean_dat)^2*length(dat[dat[,"iv"]== "red","dv"]) + (mean_orange - mean_dat)^2*length(dat[dat[,"iv"]== "orange","dv"]) + (mean_blue - mean_dat)^2*length(dat[dat[,"iv"]== "blue","dv"]))
これを何度も繰り返すと、以下のように平方和の分布を求めることができます。
getSS_between <- function(){
dat <- data.frame(dv = c(rnorm(5),rnorm(5),rnorm(5)),iv = c("red", "red", "red", "red", "red", "orange", "orange", "orange", "orange", "orange", "blue", "blue", "blue", "blue", "blue"))
mean_dat <- mean(dat$dv)
mean_red <- mean(dat[dat[,"iv"]== "red","dv"])
mean_orange <- mean(dat[dat[,"iv"]== "orange","dv"])
mean_blue <- mean(dat[dat[,"iv"]== "blue","dv"])
SS_between <- ((mean_red - mean_dat)^2*length(dat[dat[,"iv"]== "red","dv"]) + (mean_orange - mean_dat)^2*length(dat[dat[,"iv"]== "orange","dv"]) + (mean_blue - mean_dat)^2*length(dat[dat[,"iv"]== "blue","dv"]))
return(MSS_group)
}
res <- replicate(100000,getSS_between())
実際にやってみたところ、このような分布ができました。

理論的には、自由度2のカイ二乗分布となります。
条件内・グループ内のデータのばらつき
では、次に、条件内・グループ内のデータのばらつきを考えてみましょう。先ほどのグループ間の計算と同じように、平均値からのズレを二乗したものを合計して平方和を求めます。
getSS_within <- function(){
dat <- data.frame(dv = c(rnorm(5),rnorm(5),rnorm(5)),iv = c("red", "red", "red", "red", "red", "orange", "orange", "orange", "orange", "orange", "blue", "blue", "blue", "blue", "blue"))
mean_red <- mean(dat[dat[,"iv"]== "red","dv"])
mean_orange <- mean(dat[dat[,"iv"]== "orange","dv"])
mean_blue <- mean(dat[dat[,"iv"]== "blue","dv"])
SS_within <- sum((dat[dat[,"iv"] == "red","dv"] - mean_red)^2) + sum((dat[dat[,"iv"] == "orange","dv"] - mean_orange)^2) + sum((dat[dat[,"iv"] == "blue","dv"] - mean_blue)^2)
return(SS_within)
}
res <- replicate(100000,getSS_within())
実際に100000回繰り返して分布を描き出すと以下のようになります。

これは理論として自由度12(データ数15から3を引いた)のカイ二乗分布に一致しました。
F分布
F分布は、2つの平方和のそれぞれを自由度で割った値(平均平方和)の比で求めます。分布の形状としては、分子であるグループ間の平均値のばらつきを示す平方和の分布形状に影響を受けやすく、類似します。