На сколько одна накладная "похожа" на другую и получить коэффициент похожести?
Я понимаю, что скорее всего надо это решать с помощью https://ru.wikipedia.org/wiki/Коэффициент_Жаккара
На сколько долгий будет расчет просто с бумажкой и ручкой без компа?
Вам стоит уточнить то, что вы понимаете под "похожестью", потому что из условия не совсем понятно что вы хотите, т.к. есть несколько методик по расчету таких коэфициентов,
На сколько долгий будет расчет просто с бумажкой и ручкой без компа?
на этот вопрос не ответить т.к. вы не выбрали метод для определения похожести.
pcdesign, тогда в чем пробема подставить значения в формулу и расчитать? (сначала с бумажкой и ручкой)
upd: как я понял вы хотите, чтобы значения ключей тоже учитывались тогда "a+b" у вас должно быть равно сумме значений ключей, а "c" кол-ву схожих элементов 3/(6+5-3) для вашего случая.
pcdesign, алгоритм такой:
1) подсчитываете значение ключей в первом словаре
2) подсчитываете значение ключей во втором словаре
3) находите одинаковые ключи в словарях
4) берете меньше значение из 2 и суммируете с переменной, которая играет роль "c"
5) рассчитываете значение по формуле
Не совсем понятно как вы собираетесь применить коэффициент Жаккарда в чистом виде, если у вас важно количество? Очевидно требуется какая-то модификация и вероятно их можно придумать несколько вопрос лишь в том, что именно вы в своем случае понимаете под похожестью и для чего собираетесь использовать.
Что более важно для похожести - наличие элемента или его количество?
Самое примитивное решение в лоб использовать "дробное" количество видов. Например считать за один вид максимальное количество по обеем накладным. В данном случае у вас 2 вида в первой накладоной, и 1,66 во второй, и разность 1,66
pcdesign, ну тут отсутствие элемента это фактически его наличие с нулевым количеством, а вы говорили, что вам важнее отсутствие/наличие чем количество.
Но можно взять среднее между Жаккадом и этим методом... не знаю как его назвать - нормализованной дистанции?
Значения важны.
Иначе вопрос был бы как сравнить два списка и вычислить похожесть двух списков.
И вопрос стоит в коэффициенте похожести, а не в банальном сравнении ключей.
pcdesign, в таком случае видимо речь про расширенную формулу
Насколько я понимаю, она подразумевает это:
def coeffj(d1, d2):
a = sum(d1.values())
b = sum(d2.values())
c = sum(min(d1.get(key,0), d2.get(key,0)) for key in d1.keys()|d2.keys())
return c/(a + b - c)
Если не то, то изложите своим языком, как должен рассчитываться этот критерий. К тому же не понятно, как должна работать для отрицательных значений. Если они должны учитываться как-то по-другому, то можете доработать функцию (изменить обработку get(, 0)) . Сейчас отсутствующий ключ приравнивается к 0.
Если отсутствие слова в словаре равносильно слову с весом в 0, то можно считать какую-угодно меру от векторов чисел. Хоть корень из суммы квадратов разностей по каждому слову.
В вашем примере это будет (1-2)^2+(2-2)^2+(3-0)^2+(1-0)^2 = 11.
Чем меньше это число, тем похожее словари. Можно ее еще как-то нормировать, поделив на, допустим количество уникальных ключей в обоих словарях. Или на количество всевозможных слов.
Если ваш язык/структура позволяет пройтись по словарю в лексикографическом порядке, то можно подсчитать такую меру за линейное время выполняя что-то вроде слияния сортированных списков. Изначально 2 указателя на минимальные элементы (по словарю) в каждом словаре. Если два элемента с одинаковым ключем, то считайте разность двух весов и двигайте оба указателья. Иначе считайте разность веса с минимальным ключем и 0 и двигайте только этот указатель. Случай, когда один из словарей уже пуст совпадает со вторым случаем.
В питоне позволяет обходить ключи по порядку OrderedDict.