Calcular la similitud del coseno dadas 2 cadenas de oraciones


De Python: tf-idf-coseno: para encontrar la similitud de documentos, es posible calcular la similitud de documentos usando el coseno tf-idf. Sin importar bibliotecas externas, ¿hay alguna forma de calcular la similitud de coseno entre 2 cadenas?

s1 = "This is a foo bar sentence ."
s2 = "This sentence is similar to a foo bar sentence ."
s3 = "What is this string ? Totally not related to the other two lines ."

cosine_sim(s1, s2) # Should give high cosine similarity
cosine_sim(s1, s3) # Shouldn't give high cosine similarity value
cosine_sim(s2, s3) # Shouldn't give high cosine similarity value
Author: Ronak Shah, 2013-03-02

4 answers

Una implementación simple de pure-Python sería:

import re, math
from collections import Counter

WORD = re.compile(r'\w+')

def get_cosine(vec1, vec2):
     intersection = set(vec1.keys()) & set(vec2.keys())
     numerator = sum([vec1[x] * vec2[x] for x in intersection])

     sum1 = sum([vec1[x]**2 for x in vec1.keys()])
     sum2 = sum([vec2[x]**2 for x in vec2.keys()])
     denominator = math.sqrt(sum1) * math.sqrt(sum2)

     if not denominator:
        return 0.0
     else:
        return float(numerator) / denominator

def text_to_vector(text):
     words = WORD.findall(text)
     return Counter(words)

text1 = 'This is a foo bar sentence .'
text2 = 'This sentence is similar to a foo bar sentence .'

vector1 = text_to_vector(text1)
vector2 = text_to_vector(text2)

cosine = get_cosine(vector1, vector2)

print 'Cosine:', cosine

Impresiones:

Cosine: 0.861640436855

La fórmula del coseno utilizada aquí se describe aquí.

Esto no incluye la ponderación de las palabras por tf-idf, pero para usar tf-idf, necesita tener un corpus razonablemente grande a partir del cual estimar los pesos de tfidf.

También puede desarrollarlo aún más, utilizando una forma más sofisticada de extraer palabras de un fragmento de texto, derivarlo o lematizarlo, etc.

 128
Author: vpekar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-02 12:49:00

La respuesta corta es "no, no es posible hacer eso de una manera basada en principios que funcione ni remotamente bien". Es un problema sin resolver en la investigación de procesamiento del lenguaje natural y también pasa a ser el tema de mi trabajo de doctorado. Voy a resumir muy brevemente dónde estamos y le señalaré algunas publicaciones:

Significado de las palabras

La suposición más importante aquí es que es posible obtener un vector que representa cada palabra en la oración en quesion. Este vector generalmente se elige para capturar los contextos en los que puede aparecer la palabra. Por ejemplo, si solo consideramos los tres contextos "eat", "red" y "fluffy", la palabra "cat" podría representarse como [98, 1, 87], porque si leyeras un fragmento de texto muy largo (unos pocos miles de millones de palabras no son infrecuentes para el estándar de hoy), la palabra "cat" aparecería muy a menudo en el contexto de "fluffy" y "eat", pero no tan a menudo en el contexto de "red". De la misma manera, "perro" podría ser representado como [87,2,34] y" umbrella " podría ser [1,13,0]. Imaginando estos vectores como puntos en el espacio 3D, " gato "está claramente más cerca de" perro "que de" paraguas", por lo tanto" gato "también significa algo más similar a" perro "que a un"paraguas".

Esta línea de trabajo ha sido investigada desde principios de los 90 (por ejemplo, este trabajo de Greffenstette) y ha dado algunos resultados sorprendentemente buenos. Por ejemplo, aquí hay algunas entradas aleatorias en un tesauro que construí recientemente al tener mi computadora leer wikipedia:

theory -> analysis, concept, approach, idea, method
voice -> vocal, tone, sound, melody, singing
james -> william, john, thomas, robert, george, charles

Estas listas de palabras similares se obtuvieron completamente sin intervención humana - usted introduce texto y regresa unas horas más tarde.

El problema con las frases

Usted podría preguntarse por qué no estamos haciendo lo mismo para frases más largas, como "los zorros de jengibre aman la fruta". Es porque no tenemos suficiente texto. Para que establezcamos de manera confiable a qué es similar X, necesitamos ver muchos ejemplos de X que se usan en contexto. Cuando X es una sola palabra como "voz", esto no es demasiado difícil. Sin embargo, a medida que X se hace más largo, las posibilidades de encontrar ocurrencias naturales de X se vuelven exponencialmente más lentas. Para comparar, Google tiene aproximadamente 1B páginas que contienen la palabra "zorro "y no una sola página que contenga" zorros de jengibre aman la fruta", a pesar del hecho de que es una frase perfectamente válida en inglés y todos entendemos lo que significa.

Composición

Para abordar el problema de la escasez de datos, queremos realizar la composición, es decir, tomar vectores para las palabras, que son fáciles de obtener a partir de texto real, y poner los juntos de una manera que captura su significado. La mala noticia es que nadie ha sido capaz de hacerlo bien hasta ahora.

La forma más simple y obvia es sumar o multiplicar los vectores de palabras individuales juntos. Esto conduce a un efecto secundario indeseable que "los gatos persiguen a los perros" y "los perros persiguen a los gatos" significaría lo mismo para su sistema. Además, si estás multiplicando, tienes que ser extra cuidado o cada oración terminará representada por [0,0,0,..., 0], lo que derrota el punto.

Otras lecturas

No voy a discutir los métodos más sofisticados para la composición que se han propuesto hasta ahora. Le sugiero que lea Katrin Erk "Vector space models of word meaning and phrase meaning: a survey". Esta es una muy buena encuesta de alto nivel para empezar. Desafortunadamente, no está disponible gratuitamente en el sitio web del editor, envíe un correo electrónico al autor directamente para obtener una copia. En ese documento encontrará referencias a muchos métodos más concretos. Los más comprensibles son porMitchel y Lapata (2008) yBaroni y Zamparelli (2010) .


Editar después del comentario de @vpekar: La conclusión de esta respuesta es enfatizar el hecho de que si bien existen métodos ingenuos (por ejemplo, adición, multiplicación, similitud superficial, etc.), estos son fundamentalmente defectuosos y en general uno no debería esperar gran actuación de ellos.

 47
Author: mbatchkarov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-05 20:59:49

Gracias @vpekar por su implementación. Ayudó mucho. Acabo de descubrir que pierde el peso tf-idf mientras calcula la similitud del coseno. El Contador (palabra) devuelve un diccionario que tiene la lista de palabras junto con su ocurrencia.

Cos(q, d) = sim(q, d) = (q · d)/(|p|,|d|) = (sum(qi, di)/(sqrt(sum(qi2)))*(sqrt(sum(vi2))), donde i = 1 v)

  • qi es el peso tf-idf del término i en la consulta.
  • di es el tf-idf
  • peso del término i en el documento. / q| y / d / son las longitudes de q y d.
  • Esta es la similitud de coseno de q y d . . . . . . o, equivalentemente, el coseno del ángulo entre q y d.

Por favor, siéntase libre de ver mi código aquí. Pero primero tendrá que descargar el paquete anaconda. Se establecerá automáticamente la ruta de Python en Windows. Agregue este intérprete de python en Eclipse.

 1
Author: novice_dev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-11 23:41:32

Bueno, si eres consciente de incrustaciones de palabras como Glove/Word2Vec/Numberbatch, tu trabajo está a medio hacer. Si no, permítanme explicar cómo se puede abordar esto. Convierta cada oración en tokens de palabras, y represente cada uno de estos tokens como vectores de alta dimensión (utilizando las incrustaciones de palabras pre-entrenadas, o podría entrenarlas usted mismo incluso!). Por lo tanto, ahora simplemente no capturan su similitud superficial, sino que extraen el significado de cada palabra que comprende la oración como un todo. Después de esto calcular su similitud coseno y se establece.

 1
Author: TheSN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-05 05:44:39