4

我需要实现一个标准化坐标的函数。我将规范化定义为(如果我错了,请提出更好的术语):

将数据集的条目从其自然范围映射到 0 到 1 之间的值。

现在这在一个维度上很容易:

    static List<float> Normalize(float[] nums)
    {
        float max = Max(nums);
        float min = Min(nums);
        float delta = max - min;

        List<float> li = new List<float>();
        foreach (float i in nums)
        {
            li.Add((i - min) / delta);
        }
        return li;
    }

我还需要一个 2D 版本,并且必须保持纵横比不变。但是我在计算数学时遇到了一些麻烦。

尽管发布的代码是用 C# 编写的,但答案不一定是。

提前致谢。:)

4

3 回答 3

7

我将我的回复作为答案发布,因为我没有足够的分数来发表评论。

我对这个问题的解释:我们如何标准化二维空间中一组点的坐标?

归一化操作涉及“移位和缩放”操作。在一维空间的情况下,这是相当简单和直观的(正如@Mizipzor 所指出的)。

normalizedX=(originalX-minX)/(maxX-minX)

在这种情况下,我们首先将值移动minX的距离,然后按(maxX-minX)给出的范围对其进行缩放shift操作确保最小值移动到 0,并且scale操作压缩分布,使得分布的上限为 1

在 2d 的情况下,仅除以最大维度是不够的。为什么?

考虑只有 2 个点的简化情况,如下所示。 在此处输入图像描述 任何维度的最大值是B点的Y值和这个10000

Coordinates of normalized A=>5000/10000,8000/10000 ,i.e 0.5,0.8
Coordinates of normalized A=>7000/10000,10000/10000 ,i.e 0.7,1.0

X 和 Y 值都是 0 和 1。但是,归一化值的分布很不均匀。最小值仅为 0.5。理想情况下,这应该更接近于 0。

标准化二维坐标的首选方法

为了获得更均匀的分布,我们应该围绕所有 X 值的最小值和所有 Y 值的最小值进行“移位”操作。这也可以围绕 X 的平均值和 Y 的平均值来完成。考虑到上面的例子,

  • 所有 X 的最小值是 5000
  • 所有 Y 的最小值是 8000

第 1 步 - 移位操作

A=>(5000-5000,8000-8000), i.e (0,0)
B=>(7000-5000,10000-8000), i.e. (2000,2000)

第 2 步 - 规模操作

为了缩小值,我们需要一些最大值。我们可以使用长度为 2000 的对角线 AB

A=>(0/2000,0/2000),     i.e. (0,0)
B=>(2000/2000,2000/2000)i.e. (1,1)

当超过 2 个点时会发生什么? 在此处输入图像描述 方法仍然相似。我们找到适合所有点的最小边界框的坐标。

  • 我们从所有点中找到 X 的最小值 (MinX) 和 Y 的最小值 (MinY) 并进行移位操作。这会将原点更改为边界框的左下角。
  • 我们从所有点中找到 X 的最大值 (MaxX) 和 Y 的最大值 (MaxY)。
  • 我们计算连接 (MinX,MinY) 和 (MaxX,MaxY) 的对角线的长度,并使用该值进行缩放操作。

.

length of diagonal=sqrt((maxX-minX)*(maxX-minX) + (maxY-minY)*(maxY-minY))   

normalized X = (originalX - minX)/(length of diagonal) 
normalized Y = (originalY - minY)/(length of diagonal)

如果我们有超过 2 个维度,这个逻辑会如何变化?

概念保持不变。- 我们在每个维度 (X,Y,Z) 中找到最小值 - 我们在每个维度 (X,Y,Z) 中找到最大值 - 计算对角线的长度作为比例因子 - 使用移动原点的最小值。

length of diagonal=sqrt((maxX-minX)*(maxX-minX)+(maxY-minY)*(maxY-minY)+(maxZ-minZ)*(maxZ-minZ))

normalized X = (originalX - minX)/(length of diagonal) 
normalized Y = (originalY - minY)/(length of diagonal)
normalized Z = (originalZ - minZ)/(length of diagonal)
于 2018-08-05T00:18:22.147 回答
6

似乎您希望每个向量(1D、2D 或 ND)都具有 length <= 1
如果这是唯一的要求,您可以将每个向量除以最长向量的长度。

double max = maximum (|vector| for each vector in 'data');
foreach (Vector v : data) {
    li.add(v / max);
}

这将使结果列表中最长的向量的长度为 1。

但这并不等同于您当前的一维案例代码,因为您无法在平面上的一组点中找到最小值或最大值。因此,没有delta

于 2010-10-05T08:53:45.427 回答
1

简单的想法:找出哪个维度更大,并在这个维度上进行归一化。第二个维度可以通过使用比率来计算。这样比率就保持不变,并且您的值介于 0 和 1 之间。

于 2010-10-05T08:51:41.910 回答