- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
让数组A
中的值从高斯采样分配。我想将 A
中的每个值替换为 n_R
之一R
中的“representatives”,以便总量化误差为最小化。
这是进行线性量化的 NumPy 代码:
n_A, n_R = 1_000_000, 256
mu, sig = 500, 250
A = np.random.normal(mu, sig, size = n_A)
lo, hi = np.min(A), np.max(A)
R = np.linspace(lo, hi, n_R)
I = np.round((A - lo) * (n_R - 1) / (hi - lo)).astype(np.uint32)
L = np.mean(np.abs(A - R[I]))
print('Linear loss:', L)
-> Linspace loss: 2.3303939600700603
虽然这有效,但量化误差很大。有没有更聪明的怎么办?我认为人们可以利用 A
正态分布或可能使用迭代过程最小化“损失”函数。
更新在研究这个问题时,我发现了 related question关于“加权”量化。调整他们的方法有时会给出更好的量化结果:
from scipy.stats import norm
dist = norm(loc = mu, scale = sig)
bounds = dist.cdf([mu - 3*sig, mu + 3*sig])
pp = np.linspace(*bounds, n_R)
R = dist.ppf(pp)
# Find closest matches
lhits = np.clip(np.searchsorted(R, A, 'left'), 0, n_R - 1)
rhits = np.clip(np.searchsorted(R, A, 'right') - 1, 0, n_R - 1)
ldiff = R[lhits] - A
rdiff = A - R[rhits]
I = lhits
idx = np.where(rdiff < ldiff)[0]
I[idx] = rhits[idx]
L = np.mean(np.abs(A - R[I]))
print('Gaussian loss:', L)
-> Gaussian loss: 1.6521974945326285
K-means 聚类可能更好,但似乎太慢了适用于大型阵列。
最佳答案
K-means clustering might be better but seem to be too slow to be practical on large arrays.
对于一维聚类情况,有比 K 均值更快的算法。请参阅https://stats.stackexchange.com/questions/40454/determine-different-clusters-of-1d-data-from-database
我选择了其中一种算法,Jenks Natural Breaks ,并在数据集的随机子样本上运行它:
A_samp = np.random.choice(A, size=10000)
breaks = np.array(jenkspy.jenks_breaks(A_samp, n_classes=n_R))
R = (breaks[:-1] + breaks[1:]) / 2
这相当快,整个数据集的量化损失约为 1.28。
为了可视化这些方法的作用,我绘制了每个方法针对断点 R 内的索引得出的断点的 cdf。
根据定义,高斯是一条直线。这意味着它在分布的每个百分位数上都有相同数量的中断。线性方法在分布的中间花费很少的中断,而在尾部使用大部分中断。 Jenks 在两人之间找到了妥协方案。
看着上面的图表,我有了一个想法:所有这些选择中断的方法在分位数域中绘制时都是各种 S 型曲线。 (如果你把它看作一个真正延伸的 sigmoid,那么高斯就很适合。)
我编写了一个函数,该函数使用单个变量“强度”对每条曲线进行参数化,强度是 sigmoid 弯曲的速度。完成后,我使用 scipy.optimize.minimize 自动搜索一条使损失最小化的曲线。
事实证明,如果让 Scipy 对此进行优化,它会选择一条非常接近 Jenks 的曲线强度,并且它找到的曲线比 Jenks 稍差,损失约为 1.33。
您可以看到采用此失败方法的笔记本 here .
在需要创建 2^16 个不同代表的情况下,使用 Jenks 在计算上是不可行的。但是,您可以做一些非常接近的事情:具有少量类的 Jenks 加上线性插值。
这是此操作的代码:
import itertools
def pairwise(iterable):
"s -> (s0, s1), (s1, s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
def linspace_jenks(A, n_R, jenks_classes, dist_lo, dist_hi):
assert n_R % jenks_classes == 0, "jenks_classes must be divisor of n_R"
simplify_factor = n_R // jenks_classes
assert jenks_classes ** 2 <= len(A), "Need more data to estimate"
breaks = jenkspy.jenks_breaks(A, n_classes=jenks_classes)
# Adjust lowest and highest break to match highest/lowest observed value
breaks[0] = dist_lo
breaks[-1] = dist_hi
linspace_classes = []
for lo, hi in pairwise(breaks):
linspace_classes.append(np.linspace(lo, hi, simplify_factor, endpoint=False))
linspace_classes = np.hstack(linspace_classes)
assert len(linspace_classes) == n_R
return linspace_classes
调用示例:
A_samp = np.random.choice(A, size = 2**16)
jenks_R = linspace_jenks(A_samp, n_R, 128, np.min(A), np.max(A))
与线性方法相比,性能如何?在我的系统上,n_R=2^16 的线性损失为 0.009421。下图显示了 linspace_jenks
方法针对 jenks_classes 的每个值获得的损失。
只需 32 个 Jenks 类,并用线性插值填充其余部分,损失就会降至 0.005031。
关于python - 在 Python 和 NumPy 中量化正态分布 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76798643/
我有一个数字列表,其中包含这些数字的样本平均值和标准差。现在我正在尝试找出平均值+-SD、平均值+-2SD 和平均值+-3SD 中的数字。例如,在mean+-SD部分,我编写了这样的代码: ND1 =
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: erf(x) and math.h Best library for statistics in C++?
我正在尝试模拟球迷到达体育场。系统本身,我相信不会有问题,但是,粉丝的到来是一个正态分布。 我的问题是: 我有一个特定的到达时间,比如 100 分钟和 1000 个粉丝,我需要在该分布之后的某个时间生
在 Julia 中,有人实现了正态分布 pdf 或 cdf 来支持任意精度的 BigFloats。 例如,此代码返回 0.0,而实际上这些值应该略有不同。 x = parse(BigFloat, "2
给定具有上限和下限误差的平均值,计算分割正态分布的最佳方法是什么? 到目前为止我已经: from random import choice, gauss def random_split_normal
我希望用户指定分布的范围 delta、sigma 以及它应该产生的随机值的数量。但是在 Iron Python 中生成具有正态分布的随机值的最佳方法是什么?我在 NumPy 中找到了一个可以执行此操作
我的说明:编写一个程序,开始询问用户正态分布的均值 u 和标准差 s(参见 wiki article) 程序然后要求 N,然后要求 N 个值 x。对于每个 x,它都会将 f(x) 写到屏幕上。请注意,
通用的 Accept 拒绝算法和往常一样。 1 从 Unif[0,1] 生成 U 1 ,U 2 ,U 3 2 X ← −log(U 1 ) 3 if U 2 > exp(−0.5(X − 1) 2 )
我需要计算两条曲线之间的面积。我有很多数据,所以我想以编程方式进行。 基本上,我总是有 2 个正态分布,根据平均值和标准差计算得出。然后我想计算它们相交的程度。这是一个 example我的意思,还有一
我想知道 JavaScript 函数 Math.random 是否使用正态分布(相对于均匀分布)。 如果不是,我怎样才能得到使用正态分布的数字?对于创建随机正态分布数字的算法,我尚未在 Interne
我想在 d3.js 中创建正态分布图(钟形曲线)。 像这样[ http://statwiki.ucdavis.edu/@api/deki/files/73/a9f781e1b0891ceedd50cd
我的教授正在模拟客户到达银行的情况。它表示客户到达时遵循均值 3.5 和标准偏差 1.3 的正态分布。 问题是我很难理解为什么使用这段代码。我相信他提供的代码正在接收一个流、平均值和标准差来生成随机数
我正在生成一些随机数并出现可疑行为。这是我的代码: // initialized earlier... in the constructor of a class boost::mt1
用 ruby 生成正态分布随机数的代码是什么? (注意:我回答了我自己的问题,但我会等几天再接受,看看是否有人有更好的答案。) 编辑: 为此,我查看了两次搜索产生的 SO 上的所有页面: +“正态
我尝试编写 R 代码来查找 mu s.t. 的值。正态分布满足概率 P(N(mu, 1)>1.96)=0.95 (即 P(Z>1.96)=0.95 其中 Z~ N(mu, 1) 和 mu 是我想要得到
我是一名优秀的程序员,十分优秀!