Python: расстояние Jaccard с использованием пересечения слов, но не пересечения символов
Я не понял, что функция набора Python фактически разделяет строку на отдельные символы. Я написал функцию python для Jaccard и использовал метод пересечения python. Я передал два набора в этот метод и перед передачей двух наборов в мою функцию jaccard я использую функцию set на сетринге.
пример: Предположим у меня есть строка NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg
Я бы назвал set(NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg)
который будет разделять строку на символы. Поэтому, когда я отправляю его на пересечение функций jaccard, на самом деле посмотрите на пересечение символов вместо пересечения слов. Как я могу сделать слово в слово пересечение.
#implementing jaccard
def jaccard(a, b):
c = a.intersection(b)
return float(len(c)) / (len(a) + len(b) - len(c))
если я не называю set
функция на моей строке NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg
Я получаю следующую ошибку:
c = a.intersection(b)
AttributeError: 'str' object has no attribute 'intersection'
вместо пересечения символов с символами я хочу сделать пересечение слов и получить сходство джаккарда.
4 ответов
попробуйте сначала разделить строку на слова:
word_set = set(your_string.split())
пример:
>>> word_set = set("NEW Fujifilm 16MP 5x".split())
>>> character_set = set("NEW Fujifilm 16MP 5x")
>>> word_set
set(['NEW', '16MP', '5x', 'Fujifilm'])
>>> character_set
set([' ', 'f', 'E', 'F', 'i', 'M', 'j', 'm', 'l', 'N', '1', 'P', 'u', 'x', 'W', '6', '5'])
моя функция для вычисления расстояния Жаккара:
def DistJaccard(str1, str2):
str1 = set(str1.split())
str2 = set(str2.split())
return float(len(str1 & str2)) / len(str1 | str2)
>>> DistJaccard("hola amigo", "chao amigo")
0.333333333333
это свойство не является уникальным для комплектов:
>>> list('NEW Fujifilm')
['N', 'E', 'W', ' ', 'F', 'u', 'j', 'i', 'f', 'i', 'l', 'm']
что происходит здесь заключается в том, что строка рассматривается как последовательность Iterable и обрабатывается посимвольно.
то же самое, что вы видите с set:
>>> set('string')
set(['g', 'i', 'n', 's', 'r', 't'])
исправить, использовать .add () на существующем наборе, так как.add () не использует interable:
>>> se=set()
>>> se.add('NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg')
>>> se
set(['NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'])
или используйте split (), кортеж, список или некоторую альтернативную итерацию, чтобы строка не рассматривалась как iterable:
>>> set('something'.split())
set(['something'])
>>> set(('something',))
set(['something'])
>>> set(['something'])
set(['something'])
добавить больше элементов на основе вашей строки на основе слово за словом:
>>> se=set(('Something',)) | set('NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'.split())
или, если вам нужно понимание для некоторой логики, как вы добавляете к набору:
>>> se={w for w in 'NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'.split()
if len(w)>3}
>>> se
set(['Shoot', 'CAMERA', 'Point', 'screen.jpg', 'Zoom', 'Fujifilm', '16MP', 'Optical'])
и это работает так, как вы ожидаете сейчас:
>>> 'Zoom' in se
True
>>> s1=set('NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'.split())
>>> s2=set('Fujifilm Optical Zoom CAMERA NONE'.split())
>>> s1.intersection(s2)
set(['Optical', 'CAMERA', 'Zoom', 'Fujifilm'])
Это тот, который я написал на основе функции set -
def jaccard(a,b):
a=a.split()
b=a.split()
union = list(set(a+b))
intersection = list(set(a) - (set(a)-set(b)))
print "Union - %s" % union
print "Intersection - %s" % intersection
jaccard_coeff = float(len(intersection))/len(union)
print "Jaccard Coefficient is = %f " % jaccard_coeff