Twitter で行った4択アンケートの結果を本気で分析する(打ち切りと丸めによって生成されたヒストグラムのモデリング)

経緯

事前の想像では最頻値は 40 or 41 になるのではないかと考えていたため Twitter のアンケート機能で利用可能な4択を上記のように設定したのですが、予想が外れて「42℃以上」が最頻値となってしまいました。これでは結局何℃にしている人が一番多いのかよくわかりません。

アンケートの回答の総数が 28 だったため、割合から逆算して以下のようなデータが得られました。

温度 回答数
39℃以下 2
40℃ 5
41℃ 10
42℃以上 11

分析で知りたいこと

  1. 一般のご家庭の平均的なお風呂の設定温度を知りたい
  2. お風呂の温度を43℃に設定しているご家庭がどれくらいあるのか知りたい

愚直な分析で困ること

打ち切り

39℃以下を39、42℃以上を42と扱っても、それっぽい平均は計算できます。しかし「42℃以上」と回答した人は11人もいるので43℃や44℃に設定している人も何人かいそうです。よって真の平均はそれより少し高くなりそうです。

丸め

各家庭が本当に好むお風呂の温度は本来実数でなければ表現できないはずですが、アンケートの都合により回答を整数で入力させました。これにより、たとえば41.6℃が最適な人でも「42℃以上」と回答することになります。この丸めによって平均値がずれることがありそうです。

仮定

各家庭が本当に好むお風呂の温度が実数で回答できて打ち切りがない場合にアンケートの結果が正規分布に従うと仮定します。

関連するモデリング

Stan で打ち切りを含むデータをモデリングしたい場合は以下の方法を使うことができます。

4.3 Censored data | Stan User’s Guide

整数に丸めたデータを扱う場合は以下の方法を使うことができます。打ち切りとほとんど同じです。

6.1 Bayesian measurement error model | Stan User’s Guide

上記2つをまとめると以下のスライドと同じような考え方になります。

モデル

お風呂の温度の好みが平均 \mu、分散 \sigma^2正規分布から生成され、打ち切りと丸めによって 39.5, 40.5, 41.5 を区切りとして「39℃以下」「40℃」「41℃」「42℃以上」に振り分けられるとします。このときそれぞれの項目に割り振られる確率 \theta は累積分布関数 (normal_cdf) を使って表すことができます。

\theta が分かっていて回答の総数が N のとき、所望のアンケート結果 y が得られる確率は多項分布 \mathrm{Multinomial}(y|\theta) として表すことができます。今回はこの考え方に従って Stan の multinomial 関数を使いましたが、多項係数の部分は尤度の計算においては推定したい未知パラメータの MCMC に対して不変のため、(私の理解が間違っていなければ)必ずしも使う必要はないはずです。

Stan のモデルコードは以下のとおりです。

data {
  int<lower=0> Y[4];
}

parameters {
  real mu;
  real<lower=0> sigma;
}

transformed parameters {
  vector<lower=0>[4] theta;
  theta[1] = normal_cdf(39.5 | mu, sigma);
  theta[2] = normal_cdf(40.5 | mu, sigma) - normal_cdf(39.5 | mu, sigma);
  theta[3] = normal_cdf(41.5 | mu, sigma) - normal_cdf(40.5 | mu, sigma);
  theta[4] = 1 - normal_cdf(41.5 | mu, sigma);
}

model {
  Y ~ multinomial(theta);
}

generated quantities {
  int<lower=0> Y_pred[4];
  Y_pred = multinomial_rng(theta, sum(Y));
}

結果

詳細を見たい人は以下の Jupyter Notebook を見てください。

https://gist.github.com/arosh/69331f37ae160b71917d53ddcd3c279c

平均 \mu の事後分布は以下のようになりました。95% 信用区間は 40.7 〜 41.9 となり、40℃に設定している人(私だ)は平均よりぬるい温度を好んでいると言えそうです。また43℃に設定している人は平均より熱いお風呂を好んでいると言えそうです。

f:id:kujira16:20220102152752p:plain
平均 μ の事後分布

\mu\sigma を MAP 推定すると \mu = 41.2, \sigma = 1.19 となりました。「愚直な分析で困ること」で書いたように39℃以下を39、42℃以上を42と扱って平均を計算すると 41.1 だったため、思ったよりは差が出なかったなという印象です。

MAP 推定から得られた \mu = 41.2, \sigma = 1.19 を使って正規分布をつくり 39.5, 40.5, 41.5 を区切りとして「39℃以下」「40℃」「41℃」「42℃以上」の項目に割り振られる確率を計算すると以下のようになりました。

f:id:kujira16:20220102153553p:plain
正規分布を仮定した場合の各項目の回答率

もとのアンケートの結果を再掲します。おおむね再現できていると言えそうです。

最後に、私の実家のように43℃に設定している家庭がどれくらいあるのか推定してみたいと思います。上記の正規分布について累積分布関数を用いて 42.5 〜 43.5 の範囲の割合を計算すると 11% でした。10件に1件くらいは43℃に設定している家庭がありそうです。

f:id:kujira16:20220102154240p:plain
43℃に設定している家庭の割合

まとめ

Twitter の4択アンケートのように回答の種類が限られている場合でも統計モデリングを使えば「△△以上」「▽▽以下」のように打ち切られた部分の外側をある程度予想したり整数に丸められた細かい部分が分析したりすることができました。

皆さんはこんな大掛かりな分析をしなくても良いようにアンケートをとるときは回答項目を正しく設定しましょう!