【R】シンプソンのパラドックス

Simpson’s ParadoxをRで実践してみます。
ある3次元のデータ(X, Y, Z)があった時に、(X, Y)でデータの相関を見ると強い負の相関があったとしても、Zの情報をいれると、それが実は5つの群に分かれていて、それぞれの群を見ると強い正の相関であることがわかります。

次のコードで疑似的にデータを作成し、3つのプロットでそれを確認します。
最初のプロットではZの情報はなく、X,Yの情報だけでX,Yの相関を見ています。この時、相関係数は-0.73と強い負の相関です。

次のプロットでは、Zの情報を入れて、それぞれの群を色分けします。各郡の相関係数を計算すると、それぞれ0.78, 0.75, 0.75, 0.62, 0.75と強い正の相関であることがわかります。

3番目のプロットでは各郡に名前を付けています。

3つのプロットをgifで出力し、Animated GIF makerにてアニメーションgifを作りました。

library(tidyverse)
library(dslabs)
ds_theme_set()

## simulate data 
N <- 100
Sigma <- matrix(c(1,0.75,0.75, 1), 2, 2)*1.5
means <- list(c(11,3), c(9,5), c(7,7), c(5,9), c(3,11))
dat <- lapply(means, function(mu) 
  MASS::mvrnorm(N, mu, Sigma))
dat<-as.data.frame(Reduce(rbind, dat)) %>%
  mutate(Z = as.character(rep(seq_along(means), each = N)))
names(dat) <- c("X", "Y", "Z")

## First plot
dat %>% ggplot(aes(X,Y)) + geom_point(alpha = .5) +
  ggtitle(paste("correlation = ", round(cor(dat$X, dat$Y), 2))) 

## second plot
means <- as.data.frame(Reduce(rbind, means)) %>% setNames(c("x","y")) %>%
  mutate(z = as.character(seq_along(means)))

corrs <- dat %>% group_by(Z) %>% summarize(cor = cor(X,Y)) %>% .$cor 

p <- dat %>% ggplot(aes(X, Y, color = Z)) + 
  geom_point(show.legend = FALSE, alpha = 0.5) +
  ggtitle(paste("correlations =",  paste(signif(corrs,2), collapse=" ")))
p

## third plot
p + annotate("text", x = means$x, y = means$y, 
             label = paste("Z=", means$z), cex = 5)  

Code for my educational gifsのページを参考にさせていただきました。

Add a Comment

メールアドレスが公開されることはありません。