在 Scipy 中,为什么 custom.rvs() 具有均匀概率 return 的值仅在开始区域?
In Scipy why does custom.rvs() having uniform probability return the values in the begining region only?
如果我生成一个数组
custom=np.ones(800, dtype=np.float32)
然后使用
从中创建自定义概率分布
custom=normalize(custom)[0]
customPDF = stats.rv_discrete(name='pdfX', values=(np.arange(800), custom))
那如果我用
customPDF.rvs()
我得到的返回值在 0 - 20 范围内,而我期望随机数在 0 到 800 之间变化。
下面的代码给出了我需要的输出,
random.uniform(0,800)
但是由于需要能够通过改变自定义数组来操纵概率分布,我必须使用 customPDF.rvs()
有解决办法吗?为什么会这样?
In [206]: custom=np.ones(800, dtype=np.float32)
In [207]: custom=normalize(custom)[0]
/usr/local/lib/python3.4/dist-packages/sklearn/utils/validation.py:386: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and willraise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.
DeprecationWarning)
In [208]: customPDF = stats.rv_discrete(name='pdfX', values=(np.arange(800), custom))
In [209]: customPDF.rvs()
Out[209]: 7
In [210]: customPDF.rvs()
Out[210]: 13
In [211]: customPDF.rvs()
Out[211]: 15
In [212]: customPDF.rvs()
Out[212]: 3
In [213]: customPDF.rvs()
Out[213]: 8
In [214]: customPDF.rvs()
Out[214]: 10
In [215]: customPDF.rvs()
Out[215]: 10
In [216]: customPDF.rvs()
Out[216]: 11
In [217]: customPDF.rvs()
Out[217]: 15
In [218]: customPDF.rvs()
Out[218]: 6
In [219]: customPDF.rvs()
Out[219]: 7
In [220]: random.uniform(0,800)
Out[220]: 707.0265562968543
问题出在这一行:
custom=normalize(custom)[0]
根据警告,normalize
似乎指的是 sklearn.preprocessing.normalize
。 normalize
需要一个 [n_samples, n_features]
二维数组——因为你给它一个一维向量,它会插入一个新维度并将其视为一个 [1, n_features]
数组(因此你要索引第 0 个元素输出)。
默认情况下,它会将每行特征的 L2 (Euclidean) norm 调整为等于 1。这 not 与使元素总和为 1 相同:
print(normalize(np.ones(800))[0].sum())
# 28.2843
由于custom
的总和远大于1,所以在到达概率向量的末尾之前,绘制特定整数的累积概率达到1:
print(custom.cumsum().searchsorted(1))
# 28
结果是你永远不会画出大于28的整数:
print(customPDF.rvs(size=100000).max())
# 28
为了使 custom
正常化,您应该除以其总和:
custom /= custom.sum()
# or alternatively:
custom = np.repeat(1./800, 800)
如果我生成一个数组
custom=np.ones(800, dtype=np.float32)
然后使用
从中创建自定义概率分布custom=normalize(custom)[0]
customPDF = stats.rv_discrete(name='pdfX', values=(np.arange(800), custom))
那如果我用
customPDF.rvs()
我得到的返回值在 0 - 20 范围内,而我期望随机数在 0 到 800 之间变化。
下面的代码给出了我需要的输出,
random.uniform(0,800)
但是由于需要能够通过改变自定义数组来操纵概率分布,我必须使用 customPDF.rvs()
有解决办法吗?为什么会这样?
In [206]: custom=np.ones(800, dtype=np.float32)
In [207]: custom=normalize(custom)[0]
/usr/local/lib/python3.4/dist-packages/sklearn/utils/validation.py:386: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and willraise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.
DeprecationWarning)
In [208]: customPDF = stats.rv_discrete(name='pdfX', values=(np.arange(800), custom))
In [209]: customPDF.rvs()
Out[209]: 7
In [210]: customPDF.rvs()
Out[210]: 13
In [211]: customPDF.rvs()
Out[211]: 15
In [212]: customPDF.rvs()
Out[212]: 3
In [213]: customPDF.rvs()
Out[213]: 8
In [214]: customPDF.rvs()
Out[214]: 10
In [215]: customPDF.rvs()
Out[215]: 10
In [216]: customPDF.rvs()
Out[216]: 11
In [217]: customPDF.rvs()
Out[217]: 15
In [218]: customPDF.rvs()
Out[218]: 6
In [219]: customPDF.rvs()
Out[219]: 7
In [220]: random.uniform(0,800)
Out[220]: 707.0265562968543
问题出在这一行:
custom=normalize(custom)[0]
根据警告,normalize
似乎指的是 sklearn.preprocessing.normalize
。 normalize
需要一个 [n_samples, n_features]
二维数组——因为你给它一个一维向量,它会插入一个新维度并将其视为一个 [1, n_features]
数组(因此你要索引第 0 个元素输出)。
默认情况下,它会将每行特征的 L2 (Euclidean) norm 调整为等于 1。这 not 与使元素总和为 1 相同:
print(normalize(np.ones(800))[0].sum())
# 28.2843
由于custom
的总和远大于1,所以在到达概率向量的末尾之前,绘制特定整数的累积概率达到1:
print(custom.cumsum().searchsorted(1))
# 28
结果是你永远不会画出大于28的整数:
print(customPDF.rvs(size=100000).max())
# 28
为了使 custom
正常化,您应该除以其总和:
custom /= custom.sum()
# or alternatively:
custom = np.repeat(1./800, 800)