6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python/Matplotlibで両側95%信頼区間を図に加える

Last updated at Posted at 2017-04-05

基本の作図

例えばこんな感じのデータフレームがあったとする.

    x         y
0   2  0.954025
1   3  0.146810
2   1  0.409961
3   1  0.164558
4   3  0.782152
5   2  0.905869
6   3  0.210528
7   1  0.437970
8   1  0.801206
9   3  0.089576
10  2  0.960357
11  2  0.670732

このデータフレームから標準誤差付きの図を描こうとすると,こんな感じ.

import numpy as np
import matplotlib.pyplot as plt
 
m = df.pivot_table(index='x', values='y', aggfunc='mean')
e = df.pivot_table(index='x', values='y', aggfunc='sem')
m.plot(xlim=[0.8, 3.2], yerr=e)

20161010_1.png

このように,yerrに誤差の大きさを指定することで,誤差棒を作成することができる.

信頼区間を用いた作図

そこで,信頼区間の長さを求めるcilenを定義して利用することにする.

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt


def cilen(arr, alpha=0.95):
    if len(arr) <= 1:
        return 0
    m, e, df = np.mean(arr), stats.sem(arr), len(arr) - 1
    interval = stats.t.interval(alpha, df, loc=m, scale=e)
    cilen = np.max(interval) - np.mean(interval)
    return cilen

m = df.pivot_table(index='x', values='y', aggfunc='mean')
e = df.pivot_table(index='x', values='y', aggfunc=cilen)
m.plot(xlim=[0.8, 3.2], yerr=e)

20161010_2.png

信頼区間付きの図を作成することができた.

おまけ

信頼区間を計算する方法は「nかn-1か」問題のせいでごちゃごちゃしてます.

「車輪の再発明は避けよ」に従って,とりあえず「信頼区間 Python」とかで検索した人は,

  1. Pythonで正規分布の平均値の信頼区間を計算する方法
  2. keiskS @technote – pythonで信頼区間

あたりを見て,微妙に違うことに困惑しつつも両方試してみて,そして結果が違うことに辟易することになると思います (なりました).

Rと同じ答えになるのは1の方.違うのは2の方です.ちょっと試してみます.

> x <- c(1, 1, 3, 3)
> t.test(x)

    One Sample t-test

data:  x
t = 3.4641, df = 3, p-value = 0.04052
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 0.1626138 3.8373862
sample estimates:
mean of x
        2

1の方法

import numpy as np
from scipy import stats

alpha     = 0.95
data = [1, 1, 3, 3]

mean_val = np.mean(data)
sem_val  = stats.sem(data)  # standared error of the mean
ci       = stats.t.interval(alpha, len(data)-1, loc=mean_val, scale=sem_val)

print(ci)

>> (0.16261376896260105, 3.837386231037399)

2の方法

import math
import numpy as np
from scipy import stats

alpha     = 0.95
data = [1, 1, 3, 3]

mean_val = np.mean(data)
std_val = np.std(data)
ci = stats.t.interval(alpha,len(data)-1,loc=mean_val,scale=std_val/math.sqrt(len(data)))
print(ci)

>> (0.40877684735786857, 3.5912231526421312)

今回は天下のRに従うことにしたので1を採用しています.

なお,2は何が違うのかというと,ciを計算する箇所の最後の方

math.sqrt(len(data))

これです.nで割ってます.しかし推測統計を行うのであればn-1で割った方が良いです.t分布を仮定するからですね.実際,

math.sqrt(len(data) - 1)

とすると,方法2の答えもRと完全に一致します.

6
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?