Есть ли способ получить процент уникальности в массиве объектов? - PullRequest
0 голосов
/ 09 марта 2020

я впервые пишу на этом сайте.

Поэтому мне нужно сгенерировать набор случайных данных с помощью функции, которая возвращает объект. Этот объект выбирает некоторые свойства (на действительно вложенных уровнях) случайным образом из других массивов объектов. Таким образом, функция возвращает один и тот же объект в структуре, но разные значения в своих свойствах.

Есть ли способ рассчитать коэффициент уникальности или что-то в этом роде? Например, если в наборе есть один сгенерированный объект, в точности равный другому, он вернет уникальность 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.asso c.

. Проверка массива процентных различий дает мне что-то вроде этого:

[
  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
]

Каждый из них является отношением уникальности. Я прикрепляюсь к объектам.

Однако я думаю, что мое решение ошибочно, я чувствую, что здесь что-то странное. Это была моя логика c для решения этой проблемы.

Я спрашиваю вас, как бы вы решили это? В конце проблема состоит в том, чтобы написать алгоритм, который вычисляет значение уникальности каждого объекта в наборе объектов той же структуры, но различных значений.

Я не прошу код, только некоторые идеи, чтобы сделать эту работу надлежащим образом. Я не ученый данных или математик, поэтому я пошел своим наивным путем достижения этого.

Надеюсь, это прояснит ситуацию.

Спасибо.

1 Ответ

0 голосов
/ 10 марта 2020

Несколько других вопросов показывают, что если вы ищете оптимизированное решение, этот вопрос сложен для NP. Я не знаю, есть ли какой-нибудь алгоритм лучше, чем грубая сила для этого. И об этом не может быть и речи, поскольку (100 выбирают 20) довольно велико (535983370403809682970) - если у вас нет какого-либо оборудования, о котором я действительно хотел бы знать!

Но Я думаю, что вы можете найти местный оптимум, который, вероятно, не будет плохой догадкой. Это может включать

  1. Расчет матрицы разностей
  2. Суммирование строк
  3. Выбор максимального значения
  4. Добавление этого значения в список
  5. Если вам все еще нужно больше элементов, удалите этот индекс из строки и столбца и go вернитесь к шагу 2.

Или, конечно, вы можете использовать имитированный отжиг Техника, чтобы найти еще лучший локальный максимум.


Что касается различий, как я предположил в комментарии, deep-diff может быть больше, чем вам нужно. Вы можете использовать функцию , например, :

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 работает хорошо для вас, нет причин для изменения; это просто проверка того, чего, как я понимаю, ваших требований там не будет.

...