machine-learning - start - machine learning step by step
¿Cómo se escribe un programa para encontrar si ciertas palabras son similares? (5)
Es decir: "college" y "schoolwork" y "academy" pertenecen al mismo grupo; las palabras "essay", "scholarships", "money" también pertenecen al mismo cluster. ¿Es esto un problema de ML o NLP?
Supongo que podría compilar su propia base de datos de tales asociaciones para cantar las técnicas ML y NLP, pero también podría considerar consultar recursos existentes como WordNet para hacer el trabajo.
La cita famosa con respecto a su pregunta es por John Rupert Firth en 1957:
Usted sabrá una palabra de la compañía que mantiene
Para comenzar a profundizar en este tema, puede consultar esta presentación .
Si tiene una gran cantidad de documentos relacionados con el tema de interés, es posible que desee consultar Lacate Direchlet Allocation . LDA es una técnica NLP bastante estándar que agrupa automáticamente las palabras en temas, donde la similitud entre las palabras se determina mediante la colocación en el mismo documento (puede tratar una sola oración como un documento si eso satisface sus necesidades mejor).
Encontrará una serie de kits de herramientas de LDA disponibles. Necesitaríamos más detalles sobre su problema exacto antes de recomendar uno sobre otro. No soy lo suficientemente experto como para hacer esa recomendación de todos modos, pero al menos puedo sugerirle que mire a LDA.
Depende de cuán estricta sea tu definición de similar .
Técnicas de aprendizaje automático
Como han señalado otros , puede utilizar algo así como el análisis semántico latente o la correspondiente asignación latente de Dirichlet .
Similitud Semántica y WordNet
Como se señaló , es posible que desee utilizar un recurso existente para algo como esto.
Muchos trabajos de investigación ( ejemplo ) usan el término similitud semántica . La idea básica es computar que esto generalmente se hace al encontrar la distancia entre dos palabras en un gráfico, donde una palabra es un niño si es un tipo de su padre. Ejemplo: "pájaro cantor" sería un hijo de "pájaro". La similitud semántica se puede usar como una métrica de distancia para crear clusters, si lo desea.
Ejemplo de implementación
Además, si pone un umbral en el valor de alguna medida de similitud semántica, puede obtener un valor booleano True
o False
. Aquí hay un Gist que creé ( word_similarity.py ) que usa el lector de corpus de NLTK para WordNet . Es de esperar que eso te guíe en la dirección correcta y te brinde algunos términos de búsqueda más.
def sim(word1, word2, lch_threshold=2.15, verbose=False):
"""Determine if two (already lemmatized) words are similar or not.
Call with verbose=True to print the WordNet senses from each word
that are considered similar.
The documentation for the NLTK WordNet Interface is available here:
http://nltk.googlecode.com/svn/trunk/doc/howto/wordnet.html
"""
from nltk.corpus import wordnet as wn
results = []
for net1 in wn.synsets(word1):
for net2 in wn.synsets(word2):
try:
lch = net1.lch_similarity(net2)
except:
continue
# The value to compare the LCH to was found empirically.
# (The value is very application dependent. Experiment!)
if lch >= lch_threshold:
results.append((net1, net2))
if not results:
return False
if verbose:
for net1, net2 in results:
print net1
print net1.definition
print net2
print net2.definition
print ''path similarity:''
print net1.path_similarity(net2)
print ''lch similarity:''
print net1.lch_similarity(net2)
print ''wup similarity:''
print net1.wup_similarity(net2)
print ''-'' * 79
return True
Ejemplo de salida
>>> sim(''college'', ''academy'')
True
>>> sim(''essay'', ''schoolwork'')
False
>>> sim(''essay'', ''schoolwork'', lch_threshold=1.5)
True
>>> sim(''human'', ''man'')
True
>>> sim(''human'', ''car'')
False
>>> sim(''fare'', ''food'')
True
>>> sim(''fare'', ''food'', verbose=True)
Synset(''fare.n.04'')
the food and drink that are regularly served or consumed
Synset(''food.n.01'')
any substance that can be metabolized by an animal to give energy and build tissue
path similarity:
0.5
lch similarity:
2.94443897917
wup similarity:
0.909090909091
-------------------------------------------------------------------------------
True
>>> sim(''bird'', ''songbird'', verbose=True)
Synset(''bird.n.01'')
warm-blooded egg-laying vertebrates characterized by feathers and forelimbs modified as wings
Synset(''songbird.n.01'')
any bird having a musical call
path similarity:
0.25
lch similarity:
2.25129179861
wup similarity:
0.869565217391
-------------------------------------------------------------------------------
True
>>> sim(''happen'', ''cause'', verbose=True)
Synset(''happen.v.01'')
come to pass
Synset(''induce.v.02'')
cause to do; cause to act in a specified manner
path similarity:
0.333333333333
lch similarity:
2.15948424935
wup similarity:
0.5
-------------------------------------------------------------------------------
Synset(''find.v.01'')
come upon, as if by accident; meet with
Synset(''induce.v.02'')
cause to do; cause to act in a specified manner
path similarity:
0.333333333333
lch similarity:
2.15948424935
wup similarity:
0.5
-------------------------------------------------------------------------------
True
Word2Vec puede desempeñar un papel para encontrar palabras similares (contextualmente / semánticamente). En word2vec, tenemos palabras como vector en el espacio n-dimensional, y podemos calcular la distancia entre las palabras (distancia euclidiana) o simplemente podemos hacer clusters.
Después de esto, podemos encontrar algún valor numérico para la similitud b / w 2 palabras.