Соответствие несопоставленных строк на основе неизвестного шаблона - PullRequest
2 голосов
/ 03 апреля 2010

Хорошо, ребята, я действительно повредил свой мозг из-за этого, и мне любопытно, если вы, ребята, можете дать мне какие-либо указатели в правильном направлении, я должен идти.

Ситуация такова:

Допустим, у меня есть коллекция строк (пусть будет ясно, что структура этих строк неизвестна. Фактически, я могу сказать, что строка содержит только знаки из таблицы ASCII, и поэтому я не надо беспокоиться о странных китайских знаках).

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

"[001].[FOO].[TEST] - 'foofoo.test'",  
"[002].[FOO].[TEST] - 'foofoo.test'",  
"[003].[FOO].[TEST] - 'foofoo.test'",  
"[001].[FOO].[TEST] - 'foofoo.test.sample'",  
"[002].[FOO].[TEST] - 'foofoo.test.sample'",    
"-001- BAR.[TEST] - 'bartest.xx1",  
"-002- BAR.[TEST] - 'bartest.xx1"  

Теперь мне нужно найти способ найти логические группы (и подгруппы) из этого набора строк, поэтому в приведенном выше примере, просто рациональным мышлением, вы можете объединить первые 3, 2 после этого и последние 2. Также результирующие группы из первых 5 могут быть объединены в одну основную группу с 2 подгруппами, это должно дать вам что-то вроде этого:

{
    {
        "[001].[FOO].[TEST] - 'foofoo.test'",  
        "[002].[FOO].[TEST] - 'foofoo.test'",  
        "[003].[FOO].[TEST] - 'foofoo.test'",  
    }
    {
        "[001].[FOO].[TEST] - 'foofoo.test.sample'",  
        "[002].[FOO].[TEST] - 'foofoo.test.sample'",    
    }
}
{
    {
        "-001- BAR.[TEST] - 'bartest.xx1",  
        "-002- BAR.[TEST] - 'bartest.xx1"  
    }
}

Извините за макет выше, но отступ в 4 пробела, кажется, не работает правильно (или я не в порядке).

В любом случае, я не уверен, как решить эту проблему (как получить желаемый результат, как указано выше).

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

Еще одна мысль, о которой я подумал, - это анализ каждого отдельного слова в строке (поэтому уберите все не алфавитные или числовые символы и разделите их по ним), и если X% совпадает, я могу предположить, что строки принадлежат одной и той же группе. (где Х, вероятно, будет около 80/90). Тем не менее, я нахожу область спекуляции довольно большой. Например, при сопоставлении строк с каждыми 20 словами изменение попадания выше 80% является довольно большим (это означает, что 4 слова могут отличаться), однако при сопоставлении только 8 слов могут различаться не более 2 слов.

Мой вопрос к вам: каков логичный подход в вышеуказанной ситуации?

Что касается примера reallife:

Заранее спасибо!

Ответы [ 5 ]

3 голосов
/ 03 апреля 2010

По сути, я бы рассматривал каждую строку как набор символов. Я бы определил вид расстояния между двумя строками, который будет выглядеть как «количество символов, принадлежащих обеим строкам», деленное на «общее количество символов в строке 1 + общее количество символов в строке 2». (ну, это не математически расстояние ...) и тогда я бы попробовал применить некоторые алгоритмы к cluster вашему набору строк.

Ну, это просто базовая идея, но я думаю, что это было бы хорошим началом для экспериментов ...

1 голос
/ 03 апреля 2010

Опираясь на ответ @PierrOz ', вы можете поэкспериментировать с несколькими показателями и провести статистический кластерный анализ по этим показателям.

Например, вы можете использовать четыре показателя:

  1. Сколько букв (в верхнем / нижнем регистре)
  2. Сколько цифр
  3. Сколько из ([,],.)
  4. Сколько других символов (вероятно) не включено выше

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

R имеет ряд функций для кластерного анализа. Это может быть хорошей отправной точкой .


Запоздалая мысль: мерами могут быть практически все, что вы придумываете. Еще несколько примеров:

  • Binary: содержит ли строка заданный символ (0 или 1)?
  • Binary: содержит ли строка заданную подстроку?
  • Количество: сколько раз появляется данная подстрока?
  • Двоичный код: содержит ли строка все эти символы?

Достаточно, чтобы хотя бы на выходных повозиться ...

1 голос
/ 03 апреля 2010

Я бы рекомендовал использовать это: http://en.wikipedia.org/wiki/Hamming_distance в качестве расстояния.

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

[BSS]_Darker_Than_Black_-_The_Black_Contractor_-_Gaiden_-_01_[35218661].mkv
->
[BSS]_Darker_Than_Black_-_The_Black_Contractor_-_Gaiden_-_01_.mkv

Проверка проста - это всегда 10 символов, первый - [, последний - ], а остальные ALPHA-numeric:)

С эвристикой и максимальным расстоянием до 4 ваши вещи будут работать в подавляющем большинстве случаев.

Удачи!

1 голос
/ 03 апреля 2010

Ваш вопрос нелегко понять, но я думаю, что то, что вы спрашиваете, невозможно сделать удовлетворительным образом, учитывая любую группу строк. Возьмите эти строки, например:

[1].[2].[3].[4].[5]
[a].[2].[3].[4].[5]
[a].[b].[3].[4].[5]
[a].[b].[c].[4].[5]
[a].[b].[c].[d].[5]
[a].[b].[c].[d].[e]

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

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

Редактировать: Интересно, будет ли хорошо, если одна строка окажется в нескольких разных группах? Это может значительно упростить проблему и более надежно дать вам полезную информацию, но в итоге вы получите более крупное дерево группирования с тем же узлом, скопированным в разные ветви.

0 голосов
/ 03 апреля 2010

Я бы испытал искушение заняться этим с помощью кластерного анализа методов. Хит Википедия для вступления. И другие ответы, вероятно, относятся к области кластерного анализа, но вы можете найти некоторые другие полезные подходы, прочитав немного шире.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...