Mrodeの本(Linear models for the prediction of animal breeding values)の輪読をしていて、
3章のBLUPにでてくる V
\[ V = ZGZ^\top + R \]
がBLUPの予測に実際どう効くのかという疑問があったのでシミュレーションで確認してみた。
まず、誤差と(遺伝)効果の分散共分散を次で定義する:
\[ \mathrm{Var}(e) = I\sigma_e^2 = R \]
\[ \mathrm{Var}(a) = A\sigma_a^2 = G \]
ここで \(A\) は(例:血縁行列 / GRM などの)既知の関係行列を表す。
LMM (Linear Mixed Model) は、
線形回帰に「相関構造(ランダム効果)」を明示的に組み込んだモデルである。
モデルは次で定義される:
\[ y = Xb + Za + e \]
\[ a \sim N(0, G), \qquad e \sim N(0, R), \qquad a \perp e \]
ランダム効果 \(a\) を積分消去すると,
\[ y \sim N(Xb,\ V) \]
\[ V = ZGZ^\top + R \]
となる。
\[ y = Xb + \tilde e \]
where
\[ \tilde e \sim N(0,\ V) \]
\[ \hat b = (X^\top V^{-1} X)^{-1} X^\top V^{-1} y \]
\[ \hat a = G Z^\top V^{-1}(y - X\hat b) \]
LMM では:
が同時に得られる。
\[ \hat a = \underbrace{G Z^\top}_{\text{構造}} \;\underbrace{V^{-1}}_{\text{重み調整}} \;\underbrace{(y - X\hat b)}_{\text{固定効果で説明できない残差}} \]
\(V^{-1}\) の役割は:
このセクションでは,LMM における BLUP
\[ \hat a = GZ^\top V^{-1} r \qquad (r := y - X\hat\beta) \]
が,観測間共分散 \(V\) の仮定によってどのように変化するかを,最小例(\(n=4\))で確認する。
ここでは 残差(固定効果で説明できない成分)を一定にするため,
\[ r = y - X\hat\beta = (1,1,1,1)^\top \]
と固定する。
この \(r\)
は「全個体が同じ方向(平均方向)にずれている」状況を表し,
\(V\) に強い相関がある場合に \(V^{-1}\)
がどの程度その方向を抑制するかが分かりやすい。
また,ランダム効果の割当は
\[ Z = I \]
とし,遺伝構造(関係行列)も
\[ A=I \]
とする(すなわち個体間の遺伝相関は無い,独立な遺伝効果)。
本例では分散成分を
\[ \mathrm{Var}(a) = G = \sigma_a^2 I,\qquad \mathrm{Var}(e) = R = \sigma_e^2 I \]
とし,遺伝率を
\[ h^2 = \frac{\sigma_a^2}{\sigma_a^2+\sigma_e^2} = 0.7 \]
に固定する。 ベースラインの \(V\) はスカラー倍の単位行列に一致する:
\[ V = ZGZ^\top + R = 0.7I + 0.3I = I \]
本コードでは,次の 3 パターンの \(V\) を用意し,それぞれの
\[ \hat a = GZ^\top V^{-1}r \]
を比較する。
\[ V_1 = ZGZ^\top + R = I \] この場合 \(V_1^{-1} = I\) であり,
\[ \hat a = G r = 0.7\,r \]
となる。
Case A の \(V\) をベースに,(1,4) と (4,1) のみ共分散を付加する:
\[ (V_2)_{14} = (V_2)_{41} = \rho\quad (\rho=0.7) \]
ここでは,観測 1 と 4
が「冗長な情報」を共有していると仮定したことになる。
その結果,\(V_2^{-1}\) は 1 と 4
の方向の情報を独立とみなして過大評価せず,
\(\hat a\) の推定値も Case A
から変化する。
\[ (V_3)_{ii}=1,\qquad (V_3)_{ij}=0.95\ (i\neq j) \]
これは「全観測がほぼ同じ誤差(共通成分)を共有している」極端な状況であり,
\(V_3\) は 1
方向(平均方向)に大きな分散を持つ一方で,
それ以外の方向の分散は小さくなる(ほぼランク 1 に近い)。
本例では\(V_3^{-1}\) によってその方向が強く抑制され,\(\hat a\) は Case A よりも大きく縮小されることが期待される。
# -------------------------
# Setup (n = 4)
# -------------------------
n <- 4
Z <- diag(n)
r<-c(1,1,1,1)
sigma_a2 <- 0.7
sigma_e2 <- 0.3 # <- もし Sigma=I にしたいなら 1-sigma_a2
G <- sigma_a2 * diag(n) # Var(a)
R <- sigma_e2 * diag(n) # Var(e)
# -------------------------
# Case A: Sigma = I
# -------------------------
Sigma1 <- Z %*% G %*% t(Z) + R
Sinv1 <- solve(Sigma1)
a_hat1 <- as.vector(G %*% t(Z) %*% Sinv1 %*% r)
# -------------------------
# Case B: Sigma = I + off-diagonal correlation (1,4)
# -------------------------
rho <- 0.7
Sigma2 <- Z %*% G %*% t(Z) + R
Sigma2[1,4] <- rho
Sigma2[4,1] <- rho
Sinv2 <- solve(Sigma2)
a_hat2 <- as.vector(G %*% t(Z) %*% Sinv2 %*% r)
# -------------------------
# Case C: diag = 1, offdiag = 0.99 (almost fully correlated)
# -------------------------
rho_all <- 0.95
Sigma3 <- matrix(rho_all, n, n)
diag(Sigma3) <- 1
Sinv3 <- solve(Sigma3)
a_hat3 <- as.vector(G %*% t(Z) %*% Sinv3 %*% r)
# -------------------------
# Data for plotting
# -------------------------
df <- data.frame(
sample = factor(1:4),
r = r,
a_I = a_hat1,
a_corr = a_hat2,
a_all = a_hat3
)
# y-limits (3 panels共通) : r と a_hat の範囲を全部含める
ylim_all <- range(c(df$r, df$a_I, df$a_corr, df$a_all))
# -------------------------
# Helper: simple heatmap (base)
# -------------------------
plot_heat <- function(M, title = ""){
image(
x = 1:nrow(M), y = 1:ncol(M), z = t(M)[, nrow(M):1],
axes = FALSE, xlab = "", ylab = "", main = title
)
axis(1, at = 1:nrow(M), labels = 1:nrow(M))
axis(2, at = 1:ncol(M), labels = rev(1:ncol(M)))
box()
# values overlay (見やすいので数値も表示)
for(i in 1:nrow(M)){
for(j in 1:ncol(M)){
text(i, nrow(M)-j+1, labels = sprintf("%.2f", M[i,j]), cex = 0.9)
}
}
}
# -------------------------
# Plot: 1st row = barplots (a_hat)
# 2nd row = heatmaps (Sigma)
# -------------------------
par(mfrow = c(2, 3), mar = c(4,4,3,1))
# Panel 1: Sigma = I
barplot(
height = df$a_I,
names.arg = df$sample,
col = "grey70",
ylim = c(0,1),
main = expression(Sigma == I),
ylab = expression(hat(a))
)
abline(h = 0)
abline(h = sigma_a2, lty = "dashed")
# Panel 2: Sigma with (1,4) correlation
barplot(
height = df$a_corr,
names.arg = df$sample,
col = "steelblue",
ylim = c(0,1),
main = expression(~Sigma~"(1,4 corr)"),
ylab = expression(hat(a))
)
abline(h = 0)
abline(h = sigma_a2, lty = "dashed")
# Panel 3: Sigma with offdiag 0.99
barplot(
height = df$a_all,
names.arg = df$sample,
col = "tomato",
ylim = c(0,1),
main = expression(Sigma~"diag=1, offdiag=0.99"),
ylab = expression(hat(a))
)
abline(h = 0)
abline(h = sigma_a2, lty = "dashed")
# -------------------------
# 共通カラースケールを計算
# -------------------------
zlim_all <- range(c(Sigma1, Sigma2, Sigma3))
# -------------------------
# 共通カラースケール
# -------------------------
zlim_all <- range(c(Sigma1, Sigma2, Sigma3))
# -------------------------
# Helper: heatmap (white -> black)
# -------------------------
plot_heat <- function(M, title = "", zlim){
image(
x = 1:nrow(M),
y = 1:ncol(M),
z = t(M)[, nrow(M):1],
axes = FALSE,
xlab = "",
ylab = "",
main = title,
zlim = zlim,
col = gray.colors(100, start = 1, end = 0) # white -> black
)
axis(1, at = 1:nrow(M), labels = 1:nrow(M))
axis(2, at = 1:ncol(M), labels = rev(1:ncol(M)))
box()
# 数値を重ねる
for(i in 1:nrow(M)){
for(j in 1:ncol(M)){
text(i, nrow(M)-j+1,
labels = sprintf("%.2f", M[i,j]),
cex = 0.9,
col = ifelse(M[i,j] > mean(zlim), "white", "black"))
}
}
}
# -------------------------
# Heatmaps (same scale, white -> black)
# -------------------------
plot_heat(Sigma1, title = expression("Heatmap of V: "~Sigma==I), zlim = zlim_all)
plot_heat(Sigma2, title = expression("Heatmap of V: "~Sigma~"(1,4 corr)"), zlim = zlim_all)
plot_heat(Sigma3, title = expression("Heatmap of V: "~Sigma~"(offdiag=0.99)"), zlim = zlim_all)
この 4 サンプル例では,\(r\) を固定した上で,
つまり,\(V^{-1}\) は単なる逆行列ではなく,残差から「独立で信頼できる成分」を抽出するフィルタ(白色化・重み付け)として働き,BLUP の縮小量を決める。
Mrode, R. (2014). Linear models for the prediction of animal breeding values. https://www.cabidigitallibrary.org/doi/book/10.1079/9780851990002.0000