統計コンサルの議事メモ

統計や機械学習の話題を中心に、思うがままに

Anscombeの例

二変数間の関連性の強さを評価する上で最も良く使われる指標は、間違いなくPearsonの積率相関係数、いわゆる相関だと思う。Excelでも関数により算出でき、関連の強さを-1〜1で評価できるというお手軽さが受け入れられやすいのだと思う。

さて、この相関は直線的な関係性しか評価できないため、必ず散布図とセットで見なくてはならない。表題の「Anscombeの例」とは、統計量が同じであってもデータセットが示す内容は大きく異なることがあるということを明確に教えてくれる良い教材である。実際に見てみよう。

## Load libraries
library(tidyverse)
library(broom)
library(forcats)
library(ggplot2)

まずはRに標準で格納されているデータセットanscombeを使う。

> anscombe
   x1 x2 x3 x4    y1   y2    y3    y4
1  10 10 10  8  8.04 9.14  7.46  6.58
2   8  8  8  8  6.95 8.14  6.77  5.76
3  13 13 13  8  7.58 8.74 12.74  7.71
4   9  9  9  8  8.81 8.77  7.11  8.84
5  11 11 11  8  8.33 9.26  7.81  8.47
6  14 14 14  8  9.96 8.10  8.84  7.04
7   6  6  6  8  7.24 6.13  6.08  5.25
8   4  4  4 19  4.26 3.10  5.39 12.50
9  12 12 12  8 10.84 9.13  8.15  5.56
10  7  7  7  8  4.82 7.26  6.42  7.91
11  5  5  5  8  5.68 4.74  5.73  6.89

anscombeにはこのように、4つのデータセットそれぞれがxとyを持つ。
このままだと少し使いにくいので整形する。

## Anscombe
dataAns <- select(anscombe, "x" = x1, "y" = y1) %>% 
   bind_rows(select(anscombe, "x" = x2, "y" = y2)) %>% 
   bind_rows(select(anscombe, "x" = x3, "y" = y3)) %>% 
   bind_rows(select(anscombe, "x" = x4, "y" = y4)) %>% 
   mutate("dataset" = c(rep("I", nrow(anscombe)), rep("II", nrow(anscombe)),
                        rep("III", nrow(anscombe)), rep("IV", nrow(anscombe))))

出来上がったデータに対して平均と標準偏差を求める。

dataAns %>% 
   group_by(dataset) %>% 
   summarise_each(funs(mean, sd), vars = c(x, y))

# A tibble: 4 × 5
  dataset vars1_mean vars2_mean vars1_sd vars2_sd
    <chr>      <dbl>      <dbl>    <dbl>    <dbl>
1       I          9   7.500909 3.316625 2.031568
2      II          9   7.500909 3.316625 2.031657
3     III          9   7.500000 3.316625 2.030424
4      IV          9   7.500909 3.316625 2.030579

平均と標準偏差が小数点以下2位まで揃っている。それぞれのデータセットについて相関を求めてみると:

dataAns %>% 
   group_by(dataset) %>% 
   summarise("COR" = cor(x, y))

# A tibble: 4 × 2
  dataset       COR
    <chr>     <dbl>
1       I 0.8164205
2      II 0.8162365
3     III 0.8162867
4      IV 0.8165214

これもほぼ同じ値となる。平均、標準偏差、相関が等しいデータセットなのでxとyも同じような値と取っているのだろうと思うのだが、プロットしてみると:

ggplot(dataAns, aes(x = x, y = y, label = dataset)) +
   facet_wrap(~ dataset, nrow = 2) +
   geom_point() +
   geom_smooth(method = "lm", formula = y ~ x, se = FALSE)


f:id:ushi-goroshi:20170708002403p:plain

このように曲線を描くものや外れ値に影響を受けているものがあることがわかる。
なお相関が同じなので当然と言えば当然だが、回帰係数も同じような値となる:

dataAns %>% 
   split(.$dataset) %>% 
   map(., ~ lm(y ~ x, data = .) %>% tidy()) %>% 
   bind_rows()

         term  estimate std.error statistic     p.value
1 (Intercept) 3.0000909 1.1247468  2.667348 0.025734051
2           x 0.5000909 0.1179055  4.241455 0.002169629
3 (Intercept) 3.0009091 1.1253024  2.666758 0.025758941
4           x 0.5000000 0.1179637  4.238590 0.002178816
5 (Intercept) 3.0024545 1.1244812  2.670080 0.025619109
6           x 0.4997273 0.1178777  4.239372 0.002176305
7 (Intercept) 3.0017273 1.1239211  2.670763 0.025590425
8           x 0.4999091 0.1178189  4.243028 0.002164602


このanscombeと同様に、統計量が同程度で全く内容が異なるデータセットとしてdatasaurusというものがある。これを用いて同様に見てみよう。

## Datasaurus
datasaurus <- read_table2("../Data/DatasaurusDozen.tsv",
                          col_names = TRUE, col_types = "cnn") %>%
   mutate(dataset = as_factor(dataset))
> print(datasaurus)
# A tibble: 1,846 × 3
   dataset       x       y
    <fctr>   <dbl>   <dbl>
1     dino 55.3846 97.1795
2     dino 51.5385 96.0256
3     dino 46.1538 94.4872
4     dino 42.8205 91.4103
5     dino 40.7692 88.3333
6     dino 38.7179 84.8718
7     dino 35.6410 79.8718
8     dino 33.0769 77.5641
9     dino 28.9744 74.4872
10    dino 26.1538 71.4103
# ... with 1,836 more rows

このデータをプロットしてみるとどうか。

ggplot(datasaurus, aes(x = x, y = y)) +
   facet_wrap(~ dataset, nrow = 3) +
   geom_point()

f:id:ushi-goroshi:20170708002923p:plain

なんと、全く違う!
これらの全てが本当に同様の統計量を持っているのだろうか?

datasaurus %>% 
   group_by(dataset) %>% 
   summarise_each(funs(mean, sd), vars = c(x, y))
# A tibble: 13 × 5
      dataset vars1_mean vars2_mean vars1_sd vars2_sd
       <fctr>      <dbl>      <dbl>    <dbl>    <dbl>
1        dino   54.26327   47.83225 16.76514 26.93540
2        away   54.26610   47.83472 16.76982 26.93974
3     h_lines   54.26144   47.83025 16.76590 26.93988
4     v_lines   54.26993   47.83699 16.76996 26.93768
5     x_shape   54.26015   47.83972 16.76996 26.93000
6        star   54.26734   47.83955 16.76896 26.93027
7  high_lines   54.26881   47.83545 16.76670 26.94000
8        dots   54.26030   47.83983 16.76774 26.93019
9      circle   54.26732   47.83772 16.76001 26.93004
10   bullseye   54.26873   47.83082 16.76924 26.93573
11   slant_up   54.26588   47.83150 16.76885 26.93861
12 slant_down   54.26785   47.83590 16.76676 26.93610
13 wide_lines   54.26692   47.83160 16.77000 26.93790

anscombe同様に、平均と分散が小数点以下2位まで同じとなっている。

このように、データから得られる統計量が同一であっても内容が同じ傾向を示すとは限らない。そのため統計量を求める場合には必ずデータをプロットすることが重要である。平均や分散ならヒストグラムを、相関なら散布図を描くことでデータの分布について大まかに把握することができるだろう。

データの可視化というものは特に分析の後半に入ってくると忘れられがちであるが、データの特性を教えてくれる重要な手法である。分析を実施する時にはまず可視化を行うことを大切にしよう。