что является хорошей метрикой для определения того, являются ли 2 строки «достаточно похожими»

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

В настоящее время я делю общее количество правок на размер большей строки. Если это значение ниже некоторого порога, в настоящее время случайно установленного на 25%, то они «достаточно похожи».

Однако это совершенно произвольно, и я не думаю, что это очень хороший способ вычислить сходство. Есть ли какое-то математическое уравнение или подход к вероятности / статистике, чтобы взять данные о расстоянии Левенштейна и использовать их, чтобы сказать: «Да, эти строки достаточно похожи, исходя из количества сделанных изменений и размера строк»?

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

ОБНОВЛЕНИЕ

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


На данный момент мой алгоритм (псевдокод) примерно такой:

/*
 * The input lists represent the Strings I want to test for similarity. The
 * Strings are split apart based on new lines / carriage returns because Java
 * stack traces are not a giant one-line String, rather a multi-line String.
 * So each element in the input lists is a "line" from its stack trace.
 */
calculate similarity (List list1, List list2) {

    length1 = 0;
    length2 = 0;
    levenshteinDistance = 0;

    iterator1 = list1.iterator();
    iterator2 = list2.iterator();

    while ( iterator1.hasNext() && iterator2.hasNext() ) {

        // skip blank/empty lines because they are not interesting
        str1 = iterator1.next();    length1 += str1.length();
        str2 = iterator2.next();    length2 += str2.length();

        levensteinDistance += getLevenshteinDistance(str1, str2);
    }

    // handle the rest of the lines from the iterator that has not terminated

    difference = levenshteinDistance / Math.max(length1, length2);

    return (difference < 0.25) ? true : false; // <- arbitrary threshold, yuck!
}

23
задан Hristo 11 December 2011 в 22:37
поделиться