2011-08-08 15 views
6

Estoy buscando usar WordNet para buscar una colección de términos similares a partir de un conjunto básico de términos.Word Net - Word Sinónimos y construcciones de palabras relacionadas - Java o Python

Por ejemplo, la palabra 'desanimados' - sinónimos potenciales podrían ser: daunted, glum, deterred, pessimistic.

También quise identificar bi-gramos potenciales como; beat down, put off, caved in etc.

¿Cómo hago para extraer esta información usando Java o Python? ¿Hay alguna base de datos/interfaces web de WordNet alojadas que permitan tales consultas?

Gracias!

Respuesta

3

Es más fácil de entender los datos de WordNet mirando en los archivos Prolog. Están documentadas aquí:

http://wordnet.princeton.edu/wordnet/man/prologdb.5WN.html

WordNet términos son grupo en synsets. Un synset es un conjunto de sinónimos máximo de . Los sintonizadores tienen una clave primaria para que se puedan usar en relaciones semánticas.

Así que respondiendo a la primera pregunta, se puede enumerar los diferentes sentidos y sus correspondientes sinónimos de una palabra de la siguiente manera:

Input X: Term 
Output Y: Sense 
Output L: Synonyms in this Sense 

s_helper(X,Y) :- s(X,_,Y,_,_,_). 
?- setof(H,(s_helper(Y,X),s_helper(Y,H)),L). 

Ejemplo:

?- setof(H,(s_helper(Y,'discouraged'),s_helper(Y,H),L). 
Y = 301664880, 
L = [demoralised, demoralized, discouraged, disheartened] ; 
Y = 301992418, 
L = [discouraged] ; 
No 

Para la segunda parte de su pregunta, Los términos de WordNet son secuencias de palabras. Así que usted puede buscar estos términos WordNet para las palabras de la siguiente manera:

Input X: Word 
Output Y: Term 

s_helper(X) :- s(_,_,X,_,_,_). 
word_in_term(X,Y) :- atom_concat(X,' ',H), sub_atom(Y,0,_,_,H). 
word_in_term(X,Y) :- atom_concat(' ',X,H), atom_concat(H,' ',J), sub_atom(Y,_,_,_,J). 
word_in_term(X,Y) :- atom_concat(' ',X,H), sub_atom(Y,_,_,0,H). 
?- s_helper(Y), word_in_term(X,Y). 

Ejemplo:

?- s_helper(X), word_in_term('beat',X). 
X = 'beat generation' ; 
X = 'beat in' ; 
X = 'beat about' ; 
X = 'beat around the bush' ; 
X = 'beat out' ; 
X = 'beat up' ; 
X = 'beat up' ; 
X = 'beat back' ; 
X = 'beat out' ; 
X = 'beat down' ; 
X = 'beat a retreat' ; 
X = 'beat down' ; 
X = 'beat down' ; 
No 

Esto le daría potenciales n-gramas, pero no tanto variación morfológica.WordNet también exhibe algunas relaciones léxicas , que podrían ser útiles.

Pero las dos consultas Prolog que he dado no son muy eficientes. El problema es la falta de indexación de algunas palabras. Una implementación Java podría, por supuesto, implementar algo mejor. Imagínese algo a lo largo:

class Synset { 
    static Hashtable<Integer,Synset> synset_access; 
    static Hashtable<String,Vector<Synset>> term_access; 
} 

Algunos Prolog puede hacer lo mismo, por una directiva de indexación, es posible indicar al sistema Prolog al índice en múltiples argumentos de un predicado.

La instalación de un servicio web no debería ser tan difícil, ya sea en Java o Prolog. Muchos sistemas Prologs permiten incrustar fácilmente programas Prolog en servidores web y servlets de campeones de Java.

Una lista de los prólogos que soportan los servidores web se puede encontrar aquí:

http://en.wikipedia.org/wiki/Comparison_of_Prolog_implementations#Operating_system_and_Web-related_features

Saludos

+0

Gracias por esta información, muy, muy útil. Pregunta rápida, todavía no estoy 100% seguro de esto, pero si es posible, ¿cuál sería la mejor manera de vincular programáticamente una palabra como "desalentado" a "golpear"? – NightWolf

+0

Depende del "enlace" y del lenguaje de programación. En WordNet hay dos tipos de "enlaces", semánticos y léxicos. A través de Prolog, para un enlace semántico, afirmarías un enlace de hecho (synset_id1, synset_id2). Para un enlace léxico, debe afirmar un enlace de hecho (synset_id1, word_num1, synset_id2, word_num2). En Java usaría su estructura/servicio de datos apropiado. O coloque las dos palabras en el mismo synset, o cree un nuevo synset donde estén juntas. El último se aplica en caso de que su "enlace" represente el mismo sentido. –

3

Estos son dos problemas diferentes.

1) Wordnet y python. Use NLTK, tiene un buen interface to wordnet. Podrías escribir algo por tu cuenta, pero, sinceramente, ¿por qué hacer la vida difícil? Lingpipe probablemente también tiene algo incorporado, pero NLTK es mucho más fácil de usar. Creo que nltk acaba de descargar una base de datos de ntlk, pero estoy bastante seguro de que hay apis para hablar con wordnet.

2) Para obtener los bigrams en nltk follow this tutorial. En general, tokensize el texto y luego itere sobre la oración obteniendo todos los n-grams para cada palabra mirando hacia adelante y hacia atrás.

+0

Gracias por los enlaces. De mis pruebas con WordNet, ciertas frases como "golpear" no se pueden identificar, ¿es correcto? – NightWolf

+0

Si usa wordnet en línea, puede ver algunos sinónimos: http://wordnetweb.princeton.edu/perl/webwn?c=8&sub=Change&o2=&o0=1&o8=1&o1=1&o7=&o5=&o9=&o6=&o3=&o4= & i = -1 & h = 000 & s = vencer + bajar – nflacco

+0

¿Tal vez la versión en línea es un db de palabras más nuevo? – nflacco

2

Como alternativa a NLTK, puede usar one de puntos finales de WordNet SPARQL disponibles para recuperar dicha información. consulta de ejemplo:

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX wordnet: <http://www.w3.org/2006/03/wn/wn20/schema/> 

SELECT DISTINCT ?label { 
    ?input_word a wordnet:WordSense; 
    rdfs:label ?input_label. 
    FILTER (?input_label = 'run') 
    ?synset wordnet:containsWordSense ?input_word. 
    ?synset wordnet:containsWordSense ?synonym. 
    ?synonym rdfs:label ?label. 
} LIMIT 100 

En el universo de Java, Jena y Sesame marcos pueden ser utilizados.

+0

si reemplazo 'ejecutar' con 'bicicleta', como resultado obtengo bicicleta, bicicleta, ciclo, pero también rueda y pedal <- ¿por qué estas 2 últimas? – Renaud