【问题标题】:Creating an efficient function to fit a dataset创建一个有效的函数来拟合数据集
【发布时间】:2011-09-24 12:32:15
【问题描述】:

基本上,我有一个 4 字节输入及其对应的 4 字节输出的大数据集(可以得到 100,000-150,000 个值)。不能保证输入是唯一的(这不是真正的问题,因为我认为我可以生成伪随机数来添加或异或输入,以便它们变得唯一),但不能保证输出也是唯一的(因此两组不同的输入可能具有相同的输出)。

我正在尝试创建一个函数来有效地模拟我的数据集中的值。我不需要它来有效地插值,甚至根本不需要它(我的意思是我永远不会向它提供不包含在这个静态数据集中的输入)。但是,它确实需要尽可能高效。我研究了插值,发现它并不真正适合我正在寻找的东西。例如,大量值意味着样条插值不起作用,因为它会为每个间隔创建一个多项式。

此外,据我了解,多项式插值的计算成本太高(n 值意味着多项式可能包含高达 pow(x,n-1) 的项。对于 x= 4 字节数和 n=100,000这是不可行的)。我已经尝试在网上搜索了一段时间,但我的数学不是很强,而且我一定不知道正确的搜索词,因为到目前为止我还没有遇到过类似的东西。

我可以看出这并不完全(委婉地说)一个编程问题,我提前道歉。我不是在寻找确切的解决方案,甚至不是完整的答案。我只需要关于我需要阅读的主题的指针,这样我就可以自己解决这个问题。谢谢!

TL;DR - 我需要一种插值变体,它只需要适合最初给定的数据点,但计算效率很高。

编辑: 一些澄清 - 我确实需要输出准确而不是近似值。这是对我目前正在做的一些研究工作的一种优化,我需要在没有输出的实际字节出现在我的程序中的情况下实现这个查找。目前我真的不能说太多,但我会说,就我的工作而言,加密(或压缩或任何其他形式的混淆)不是隐藏表格的选项。我需要一个数学函数,只要它可以访问输入,它就可以重新创建输出。我希望这能把事情弄清楚一点。

【问题讨论】:

  • 插值本质上是计算昂贵的。您可能需要考虑使用回归。
  • 1.您正在寻找的功能是否必须完全适合这些数据点?或者它可以只是一个近似值? 2. 如果你永远不会给它一个不在你的数据集中的输入,你为什么需要这个函数呢?插值的目的是得到中间值。
  • @Steve - 回归可以给我一个函数来精确地再现输出或只是近似它们吗?我编辑了我的问题以澄清我需要精确度。
  • @tskuzzy - 我已经编辑了我的问题以提供更多细节,但基本上我确实需要它是准确的,不幸的是我不能真正使用表格本身。
  • @bridgeburner:如果您需要精确的数字,那么您将需要使用插值,而且真的没有办法绕过它。我真的看不出插值占用的空间比精确值少——只需从一些数据存储中查找它们,这样您就不需要硬编码任何东西。它也会更快。 (:

标签: math interpolation data-fitting


【解决方案1】:

我建议一个巨大的Lookup Table 充满未使用的条目。这是蛮力方法,有一个有序的输出表,按输入的每个可能值排序(不仅是数据集,还包括所有其他可能的 4 字节值)。

虽然您的所有数据都在那里,您可以用随机、任意或随机的(在可能复杂的约束条件下随机)数据填充未使用的输入。如果你让它令人信服,那么没有人可以从中挑选出你的真实数据。如果一个“真实”函数对您的所有数据进行了插值,它也将“包含”您真实数据的所有信息,并且有权访问它的任何人都可以使用它来生成如上所述的 LUT

LUT 速度快如闪电,但非常消耗内存。您的案例处于可行性边缘,需要 (2^32)*32= 16 GB 的 RAM,这需要 64 位机器才能运行。这仅适用于数据,而不适用于程序、操作系统或其他数据。最好have 24, just to be sure。如果你能负担得起,他们就是要走的路。

【讨论】:

  • 您的方法是隐藏“真实”数据的好方法,但我的目标实际上是更隐写的,因为我试图尽可能避免静态数据以支持某些东西这几乎完全是代码。自从发布我的问题以来,我已经意识到,尽管信息论基本上表明,即使存储我使用的任何参数方程的系数也将是大量的“静态”数据。又被现实给骗了! :)
【解决方案2】:

这是一个想法。使您的函数成为所有 4 字节整数的线性函数的总和 (mod 232),一个分段线性函数,其片段取决于第一位的值,另一个分段线性函数,其片段取决于前两位的值,依此类推。

实际输出值无处显示,您必须将线性项相加才能得到它们。也没有直接记录您拥有哪些输入值。 (有人可以对这些输入值得出一些结论,但不是它们的实际值。)

您需要的各种系数可以存储在哈希中。您执行的任何未在哈希中找到的查找都假定为 0。

如果您在开始相当有效地编码数据集之前向数据集添加了一定数量的随机“噪声”,则很难判断您的输入值是什么,甚至在不知道的情况下也很难判断输出值是多少输入。

【讨论】:

  • 我喜欢这个主意!我不认为我可以直接使用它,但它是进行一些富有成效的探索的一个很好的起点。非常感谢!
【解决方案3】:

由于您没有对函数施加任何限制(连续、平滑等),您可以简单地进行分段常数插值:

或线性插值:

我假设你可以不费吹灰之力地弄清楚如何构造这样一个函数。

编辑:鉴于您的附加要求,即此类函数应“隐藏”数据点...

对于分段常数插值,常数间隔应随机化,以免显示数据点的位置。因此,例如在图片中,间隔以它插值的数据点为中心。相反,您可能想要执行以下操作:

[0 , 0.3) -> 0
[0.3 , 1.9) -> 0.8
[1.9 , 2.1) -> 0.9
[2.1 , 3.5) -> 0.2
etc

当然,这只是隐藏了 x 坐标。要同时隐藏 y 坐标,您可以使用线性插值。

只需让它“尖”部分不在数据点所在的位置。选择随机 x 值,使得每个相邻数据点之间都有这些 x 值之一。然后进行插值,使“尖”部分位于这些 x 值处。

【讨论】:

  • 在我实际发布问题之前,我查看了这两个。分段方式本质上与查找表相同,因此不可行。线性要求每个区间都有一个线方程 - 肯定会有很多,所以我想避免这种情况。
  • 我刚刚阅读了您的编辑并相应地修改了我的答案。你说它需要很多方程,但实际上没有其他方法可以处理这么多数据点。即使多项式插值在计算上是可行的,你仍然会得到一个 150,000 度的多项式。
  • 是的,我一直在考虑它,我可能不得不放弃这种方法,转而采用其他方法。我可能完全错了(再次),但我目前正在尝试看看我是否可以训练一个神经网络来尽可能接近我想要的功能。不过谢谢!
  • 如果您打算走近似路线,您可能需要研究遗传算法。我记得写过一个程序,它使用遗传算法进行回归并取得了相对成功。不过,我几乎不是这方面的专家,所以我不确定解决问题的最佳方法是什么。
  • 支持遗传算法。这是我目前正在探索的选项之一。
猜你喜欢
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 2015-06-16
  • 2018-02-22
  • 2016-12-21
  • 2021-10-20
  • 2021-05-10
  • 1970-01-01
相关资源
最近更新 更多