python numpy 具有偏好方向的偏置概率随机向量

Cob*_*bry 4 python numpy python-2.7

生成有偏概率随机向量的最佳方法是什么?换句话说,给定方向向量“D(dx,dy,dz)”,有偏随机向量生成器仍将在所有方向上生成随机向量,但更有可能在 D 方向上生成向量

import numpy as np
# generate 1000 vectors in all directions
vectors = np.random.random((1000,3))-np.random.random((1000,3))
# generate biased vectors probability
# proba argument gives the biasing intensity or probability to be close to D vector
vectors = biased_proba_random_vectors(directon=(dx,dy,dz), proba=0.7,size=(1000,3))
# biased_proba_random_vectors is a representation, any other implementation is welcomed
Run Code Online (Sandbox Code Playgroud)

应该如下图所示 在此输入图像描述

Joe*_*ton 5

一般来说,您应该研究各种圆形分布(例如 vonMises,又名“圆形正态分布”)。

举个简单的例子:

import numpy as np
import matplotlib.pyplot as plt

# Note higher "kappas" (second arg) result in a _narrower_ distribution
thetas = np.random.vonmises(np.radians(50), 1.5, 100)

# Convert to x, y, dx, dy...
x, y = np.zeros_like(thetas), np.zeros_like(thetas)
dx, dy = np.cos(thetas), np.sin(thetas)

fig, ax = plt.subplots()
ax.quiver(x, y, dx, dy, angles='xy', scale_units='xy', scale=1)
ax.set(xlim=[-1, 1], ylim=[-1, 1], aspect=1)
ax.axis('off')

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


但是,如果您希望大小如您所图示的那样变化,则有一种更简单的方法。

快速解决方法是在距原点固定距离(小于标准差)处创建正态分布点。分布的标准差使您可以控制向量中的“偏差”程度。

举一个简单的例子(为了便于绘图,我将在 2D 中进行此操作,但很容易适应 3D):

import numpy as np
import matplotlib.pyplot as plt

# Input, higher bias results in a _narrower_ distribution
bias, num = 1, 100
direction = np.radians(50)

# Shift the distributions from the center
dx, dy = np.random.normal(0, 0.5, (2, num))
dx += bias * np.cos(direction)
dy += bias * np.sin(direction)

# Plot the results
fig, ax = plt.subplots()
x, y = np.zeros_like(dx), np.zeros_like(dy)
ax.quiver(x, y, dx, dy, angles='xy', scale_units='xy', scale=1)
ax.set(xlim=[-1, 2], ylim=[-1, 2], aspect=1)
ax.axis('off')

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


作为最后的替代方案,如果您希望幅度平滑变化,可以使用 vonMises 分布,然后让幅度成为 的函数theta。举个例子:

import numpy as np
import matplotlib.pyplot as plt

bias, num = 1.5, 100
direction = np.radians(50)

# Note higher "kappas" (second arg) result in a _narrower_ distribution
thetas = np.random.vonmises(direction, bias, 100)

# Vary magnitude by theta
mag = np.cos(thetas - direction)

# Convert to x, y, dx, dy...
x, y = np.zeros_like(thetas), np.zeros_like(thetas)
dx, dy = mag * np.cos(thetas), mag * np.sin(thetas)

fig, ax = plt.subplots()
ax.quiver(x, y, dx, dy, angles='xy', scale_units='xy', scale=1)
ax.set(xlim=[-0.5, 1], ylim=[-0.5, 1], aspect=1)
ax.axis('off')

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述