我有以下向量:
import numpy as np
my_vector = np.array([0.001, -0.05, 0.3, 0.5, 0.01, -0.03])
有人可以建议一种方法来随机生成相似的向量,只是值略有不同吗?例如,所需的输出是:
[0.002, -0.06, 0.2, 0.4, 0.02, -0.02]
为了提供一些背景信息,该向量表示我输入分类模型的样本。我的计划是随机生成一组相似的样本并将它们输入到同一模型中以观察其输出的变化。最终目标是验证模型是否为相似的样本生成相似的输出。
我尝试创建给定余弦相似度的随机向量并将所需的余弦相似度设置为1,但使用这种方法我只能获得一个相似的向量(见下文)。我至少需要 10 个。
def rand_cos_sim(v, costheta):
# Form the unit vector parallel to v:
u = v / np.linalg.norm(v)
# Pick a random vector:
r = np.random.multivariate_normal(np.zeros_like(v), np.eye(len(v)))
# Form a vector perpendicular to v:
uperp = r - r.dot(u)*u
# Make it a unit vector:
uperp = uperp / np.linalg.norm(uperp)
# w is the linear combination of u and uperp with coefficients costheta
# and sin(theta) = sqrt(1 - costheta**2), respectively:
w = costheta*u + np.sqrt(1 - costheta**2)*uperp
return w
new_vector = rand_cos_sim(my_vector, 1)
print(new_vector)
# [ 0.00170622 -0.08531119 0.51186714 0.8531119 0.01706224 -0.05118671]
我没有想到特定的相似性度量,它可以是欧几里得,余弦,无论哪个效果最好。欢迎任何建议。
请注意,我提供的
my_vector
仅供说明之用,实际上,根据我正在测试的模型和不同的数据,我的向量将具有不同的值范围。
谢谢你。
也许我过于简单化了,但是你能不能只生成与你的大小相同的随机向量,然后将它们添加到你的向量中以使它们相似(或者加一,然后相乘,因为你的示例似乎在较小的数字上变化较小) ?
def similar_vector(my_vector):
return (0.95+numpy.random.rand(len(my_vector))*0.1)*my_vector
您可以通过调用
numpy.random.lognormal
生成随机乘法因子。使用 mean=0
和较小的 sigma
值生成接近 1 的随机值。
例如,
In [23]: my_vector = np.array([0.001, -0.05, 0.3, 0.5, 0.01, -0.03])
In [24]: a = np.random.lognormal(sigma=0.1, size=my_vector.shape)
In [25]: a
Out[25]:
array([1.07162745, 0.99891183, 1.02511718, 0.85346562, 1.04191125,
0.87158183])
In [26]: a * my_vector
Out[26]:
array([ 0.00107163, -0.04994559, 0.30753516, 0.42673281, 0.01041911,
-0.02614745])
我认为最好的方法是在两个值之间添加一个随机数。为此目的,请研究随机。
import numpy as np
import random
my_vector = np.array([0.001, -0.05, 0.3, 0.5, 0.01, -0.03])
for i in range(len(my_vector)):
my_vector[i] += random.uniform(.001,.1)
print(my_vector)
您可以通过调整值范围来调整它
我不是Python程序员,但我可以看到你的问题很容易解决,只需将原始向量绕其原点旋转随机量(theta)即可。
如果您使用 32 位浮点数,您可能需要记录 vstart 的初始长度,然后使用归一化向量进行旋转,以避免舍入误差并保持准确性。完成后,将 vnew 乘以 vslength 即可得到最终结果。我不知道这是如何在 python 中实现的,但我可以在这里给你一些伪代码:
vstart = some random vector
// get the normal of vstart which will return a float
vslength = vector normal (vstart)
// get the unit vector of vstart which will return a normalized vector
vsunit = normalize vector (vstart)
// create three random Euler angles with a ceiling of theta
xangle = random * theta
yangle = random * theta
zangle = random * theta
// create a rotation matrix for each Euler angle
xmatrix = create rotation matrix from xangle
ymatrix = create rotation matrix from yangle
zmatrix = create rotation matrix from zangle
// perform the rotation
vnew = vstart * xmatrix * ymatrix * zmatrix
// scale the rotated unit vector to the original length
vnscaled = vnew * vslength
即使在紧密循环中,甚至在 CPU 上计算,尽管有矩阵乘法,它也应该表现得相当好,尽管 python 中必须有一个函数可以通过欧拉旋转或四元数中的等效旋转来旋转 3 个通道向量。你应该检查几何库。