0

R^n我正在尝试在n未知的球体上实现网格搜索(在 Python 中,如果重要的话) 。

输入包括球体的半径和中心,以及theta控制网格分辨率的超参数。我想将这个球体中的每个点表示为这三个参数的函数。

我也愿意考虑立方体搜索,只迭代立方体的面。(即,迭代L_inf球体

如果我知道 n=2,我会做的是:

import numpy as np

def enumerate_2d_sphere(R,theta,center=(0,0)):
    for n in xrange(int(2*np.pi / theta)+1):
        degree = n*theta
        point =(center[0]+R*np.cos(degree),center[1]+R*np.sin(degree))
        yield point

for p in enumerate_2d_sphere(1,0.1):
    print p

由于n可以任意大,我正在寻找一种有效地迭代球体\立方体的方法。

有任何想法吗?

++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++

我最终使用了一个修改后的版本:

import itertools
import numpy as np
import matplotlib.pyplot as plt

def f(d, center, scale=1):
    dim = len(center)
    print d/-2.0
    diff = scale * np.array([d/-2.0 for _ in xrange(dim)])
    bias = diff + center
    for i in range(dim):
        l = ([ xrange(1,d) for _ in xrange(i)] +
             [[0,d]] +
             [ xrange(d+1) for _ in xrange(dim-i-1)]
            )
        for r in itertools.product(*l):
            yield scale*np.array(r)+bias
#example for R^2:
center = (1,1.5)
data = np.array([x for x in f(20,center,scale = 0.1)])


plt.scatter(data[:,0], data[:,1],color='r',s=100,alpha=0.5)
plt.scatter(center[0], center[1],color='b',s=300,alpha=0.5)
plt.show()

输出图:

在此处输入图像描述

另一种选择是在 sphere 上生成 均匀分布的样本。请注意,样本数控制点的“密度”(或预期密度):

import numpy as np
def generate_random_points(R,center,quantity=1000):
    """
    :param R: float
    :param center: np.array
    :param quantity: int
    """
    dim = len(center)
    for n in xrange(quantity):
        s = np.random.normal(0, 1,dim)
        r = np.sqrt(np.dot(s,s))
        s = (R/r) * s
        yield s+center

最糟糕的方法(就简单性和效率而言)是使用n-1 角度的枚举在球体上生成点。效率低下是因为需要计算产品sin并且cos经常(尽管这也可能被黑客入侵)

4

2 回答 2

1

您可以在 n 维中使用球坐标(参见例如wikipedia),或者您可以使用欧几里得坐标,只需将最后一个坐标设置为获得正确半径(加或减)所需的任何值。这两个都是很好的参数化,会给你球体上的所有点——用正确数量的参数来迭代。

但是它们不会自然地导致恒定的面积(体积)元素——这很容易通过考虑 3 球体来看出。这个问题没有简单的解决方案。

我认为一种可能的方法是使用 n-1 维网格参数化,但根据体积将第 n 个组件细分为可变数量的值。

n 立方体的面更容易:只需生成第 n 坐标最小或最大的 n 对面。因此,例如,考虑从原点开始的大小为 1 的 n 立方体:

将第一个坐标设置为零并在其余部分上枚举一个网格。然后将其设置为 1 并再次执行此操作。然后重复第二个坐标。等等。

这是使用itertools.product. 为了简单和高效,我已将框缩放为整数坐标:您需要重新缩放并移动中心。n维度数和d沿每个轴的细分数也是如此。

import itertools

def f(n,d):

    for i in range(n):
        l = ([ range(1,d-1) for _ in range(i)] +
             [[0,d-1]] +
             [ range(d) for _ in range(n-i-1)]
            )
        for r in itertools.product(*l):
            yield r

print(list(f(4,3)))
于 2016-02-28T08:52:19.703 回答
0

我不认为 sklearn 网格搜索功能有这个选项,但是手动实现这个应该不难

  • 迭代 n 的值
  • 对于每个 n,迭代 n 个不同的角度参数,theta 步幅从 0 到 360
  • 如果你不想要球体体积,也迭代半径 - 如果你只想要表面,保持半径不变
于 2016-02-28T08:03:48.387 回答