Добрый день.
Пытаюсь решить следующую задачу. Нужно определить степень похожести двух массивов
и
, причём меряется это похожесть довольно хитро (из-за специфики их происхождения — массивы берутся из реальных данных, измеряемых приборами).
Оба массива являются массивами расстояний до целей, в идеальных условиях они должны были бы попросту совпасть поэлементно (может только отличаться порядок следования чисел). Но получены они разным способом, каждый из которых имеет тенденцию к ошибкам, которые нужно попытаться обнаружить путём сравнения массивов.
Массив
может иметь ошибку следующего характера. Одна и та же цель может дать в массив несколько записей, которые будут немного отличаться (из-за погрешности измерений).
Массив
может иметь ошибку другого рода. В нём может появиться большое количество фиктивных целей, которые появились как шум (то есть помимо записей, соответствующих реальным целям, массив
содержит также данные, которые в общем-то можно считать случайными). При этом массив
не может содержать две записи об одной и той же цели (шумовые записи тоже не могут совпасть с каким-то "полезным" сигналом, так как
это на самом деле данные от радара, и если он увидит две записи с одинаковыми значениями дальности, он их просто запишет как одну запись).
Таким образом, массив
должен быть признан близким к массиву
, если
можно преобразовать в
посредством сопоставления некоторым записям массива
набора записей из массива
, причём одна запись из
не может быть приписана к двум различным записям из
, также нужно учесть возможность погрешности измерения, то есть если некоторая запись из
приписывается некоторой записи из
, то разница соответствующих чисел (расстояний) должна быть мала (на самом деле тут имеет смысл брать квадрат этой разницы и суммировать его к невязке, которая и будет мерой отклонения массивов).
Сейчас эту задачу я решаю дурацким образом. Просто сортирую оба массива по возрастанию, затем считаю расстояние Левенштейна от
до
, задав цены операций так: вставка — нуль, удаление — бесконечность, замена — квадрат разности чисел (то есть разрешено неограниченное число вставок — решает проблему шума, запрещены удаления — каждая запись получит соответствие, цена замены просто некоторая весовая функция, можно в принципе и другую было взять, это уже не важно). Такой подход не решает последнюю проблему — одному объекту может соответствовать несколько записей из
(при указанном подходе каждому числу из
будет сопоставлено число из
, причём разным элементам сопоставляются разные элементы). Если реальные данные будут иметь такую коллизию, то мы получим огромную невязку, хотя в действительности массивы очень похожи (просто некоторые элементы продублированы). Например если таким образом посчитать разницу между массивами
и
, то невязку будет огромная, так как они будут сопоставлены как
(по индексам), в действительности же видно, что скорее всего набор чисел
это всё число
, измеренное с погрешностью.
Подскажите, пожалуйста, как можно попытаться устранить этот недостаток?
У меня есть идея — выполнить предобработку массива
, попытавшись предсказать группы записей, относящиеся к одной цели, и затем склеить их, заменив, скажем, средним значением, но тут можно по-разному делать, наивный способ — ввести порог
, и если в отсортированном массиве соседние элементы отстоят не более чем на
, то записываем их в одну группу, но тогда в одной группе могут оказаться элементы с очень большим разбросом, при этом нельзя разумно ограничить разброс, так как тогда при равномерно распределённых данных мы можем распределить элементы совсем неправильно, например пусть массив представляет собой последовательность
, тогда при максимально допустимом разбросе равном
допустимы разбиения
и
, причём оба они могут быть реальными, но нет никакого способа предпочесть одно разбиение другому.
Другой способ выполнить разбиение основан на анализе массива
с помощью данных из массива
. Сортируем
, затем наносим точки массива
на числовую прямую и применяем к
правило ближайшего соседа — каждую точку
относим к той записи из
, к которой она наиболее близка. Такой подход мне кажется намного корректнее, но я пока не уверен в его правильности.
Ещё можно пытаться считать расстояние Левенштейна, но ввести дополнительную операцию — клонирование элемента массива
, приписав ей цену нуль. Но этот подход я пока не очень хорошо продумал.
Может есть какие-то ещё разумные способы найти степень различия массивов?
Возможно эта задача относится больше к анализу данных, а не к программированию. Если тут как-то могут сработать методы машинного обучения, это тоже будет очень хорошо — в там, где эта задача будет применяться, есть возможность накапливать статистику таких массивов, а значит можно как-то со временем уточнять какие-нибудь параметры метода...
PS. В тексте я упомянул радар, скорее всего кто-то это заметит, и скажет, что радар обычно даёт помимо дистанции до цели ещё и её скорость. Это правда, в моих данных скорость также присутствует, то есть в действительности массив
представляет собой множество пар расстояние-скорость, но во-первых для массива
скорость установить весьма проблематично, а во-вторых, если бы она и была, то задача просто повысила бы размерность с
до
, и скорее всего метод обработки был бы аналогичным (просто мерить расстояние между точками на плоскости, а не на прямой, или же ещё проще — сначала выполнить обработку по расстояниям, затем для групп одинаковых расстояний сделать обработку по скоростям, это кстати по-моему соответствует какой-то метрике на плоскости, что-нибудь типа
при достаточно большом
, учитываем тот факт, что для реальных данных значения координат
ограничены сверху, и поэтому нам реально нужна метрика не на всей плоскости, а лишь на ограниченной её области, для которой достаточно большое
в указанной выше формуле вполне сгодится).
-- 31.05.2016, 14:27 --Цитата:
Программирование
Обсуждение вопросов, связанных с программированием на языках общего назначения, таких как C/C++, Pascal/Delphi, Java, C#, Perl, Python и т.д. Обсуждение алгоритмов без привязки к языку программирования ведется НЕ ЗДЕСЬ, а в корне раздела Computer Science
Прошу модераторов переместить тему в корень раздела Computer Science, тема относится к алгоритмике (и скорее даже к анализу данных), а не к языкам программирования. Извините за оплошность.