回答編集履歴
6
d
answer
CHANGED
@@ -158,4 +158,75 @@
|
|
158
158
|
「カーネル密度推定の確率密度関数 (オレンジ)」は「真の確率密度関数」と一致して重なっている。
|
159
159
|
「正規化されたヒストグラム(緑)」も「真の確率密度関数」とほぼ一致している。
|
160
160
|
|
161
|
-

|
161
|
+

|
162
|
+
|
163
|
+
## 追記 distplot の仕様確認
|
164
|
+
|
165
|
+
引数の優先度としては、norm_hist < kde < hist_kws のようですので、
|
166
|
+
正規化したくない場合は、`kde=False` または `hist_kws={"density": False}` を指定するのがよさそうです。
|
167
|
+
|
168
|
+
| kde | density | ヒストグラム |
|
169
|
+
| --- | --- | --- |
|
170
|
+
| False | False | 正規化されない |
|
171
|
+
| False | True | 正規化される |
|
172
|
+
| True | False | 正規化されない |
|
173
|
+
| True | True | 正規化される |
|
174
|
+
|
175
|
+
```python
|
176
|
+
import matplotlib.pyplot as plt
|
177
|
+
import numpy as np
|
178
|
+
import seaborn as sns
|
179
|
+
|
180
|
+
sns.set()
|
181
|
+
np.random.seed(0)
|
182
|
+
|
183
|
+
x = np.random.randn(1000)
|
184
|
+
|
185
|
+
fig, axes = plt.subplots(2, 2, figsize=(8, 8))
|
186
|
+
axes = axes.ravel()
|
187
|
+
|
188
|
+
axes[0].set_title("kde=False, density=False")
|
189
|
+
sns.distplot(x, kde=False, hist_kws={"density": False}, ax=axes[0])
|
190
|
+
axes[1].set_title("kde=False, density=True")
|
191
|
+
sns.distplot(x, kde=False, hist_kws={"density": True}, ax=axes[1])
|
192
|
+
axes[2].set_title("kde=True, density=False")
|
193
|
+
sns.distplot(x, kde=True, hist_kws={"density": False}, ax=axes[2])
|
194
|
+
axes[3].set_title("kde=True, density=True")
|
195
|
+
sns.distplot(x, kde=True, hist_kws={"density": True}, ax=axes[3])
|
196
|
+
plt.show()
|
197
|
+
```
|
198
|
+
|
199
|
+

|
200
|
+
|
201
|
+
| kde | norm_hist | ヒストグラム |
|
202
|
+
| --- | --- | --- |
|
203
|
+
| False | False | 正規化されない |
|
204
|
+
| False | True | 正規化される |
|
205
|
+
| True | False | 正規化される |
|
206
|
+
| True | True | 正規化される |
|
207
|
+
|
208
|
+
```
|
209
|
+
import matplotlib.pyplot as plt
|
210
|
+
import numpy as np
|
211
|
+
import seaborn as sns
|
212
|
+
|
213
|
+
sns.set()
|
214
|
+
np.random.seed(0)
|
215
|
+
|
216
|
+
x = np.random.randn(1000)
|
217
|
+
|
218
|
+
fig, axes = plt.subplots(2, 2, figsize=(8, 8))
|
219
|
+
axes = axes.ravel()
|
220
|
+
|
221
|
+
axes[0].set_title("kde=False, norm_hist=False")
|
222
|
+
sns.distplot(x, kde=False, norm_hist=False, ax=axes[0])
|
223
|
+
axes[1].set_title("kde=False, norm_hist=True")
|
224
|
+
sns.distplot(x, kde=False, norm_hist=True, ax=axes[1])
|
225
|
+
axes[2].set_title("kde=True, norm_hist=False")
|
226
|
+
sns.distplot(x, kde=True, norm_hist=False, ax=axes[2])
|
227
|
+
axes[3].set_title("kde=True, norm_hist=True")
|
228
|
+
sns.distplot(x, kde=True, norm_hist=True, ax=axes[3])
|
229
|
+
plt.show()
|
230
|
+
```
|
231
|
+
|
232
|
+

|
5
d
answer
CHANGED
@@ -155,7 +155,7 @@
|
|
155
155
|
plt.show()
|
156
156
|
```
|
157
157
|
|
158
|
-
「カーネル密度推定の確率密度関数」は「真の確率密度関数」と一致して重なっている。
|
158
|
+
「カーネル密度推定の確率密度関数 (オレンジ)」は「真の確率密度関数」と一致して重なっている。
|
159
|
-
ヒストグラムも「真の確率密度関数」とほぼ一致している。
|
159
|
+
「正規化されたヒストグラム(緑)」も「真の確率密度関数」とほぼ一致している。
|
160
160
|
|
161
161
|

|
4
d
answer
CHANGED
@@ -120,9 +120,10 @@
|
|
120
120
|
## 補足
|
121
121
|
|
122
122
|
正規化されたヒストグラム、カーネル密度推定で推定した確率密度関数ですが、どちらも(不明な)真の確率密度関数を近似するのが目的です。
|
123
|
-
非常に沢山のデータがあり、ビンの幅を小さくした正規化されたヒストグラムを作成すれば、それで真の確率密度関数を近似できます。
|
124
|
-
曲線とx軸の間の面積を求めるのに、x 軸を細かい区間で分割して、長方形を敷き詰めて、メ面積を計算するというのが、リーマン積分の考え方なので、大量のデータを用意して、ビンの幅を小さくしたヒストグラムを作成するということは、まさに同じことをやっています。
|
125
123
|
|
124
|
+
曲線とx軸の間の面積を求めるのに、x 軸を細かい区間で分割して、長方形を敷き詰めて、面積を計算するというのが、リーマン積分の考え方です。
|
125
|
+
なので、大量のデータを用意して、ビンの幅を小さくした正規化されたヒストグラムを作成すれば、それで真の確率密度関数を近似できます。
|
126
|
+
|
126
127
|

|
127
128
|
リーマン積分の考え方
|
128
129
|
|
3
d
answer
CHANGED
@@ -86,4 +86,75 @@
|
|
86
86
|
plt.show()
|
87
87
|
```
|
88
88
|
|
89
|
-

|
89
|
+

|
90
|
+
|
91
|
+
## 追記
|
92
|
+
|
93
|
+
> 2つのグラフで「y」の値が、一方は少数、一方は整数となっておりますが、これは何故かがわかりません。
|
94
|
+
|
95
|
+
グラフの目盛りがすべて整数なら整数、小数が含まれるなら小数で表示するという matplotlib の仕様によるものなので、整数か小数かはグラフの表示上の問題であり、重要ではありません。
|
96
|
+
注目するべきは、y 軸のスケールが左と右で大きく違うことでしょう。
|
97
|
+
これは、他の回答者様のコメント欄で hayataka2049 さんがご指摘されていますが、ヒストグラムの正規化 (デフォルトで有効) によるものです。
|
98
|
+
通常、ヒストグラムは y 軸は各ビンに属するデータ数 (頻度値) ですが、この正規化が有効の場合、棒の面積の合計が1となるように棒の高さが調整されます。
|
99
|
+
|
100
|
+
数式で表すと、n 個のビンの幅が w1, w2, ..., wn、頻度値が f1, f2, ..., fn としたとき、
|
101
|
+
w1 * f1 + w2 * f2 + ... + wn + fn = 1
|
102
|
+
となるように f1, f2, ..., fn の値を正規化します。
|
103
|
+
|
104
|
+
左のほうが右より棒の高さが高いのは、左の方はビンの幅が小さいので、棒の面積の合計が1にするためには棒の高さをその分高くする必要があるからです。
|
105
|
+
棒の高さをそのビンに属するデータ数として解釈したい場合は distplot() で norm_hist=False を指定してください。
|
106
|
+
|
107
|
+
この正規化の仕様は、内部でヒストグラム作成に使用している [numpy.histogram](https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html) から来ています。
|
108
|
+
|
109
|
+
> また、can110さんのご回答で、「描かれた曲線とx軸とを囲む領域の面積がデータ値の出現個数の総数になるように補正、正規化された値だということのようです。」とあるのですが、
|
110
|
+
> 仮に左側の画像の総面積を求めてみますと、x軸が「0.0 ~ 0.3」の為、「0.3」y軸を大体ではありますが「6」と考えた場合、「0.3 × 6 ÷ 2」 = 「0.9」となります。
|
111
|
+
> こちらのデータ値の出現個数の総数が「0.9」であるという意味がいまいち分からない為、ご助言頂けましたら幸いです...
|
112
|
+
|
113
|
+
曲線のほうは、先の回答の通り、推定した確率密度関数です。
|
114
|
+
「描かれた曲線とx軸とを囲む領域の面積」とは、確率密度関数を (-∞, +∞) の区間で積分すると求められ、これは1になります。
|
115
|
+
|
116
|
+

|
117
|
+
|
118
|
+
この計算の解釈は、確率変数 X は実数の値をとるので、(-∞, +∞) の間の値をとる確率は100%であるということを言っています。
|
119
|
+
|
120
|
+
## 補足
|
121
|
+
|
122
|
+
正規化されたヒストグラム、カーネル密度推定で推定した確率密度関数ですが、どちらも(不明な)真の確率密度関数を近似するのが目的です。
|
123
|
+
非常に沢山のデータがあり、ビンの幅を小さくした正規化されたヒストグラムを作成すれば、それで真の確率密度関数を近似できます。
|
124
|
+
曲線とx軸の間の面積を求めるのに、x 軸を細かい区間で分割して、長方形を敷き詰めて、メ面積を計算するというのが、リーマン積分の考え方なので、大量のデータを用意して、ビンの幅を小さくしたヒストグラムを作成するということは、まさに同じことをやっています。
|
125
|
+
|
126
|
+

|
127
|
+
リーマン積分の考え方
|
128
|
+
|
129
|
+
```python
|
130
|
+
from scipy.stats import norm, gaussian_kde
|
131
|
+
import numpy as np
|
132
|
+
import matplotlib.pyplot as plt
|
133
|
+
|
134
|
+
# 平均0、分散1の1変量正規分布に従う確率変数
|
135
|
+
rv = norm(loc=0, scale=1)
|
136
|
+
|
137
|
+
# 大量の標本を生成する。
|
138
|
+
samples = rv.rvs(300000)
|
139
|
+
|
140
|
+
# この得られた標本から元となる確率密度関数を推定する。
|
141
|
+
kernel = gaussian_kde(samples)
|
142
|
+
|
143
|
+
fig, ax = plt.subplots()
|
144
|
+
|
145
|
+
# 確率密度関数を描画する。
|
146
|
+
xs = np.linspace(-5, 5, 1000)
|
147
|
+
ax.plot(xs, rv.pdf(xs), label="確率密度関数")
|
148
|
+
ax.plot(xs, kernel(xs), label="KDE で推定した確率密度関数")
|
149
|
+
|
150
|
+
# ヒストグラムを描画する。
|
151
|
+
bins = np.linspace(-5, 5, 1000)
|
152
|
+
ax.hist(samples, bins, density=True)
|
153
|
+
ax.legend(loc="upper left")
|
154
|
+
plt.show()
|
155
|
+
```
|
156
|
+
|
157
|
+
「カーネル密度推定の確率密度関数」は「真の確率密度関数」と一致して重なっている。
|
158
|
+
ヒストグラムも「真の確率密度関数」とほぼ一致している。
|
159
|
+
|
160
|
+

|
2
d
answer
CHANGED
@@ -23,4 +23,67 @@
|
|
23
23
|
|
24
24
|
確率密度関数の見方としては、**確率密度関数 f(x) の値が大きいところは、そのあたりの x の値が現れる可能性が高い**という理解でいいと思います。
|
25
25
|
|
26
|
-
体系的に理解したい場合は [統計学](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) の教科書を当たると、最初のほうで必ず紹介されていると思うので、それを参照してください。
|
26
|
+
体系的に理解したい場合は [統計学](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) の教科書を当たると、最初のほうで必ず紹介されていると思うので、それを参照してください。
|
27
|
+
|
28
|
+
## 追記
|
29
|
+
|
30
|
+
ストーリーとしては、以下のようになります。
|
31
|
+
|
32
|
+
いくつかのデータが得られた
|
33
|
+
↓
|
34
|
+
データが得られた背景となる確率分布があるけど、それはわからない
|
35
|
+
↓
|
36
|
+
データから確率分布を推定する
|
37
|
+
|
38
|
+
----
|
39
|
+
|
40
|
+
統計学の考え方としては、まずなんらかの真の確率分布があり (現実ではこれはわからない)、データはその確率分布から得られた標本 (値の例) であると考えます。
|
41
|
+
|
42
|
+
以下、例として、標準正規分布としておきます。
|
43
|
+
|
44
|
+
```python
|
45
|
+
from scipy.stats import norm, gaussian_kde
|
46
|
+
import numpy as np
|
47
|
+
import matplotlib.pyplot as plt
|
48
|
+
|
49
|
+
# 平均0、分散1の1変量正規分布に従う確率変数
|
50
|
+
rv = norm(loc=0, scale=1)
|
51
|
+
|
52
|
+
fig, ax = plt.subplots()
|
53
|
+
ax.plot(xs, rv.pdf(xs), label="確率密度関数")
|
54
|
+
ax.legend(loc="upper left")
|
55
|
+
ax.set_xlim(-5, 5)
|
56
|
+
plt.show()
|
57
|
+
```
|
58
|
+
|
59
|
+

|
60
|
+
|
61
|
+
このような分布があって、そこから1000 個の値が得られたとします。
|
62
|
+
ヒストグラムを描画すると以下のようになります。
|
63
|
+
|
64
|
+

|
65
|
+
|
66
|
+
現実では、いくつかのデータが得られたとして、真の確率分布というのはわからないわけです。
|
67
|
+
例えば、100人に身長を聞いて、[168, 172, 180, ...] と100人分のデータが得られたとして、その元となった真の確率分布というのはわかりません。
|
68
|
+
|
69
|
+
わからないので、それを今持っているデータから推定するというのが、統計学の1つの目的になります。
|
70
|
+
カーネル密度推定はその手法の1つです。
|
71
|
+
カーネル密度推定を使って推定すると、以下のようになります。
|
72
|
+
元の分布 (青) がわからなくても、データからある程度それに近い分布 (オレンジ) が得られました。
|
73
|
+
|
74
|
+
```python
|
75
|
+
# この得られた標本から元となる確率密度関数を推定する。
|
76
|
+
kernel = gaussian_kde(samples)
|
77
|
+
|
78
|
+
# 確率密度関数を描画する。
|
79
|
+
xs = np.linspace(-5, 5, 1000)
|
80
|
+
|
81
|
+
fig, ax = plt.subplots()
|
82
|
+
ax.plot(xs, rv.pdf(xs), label="確率密度関数")
|
83
|
+
ax.plot(xs, kernel(xs), label="推定した確率密度関数")
|
84
|
+
ax.legend(loc="upper left")
|
85
|
+
ax.set_xlim(-5, 5)
|
86
|
+
plt.show()
|
87
|
+
```
|
88
|
+
|
89
|
+

|
1
d
answer
CHANGED
@@ -23,4 +23,4 @@
|
|
23
23
|
|
24
24
|
確率密度関数の見方としては、**確率密度関数 f(x) の値が大きいところは、そのあたりの x の値が現れる可能性が高い**という理解でいいと思います。
|
25
25
|
|
26
|
-
|
26
|
+
体系的に理解したい場合は [統計学](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) の教科書を当たると、最初のほうで必ず紹介されていると思うので、それを参照してください。
|