回答編集履歴

1

回答の追記

2020/04/30 21:34

投稿

R.Shigemori
R.Shigemori

スコア3376

test CHANGED
@@ -13,3 +13,77 @@
13
13
 
14
14
 
15
15
  私自身は実装経験がないので、ただちにサンプルコードを示すことができませんが、「stan 打ち切りモデル」で検索すればstanのサンプルコードが見つかるはずです。
16
+
17
+
18
+
19
+ stanのチュートリアルに該当するものがあったので、実験しました。
20
+
21
+
22
+
23
+ ```python
24
+
25
+ sample = stats.norm.rvs(loc=0,scale=0.5,size=10000) # 推計したいデータ
26
+
27
+ Choice = sample[sample<-0.5] # -0.5以上は観察されないことにした実験用データ
28
+
29
+
30
+
31
+ # stan本体のコード
32
+
33
+ stancode = """
34
+
35
+ data {
36
+
37
+ int<lower=0> N_obs; // 観測値の件数
38
+
39
+ int<lower=0> N_cens; // 打ち切られたデータの件数
40
+
41
+ real y_obs[N_obs]; // 観測値
42
+
43
+ real<lower=max(y_obs)> U; // 打ち切りポイント
44
+
45
+ }
46
+
47
+ parameters {
48
+
49
+ real<lower=U> y_cens[N_cens]; // 打ち切られたデータ 必ず打ち切りポイント以上になると設定
50
+
51
+ real mu; // 推計したい平均
52
+
53
+ real<lower=0> sigma; // 推計したい分散
54
+
55
+ }
56
+
57
+ model {
58
+
59
+ y_obs ~ normal(mu,sigma); // 観測値が正規分布に従うことを示すモデル
60
+
61
+ y_cens ~ normal(mu,sigma); // 欠損値が正規分布に従うことを示すモデル
62
+
63
+ }
64
+
65
+ """
66
+
67
+ model = pystan.StanModel(model_code=stancode) # コードのコンパイル
68
+
69
+
70
+
71
+ standata = {'N_obs':len(Choice), # stanに与えるデータの生成
72
+
73
+ 'N_cens':10000, # 打ち切られたデータは10000件とした
74
+
75
+ 'y_obs':Choice,
76
+
77
+ 'U':np.max(Choice)}
78
+
79
+
80
+
81
+ result = model.sampling(data=standata) # samplingの実行
82
+
83
+
84
+
85
+ ```
86
+
87
+
88
+
89
+ 結果として平均は0.030とそれなりのものが得られました。(観測値の件数が1630件と本来のデータの20%弱からの推計なので、いいほうだということもできそうです)