2012-08-11 23 views
6

No me di cuenta de que la función de ajuste de Python realmente separaba la cadena en caracteres individuales. Escribí la función python para Jaccard y usé el método de intersección de python. Pasé dos juegos en este método y antes de pasar los dos juegos a mi función jaccard utilizo la función set en el setring.Python: Distancia de Jaccard usando la intersección de palabras pero no la intersección de caracteres

ejemplo: supongo que tengo la cadena NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg que llamaría set(NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg) que separará cadena en caracteres. Entonces, cuando lo envío a la intersección con la función jaccard, en realidad miran intersección de caracteres en lugar de intersección de palabra a palabra. ¿Cómo puedo hacer una intersección de palabra a palabra?

#implementing jaccard 
def jaccard(a, b): 
    c = a.intersection(b) 
    return float(len(c))/(len(a) + len(b) - len(c)) 

si no llamo set función en mi cadena NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg me sale el siguiente error:

c = a.intersection(b) 
AttributeError: 'str' object has no attribute 'intersection' 

En vez de carácter a carácter intersección que quiero hacer palabra a palabra intersección y obtener el Jaccard semejanza.

Respuesta

9

Intenta dividir la cadena en las primeras palabras:

word_set = set(your_string.split()) 

Ejemplo:

>>> 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']) 
+0

En realidad, esto es exactamente lo que estaba buscando cuando uso la función de agregar durante la intersección busca la coincidencia completa. –

2

Esta propiedad ya no es exclusivo de los conjuntos:

>>> list('NEW Fujifilm') 
['N', 'E', 'W', ' ', 'F', 'u', 'j', 'i', 'f', 'i', 'l', 'm'] 

Lo que está pasando aquí es que la cadena está siendo tratado como una secuencia de iterable y está procesando carácter por carácter.

Lo mismo que está viendo con juego:

>>> set('string') 
set(['g', 'i', 'n', 's', 'r', 't']) 

Para el montaje, utilice .add() en un conjunto existente, ya que .add() no utiliza un 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']) 

o bien, utilizar split(), una tupla, una lista, o alguna alternativa iterables lo que la cadena no es tratado como un iterable:

>>> set('something'.split()) 
set(['something']) 
>>> set(('something',)) 
set(['something']) 
>>> set(['something']) 
set(['something']) 

añadir más elementos Está basado en la cadena en una base palabra por palabra:

>>> se=set(('Something',)) | set('NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'.split()) 

O, si usted necesita una comprensión de algo de lógica a medida que añada al conjunto:

>>> 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']) 

Y funciona cómo esperar ahora:

>>> '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']) 
+1

De la "palabra de intersección palabra" Creo que el OP realmente está después de 'set (a.split()). Intersection (b.split())' (caso del módulo y detalles de la puntuación).) – DSM

+0

@drewk gracias por el ejemplo y una gran explicación. ¡¡¡Brillante!!! –

6

Mi función para calcular Jaccard distancia:

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 
2

Este es el que escribió basándose en la función 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