从“部分”二项式分布进行有效采样 错误修正

问题描述

我想从二项式分布B(n,p)中进行采样,但是要附加一个约束,即采样值属于[a,b]范围(而不是正态0到n范围)。换句话说,我必须从二项式分布中抽取一个值,假设它位于[a,b]范围内。在数学上,我可以用二项式分布public class MainActivity extends AppCompatActivity { private static final String MAP_VIEW_BUNDLE_KEY = "MapViewBundleKey"; static final LatLng KYIV = new LatLng(50.450311,30.523730); private GoogleMap mGoogleMap; private RelativeLayout mMapViewRoot; private MapView mGoogleMapView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Bundle mapViewBundle = null; if (savedInstanceState != null) { mapViewBundle = savedInstanceState.getBundle(MAP_VIEW_BUNDLE_KEY); } mMapViewRoot = (RelativeLayout) findViewById(R.id.mapview_root); // dummy transparent view final View transparentView = View.inflate(getApplicationContext(),R.layout.transparent_view,mMapViewRoot); mGoogleMapView = (MapView) findViewById(R.id.mapview); mGoogleMapView.onCreate(mapViewBundle); mGoogleMapView.getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googleMap) { mGoogleMap = googleMap; mGoogleMap.addMarker(new MarkerOptions().position(KYIV).title("Kyiv")); mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { // get screen coordinates of the marker Projection projection = mGoogleMap.getProjection(); Point viewPosition = projection.toScreenLocation(marker.getPosition()); // place dummy transparent view over the marker transparentView.setLeft(viewPosition.x); transparentView.setTop(viewPosition.y); return false; } }); mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(KYIV)); ... } }); } ... 的pmf来表示该分布(f(x))的pmf为

bin(x) = [(nCx)*(p)^x*(1-p)^(n-x)]

从这种分布进行采样的一种方法是对均匀分布的数字进行采样,然后应用CDF的倒数(使用pmf获得)。但是,我认为这不是一个好主意,因为pmf计算很容易变得非常耗时。

在我的情况下,sum = 0 for i in range(a,b+1): sum += bin(i) f(x) = bin(x)/sum 的值非常大,由于n,x,a,b中的阶乘项,这种计算pmf然后使用统一随机变量生成样本的方法似乎效率极低。 / p>

有什么好的/有效的方法来实现这一目标?

解决方法

这是一种在很短的时间内收集bin的所有值的方法:

from scipy.special import comb
import numpy as np
def distribution(n,p=0.5):
    x = np.arange(n+1)
    return comb(n,x,exact=False) * p ** x * (1 - p) ** (n - x)

n=1000可以在四分之一微秒内完成。

样品运行:

>>> distribution(4):
array([0.0625,0.25,0.375,0.0625])

您可以像这样对这个数组的特定部分求和:

>>> np.sum(distribution(4)[2:4])
0.625

注释::对于n>1000,此分布的中间值需要使用非常大的数字进行乘法运算,因此会提高RuntimeWarning

错误修正

您可以等效地使用scipy.stats.binom

from scipy.stats import binom
def distribution(n,p):
    return binom.pmf(np.arange(n+1),n,p)

这与上述方法非常有效(n=1000000占三分之一)。另外,您可以使用binom.cdf(np.arange(n+1),p)来计算binom.pmf的累积和。然后将该数组的第b和第a项相减得出的输出非常接近您的期望。

,

另一种方法是使用CDF,它是相反的,例如:

ffmpeg -i input.mp3 /home/aix/music/encoded/output.mp3

应为我们提供该范围内的值。请注意,由于浮点精度的原因,这可能会给您带来超出您期望值的值。在分布的平均值之上变得更糟

请注意,对于较大的值,您也可以使用常规近似值

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...