回答編集履歴

6

d

2020/02/11 07:19

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -319,3 +319,145 @@
319
319
 
320
320
 
321
321
  ![イメージ説明](54f7b2ad4dee3ed965e7a2a3d54b8dc1.png)
322
+
323
+
324
+
325
+ ## 追記 distplot の仕様確認
326
+
327
+
328
+
329
+ 引数の優先度としては、norm_hist < kde < hist_kws のようですので、
330
+
331
+ 正規化したくない場合は、`kde=False` または `hist_kws={"density": False}` を指定するのがよさそうです。
332
+
333
+
334
+
335
+ | kde | density | ヒストグラム |
336
+
337
+ | --- | --- | --- |
338
+
339
+ | False | False | 正規化されない |
340
+
341
+ | False | True | 正規化される |
342
+
343
+ | True | False | 正規化されない |
344
+
345
+ | True | True | 正規化される |
346
+
347
+
348
+
349
+ ```python
350
+
351
+ import matplotlib.pyplot as plt
352
+
353
+ import numpy as np
354
+
355
+ import seaborn as sns
356
+
357
+
358
+
359
+ sns.set()
360
+
361
+ np.random.seed(0)
362
+
363
+
364
+
365
+ x = np.random.randn(1000)
366
+
367
+
368
+
369
+ fig, axes = plt.subplots(2, 2, figsize=(8, 8))
370
+
371
+ axes = axes.ravel()
372
+
373
+
374
+
375
+ axes[0].set_title("kde=False, density=False")
376
+
377
+ sns.distplot(x, kde=False, hist_kws={"density": False}, ax=axes[0])
378
+
379
+ axes[1].set_title("kde=False, density=True")
380
+
381
+ sns.distplot(x, kde=False, hist_kws={"density": True}, ax=axes[1])
382
+
383
+ axes[2].set_title("kde=True, density=False")
384
+
385
+ sns.distplot(x, kde=True, hist_kws={"density": False}, ax=axes[2])
386
+
387
+ axes[3].set_title("kde=True, density=True")
388
+
389
+ sns.distplot(x, kde=True, hist_kws={"density": True}, ax=axes[3])
390
+
391
+ plt.show()
392
+
393
+ ```
394
+
395
+
396
+
397
+ ![イメージ説明](d73de753672cc8c90ac87d8c90e118bd.png)
398
+
399
+
400
+
401
+ | kde | norm_hist | ヒストグラム |
402
+
403
+ | --- | --- | --- |
404
+
405
+ | False | False | 正規化されない |
406
+
407
+ | False | True | 正規化される |
408
+
409
+ | True | False | 正規化される |
410
+
411
+ | True | True | 正規化される |
412
+
413
+
414
+
415
+ ```
416
+
417
+ import matplotlib.pyplot as plt
418
+
419
+ import numpy as np
420
+
421
+ import seaborn as sns
422
+
423
+
424
+
425
+ sns.set()
426
+
427
+ np.random.seed(0)
428
+
429
+
430
+
431
+ x = np.random.randn(1000)
432
+
433
+
434
+
435
+ fig, axes = plt.subplots(2, 2, figsize=(8, 8))
436
+
437
+ axes = axes.ravel()
438
+
439
+
440
+
441
+ axes[0].set_title("kde=False, norm_hist=False")
442
+
443
+ sns.distplot(x, kde=False, norm_hist=False, ax=axes[0])
444
+
445
+ axes[1].set_title("kde=False, norm_hist=True")
446
+
447
+ sns.distplot(x, kde=False, norm_hist=True, ax=axes[1])
448
+
449
+ axes[2].set_title("kde=True, norm_hist=False")
450
+
451
+ sns.distplot(x, kde=True, norm_hist=False, ax=axes[2])
452
+
453
+ axes[3].set_title("kde=True, norm_hist=True")
454
+
455
+ sns.distplot(x, kde=True, norm_hist=True, ax=axes[3])
456
+
457
+ plt.show()
458
+
459
+ ```
460
+
461
+
462
+
463
+ ![イメージ説明](58f7efa143a579814f417d172a8034c8.png)

5

d

2020/02/11 07:19

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -312,9 +312,9 @@
312
312
 
313
313
 
314
314
 
315
- 「カーネル密度推定の確率密度関数」は「真の確率密度関数」と一致して重なっている。
315
+ 「カーネル密度推定の確率密度関数 (オレンジ)」は「真の確率密度関数」と一致して重なっている。
316
-
316
+
317
- ヒストグラムも「真の確率密度関数」とほぼ一致している。
317
+ 「正規化されたヒストグラム(緑)」も「真の確率密度関数」とほぼ一致している。
318
318
 
319
319
 
320
320
 

4

d

2020/02/10 16:06

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -242,9 +242,11 @@
242
242
 
243
243
  正規化されたヒストグラム、カーネル密度推定で推定した確率密度関数ですが、どちらも(不明な)真の確率密度関数を近似するのが目的です。
244
244
 
245
+
246
+
247
+ 曲線とx軸の間の面積を求めるのに、x 軸を細かい区間で分割して、長方形を敷き詰めて、面積を計算するというのが、リーマン積分の考え方です。
248
+
245
- 非常に沢山のデータがあり、ビンの幅を小さくした正規化されたヒストグラムを作成すれば、それで真の確率密度関数を近似できます。
249
+ で、大量のデータを用意して、ビンの幅を小さくした正規化されたヒストグラムを作成すれば、それで真の確率密度関数を近似できます。
246
-
247
- 曲線とx軸の間の面積を求めるのに、x 軸を細かい区間で分割して、長方形を敷き詰めて、メ面積を計算するというのが、リーマン積分の考え方なので、大量のデータを用意して、ビンの幅を小さくしたヒストグラムを作成するということは、まさに同じことをやっています。
248
250
 
249
251
 
250
252
 

3

d

2020/02/10 16:05

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -175,3 +175,145 @@
175
175
 
176
176
 
177
177
  ![イメージ説明](f7ca8495379de0e9ea5450376c2e4894.png)
178
+
179
+
180
+
181
+ ## 追記
182
+
183
+
184
+
185
+ > 2つのグラフで「y」の値が、一方は少数、一方は整数となっておりますが、これは何故かがわかりません。
186
+
187
+
188
+
189
+ グラフの目盛りがすべて整数なら整数、小数が含まれるなら小数で表示するという matplotlib の仕様によるものなので、整数か小数かはグラフの表示上の問題であり、重要ではありません。
190
+
191
+ 注目するべきは、y 軸のスケールが左と右で大きく違うことでしょう。
192
+
193
+ これは、他の回答者様のコメント欄で hayataka2049 さんがご指摘されていますが、ヒストグラムの正規化 (デフォルトで有効) によるものです。
194
+
195
+ 通常、ヒストグラムは y 軸は各ビンに属するデータ数 (頻度値) ですが、この正規化が有効の場合、棒の面積の合計が1となるように棒の高さが調整されます。
196
+
197
+
198
+
199
+ 数式で表すと、n 個のビンの幅が w1, w2, ..., wn、頻度値が f1, f2, ..., fn としたとき、
200
+
201
+ w1 * f1 + w2 * f2 + ... + wn + fn = 1
202
+
203
+ となるように f1, f2, ..., fn の値を正規化します。
204
+
205
+
206
+
207
+ 左のほうが右より棒の高さが高いのは、左の方はビンの幅が小さいので、棒の面積の合計が1にするためには棒の高さをその分高くする必要があるからです。
208
+
209
+ 棒の高さをそのビンに属するデータ数として解釈したい場合は distplot() で norm_hist=False を指定してください。
210
+
211
+
212
+
213
+ この正規化の仕様は、内部でヒストグラム作成に使用している [numpy.histogram](https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html) から来ています。
214
+
215
+
216
+
217
+ > また、can110さんのご回答で、「描かれた曲線とx軸とを囲む領域の面積がデータ値の出現個数の総数になるように補正、正規化された値だということのようです。」とあるのですが、
218
+
219
+ > 仮に左側の画像の総面積を求めてみますと、x軸が「0.0 ~ 0.3」の為、「0.3」y軸を大体ではありますが「6」と考えた場合、「0.3 × 6 ÷ 2」 = 「0.9」となります。
220
+
221
+ > こちらのデータ値の出現個数の総数が「0.9」であるという意味がいまいち分からない為、ご助言頂けましたら幸いです...
222
+
223
+
224
+
225
+ 曲線のほうは、先の回答の通り、推定した確率密度関数です。
226
+
227
+ 「描かれた曲線とx軸とを囲む領域の面積」とは、確率密度関数を (-∞, +∞) の区間で積分すると求められ、これは1になります。
228
+
229
+
230
+
231
+ ![イメージ説明](d830ee93683ef32890091eaed0eabaa9.gif)
232
+
233
+
234
+
235
+ この計算の解釈は、確率変数 X は実数の値をとるので、(-∞, +∞) の間の値をとる確率は100%であるということを言っています。
236
+
237
+
238
+
239
+ ## 補足
240
+
241
+
242
+
243
+ 正規化されたヒストグラム、カーネル密度推定で推定した確率密度関数ですが、どちらも(不明な)真の確率密度関数を近似するのが目的です。
244
+
245
+ 非常に沢山のデータがあり、ビンの幅を小さくした正規化されたヒストグラムを作成すれば、それで真の確率密度関数を近似できます。
246
+
247
+ 曲線とx軸の間の面積を求めるのに、x 軸を細かい区間で分割して、長方形を敷き詰めて、メ面積を計算するというのが、リーマン積分の考え方なので、大量のデータを用意して、ビンの幅を小さくしたヒストグラムを作成するということは、まさに同じことをやっています。
248
+
249
+
250
+
251
+ ![イメージ説明](1272ef9914eb2cf3a76697924a3ff623.png)
252
+
253
+ リーマン積分の考え方
254
+
255
+
256
+
257
+ ```python
258
+
259
+ from scipy.stats import norm, gaussian_kde
260
+
261
+ import numpy as np
262
+
263
+ import matplotlib.pyplot as plt
264
+
265
+
266
+
267
+ # 平均0、分散1の1変量正規分布に従う確率変数
268
+
269
+ rv = norm(loc=0, scale=1)
270
+
271
+
272
+
273
+ # 大量の標本を生成する。
274
+
275
+ samples = rv.rvs(300000)
276
+
277
+
278
+
279
+ # この得られた標本から元となる確率密度関数を推定する。
280
+
281
+ kernel = gaussian_kde(samples)
282
+
283
+
284
+
285
+ fig, ax = plt.subplots()
286
+
287
+
288
+
289
+ # 確率密度関数を描画する。
290
+
291
+ xs = np.linspace(-5, 5, 1000)
292
+
293
+ ax.plot(xs, rv.pdf(xs), label="確率密度関数")
294
+
295
+ ax.plot(xs, kernel(xs), label="KDE で推定した確率密度関数")
296
+
297
+
298
+
299
+ # ヒストグラムを描画する。
300
+
301
+ bins = np.linspace(-5, 5, 1000)
302
+
303
+ ax.hist(samples, bins, density=True)
304
+
305
+ ax.legend(loc="upper left")
306
+
307
+ plt.show()
308
+
309
+ ```
310
+
311
+
312
+
313
+ 「カーネル密度推定の確率密度関数」は「真の確率密度関数」と一致して重なっている。
314
+
315
+ ヒストグラムも「真の確率密度関数」とほぼ一致している。
316
+
317
+
318
+
319
+ ![イメージ説明](54f7b2ad4dee3ed965e7a2a3d54b8dc1.png)

2

d

2020/02/10 15:50

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -49,3 +49,129 @@
49
49
 
50
50
 
51
51
  体系的に理解したい場合は [統計学](https://www.amazon.co.jp/s?k=%E6%95%B0%E7%90%86%E7%B5%B1%E8%A8%88%E5%AD%A6&__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&ref=nb_sb_noss_1) の教科書を当たると、最初のほうで必ず紹介されていると思うので、それを参照してください。
52
+
53
+
54
+
55
+ ## 追記
56
+
57
+
58
+
59
+ ストーリーとしては、以下のようになります。
60
+
61
+
62
+
63
+ いくつかのデータが得られた
64
+
65
+
66
+
67
+ データが得られた背景となる確率分布があるけど、それはわからない
68
+
69
+
70
+
71
+ データから確率分布を推定する
72
+
73
+
74
+
75
+ ----
76
+
77
+
78
+
79
+ 統計学の考え方としては、まずなんらかの真の確率分布があり (現実ではこれはわからない)、データはその確率分布から得られた標本 (値の例) であると考えます。
80
+
81
+
82
+
83
+ 以下、例として、標準正規分布としておきます。
84
+
85
+
86
+
87
+ ```python
88
+
89
+ from scipy.stats import norm, gaussian_kde
90
+
91
+ import numpy as np
92
+
93
+ import matplotlib.pyplot as plt
94
+
95
+
96
+
97
+ # 平均0、分散1の1変量正規分布に従う確率変数
98
+
99
+ rv = norm(loc=0, scale=1)
100
+
101
+
102
+
103
+ fig, ax = plt.subplots()
104
+
105
+ ax.plot(xs, rv.pdf(xs), label="確率密度関数")
106
+
107
+ ax.legend(loc="upper left")
108
+
109
+ ax.set_xlim(-5, 5)
110
+
111
+ plt.show()
112
+
113
+ ```
114
+
115
+
116
+
117
+ ![イメージ説明](2a6bddf542a6b022c309d37e1752241f.png)
118
+
119
+
120
+
121
+ このような分布があって、そこから1000 個の値が得られたとします。
122
+
123
+ ヒストグラムを描画すると以下のようになります。
124
+
125
+
126
+
127
+ ![イメージ説明](822bcb6ec0b60af5ad05c049af7017ce.png)
128
+
129
+
130
+
131
+ 現実では、いくつかのデータが得られたとして、真の確率分布というのはわからないわけです。
132
+
133
+ 例えば、100人に身長を聞いて、[168, 172, 180, ...] と100人分のデータが得られたとして、その元となった真の確率分布というのはわかりません。
134
+
135
+
136
+
137
+ わからないので、それを今持っているデータから推定するというのが、統計学の1つの目的になります。
138
+
139
+ カーネル密度推定はその手法の1つです。
140
+
141
+ カーネル密度推定を使って推定すると、以下のようになります。
142
+
143
+ 元の分布 (青) がわからなくても、データからある程度それに近い分布 (オレンジ) が得られました。
144
+
145
+
146
+
147
+ ```python
148
+
149
+ # この得られた標本から元となる確率密度関数を推定する。
150
+
151
+ kernel = gaussian_kde(samples)
152
+
153
+
154
+
155
+ # 確率密度関数を描画する。
156
+
157
+ xs = np.linspace(-5, 5, 1000)
158
+
159
+
160
+
161
+ fig, ax = plt.subplots()
162
+
163
+ ax.plot(xs, rv.pdf(xs), label="確率密度関数")
164
+
165
+ ax.plot(xs, kernel(xs), label="推定した確率密度関数")
166
+
167
+ ax.legend(loc="upper left")
168
+
169
+ ax.set_xlim(-5, 5)
170
+
171
+ plt.show()
172
+
173
+ ```
174
+
175
+
176
+
177
+ ![イメージ説明](f7ca8495379de0e9ea5450376c2e4894.png)

1

d

2020/02/09 12:11

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -48,4 +48,4 @@
48
48
 
49
49
 
50
50
 
51
- きちんと理解したい場合は [統計学](https://www.amazon.co.jp/s?k=%E6%95%B0%E7%90%86%E7%B5%B1%E8%A8%88%E5%AD%A6&__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&ref=nb_sb_noss_1) の教科書を当たると、最初のほうで必ず紹介されていると思うので、それを参照してください。
51
+ 体系的に理解したい場合は [統計学](https://www.amazon.co.jp/s?k=%E6%95%B0%E7%90%86%E7%B5%B1%E8%A8%88%E5%AD%A6&__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&ref=nb_sb_noss_1) の教科書を当たると、最初のほうで必ず紹介されていると思うので、それを参照してください。