2013-05-13 6 views
1

У меня есть набор данных, который имеет три поля: id, feature и frequency. То, что я хочу сделать, это выяснить, для группы заданных идентификаторов, какая функция имеет наибольшее распространение частот. Результат, который я хочу, состоит в том, что если я разделил группу id на две подгруппы, используя медианное значение частоты для этой функции, у меня есть две группы, которые отличаются друг от друга и все же имеют примерно одинаковый размер.Рассчитать дисперсию частот, когда набор данных не содержит записей нулевого нуля

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

Учитывая таблицы базы данных, которая выглядит примерно так:

id | feature | frequency 
---+---------+------------- 
0 | 0  | 1 
0 | 1  | 1 
0 | 2  | 0 
1 | 0  | 2 
1 | 1  | 2 
1 | 2  | 0 
2 | 0  | 3 
2 | 1  | 3 
2 | 2  | 8 
3 | 0  | 4 
3 | 1  | 8 
3 | 2  | 10 
4 | 0  | 5 
4 | 1  | 10 
4 | 2  | 12 
  • Функция 0 имеет частоты 1, 2, 3, 4, 5
  • Feature 1 имеет частоты 1, 2, 3 , 9, 10
  • Feature 2 имеет частоты 0, 0, 4, 10, 12

Мы можем видеть, что функция 2 имеет самый большой разброс, и что splittin g на 4 сделало бы приятную точку для разделения на две группы (0, 0 и 4 в одну группу и 10 и 12 в другую группу).

можно рассчитать с помощью следующего запроса SQL:

SELECT feature, variance(frequency) as f FROM Dataset WHERE id IN (<list of ids>) GROUP BY feature ORDER BY f DESC LIMIT 1; 

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

id | feature | frequency 
---+---------+------------- 
0 | 0  | 1 
0 | 1  | 1 
1 | 0  | 2 
1 | 1  | 2 
2 | 0  | 3 
2 | 1  | 3 
2 | 2  | 8 
3 | 0  | 4 
3 | 1  | 8 
3 | 2  | 10 
4 | 0  | 5 
4 | 1  | 10 
4 | 2  | 12 

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

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

Так что мои вопросы:

  1. Есть ли способ сделать это в SQL?
  2. Если нет, существует ли способ «корректировать» дисперсию, рассчитанную для учета количества нулевых записей? (Предположим, я знаю, сколько нулевых записей было опущено)
  3. Если да, есть ли способ сделать это в одном SQL-запросе, как указано выше? (опять же, предположим, что я заранее знаю, сколько нулевых записей было опущено)
  4. Если нет, существует ли способ использования энтропии и настройки для действительных значений?
  5. Есть ли какая-то другая мера (например, эксцесс?), Которую я должен рассмотреть? Есть ли какие-либо, которые могут быть легко скорректированы для отсутствия нулевых записей?
  6. Или любые другие предложения или альтернативные решения?

ответ

1

Что касается заполнения пробелов в таблице, вы можете использовать «вспомогательный» ТЕМП таблицу с действительным списком функций, UNION недостающие значения нулевой частоты путем в CROSS JOIN. «Как» действительно зависит от используемого вами языка базы данных. Например, предположим, что у вас есть таблица с именем «хелпер» с тремя строками (для трех разных функций). Тогда это может работать:

select id, feature, frequency 
from have 
union 
select b.id 
    , a.feature 
    , 0 as frequency 
from helper a 
cross join have b 
where not exists (
    select 1 from have b1 
    where b1.id=b.id 
    and b1.feature = a.feature 
    ) 

Here is an SQLFiddle.