Как я номера распознавал
Математика вещь великая. Есть такая штука, как дистанция или расстояние. Обычно оно воспринимается между координатами, но в целом никто не мешает создавать свои дистанции. Когда-то давно я делал проект, где нужно было распознавать номера автомобилей и сравнивать с тем, что задан в системе. Но неиронная сеть, которой я пользовался возвращала достаточно шумные данные. А мне нужно было при нахождении номера слать нотификацию. И тут я подумал, надо как-то определять, что номера "похожи")
Ввести расстояние удобно чисто по той причине, что можно настраивать "что считается похожим" с точки зрения некоторой точности. Типа возьмём две строки. Если расстояние между ними условные 10 или условные 100, и мы настраиваем какие значения мы принимаем за "правильные". Очевидно, что 100 может получиться менее точным, так как будет группировать в одну больше строк. Вторая причина — удобная визуализация. Распознавания с видео-камеры представляют из себя временной ряд "строка" и кадр. И в данном случае очень удобно можно введя понятие расстояния видеть, как проходило распознавание и по какой "дельте" группировать. Но вернёмся к задаче
Расстояние Левенштейна — достаточно известная штука в компьютерной лингвистике. Определяется, как если сравнивать две строки, какое количество букв нужно поменять, чтобы получить другое слово.
Например kitten → sitting — расстояние 3. Меняем k на s, e в конце на i и добавляем g в конец. Получается 3 операции.
Это было первое, что я попробовал и конечно же оно не работало. Проблема в структуре "шума" нейронки. Левинштейн очень не устойчив к перестановкам символов, что было довольно частой ошибки той нейронки)
Что Левинштейн не подошёл, давайте придумаем своё. Посидев недельку с данными, посмотрев на то, как выглядит ошибка неиронки. Я придумал следующее решение. Нашёл самые часто путающиеся символы, посчитал их количество. Задал им веса таким образом, чтобы сумма любой пары весов не давало какой-то другой вес (простые числа). И дальше просто суммировал символы по весам. Номера case insensitive — так что нужно было сравнивать только символы и числа. Допустим объединив цифры A и H которые неросеть часто путала, задав им вес 1 получалось что номера AA123A и HH123A — это одинаковые номера. Тоже самое с цифрами 3 и 8, то есть AH128H — это тот же самый номер по весу. Это работало лучше, но проблема оставалась. У нас нет расстояния, так как веса из простых чисел дают суммы, которые никак не назовёшь расстоянием) Поэтому это как-то работало, но уточнять смотря на графики не получалось
А что если поместить символы и цифры на круге? Представляем, что мы те же группы символов разместили на единичной окружности, а те которые тоже "путаются", но не так часто, просто постарались поставить соседями на этом круге. А что же является расстоянием. В номерных знаках фиксированное число символов (там есть различия с транспортными номерами, но их проще обработать программно). Поэтому в качестве расстояния мы используем — площадь многоугольника получившегося из точек на этой окружности. И вот это уже работало довольно неплохо)
Возможно компьютерные лингвисты знают решение ещё элегантнее и известное, но я специалист в первую очередь по трекингу и CV в данном случае, так что придумал вот такой велосипед. И вот пример довольно любопытного применения математики, когда просто придумываешь своё "расстояние" между строками. И на самом деле таких применений масса)