広告/統計/アニメ/映画 等に関するブログ

広告/統計/アニメ/映画 等に関するブログ

アンケートや視聴率の誤差を推測するプログラム(1)-標本誤差の計算まで-

アンケート調査や視聴率の数字を見せた時に、 「これはn数が少ないから信憑性が薄いねぇ」 と言われることがあると思います。しかし実際のところ、 ”では、今のn数だとどれくらいの幅で理解すべきなのですか?” という質問に応えてくれる人は少ないでしょう。というのも意外とその場で計算するのは容易ではないからです。

今回は、サンプルサイズから標本誤差を推定するスタンドアローンな実行ファイルを作るまで、3回に分けてブログにします。

標本誤差について

どんな統計の本にもあるような基礎的な話ですが、国勢調査などを除いて、殆どの調査は全数調査はしません。

サンプルを集めて、該当質問の平均値を取り、それを結果の値とします。

更に、以下にランダムにサンプルが集められていたとしても偏りが発生していないという絶対的な保証はありません。そのような時、 少なくとも平均値については、サンプル数が多ければ大数の法則がなりたつ ということを使って、 同じような調査を何度も何度もやったらそのうち95%は平均的に○○~○○の値に収まるであろう という何とも消極的なことしか分からないのです。

標本誤差とは?

どういう計算をするのか?はこのサイトが分かりやすいでしょう。

www.stat.go.jp

ビデオリサーチ社の視聴率の場合

標本誤差 | ビデオリサーチ

サンプルサイズから結果の値の標準誤差を知る為のプログラムを作る

  • 普段統計の計算はRを使っていますが、今回は最終的に実行ファイルにしたいのでPythonにします。
  • 現時点では実行ファイルにするにはPython2の方が良いのでPython2を使います

Pythonを使った標本誤差の計算

正しい手法はこのサイトの通り

Python正規分布の平均値の信頼区間を計算する方法 」

document

しかし先程の参照サイトの通り、母数に対してサンプルサイズがすくない場合はt分布ではなく正規分布でも良い、とありましたので、簡略化することにします。

Pythonのscipy statsを使う

使うモジュールは、scipyの中のstatsから、norm.intervalという関数を使って、平均値0、分散1の正規分布の時の95%の有意点の上下を求めます

参考にしたサイト

kaisk.hatenadiary.com

from scipy import stats as st
alpha = 0.95
a,b = st.norm.interval(alpha=alpha, loc=0, scale=1)

すると、以下のような数値が出てきます。ビデオリサーチ社のサイトでも「2」を使っていましたが、妥当な値と言えるでしょう。

(-1.959963984540054, 1.959963984540054)

サンプルサイズやアンケート結果の値を画面から入力する

サンプルサイズをコード本文にベタ打ちすると、毎度毎度コードの修正が必要になってしまうので、コンソールから都度都度入力するようにしましょう

参考にしたサイト

qiita.com

print(u"サンプル数を入力して下さい")
n_samples = float(input('>>>  '))
print (u"パーセンテージを入力して下さい。(5.5パーセントなら、5.5と入力)")
p_ori = float(input('>>>  '))

このような感じで自分で数字を打込み、それが引数となるようになります

f:id:yyhhyy:20170408213409p:plain

誤差の値を計算する

一番最初の参照サイトの簡略化された数式を実行します。配列のためだけにnumpyを使っていますが、計算自体はとてもシンプルです。

import numpy as np
p = p_ori/100.0
gosa = np.array([a,b])*np.sqrt(p * (1 - p) / n_samples)

仮にビデオリサーチ社のサイトのように900サンプルで視聴率10%だったとして入力すると、サイトの通り、プラスマイナス2%位は割り引いて考える必要があります。*1

[-0.01959964  0.01959964]

コード全体

今回のコード全体は以下のようになります

# -*- coding: utf-8 -*-
import numpy as np
from scipy import stats as st
alpha = 0.95
print(u"サンプル数を入力して下さい")
n_samples = float(input('>>>  '))
print (u"パーセンテージを入力して下さい。(5.5パーセントなら、5.5と入力)")
p_ori = float(input('>>>  '))
p = p_ori/100.0
a,b = st.norm.interval(alpha=alpha, loc=0, scale=1)
gosa = np.array([a,b])*np.sqrt(p * (1 - p) / n_samples)
print (u"標本平均の95パーセント信頼区間での値は次の間")
print ( (p + gosa) * 100)
print (u"単位パーセント")

*1:とてもややこしい話ですが、95%の確率で視聴率は8-12%だ!というわけではないのが伝統的な統計学の難しさです。同じような調査を100回やったうち95回は、8-12%の間であろう、というだけで真の値がどこかはわからないのです。