Сделали мы тут один заказ на программно-аппаратный комплекс для обнаружения нерегулярностей в сигнале (для посвященных: 353-й проект). Классно работает, всё что надо детектирует, чувствительность прекрасная, только вот ложноположительных срабатываний чуть-чуть многовато, Не то, чтобы много, но... многовато.
Я накрутил поверх детектора ещё один фильтр на анализе side-band-данных: если среднее отношение длительности импульсов меньше некоего порога -- значит ложняк (там физика процесса такая, что на регулярном сигнале положительных срабатываний быть не должно). На тестовых данных методом тыка Монте Карло определил оптимальный порог -- оказалось 25%. False positive легли в ТЗ, чувствительность пострадала, но не критично.
Псевдокод:
bool is_false_positive(int duration, int prev_duration)
{
float bias = prev_duration / duration; // отношение длительностей...
float confined_bias; // ... в диапазоне 0.5-2.0...
if (bias < 0.5)
confined_bias = 0.5;
else if (bias > 2.0)
confined_bias = 2.0;
else
confined_bias = bias;
if (confined_bias < 1.) // ... разворачивается относительно меньшей величины...
confined_bias = 1. / confined_bias; // ... теперь оно лежит в диапазоне [1..2];
float averaged_bias = exponential_average((confined_bias - 1.) * 100); // ... усредняется...
return averaged_bias <= 25; // и сравнивается с 25%
}
Нашли ошибку? Ну конечно :)
float bias = (float) prev_duration / duration;
Я тоже нашел, буквально через пару месяцев после выката проекта. Поправил -- и все развалилось. Во-первых порог в 25% съехал вниз к примерно 3%, а во-вторых фильтр начал статистически достоверно увеличивать количество ложноотрицательных (не-)срабатываний быстрее, чем уменьшать процент ложноположительных при любом пороге :) (что довольно легко объяснить, но выходит за рамки поста). Главный прикол в том, что фильтр с багой неплохо работал, хоть и на совсем другом принципе -- он срабатывал при монотонном уменьшении длительности. Ну что же, за этим есть определенная физика.
По здравому размышлению прикрутил багу обратно. Работает -- не трогай.