scipy.stats.qmc.

PoissonDisk#

class scipy.stats.qmc.PoissonDisk(d, *, radius=0.05, hypersphere='volume', ncandidates=30, optimization=None, rng=None, l_bounds=None, u_bounds=None)[原始碼]#

Poisson 圓盤取樣。

參數:
dint

參數空間的維度。

radiusfloat

取樣新候選點時,點之間保持的最小距離。

hypersphere{“volume”, “surface”}, 選用

用於產生潛在候選點以添加到最終樣本中的取樣策略。預設為 “volume”。

  • volume: 原始 Bridson 演算法,如 [1] 中所述。新的候選點在超球體內部取樣。

  • surface: 僅在超球體表面取樣。

ncandidatesint

每次迭代取樣的候選點數量。更多候選點會產生更密集的取樣,因為每次迭代可以接受更多候選點。

optimization{None, “random-cd”, “lloyd”}, 選用

是否使用最佳化方案來改善取樣後的品質。請注意,這是一個後處理步驟,不保證樣本的所有屬性都會被保留。預設為 None。

  • random-cd: 座標的隨機排列,以降低中心化差異。基於中心化差異的最佳樣本會不斷更新。與使用其他差異度量相比,基於中心化差異的取樣在 2D 和 3D 子投影中展現出更好的空間填充穩健性。

  • lloyd: 使用修改後的 Lloyd-Max 演算法擾動樣本。該過程收斂到均勻間隔的樣本。

在 1.10.0 版本中加入。

rngnumpy.random.Generator, 選用

虛擬隨機數產生器狀態。當 rng 為 None 時,將使用來自作業系統的熵建立新的 numpy.random.Generator。除了 numpy.random.Generator 之外的類型會傳遞給 numpy.random.default_rng 以實例化 Generator

在 1.15.0 版本中變更: 作為從使用 numpy.random.RandomState 過渡到 numpy.random.GeneratorSPEC-007 轉換的一部分,此關鍵字已從 seed 變更為 rng。在過渡期間,這兩個關鍵字將繼續運作,但一次只能指定一個。在過渡期之後,使用 seed 關鍵字的函式呼叫將發出警告。在棄用期之後,將移除 seed 關鍵字。

l_bounds, u_boundsarray_like (d,)

目標樣本資料的下限和上限。

註解

Poisson 圓盤取樣是一種迭代取樣策略。從種子樣本開始,在環繞種子的超球體中取樣 ncandidates 個候選點。拒絕低於特定 radius 或超出域的候選點。新的樣本被添加到樣本種子池中。當池為空或達到所需樣本數量時,該過程停止。

樣本可以包含的最大點數直接與 radius 相關。隨著空間維度的增加,較高的半徑會進一步擴散點,並有助於克服維度詛咒。請參閱 準蒙地卡羅教學 以取得更多詳細資訊。

警告

由於其迭代性質和記憶體需求,該演算法更適合低維度和取樣大小。選擇具有高維度的小半徑意味著空間可以包含比使用較低維度或較大半徑更多的樣本。

部分程式碼取自 [2],原始作者 Shamis 於 2021 年 3 月 31 日給予書面同意,可在 3 條款 BSD 條款下於 SciPy 中免費使用。

參考文獻

[1]

Robert Bridson, “任意維度中的快速 Poisson 圓盤取樣。” SIGGRAPH, 2007.

範例

使用 0.2 的 radius 產生 2D 樣本。

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from matplotlib.collections import PatchCollection
>>> from scipy.stats import qmc
>>>
>>> rng = np.random.default_rng()
>>> radius = 0.2
>>> engine = qmc.PoissonDisk(d=2, radius=radius, rng=rng)
>>> sample = engine.random(20)

視覺化 2D 樣本並顯示沒有點比 radius 更近。radius/2 用於視覺化不相交的圓。如果兩個樣本彼此之間的距離正好是 radius,那麼它們半徑為 radius/2 的圓將會接觸。

>>> fig, ax = plt.subplots()
>>> _ = ax.scatter(sample[:, 0], sample[:, 1])
>>> circles = [plt.Circle((xi, yi), radius=radius/2, fill=False)
...            for xi, yi in sample]
>>> collection = PatchCollection(circles, match_original=True)
>>> ax.add_collection(collection)
>>> _ = ax.set(aspect='equal', xlabel=r'$x_1$', ylabel=r'$x_2$',
...            xlim=[0, 1], ylim=[0, 1])
>>> plt.show()
../../_images/scipy-stats-qmc-PoissonDisk-1_00_00.png

這種視覺化可以看作是圓堆積:我們可以在空間中放置多少個圓。這是一個 NP-hard 問題。方法 fill_space 可用於新增樣本,直到無法再新增樣本為止。這是一個困難的問題,可能需要手動調整參數。請注意維度:隨著維度的增加,填滿空間所需的樣本數量呈指數級增長(維度詛咒)。

方法

fast_forward(n)

將序列快速前進 n 個位置。

fill_space()

在區間 [l_bounds, u_bounds] 中繪製 n 個樣本。

integers(l_bounds, *[, u_bounds, n, ...])

l_bounds (包含) 到 u_bounds (排除) 繪製 n 個整數,或者如果 endpoint=True,則從 l_bounds (包含) 到 u_bounds (包含)。

random([n, workers])

在半開區間 [0, 1) 中繪製 n 個樣本。

reset()

將引擎重設為基本狀態。