乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

統計

先日、大きな選挙が有りましたね。
何故にすぐ当確が出るのでしょう?

その仕組みを解説してみました。
解説動画はこちら




なぜ開票率1%で当確が出るのか?
今回は選挙のお話です。

各局がどのような仕組みで
当確を出しているかは不明ですが

少なくとも投票所の出口調査や
事前アンケートなどの結果などを用いて
統計的なサンプリング調査を元に
最終的な判断をしていると思います。


当確が分かる仕組み
無作為な1%分の投票結果が分かれば
票全体の動向が推計できます。

これはお味噌汁の味見に似ていますね。

ちゃんと掻き回したものを
お玉に一掬い程度味見すれば
味噌汁全体の味はおおよその検討はつくでしょう。

ここで用いられるのが
母比率の信頼区間です。


区間推定「母比率」の信頼区間の求め方

母比率の信頼区間を求める式
スクリーンショット 2021-11-06 16.55.09

なんだかややこしいと思いますが
R:標本比率(得票率)
z:標準化変数(Z-score)
n:標本数(サンプル)
となっています。

また信頼係数というモノがあります。

これは母集団から標本を取って
その平均からXX%信頼区間を
求めるという作業を100回やったとき
XX回はその区間の中に母平均が含まれる
というものです。

通常は95%を用いることが多いですが

信頼係数におけるzの値は
90%で1.64
95%で1.96
99%で2.58
という値になります。


さて、ここで問題を考えてみましょう。

有効投票数10万票の選挙で開票率1%(1000票)時点の
A候補者の得票率は60%でした。

このとき信頼係数95%で
母比率の信頼区間を計算してみよう。

Pythonを使って計算してみました。
#標本比率:
R=0.6
# 標準化変数
z=1.96
# 標本数
n=1000

lower = (R - z*((R*(1-R))/n)**0.5)*100
upper = (R + z*((R*(1-R))/n)**0.5)*100
print('{0:.3f} - {1:.3f}'.format(lower,upper))
56.964 - 63.036

これによると母比率の信頼区間は
最低でも56.9%、最高で63%


他に候補者がどれだけいても
過半数以上を獲得できる見込みになります。

計算式上ではサンプリングした標本数の数で
信頼区間の幅は大きく変わります。

10万票ほどの選挙区ではおよそ1%
1000票もあれば誤差は3%程度で
最終結果を導くことができます。

標本数を増やせば、区間はグッと縮まります。
開票率が上がっていけば
どんどん精度は上がりますね。

候補者同士の結果に差のない場合は
開票率100%に近付かないと
結果が出ないこともありますが

元々大差がついている選挙区では
開票率が低くても当確が出るようですね。

さてここからは
選挙区のシミュレーションをしてみましょう。

神奈川11区でシミュレーション

元セクシー担当大臣のいる選挙区の結果を用いて
シミュレーションしてみましょう。

結果は
小泉 進次郎氏 14万7634票
林 伸明氏 3万8843票
となっていました。

データ化してみます。
# 小泉票
k = ['K']*147634
# 林票
h = ['H']*38843
# 全体の票
v = k+h

print(len(v))
print(v.count('K'))
print(v.count('H'))
186477
147634
38843

これで票のデータを用意できました。
ランダムサンプリングして結果を見てみましょう。
1%でランダムサンプリング
import random

n = len(v)//100
d = random.sample(v , n)

print(len(d))
print(d.count('K'))
print(d.count('H'))
1864
1469
395

1%時の票数は1864
小泉氏は1469票獲得
林氏は395票獲得で
小泉氏の圧勝・・・・・・

一回やっただけでは分からないですよね・・・

頑張って100回対決してみましょう。
import random
import pandas as pd

n = len(v)//100
df = pd.DataFrame(columns=['小泉票','林票'])
for i in range(100):
    d = random.sample(v , n)
    k_count = d.count('K')
    h_count = d.count('H')
    tmp = pd.DataFrame([[k_count,h_count]],columns=['小泉票','林票'])
    df = df.append(tmp)

df = df.astype('int')
df.describe()
小泉票林票
count100.000000100.000000
mean1473.930000390.070000
std18.06176618.061766
min1427.000000351.000000
25%1462.000000376.000000
50%1475.000000389.000000
75%1488.000000402.000000
max1513.000000437.000000

結果から言えば
林氏はどんなに頑張っても
437票しかとれず小泉氏が圧勝です。

箱髭図にして差し上げました。
スクリーンショット 2021-11-06 17.26.44

1%の時点でこれなんで
まあ、諦めろって事ですwwwwwww

政策や人柄、人気などで
相手を上回るしかないでしょうね
まあほぼ無理ゲーでしょうけど。


まとめ
1000票ほどを集めれば
おおよその結果が予想できてしまう

得票率1%の時点で
大きく差がついていたら諦めろ

ただしデータに偏りが無いことが大前提!

あくまでもこの推定はデータに偏りがない所で
サンプリングされたデータを用いての推定です。

恣意的に歪められた結果を用いれば
作為的に誘導することも出来てしまいます。

使う側も見る側も
注意が必要なポイントです。


今回は選挙にまつわる
統計のお話でした。

それでは。

今日はいろんな平均についてのお話です。

多分超簡単です。

解説動画はこちら




さて平均と一言で言っても
実はたくさんの種類があり
計算方法も違っています。

ちなみに英語だと
meanとaverageの
二通りの訳し方がありますが

meanは統計学上の平均値をあらわし
averageはそれに加えて
「普通・標準的・平凡」などの意味合いが
含まれる言葉だそうです。

英語で平均値であればmean
一般的な平均的なお店のような場合は
average shop などと訳す感じですかね。


世間一般での平均は
算術平均の事かと思います。

算術平均
算術平均、または相加平均とも言っていて
英語はarithmetic meanです。

算術平均の計算方法としては
集合の総和を集合の要素数で割ったもの

ですね。
例として

55kg , 60kg , 80kgの人の平均体重

を求めるとすると
(55+60+80) / 3 = 65
と言うことになります。

Pythonであれば
numpyライブラリを用いて
以下のように求めることができます。
import numpy as np
data = [55,60,80]
np.mean(data)
65




続いて相乗平均(幾何平均)です。

相乗平均
英語だとgeometric mean

集合の総積の累乗根で
求めることができます。

次のような例があったとします。

ある売り上げが2018年度は10%増加
2019年度は5%増加
2020年度は3%増加したとする。

2018-2020年度にかけて
平均で毎年どれくらい
売上が伸びたと言えるだろうか?

出てきた数値を全てかけて
その個数乗根をとると計算できます。

1.1x1.05x1.03の3乗根

pythonだと次のように
求められます。
from scipy.stats.mstats import gmean
data = [1.1,1.05,1.03]
gmean(data)
1.0595945




調和平均

英語だとharmonic mean
逆数の算術平均の逆数で
計算することができます。

例えば
1kmの道を行きは時速 2 km 
帰りは時速 3 kmで往復したときの平均の速さ

と言う問題の場合
要素の逆数は1/2 , 1/3
これを足し合わせたものの
逆をとる形になります。

2/(1/2+1/3) = 2.4

pythonだとこうなります。
from scipy.stats import hmean
data = [2,3]
hmean(data)
2.4

上記3つの平均は
次のような大小関係になっているようです。

算術(相加)平均 > 相乗(幾何)平均 > 調和平均


加重平均

英語だとweighted arithmetic mean

単に相加平均をとるのでなく
重みを考慮した平均の取り方です。

例として

ある学校のクラスに男子が3人
女子が2人いてテストを行いました。

男子の平均点は60点
女子の平均点は90点です。

クラス全体の平均点は何点でしょうか。

要素x重みの合計を
要素の合計で割ります。

(60*3 + 90*2) / (3+2) = 72

Pythonだとnumpyのaverageメソッドの
weightsの値を加えることで算出できます。
import numpy as np
data , w = [60,90],[3,2]
np.average(data, weights=w)
72


最後に移動平均です。

単純移動平均(SMA)
英語だとSimple Moving Average
直近n個のデータの算術平均の値
時系列データなどでよく用いられる

n日移動平均(SMAn)

当日から遡ったn日分のデータの
算術平均の値です。

次のコードを実行すると
移動平均の値を計算することができます。

url = 'http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=44&block_no=47662&year=2020&month=12&day=&view='''
value = pd.read_html(url)[0].iloc[0:,6:7].values
data = [float(d) for d in value]
df = pd.DataFrame(data,columns=['気温'])
df['3日移動平均'] = df['気温'].rolling(3).mean()
df['5日移動平均'] = df['気温'].rolling(5).mean()
df['7日移動平均'] = df['気温'].rolling(7).mean()
df.plot()
plt.show()

download

pandasライブラリのrollingメソッドで
区間を指定し、その平均をmeanメソッドで
算出することができます。

長い区間をとると、より滑らかな
値になるのが見て分かるのでは無いでしょうか。


今回は
平均についてお伝えしました。

統計学ではまず最初に習うのが
この平均の事かと思いますので
また、統計用語について
やっていきたいと思います。

それでは

今回はとあるデータを拾ってきて
Tableauで可視化しました。

非常に興味深いデータです。

解説動画はこちら



データに関してはかなり雑な調べです。
今日現在(2020/09/05)までで
生年月日のデータが取得できた方が対象です。

全体像はこんな感じです。
4823人分のデータが取れました。

スクリーンショット 2020-09-05 17.22.33


雑に可視化しているだけなので
そこまで凝ったことはしていません。

まずは生年で見ていきましょう。
スクリーンショット 2020-09-05 17.06.46

下は2001年生まれ!!!!!
現在2020年だと18,19歳がいるかもしれません。

もっとも上は1923年!!!
おん年97では?!?!!?!

まあ、データなので間違っているかもしれないし
生きているかは不明です。調べる気もありません。

これでみるとボリュームゾーンは1984年
今年36あたりで18デビューなら
2002年あたりがデビュー年ですね。

人数はそこからやや減少傾向になり
1994年が少し増えてますね。
ここら辺はリーマンショックの後なので
影響が有ったかもしれません。

出身です。
スクリーンショット 2020-09-05 17.07.01
出身は東京都が多く
次いで神奈川、千葉、埼玉ですね。

単純に首都圏でのスカウトが多いからでしょうね。
この4都県で7割、地方の方は少数派ですね。


次に身長です。
スクリーンショット 2020-09-05 17.07.14

身長のデータは面白い傾向が出ています。

この手のデータを無作為に集めると
通常は平均値付近が最大となる
「正規分布」という分布になります。

ですがxx9cmの所とxx0cmの所では
2倍位違っているところがあります。

恐らくですが、プロフィールに
159cmと書くよりは160cmと書きたかった
のではないかな?と思われます。

149,159,169でこの傾向が大きく出ていますね。
ということで身長はサバ読んでるかも
しれないデータが混じっているだろうと思います。

その傾向はバストでも有るかもしれません。
スクリーンショット 2020-09-05 17.07.28
こちらはバストのデータ分布ですが
こちらも79,89よりも80,90が圧倒的に多いんです。

大は小を兼ねると申しますが
小さいよりは、大きい方が嬉しいですもんね!!!
鯖読みの傾向がここにも出ているかと思われます。

スクリーンショット 2020-09-05 17.07.41

血液型の分布は日本の血液型統計と
あまり変わりないんじゃないでしょうか?

日本人におけるABO式血液型の割合は
おおよそA型40%,O型30%,B型20%,AB型10%
といわれています。

少しだけO型が多いかな、というくらいですね。

そして皆様お待ちかね
カップサイズです

カップサイズはこのような分布になりました。

スクリーンショット 2020-09-05 17.07.55

4823人のデータから見ると
Dが一番多いです!!!!!!!!

次いでC,E,F,G
BよりもGが多いのが驚きです。

Aになると0.76%なので、ほぼ外れ値ですね。

このデータで行くと最大は
Pカップです!!!!

もうね、ここまでくると
手に負えないですよね。

やはり、手に負えないよりは
ギリギリ手に負えるGあたりが
自分は好きです。

ちなみにGは10%ほどおりますので
10人に一人くらいはG
という嬉しい結果となりました。

C,D,Eで6割に達しますので
日本人の大半はCDE

それよりも少し大きいのが2割
小さすぎは1割弱
大きすぎも1割ないくらいですね。

Tableauで割合をいろいろ変えて
試していますので
そちらも見ていただければと思います。

今回はこれまで
それでは!!!

このページのトップヘ