【问题标题】:Is there a way to have a percentage of uniqueness in an array of objects?有没有办法在对象数组中获得一定百分比的唯一性?
【发布时间】:2020-03-09 18:49:49
【问题描述】:

这是我第一次在这个网站上写作。

所以我需要使用返回对象的函数生成一组随机数据。 该对象从其他对象数组中随机选择一些属性(在真正嵌套的级别上)。因此,该函数在结构中返回相同的对象,但在其属性中返回不同的值。

有没有办法计算唯一性比率或类似的东西?就像如果有一个生成的对象与集合中的另一个完全相等,它将返回唯一性 0,如果没有与其他任何共享属性,则返回 100,如果一些是共享的,而另一些则不是,介于两者之间的某个百分比?

我的目标是生成一组例如 100 个并选择前 20 个最独特的生成对象。

提前感谢您的想法。

编辑:

假设我已经生成了一组数据。 所有对象具有相同的结构但不同的值。 像这样的:

{
name: 'Some Name',
propA: (picked randomly from set A),
propB: (picked randomly from a different set B),
sections: [
  {
    propC: (another random from another set C)
   },
   {...}, 
   ...
]

}

我用我用 ramda 编写的一些实用程序生成了这些对象的数组,比如从列表中随机选择,然后用 R.times 来做。

主要问题是我需要这个:

{
  ...generatedObject,
  uniqueness: 79
}

在每个对象上,唯一性是一个百分比。

到目前为止,我使用deep-diff 来获取对象之间的差异,并编写了一个函数来根据对象中更改的道具数量提取百分比。

这是那个fn:

// changes is a Number
const measureUniquenessBetweenTwoChildObjects = R.curry((changes, objA, objB) =>
  R.compose(
    R.multiply(100), 
    R.divide(R.__, changes), 
    R.length, 
    diff)(objA, objB)
  );

这样做的目的是,如果有相同的变化和生成的道具,那么差异是 100%。

然后我确实选择了列表中的每个对象,并将此函数与除自身之外的所有其他对象映射,用平均值减少差异数组,这就是我认为的最终数字。然后我用 R.assoc 将该数字附加到对象上。

检查百分比差异数组给了我这样的信息:

[
  73.02, 73.02, 72.79, 72.56,
  72.56, 72.34, 72.34, 72.11,
  71.66, 71.66,  71.2, 70.98,
  70.98, 70.98, 70.75, 70.52,
  70.29, 70.29, 70.07, 69.84
]

每一个都是我附加到对象的唯一性比率。

但是我认为我的解决方案有缺陷,我觉得这里有些奇怪。这是我解决这个问题的逻辑。

我要问的是你将如何解决这个问题?最后的问题是编写一个算法,计算一组结构相同但值不同的对象中每个对象的唯一性值。

我不是要代码,只是要一些想法以使这项工作以适当的方式工作。我不是数据科学家或数学家,所以我以天真的方式实现了这一目标。

希望这会让它更清楚。

谢谢。

【问题讨论】:

  • 请阅读 How to Ask 并创建一个 minimal reproducible example 您尝试过的内容
  • 如果数据真的是随机生成的..
  • 我认为这里潜伏着一个非常有趣的问题。请对其进行编辑,以明确您要完成的工作以及到目前为止所做的尝试。例如,您是否正在寻求生成这些随机对象的帮助?或者你想要一个你可以自己编码的唯一性公式?或者您是否想要一种算法来计算给定一组对象的这种唯一性值?还有什么?当然,我们希望看到您自己投入的工作。
  • 我投票决定重新开放。还有一些人也需要这样做。它将进入重新开放请求队列,供人们查看。但是,如果您想创建一个新问题,请随意。只需在此处添加指向它的评论。然后关闭这个。
  • 这要清楚得多。有些人可能仍然认为 StackOverflow 超出了界限,因为许多人真的只是希望能够编写代码来获得答案。但我不同意。我喜欢这个问题。结果矩阵对我来说看起来很奇怪,因为我希望它围绕主对角线对称。

标签: javascript similarity ramda.js


【解决方案1】:

几个other questions 证明如果您正在寻找优化的解决方案,这个问题是NP-hard。我不知道是否有比蛮力更好的算法。这是不可能的,因为(100 choose 20) 相当大(535983370403809682970)——除非你有一些我真的很想知道的硬件!

但我认为您可以找到一个局部最优值,这可能是一个不错的猜测。这将涉及

  1. 计算差分矩阵
  2. 对行求和
  3. 选择最大值
  4. 将该值添加到您的列表中
  5. 如果您仍需要更多项目,请从行和列中删除该索引并返回到第 2 步。

当然,您也可以使用一些simulated annealing 技术来找到更好的局部最大值。


至于差异,正如我在评论中建议的那样,deep-diff 可能超出您的需要。您也许可以使用函数like this

const findLeafPaths = (o, path = [[]]) => 
  typeof o == 'object'
    ? Object .entries (o) .flatMap (
        ([k, v]) => findLeafPaths (v, path) .map (p => [k, ...p])
      ) 
    : path

查找示例对象中的所有路径,然后对于每个对象,通过在这些对象上映射R.path 将其缩减为值数组。要找到它们之间的数值差异应该相当简单(我会从R.zipWith (R.equals) 或类似的东西开始。)但是如果deep-diff 对你很有效,那么没有理由改变;它只是在测试一些东西,据我了解,您的要求不会出现。

【讨论】:

  • 您能否详细说明为什么这是排列问题?我将其视为 O(n^2),因为可以测量 100 个对象中每一个对象的唯一性,从而产生 100 * 100 / 2 - 100 或 4900 个唯一性度量。 (我假设唯一性的度量是可交换的,即 A vs B 与 B vs A 相同,因此减半,并且没有理由根据自身来衡量对象的唯一性,因此 -100。)使用此矩阵手头的结果,可以对每个对象的唯一性度量进行平均,然后选择前 20 个...我错过了什么吗?
  • 啊,我误会了。我以为你想要最相互不同的集合。如果您想要 20 个与该系列最不同的,那么应该是衡量和选择前 20 个的问题。
  • 啊,我误会了。我以为你想要最相互不同的集合。如果您想要 20 个与该系列最不同的,那么应该是衡量和选择前 20 个的问题。
  • 啊,现在我明白了置换讨论的来源,如果问题是 20 个最不同的 集合 之一...感谢您的澄清。跨度>
猜你喜欢
  • 1970-01-01
  • 2018-07-11
  • 2014-12-04
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 2022-09-23
  • 1970-01-01
相关资源
最近更新 更多