Случайное распределение данных - PullRequest
5 голосов
/ 09 октября 2008

Как распределить небольшое количество данных в случайном порядке в гораздо больший объем данных?

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

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

Если я просто полагаюсь на генерацию случайных чисел, есть вероятность (хотя и очень небольшая), что все мои контрольные данные или, по крайней мере, их скопления, будут вставлены в довольно узкий набор «реальных» данных. Каков наилучший способ предотвратить это?

Чтобы сформулировать это иначе, я хочу вставить управляющие данные в мои реальные данные, не имея возможности для третьей стороны вычислить, какие строки являются управляющими, а какие - реальными. <ч /> Обновление: я сделал это «вики-сообществом», так что если кто-то захочет отредактировать мой вопрос, чтобы он имел больше смысла, тогда продолжайте. <ч /> Обновление: позвольте мне попробовать пример (я не хочу делать этот язык или платформу зависимыми, поскольку это не вопрос кодирования, а статистический вопрос).

  • У меня есть 3000 строк «реальных» данных (это количество будет меняться от прогона к прогоне в зависимости от объема данных, которые есть у пользователя).
  • У меня есть 20 строк «контрольных» данных (опять же, это изменится в зависимости от количества контрольных строк, которые пользователь хочет использовать, начиная с нуля и выше).

Теперь я хочу вставить эти 20 «контрольных» строк примерно после каждых 150 строк или «реальных» данных (3000/20 = 150). Однако я не хочу, чтобы это было настолько точно, как это, поскольку я не хочу, чтобы контрольные строки были идентифицируемыми просто на основе их расположения в выходных данных.

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

Ответы [ 4 ]

3 голосов
/ 09 октября 2008

Всегда есть вероятность, что они приблизятся друг к другу, если вы сделаете это действительно случайно:)

Но я бы сделал следующее:

  1. У вас есть N строк реальных данных и x из контроля данных
  2. Чтобы получить индекс строки, вы должны вставить i -ую строку управления, я бы использовал: N/(x+1) * i + r, где r - это какое-то случайное число, отличающееся для каждой из строк управления, маленькое по сравнению N/x. Выберите любой способ определения r, это может быть гауссов или даже плоский дистрибутив. i - это индекс строки управления, поэтому 1<=i<x
  3. Таким образом, вы можете быть уверены, что избежите конденсации управляющих строк в одном месте. Также вы можете быть уверены, что они не будут находиться на одинаковом расстоянии друг от друга.
0 голосов
/ 09 октября 2008

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

Итак, выберите случайный интервал, скопируйте столько строк реальных данных, вставьте контрольные данные, повторите до конца. Как выбрать этот случайный интервал?

Я бы рекомендовал использовать отклонение по Гауссу со средним значением, установленным на реальный размер данных, деленный на размер контрольных данных, первый из которых можно было бы оценить при необходимости, а не измерить или предположить известный. Установите стандартное отклонение этого гауссиана в зависимости от того, сколько «спреда» вы готовы терпеть. Меньшее значение stddev означает более лептокуротическое распределение, что означает более строгую приверженность равномерному интервалу. Большее значение stdev означает более платикюртическое распределение и более слабую приверженность равномерному интервалу.

А как насчет первого и последнего разделов файла? То есть: как насчет вставки контрольных данных в самом начале или в самом конце? Одна вещь, которую вы можете сделать, - это придумать для них особые оценки ... но хороший трюк заключается в следующем: начните свой "индекс" с реальных данных за минус половину среднего значения по Гауссу и сгенерируйте свое первое отклонение. Не выводите никаких реальных данных, пока ваш «индекс» в реальных данных не станет законным. Симметричный трюк в конце данных также должен работать довольно хорошо (просто: продолжайте генерировать отклонения, пока не достигнете «индекса», по крайней мере, половины среднего гауссова после конца реальных данных. конец, генерировать данные в конце.

Вы хотите взглянуть не только на статистику: полезно разработать алгоритм для такого рода вещей, чтобы взглянуть на элементарную теорию массового обслуживания. См. Википедию или омнибус Тьюринга, в котором есть хорошая короткая глава на тему «Симуляция».

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

0 голосов
/ 09 октября 2008

В следующем примере с 3000 строками реальных данных и 20 управляющими строками (лучше с примером, чем с английским)

Если бы вы распределяли 20 контрольных строк как можно более равномерно между 3000 строками реальных данных, вы бы вставляли по одной в каждую 150-ю строку реальных данных. Так что выберите это число, 150, для следующего индекса вставки.
а) Генерация случайного числа от 0 до 150 и вычитание его из индекса вставки
б) Вставьте туда строку управления.
в) увеличить индекс вставки на 150
г) Повторите на шаге а)

Конечно, это очень грубый алгоритм, и он нуждается в нескольких улучшениях:)

0 голосов
/ 09 октября 2008

Вот моя мысль. Почему бы вам просто не перебрать существующие строки и «подбросить монету» для каждой строки, чтобы решить, будете ли вы вставлять туда случайные данные.

for (int i=0; i<numberOfExistingRows; i++)
{    
    int r = random();
    if (r > 0.5)
    {
        InsertRandomData();
    }    
}

Это должно дать вам хорошее случайное распределение по данным.

...