2013/10/21
データいろいろ
 >  Wilson Score Interval で順位付け(3)
1. 今日やったこと
昨日の続き。というか、一部は昨日やったけど書く時間がなかった内容を含む。Wilson Score Interval について追加的に調べたことをメモし、昨日やるはずだった Hacker News のプログラミング言語好き嫌い投票への適用(二時点の集計結果について自作ストアド関数で点数算出)をした。

まず日本語のウェブ情報について。改めて調べたところ、Wilson Score Interval とは呼ばれていないが同内容のものがいくつか見つかった。例えば、

統計学自習ノート(群馬大学社会情報学部 青木繁伸先生): 母比率の信頼区間
http://aoki2.si.gunma-u.ac.jp/lecture/Hiritu/bohiritu-conf.html


母比率の信頼区間を正規分布による近似で求める際の式が、一昨日に海外のウェブサイトで見た Wilson Score Interval の式と同じ。上の例題の答えは下側 0.30948、上側 0.39281 とある。PostgreSQL のストアド関数(詳細は昨日の記事参照)の結果は下のとおり。


また下記の統計学講義では「スコア型」または「スコア法」と呼ばれている。ストアド関数の結果も合わせて示す。全体の数が16、一方の数が12。95%信頼区間の下限 0.505、上限 0.898。

正確法と近似法によるカウントデータの解析法(成蹊大学理工学部 岩崎学先生ほか)
http://www.seikeistat.jp/file/rengou2008.pdf



このように追加で調べたところ、Hacker News が用いたプログラム(詳細は一昨日の記事参照)のように Z 値を片側確率で求めているものはなかったので、ストアド関数も Z 値を両側確率で求めるようにした。

2. Hacker News の投票結果に適用
昨日はこれをメインに書くはずだったのだが…。まず、元となるデータの先頭部分を再掲する。二時点での、プログラミング言語の好き嫌き投票結果。


言語と時点順に Wilson Score Interval を表示する SQL は次のようになる。実行結果の先頭部分も合わせて示す。
WITH a AS (
SELECT 2013 wyear, * FROM "201310"."18_HackerNews_data"
UNION ALL
SELECT 2012, * FROM "201310"."20_HackerNews_data"
), b AS (
SELECT *, "201310"."20_Wilson_Calc"(points_like
, points_dislike, 0.95) p
FROM a
)
SELECT wyear, pname, points_like, points_dislike
, to_char(p[1], 'FM0.000') p_low
, to_char(p[2], 'FM0.000') p
, to_char(p[3], 'FM0.000') p_upp
FROM b
ORDER BY pname, wyear ;



3. Hacker News の修正版
上記 SQL 結果の一部を使って並べ替えるだけだが、Hacker News が間違っていた 2012年時点での Wilson Score Interval(下限の値。詳細は一昨日の記事参照)について、勝手に修正版を算出する。下が間違っていたページの先頭部分。

Hacker News : Programming Languages sorted by Wilson Score Interval
https://news.ycombinator.com/item?id=3752509


修正版を表示する SQL と、結果全体は次のとおり。信頼係数は95%にした。
WITH a AS (
SELECT * FROM "201310"."20_HackerNews_data"
), b AS (
SELECT *, "201310"."20_Wilson_Calc"(p_like
, p_dislike, 0.95) p
FROM a
)
SELECT pname "Language", p_like "Ups", p_dislike "Downs"
, to_char(p[1], 'FM0.000') "95% Confidence"
FROM b
ORDER BY p[1] DESC ;



順位付けは概ね変わらないが、一部で逆転しているところもある。ただし統計学的には、少ない差で上とか下とか言うこと自体が無意味(だから信頼区間という話になる)。この投票自体、各プログラミング言語の利用者から無作為抽出して好き嫌いを尋ねた訳ではないので、そもそも統計学的な手法を適用する意味があるかどうか。それでも、一昨日紹介した Evanmiller.org の記事 How Not To Sort By Average Rating の言うとおり、単純に「好き」票数と「嫌い」票数の差や、「好き」票数割合で順位付けるよりは意味があると思う。

最後に、二時点の値を言語ごとに横に並べ、新しい時点のスコア(95%信頼区間の下限)が高い順に。また新しい時点のスコアが過去より高くなっている場合 upp 列で示す。
WITH a AS (
SELECT 2013 wyear, * FROM "201310"."18_HackerNews_data"
UNION ALL
SELECT 2012, * FROM "201310"."20_HackerNews_data"
), b AS (
SELECT *, "201310"."20_Wilson_Calc"(points_like
, points_dislike, 0.95) p
FROM a
), c AS (
SELECT CASE pname WHEN 'Objective C' THEN 'Objective-C'
-- 両時点で表記違うので合わせた
ELSE pname END pname, p[1] p_low_2012
FROM b WHERE wyear = 2012
), d AS (
SELECT pname, p[1] p_low_2013
FROM b WHERE wyear = 2013
)
SELECT pname "Language"
, to_char(p_low_2012, 'FM0.000') "2012 95% Confidence"
, to_char(p_low_2013, 'FM0.000') "2013 95% Confidence"
, CASE WHEN p_low_2012 < p_low_2013 THEN text '↑' END upp
FROM c FULL JOIN d USING (pname)
ORDER BY p_low_2013 DESC ;



メジャーな言語のほとんどでスコアが下がっている。好き・嫌いが同程度の比率で増えていけば、サンプルサイズが増える分だけスコアが上がるが(信頼区間が狭まる)、「嫌い」票の方が多く入ったことを意味する。そんな中、SQL が正反対なのは興味深い。

以上、最初は Hacker News のプログラミング言語好き嫌い投票の結果を紹介するだけのはずだったが、Wilson Score Interval の話につながり、そのストアド関数を作る過程で Hacker News の間違いに気づいたりして、四日間にわたる記事になった。Wilson Score Interval はまた別のデータに使う時があるかも。
<< PL/Python で Excel インポート
Wilson Score Interval で順位付け… >>