Ir al contenido

elmoyer

Moderadores
  • Contenido

    593
  • Registrado

  • Última Visita

  • Días Ganando

    12

Actividad de Reputación

  1. Dar galleta
    elmoyer ha recibido reputación de nasciiboy en Natural Language Toolkit Python   
    El kit de herramientas de lenguaje natural, o más comúnmente NLTK, es un conjunto de bibliotecas y programas para el procesamiento del lenguaje natural (PLN) simbólico y estadísticos para el lenguaje de programación Python. NLTK incluye demostraciones gráficas y datos de muestra. Se acompaña de un libro que explica los conceptos subyacentes a las tareas de procesamiento del lenguaje compatibles el toolkit, además de programas de ejemplo.


    NLTK está destinado a apoyar la investigación y la enseñanza en PLN o áreas muy relacionadas, que incluyen la lingüística empírica, las ciencias cognitivas, la inteligencia artificial, la recuperación de información, y el aprendizaje de la máquina. NLTK se ha utilizado con éxito como herramienta de enseñanza, como una herramienta de estudio individual, y como plataforma para los sistemas de investigación de prototipos y construcción.
     
    Por ejemplo, se puede emplear para ver el Ordenamiento por mezcla, es un algoritmo de ordenamiento externo estable basado en la técnica divide y vencerás. Es de complejidad O(n log n):
     
     
    También se emplea para trabajar con grandes corpus:
     
     

    En su web podéis leer tanto el libro como ver el manual de instalación (http://www.nltk.org/). La instalación de NLTK es bastante sencilla:


    1.- Instalar el Setuptools: http://pypi.python.org/pypi/setuptools
    2.- Instalar Pip: sudo easy_install pip (código)
    3.- Instalar nltk: sudo pip install -U nltk (código)
    [Opcional:
    -Instalar Numpy: sudo apt-get install python-numpy
    -Instalar Matlab: sudo apt-get install python-matplotlib
    -Instalar tkinter: sudo apt-get install python-tk
    Yo recomiendo instalarlo si queremos ver gráficos o estadísticas.
    ]


    Para comprobar si lo hemos instalado bien, abrimos un terminal y tecleamos:

     
    python import nltk Si no nos da nigún error enhorabuena, ya tendremos instalado nltk en nuestro equipo


    Ahora solo falta descargar lo que necesitemos de nltk. Tenemos la opción de descargarnos el libro(entendiendo como libro unos de corpus, herramientas y varias funciones interesantes), herramientas específicas o todo. Yo me descargué todo, ya que si me aburro ya que si me aburro puedo toquetear un poco xD. Para descargarnos lo que queramos introducimos esto:

     
    nltk.download() Si hemos descargado en el python tkinter y el matlab podremos verlo en modo gráfico:





    Si no hemos instalado el tkinter, tendremos que hacerlo por el terminal y nos aparecerá algo como:

     
    nltk.download() NLTK Downloader --------------------------------------------------------------------------- d) Download l) List u) Update c) Config h) Help q) Quit --------------------------------------------------------------------------- Downloader> d Download which package (l=list; x=cancel)? Identifier> punkt Downloading package 'punkt' to D:\python27\nltk_data... Unzipping tokenizers\punkt.zip. --------------------------------------------------------------------------- d) Download l) List u) Update c) Config h) Help q) Quit --------------------------------------------------------------------------- Downloader> q Trabajando con textos:
     
    Una vez descargados los datos, solo hace falta importar lo que necesitemos. Por ejemplo la carga de txts:
     
    Los textos que tenemos a nuestra disposición son:
    -text1:Moby Dick by Herman Melville 1851
    -text2:Sense and Sensibility by Jane Austen 1811
    -text3: The Book of Genesis
    -text4: Inaugural Address Corpus
    -text5: Chat Corpus
    -text6: Monty Python and the Holy Grail
    -text7: Wall Street Journal
    -text8: Personals Corpus
    -text9: The Man Who Was Thursday by G . K . Chesterton 1908
    from nltk.book import * Los textos importados pertenecen a la clase "text" de la librería nltk, e incorporan diferentes funciones. Las funciones más útiles para el análisis semántico son:

    concordance: Devuelve las líneas del texto “text1” en las que aparece “monstrous”.
    sintaxis: text1.concordance("monstrous") 
     
    >>> text1.concordance("monstrous") Displaying 11 of 11 matches: ong the former , one was of a most monstrous size . ... This came towards us , ON OF THE PSALMS . " Touching that monstrous bulk of the whale or ork we have r ll over with a heathenish array of monstrous clubs and spears . Some were thick d as you gazed , and wondered what monstrous cannibal and savage could ever hav that has survived the flood ; most monstrous and most mountainous ! That Himmal they might scout at Moby Dick as a monstrous fable , or still worse and more de th of Radney .'" CHAPTER 55 Of the monstrous Pictures of Whales . I shall ere l ing Scenes . In connexion with the monstrous pictures of whales , I am strongly ere to enter upon those still more monstrous stories of them which are to be fo ght have been rummaged out of this monstrous cabinet there is no telling . But of Whale - Bones ; for Whales of a monstrous size are oftentimes cast up dead u >>> similar -> Devuelve palabras usadas de forma similar en el texto.
    sintaixs: text1.similar("monstrous")
     
    >>> text1.similar("monstrous") mean part maddens doleful gamesome subtly uncommon careful untoward exasperate loving passing mouldy christian few true mystifying imperial modifies contemptible common_contexts-> Encuentra contextos comparTdos por dos o más palabras. Los "_" que obtenemos como resultado, es donde iría la palabra.
    sintaxis: text2.common_contexts(["monstrous", "very"]) 
     
    >>> text2.common_contexts(["monstrous", "very"]) a_pretty is_pretty am_glad be_glad a_lucky Todas estas funciones, juegan bastante con otras funciones útiles de python como son:
    len(text1) set(text1) sorted(set(text1)) Por ejemplo, queremos tener una variable que contenga el vocabulario (por orden alfabético) de un texto: words=sorted(set(text1))
     
    También podemos hacer uso de los operadores matemáticos:
    def percentage(count,total):        return 100*count/total #calcula la frecuencia de aparición de una palabra. Ya que estamos trabajando con textos, tenemos que saber que los textos están formados por palabras, números, signos de puntuación...pero todo es un string. Por eso cuando trabajamos con el procesamiento de textos, tenemos que tener claras las herramientas que podemos utilizar:
    -s.startswith(t): test if s starts with t -s.endswith(t): test if s ends with t -t in s: test if t is contained inside s -s.islower(): test if all cased characters in s are lowercase -s.isupper(): test if all cased characters in s are uppercase -s.isalpha(): test if all characters in s are alphabetic -s.isalnum(): test if all characters in s are alphanumeric -s.isdigit(): test if all characters in s are digits -s.isTtle(): test if s is Ttlecased (all words in s have have iniTal capitals) -s.find(t): index of first instance of string t inside s (-­‐1 if not found) -s.rfind(t): index of last instance of string t inside s (-­‐1 if not found) -s.index(t):like s.find(t) except it raises ValueError if not found -s.rindex(t):like s.rfind(t) except it raises ValueError if not found -s.join(text):combine the words of the text into a string using s as the glue -s.split(t):split s into a list wherever a t is found (whitespace by default) -s.splitlines():split s into a list of strings, one per line -s.lower():a lowercased version of the string s -s.upper():an uppercased version of the string s -s.title():a titlecased version of the string s -s.strip():a copy of s without leading or trailing whitespace -s.replace(t, u):replace instances of t with u inside s Otra función bastante útil es FreqDist(Frequency Distributions), que muestra la frecuencia de aparación de cada elemento.
    fdist1=FreqDist() fdist1 es una función que genera una variable de la clase nltk.probability.freqdist. Incorpora diferentes funciones que permiten generar el vocabulario del texto y la frecuencia de aparación de cada elemento (en orden decreciente):
    >>> fdist1 = FreqDist(text1) >>> print(fdist1) <FreqDist with 19317 samples and 260819 outcomes> >>> fdist1.most_common(50) [(',', 18713), ('the', 13721), ('.', 6862), ('of', 6536), ('and', 6024), ('a', 4569), ('to', 4542), (';', 4072), ('in', 3916), ('that', 2982), ("'", 2684), ('-', 2552), ('his', 2459), ('it', 2209), ('I', 2124), ('s', 1739), ('is', 1695), ('he', 1661), ('with', 1659), ('was', 1632), ('as', 1620), ('"', 1478), ('all', 1462), ('for', 1414), ('this', 1280), ('!', 1269), ('at', 1231), ('by', 1137), ('but', 1113), ('not', 1103), ('--', 1070), ('him', 1058), ('from', 1052), ('be', 1030), ('on', 1005), ('so', 918), ('whale', 906), ('one', 889), ('you', 841), ('had', 767), ('have', 760), ('there', 715), ('But', 705), ('or', 697), ('were', 680), ('now', 646), ('which', 640), ('?', 637), ('me', 627), ('like', 624)] >>> fdist1['whale'] 906 >>> Incluye, entre otras, las siguientes funciones:
    -fdist.samples(): Genera una lista con el vocabulario -fdist.values(): Devuelve el no de veces que aparece cada palabra -fdist.N(): No total de palabras en el texto -fdist.freq(word): Devuelve la frecuencia de aparación de word -fdist.inc(palabra): Incrementa la cuenta para una palabra -fdist.max(): Palabra con máxima frecuencia -fdist.tabulate(): Tabula la distribución de frecuencia -fdist.plot(): Representación gráfica Si no queremos cargar todos los textos de NLTK, podemos importar el corpus que nos interese a nosotros. Tenemos dos formas de hacerlo:
     
    1.- Vemos los textos que hay disponibles:
    nltk.corpus.gutenberg.fileids() >>>​['austen-­‐emma.txt', 'austen-­‐persuasion.txt', ... Y seleccionamos uno de ellos:
    emma = nltk.corpus.gutenberg.words('austen-­‐emma.txt') 2.- Directamente:
    from nltk.corpus import gutenberg emma = gutenberg.words('austen-­‐emma.txt') Las métodos que se pueden emplear en los corpus son:
    fileids(): the files of the corpus fileids([categories]): the files of the corpus corresponding to these categories categories(): the categories of the corpus categories([fileids]): the categories of the corpus corresponding to these files raw(): the raw content of the corpus raw(fileids=[f1,f2,f3]):the raw content of the specified files raw(categories=[c1,c2]): the raw content of the specified categories words(): the words of the whole corpus words(fileids=[f1,f2,f3]): the words of the specified fileids words(categories=[c1,c2]): the words of the specified categories sents(): the sentences of the whole corpus sents(fileids=[f1,f2,f3]): the sentences of the specified fileids sents(categories=[c1,c2]): the sentences of the specified categories abspath(fileid): the locaTon of the given file on disk encoding(fileid): the encoding of the file (if known) open(fileid): open a stream for reading the given corpus file root(): the path to the root of locally installed corpus readme(): the contents of the README file of the corpus Ejemplos de algunos métodos para trabajar con los corpus:
     
    fileids():
    >>> import nltk >>> nltk.corpus.gutenberg.fileids() ['austen-emma.txt', 'austen-persuasion.txt', 'austen-sense.txt', 'bible-kjv.txt','blake-poems.txt', 'bryant-stories.txt', 'burgess-busterbrown.txt','carroll-alice.txt', 'chesterton-ball.txt', 'chesterton-brown.txt','chesterton-thursday.txt', 'edgeworth-parents.txt', 'melville-moby_dick.txt','milton-paradise.txt', 'shakespeare-caesar.txt', 'shakespeare-hamlet.txt','shakespeare-macbeth.txt', 'whitman-leaves.txt'] categories():
    >>> from nltk.corpus import brown >>> brown.categories() ['adventure', 'belles_lettres', 'editorial', 'fiction', 'government', 'hobbies','humor', 'learned', 'lore', 'mystery', 'news', 'religion', 'reviews', 'romance','science_fiction'] words():
    >>> nltk.corpus.udhr.words('Javanese-Latin1')[11:] ['Saben', 'umat', 'manungsa', 'lair', 'kanthi', 'hak', ...] >>> nltk.corpus.cess_esp.words() ['El', 'grupo', 'estatal', 'Electricit\xe9_de_France', ...] >>> nltk.corpus.floresta.words() ['Um', 'revivalismo', 'refrescante', 'O', '7_e_Meio', ...] sents():
    >>> macbeth_sentences = gutenberg.sents('shakespeare-macbeth.txt') >>> macbeth_sentences [['[', 'The', 'Tragedie', 'of', 'Macbeth', 'by', 'William', 'Shakespeare', '1603', ']'], ['Actus', 'Primus', '.'], ...] Objetivos:
     

     
     
    Trabajando con documentos:
     
     
    Textos planos:
     
    Se puede importar cualquier texto plano. La descarga desde un repositorio web puede hacerse así:
    >>> from __future__ import division # Python 2 users only >>> import nltk, re, pprint >>> from nltk import word_tokenize >>>from urllib import urlopen >>>url = "h{p://www.gutenberg.org/files/2554/2554.txt" >>>raw = urlopen(url).read() >>>from urllib import * >>> url = "http://www.gutenberg.org/files/2554/2554.txt" >>> response = urlopen(url) >>> raw = response.read().decode('utf8') >>> len(raw) 1176893 >>> raw[:75] 'The Project Gutenberg EBook of Crime and Punishment, by Fyodor Dostoevsky\r\n' En la variable “raw” se encuentra texto sin procesar. Antes de proceder a su procesado hay que formatearlo (tokenizaton). El formato consiste simplemente en convertirlo en una lista de elementos (palabras, frases, bigramas,trigramas...):
    tokens = nltk.word_tokenize(raw) Páginas Web:
     
    Resulta bastante interesante la importación de páginas web:
    >>> from __future__ import division # Python 2 users only >>> import nltk, re, pprint >>> from nltk import word_tokenize >>>from urllib import * >>> url = "http://news.bbc.co.uk/2/hi/health/2284783.stm" >>> html = urlopen(url).read().decode('utf8') >>> html[:60] '<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN' El problema que nos encontramos es también obtenemos todas las etiquetas HTML, perco contamos con un método para eliminar automáticamente las etiquetas antes de la "tokenización":
    >>> from bs4 import BeautifulSoup >>> raw = BeautifulSoup(html).get_text() >>> tokens = word_tokenize(raw) >>> tokens ['BBC', 'NEWS', '|', 'Health', '|', 'Blondes', "'to", 'die', 'out', ...] RSS:
    >>> import feedparser >>> llog = feedparser.parse("http://languagelog.ldc.upenn.edu/nll/?feed=atom") >>> llog['feed']['title'] 'Language Log' >>> len(llog.entries) 15 >>> post = llog.entries[2] >>> post.title "He's My BF" >>> content = post.content[0].value >>> content[:70] '<p>Today I was chatting with three of our visiting graduate students f' >>> raw = BeautifulSoup(content).get_text() >>> word_tokenize(raw) ['Today', 'I', 'was', 'chatting', 'with', 'three', 'of', 'our', 'visiting','graduate', 'students', 'from', 'the', 'PRC', '.', 'Thinking', 'that', 'I', 'was', 'being', 'au', 'courant', ',', 'I', 'mentioned', 'the', 'expression', 'DUI4XIANG4', '\u5c0d\u8c61', '("', 'boy', '/', 'girl', 'friend', '"', ...] Contenido local:
     
    -Cargar datos locales:
    >>>path = nltk.data.find('corpora/gutenberg/melville-­‐ moby_dick.txt') #Busca el texto >>>raw = open(path,'rU').read() #Carga el texto >>>tokens = nltk.word_tokenize(raw) #Formato >>>raw[1:29] 'Moby Dick by Herman Melville’ **Otra forma de seleccionar el archivo sería:
    >>>file = os.path.join('carpeta', 'subcarpeta','archivo') #Es necesario importar os (import os) Procesamiento del contenido de los documentos:
     
     
    Después de haber trabajado con los documentos el siguiente paso sería dedicarnos a su procesamiento. Dentro del procesamiento del contenido de los archivos, podemos trabajar con:
     
    -Tokenización:
    Uno de los procesos que puede llevar a cabo la tokenización es el paso de texto a frases, es decir, el programa reconoce que una frase nueva empieza despues de cada punto. Por ejemplo:   >>> from nltk.tokenize import sent_tokenize >>> frase = 'Esto es una prueba para GNU Linux Vagos. Y no se me ocurre mucho mas que poner en esta frase de prueba. Se me olvidaba, Linux rules!' >>> sent_tokenize(frase) ['Esto es una prueba para GNU Linux Vagos.', 'Y no se me ocurre mucho mas que poner en esta frase de prueba.', 'Se me olvidaba, Linux rules!'] Como vemos, cada vez que encuentra un punto da por termiada la frase encerrandola entre comillas y devolviendonos una lista con todas las frases distintas que encuentra este método. Esto se debe a la instancia PunktSentenceTokenizer, que funciona para una gran cantidad de idiomas.
     
    Sin embargo si queremos formatear muchas frases en un determinado idioma se recomienda cargar su módulo correspondiente. Disponemos de los siguientes tokenizers: danés, esloveno, finés, alemán, noruego, checo, italiano, español, polaco, griego, estonio, inglés, turco, sueco, holandés, portugues y francés.   Para poder importar el módulo que queramos tendremos que escribir lo siguiente:   >>> import nltk.data >>> tokenizer = nltk.data.load('tokenizers/punkt/german.pickle') #Donde sustituiremos german.pickle por uno de los idiomas que se encuentran disponibles.pickle, Sin embargo, da un poco "igual" importar un idioma u otro ya que antes hemos escrito: "frase = 'Esto es una prueba para GNU Linux Vagos. Y no se me ocurre mucho mas que poner en esta frase de prueba. Se me olvidaba, Linux rules!' " y acabamos de importar el idioma alemán pero el resultado que obtenemos es el mismo:
    >>> tokenizer.tokenize(frase) ['Esto es una prueba para GNU Linux Vagos.', 'Y no se me ocurre mucho mas que poner en esta frase de prueba.', 'Se me olvidaba, Linux rules!'] #Esto se debe a que se emplea un sistema bastante sencillo que hemos explicado ante. Un punto, una frase nueva #(parece primaria esto xD ) Otra posibilidad que nos ofrece la tokenización es el paso de texto a tokens, es decir, de frases a palabras:
    >>> from nltk.tokenize import word_tokenize >>> word_tokenize('Hola, GNU Linux Vagos.') ['Hola', ',', 'GNU', 'Linux', 'Vagos', '.'] #Como podemos observar, un token es tanto una palabra como un signo de puntuación. Sin #embargo en idiomas como el inglés en el que hay contracciones estas son reconocidas y no #son valoradas como un token extra. Después de haber comentado un poco como funciona seguramente mas de uno se habrá quedado pensando en la utilidad de todo esto, de que sirve separar una frase en tokens y que me los devuelva en un string? Visto así pues puede resultar poco útil, pero que os parece si jugamos un poco con las expresiones regulares? :D
     
    Una expresión regular, a menudo llamada también regex, es una secuencia de caracteres que forma un patrón de búsqueda, principalmente utilizada para la búsqueda de patrones de cadenas de caracteres u operaciones de sustituciones. Por ejemplo, el grupo formado por las cadenas Handel, Händel y Haendel se describe con el patrón "H(a|ä|ae)ndel". La mayoría de las formalizaciones proporcionan los siguientes constructores: una expresión regular es una forma de representar a los lenguajes regulares (finitos o infinitos) y se construye utilizando caracteres del alfabeto sobre el cual se define el lenguaje. En informática, las expresiones regulares proveen una manera muy flexible de buscar o reconocer cadenas de texto.   Y dejando a un lado la teoría, vamos con la practica. Seguímos utilizando los módulos de tokenización pero ahora solo hace falta importar el módulo de RegEx:   >>> from nltk.tokenize import regexp_tokenize Y ahora a jugar con las RegEx:
    >>> regexp_tokenize("i can't breathe.","[\S']+") ['i', "can't", 'breathe.'] >>> regexp_tokenize("i can't breathe.","[\w']+") ['i', "can't", 'breathe'] Si os habeís fijado bien, en la primera frase al hacer la tokenización el punto no ha sido considerado como un token y en la segunda directamente ni se tiene en cuenta. Eso se debe a "[\S']+" y "[\S']+" respectivamente. El "+" que tienen en común indica que puede haber 1 o más de un item X; la w, indica que solo se tienen en cuenta los caractéres alfanuméricos.    Os dejo por aquí la sintaxis de las expresiones regulares:   . => Wildcard ^abc => Encuentra un patrón abc al inicio de una cadena abc$ => Encuentra abc al final de una cadena [abc] => Encuentra uno de un conjunto de caracteres [A-­‐Z0-­‐9] => Encuentra uno de un rango de caracteres ed|ing|s => Encuentra una de las cadenas especificadas (disjuncTon) * => Cero o más de los ítems previos. Ej.: a*, [a-­‐z]* (Kleene Closure) + => Uno o más de los ítems previos, Ej.: a+, [a-­‐z]+ ? => Opcional, ej.: a?, [a-­‐z]? {n} => Exactamente n repeTciones {n,} => Al menos n repeticiones {,n} => No más de n repeticones {m,n} => Al menos m y no más de m a(b|c)+ => Paréntesis que indica el objeto de las operaciones \b => Word boundary (zero width) \d => Cualquier decimal (equivalente a [0-­‐9]) \D => Cualquier no decimal (equivalente a [^0-­‐9]) \s => Cualquier espacio (equivalente a [ \t\n\r\f\v] \S => Cualquier no espacio (equivalente a [^ \t\n\r\f\v]) \w => Cualquier alfanumérico (equivalente a [a-­‐zA-­‐Z0-­‐9_]) \W => Cualquier no alfanumérico (equivalente a [^a-­‐zA-­‐Z0-­‐9_]) \t => Tabulador \n => Nueva línea \r => Retorno de carro \f => Form feed (página nueva) \v => Tabulador vertical Otra utilidad de las expresiones regulares es la búsqueda de palabras que contengan por ejemplo un sufijo, prefijo, afijo o lo que queramos:
    >>>import re >>> wordlist = [w for w in nltk.corpus.words.words('en') if w.islower()]#Carga del vocabulario >>> words = [w for w in wordlist if re.search('ed$',w)]#todas las parabras que terminen en -ed >>> print words[:25] [u'abaissed', u'abandoned', u'abased', u'abashed', u'abatised', u'abed', u'aborted', u'abridged', u'abscessed', u'absconded', u'absorbed', u'abstracted', u'abstricted', u'accelerated', u'accepted', u'accidented', u'accoladed', u'accolated', u'accomplished', u'accosted', u'accredited', u'accursed', u'accused', u'accustomed', u'acetated'] Más ejemplos:
    >>> words = [w for w in wordlist if re.search('^..j..t..$', w)] >>> words [:15] [u'abjectly', u'adjuster', u'dejected', u'dejectly', u'injector', u'majestic', u'objectee', u'objector', u'rejecter', u'rejector', u'unjilted', u'unjolted', u'unjustly'] En este ejemplo estamos buscando una palabra que tenga 8 letras en las que aparezca en tercera posición una j y en sexta posición una t.
     
    -Lematización o lo que es lo mismo, la extracción de las raíces de las palabras. NLTK trabaja con 3 lematizadores, el de Porter, Lancaster y Snowball. 
    >>> raw= "Each character in a regular expression is either understood to be a metacharacter with its special meaning, or a regular character with its literal meaning. Together, they can be used to identify textual material of a given pattern, or process a number of instances of it that can vary from a precise equality to a very general similarity of the pattern." >>> tokens = nltk.word_tokenize(raw) Porter:
    >>> porter = nltk.PorterStemmer() >>> [porter.stem(t) for t in tokens] [u'Each', u'charact', u'in', u'a', u'regular', u'express', u'is', u'either', u'understood', u'to', u'be', u'a', u'metacharact', u'with', u'it', u'special', u'mean', u',', u'or', u'a', u'regular', u'charact', u'with', u'it', u'liter', u'mean', u'.', u'Togeth', u',', u'they', u'can', u'be', u'use', u'to', u'identifi', u'textual', u'materi', u'of', u'a', u'given', u'pattern', u',', u'or', u'process', u'a', u'number', u'of', u'instanc', u'of', u'it', u'that', u'can', u'vari', u'from', u'a', u'precis', u'equal', u'to', u'a', u'veri', u'gener', u'similar', u'of', u'the', u'pattern', u'.'] Lancaster:
    >>> lancaster=nltk.LancasterStemmer() >>> [lancaster.stem(t) for t in tokens] ['each', 'charact', 'in', 'a', 'regul', u'express', 'is', 'eith', 'understood', 'to', 'be', 'a', 'metacharact', 'with', 'it', 'spec', 'mean', ',', 'or', 'a', 'regul', 'charact', 'with', 'it', 'lit', 'mean', '.', 'togeth', ',', 'they', 'can', 'be', 'us', 'to', 'ident', 'text', 'mat', 'of', 'a', 'giv', 'pattern', ',', 'or', 'process', 'a', 'numb', 'of', u'inst', 'of', 'it', 'that', 'can', 'vary', 'from', 'a', 'prec', 'eq', 'to', 'a', 'very', 'gen', 'simil', 'of', 'the', 'pattern', '.'] Lematizador Snowball: Funciona con varias lenguas entre las que encontramos: inglés, frances, espanol, portugés, italiano, alemán, dutch, swedish, norwegian, danish, ruso y finés.   >>> from nltk.stem import SnowballStemmer >>> spanish_stemmer = SnowballStemmer("spanish") >>> frase = "Estoy escribiendo un poco sobre NLTK mientras estoy tomandome un cafe, tengo bastante cansancio acumulado quizas deberia dormir mas." >>> tokens = nltk.word_tokenize(frase) >>> [spanish_stemmer.stem(t) for t in tokens] [u'estoy', u'escrib', u'un', u'poc', u'sobr', u'nltk', u'mientr', u'estoy', u'tom', u'un', u'caf', u',', u'teng', u'bastant', u'cansanci', u'acumul', u'quiz', u'deberi', u'dorm', u'mas', u'.'] Lo que estamos hacieno es utilizar un lematizador que extrae la auténtica raíz de cada palabra a partir de un diccionario. NLTK utiliza WordNet(explicaré otro día un poco mas sobre esta herramienta), una base de datos léxica en inglés.
    >>>from nltk.stem import WordNetLemmatizer >>> frase = "the French stemmer turns out to be the most complicated, whereas the Russian stemmer, despite its large number of suffixes, is very simple. In fact it is interesting that English, with its minimal use of i-suffixes, has such a complex stemmer." >>> tokens = nltk.word_tokenize(frase) >>>lemmatizer = WordNetLemmatizer() >>>[lemmatizer.lemmatize(t) for t in tokens] ['the', 'French', 'stemmer', u'turn', 'out', 'to', 'be', 'the', 'most', 'complicated', ',', 'whereas', 'the', 'Russian', 'stemmer', ',', 'despite', u'it', 'large', 'number', 'of', u'suffix', ',', 'is', 'very', 'simple', '.', 'In', 'fact', 'it', 'is', 'interesting', 'that', 'English', ',', 'with', u'it', 'minimal', 'use', 'of', 'i-suffixes', ',', u'ha', 'such', 'a', 'complex', 'stemmer', '.'] Con Lancaster lo que obtenemos es la palabra con los sufijos extraidos:
    >>> lancaster = nltk.LancasterStemmer() >>> [lancaster.stem(t) for t in frase] ['t', 'h', 'e', ' ', 'f', 'r', 'e', 'n', 'c', 'h', ' ', 's', 't', 'e', 'm', 'm', 'e', 'r', ' ', 't', 'u', 'r', 'n', 's', ' ', 'o', 'u', 't', ' ', 't', 'o', ' ', 'b', 'e', ' ', 't', 'h', 'e', ' ', 'm', 'o', 's', 't', ' ', 'c', 'o', 'm', 'p', 'l', 'i', 'c', 'a', 't', 'e', 'd', ',', ' ', 'w', 'h', 'e', 'r', 'e', 'a', 's', ' ', 't', 'h', 'e', ' ', 'r', 'u', 's', 's', 'i', 'a', 'n', ' ', 's', 't', 'e', 'm', 'm', 'e', 'r', ',', ' ', 'd', 'e', 's', 'p', 'i', 't', 'e', ' ', 'i', 't', 's', ' ', 'l', 'a', 'r', 'g', 'e', ' ', 'n', 'u', 'm', 'b', 'e', 'r', ' ', 'o', 'f', ' ', 's', 'u', 'f', 'f', 'i', 'x', 'e', 's', ',', ' ', 'i', 's', ' ', 'v', 'e', 'r', 'y', ' ', 's', 'i', 'm', 'p', 'l', 'e', '.', ' ', 'i', 'n', ' ', 'f', 'a', 'c', 't', ' ', 'i', 't', ' ', 'i', 's', ' ', 'i', 'n', 't', 'e', 'r', 'e', 's', 't', 'i', 'n', 'g', ' ', 't', 'h', 'a', 't', ' ', 'e', 'n', 'g', 'l', 'i', 's', 'h', ',', ' ', 'w', 'i', 't', 'h', ' ', 'i', 't', 's', ' ', 'm', 'i', 'n', 'i', 'm', 'a', 'l', ' ', 'u', 's', 'e', ' ', 'o', 'f', ' ', 'i', '-', 's', 'u', 'f', 'f', 'i', 'x', 'e', 's', ',', ' ', 'h', 'a', 's', ' ', 's', 'u', 'c', 'h', ' ', 'a', ' ', 'c', 'o', 'm', 'p', 'l', 'e', 'x', ' ', 's', 't', 'e', 'm', 'm', 'e', 'r', '.'] El lematizador también nos ayuda a encontrar un lema para una palabra. En el caso de no encontrar un lema, devuelve la palabra:   >>> lemmatizer.lemmatize("tokens") u'token' Además el lemmatizer reconoces adjetivos(pos ='a'), sustantivos(pos='n'), adverbios(pos='r') y verbos(pos='v')
    >>> lemmatizer.lemmatize('readings', pos='n') u'reading' >>> lemmatizer.lemmatize('readings', pos='v') u'read' >>> lemmatizer.lemmatize('readings', pos='r') 'readings' # como hemos dicho, si no encuentra un lema devuelve la palabra introducida  
     
    -Eliminación de stopwords: Eliminación de palabras irrelevantes. NLTK tiene una librería para eliminar las stopwords, es decir, aquellas que no contribuyen al significado como serían "de", "la", "el", "que", "en"... La librería soporta los siguientes idiomas: noruego, italiano, portugués, francés, español, holandés, danés, finlandés, alemán, húngaro, Inglés, sueco, turco y ruso.   >>> from nltk.corpus import stopwords >>> stopwords.words('spanish') #sustituir el idioma por el que queramos. [u'de', u'la', u'que', u'el', u'en', u'y', u'a', u'los', u'del', u'se', u'las', u'por', u'un', u'para', u'con', u'no', u'una', u'su', u'al', u'lo', u'como', u'más', u'pero', u'sus', u'le', u'ya', u'o', u'este', u'sí', u'porque', u'esta', u'entre', u'cuando', u'muy', u'sin', u'sobre', u'también', u'me', u'hasta', u'hay', u'donde', u'quien', u'desde', u'todo', u'nos', u'durante', u'todos', u'uno', u'les', u'ni', u'contra', u'otros', u'ese', u'eso', u'ante', u'ellos', u'e', u'esto', u'mí', u'antes', u'algunos', u'qué', u'unos', u'yo', u'otro', u'otras', u'otra', u'él', u'tanto', u'esa', u'estos', u'mucho', u'quienes', u'nada', u'muchos', u'cual', u'poco', u'ella', u'estar', u'estas', u'algunas', u'algo', u'nosotros', u'mi', u'mis', u'tú', u'te', u'ti', u'tu', u'tus', u'ellas', u'nosotras', u'vosostros', u'vosostras', u'os', u'mío', u'mía', u'míos', u'mías', u'tuyo', u'tuya', u'tuyos', u'tuyas', u'suyo', u'suya', u'suyos', u'suyas', u'nuestro', u'nuestra', u'nuestros', u'nuestras', u'vuestro', u'vuestra', u'vuestros', u'vuestras', u'esos', u'esas', u'estoy', u'estás', u'está', u'estamos', u'estáis', u'están', u'esté', u'estés', u'estemos', u'estéis', u'estén', u'estaré', u'estarás', u'estará', u'estaremos', u'estaréis', u'estarán', u'estaría', u'estarías', u'estaríamos', u'estaríais', u'estarían', u'estaba', u'estabas', u'estábamos', u'estabais', u'estaban', u'estuve', u'estuviste', u'estuvo', u'estuvimos', u'estuvisteis', u'estuvieron', u'estuviera', u'estuvieras', u'estuviéramos', u'estuvierais', u'estuvieran', u'estuviese', u'estuvieses', u'estuviésemos', u'estuvieseis', u'estuviesen', u'estando', u'estado', u'estada', u'estados', u'estadas', u'estad', u'he', u'has', u'ha', u'hemos', u'habéis', u'han', u'haya', u'hayas', u'hayamos', u'hayáis', u'hayan', u'habré', u'habrás', u'habrá', u'habremos', u'habréis', u'habrán', u'habría', u'habrías', u'habríamos', u'habríais', u'habrían', u'había', u'habías', u'habíamos', u'habíais', u'habían', u'hube', u'hubiste', u'hubo', u'hubimos', u'hubisteis', u'hubieron', u'hubiera', u'hubieras', u'hubiéramos', u'hubierais', u'hubieran', u'hubiese', u'hubieses', u'hubiésemos', u'hubieseis', u'hubiesen', u'habiendo', u'habido', u'habida', u'habidos', u'habidas', u'soy', u'eres', u'es', u'somos', u'sois', u'son', u'sea', u'seas', u'seamos', u'seáis', u'sean', u'seré', u'serás', u'será', u'seremos', u'seréis', u'serán', u'sería', u'serías', u'seríamos', u'seríais', u'serían', u'era', u'eras', u'éramos', u'erais', u'eran', u'fui', u'fuiste', u'fue', u'fuimos', u'fuisteis', u'fueron', u'fuera', u'fueras', u'fuéramos', u'fuerais', u'fueran', u'fuese', u'fueses', u'fuésemos', u'fueseis', u'fuesen', u'sintiendo', u'sentido', u'sentida', u'sentidos', u'sentidas', u'siente', u'sentid', u'tengo', u'tienes', u'tiene', u'tenemos', u'tenéis', u'tienen', u'tenga', u'tengas', u'tengamos', u'tengáis', u'tengan', u'tendré', u'tendrás', u'tendrá', u'tendremos', u'tendréis', u'tendrán', u'tendría', u'tendrías', u'tendríamos', u'tendríais', u'tendrían', u'tenía', u'tenías', u'teníamos', u'teníais', u'tenían', u'tuve', u'tuviste', u'tuvo', u'tuvimos', u'tuvisteis', u'tuvieron', u'tuviera', u'tuvieras', u'tuviéramos', u'tuvierais', u'tuvieran', u'tuviese', u'tuvieses', u'tuviésemos', u'tuvieseis', u'tuviesen', u'teniendo', u'tenido', u'tenida', u'tenidos', u'tenidas', u'tened'] Como podéis ver la herramienta de NLTK es muy útil y se puede emplear para hacer bastantes cosas. Esto ha sido una pequeña introducción, a medida que yo también vaya avanzando con NLTK iré comentando que he aprendido nuevo, algún que otro ejercicio...
     
     
    Oos recomiendo que busquéis algo mas sobre python para trabajar con mas soltura 

    http://gnulinuxvagos.es/topic/68-manual-python-para-todos-creative-commons/

    http://gnulinuxvagos.es/topic/1915-pep-gu%C3%ADa-de-estilo-de-programaci%C3%B3n-en-python/
     
     
  2. Me Gusta
    elmoyer ha recibido reputación de portaro en Natural Language Toolkit Python   
    Buenas tarde, hoy vamos a trabajar con uno de los campos más interesantes(a mi parecer) de la lingüística computacional, word-sense disambiguation(desambiguación del significado de la palabra). Para ello vamos a usar nuestro querido NLTK y su módulo de WordNet así que vamos a ello!
     
    WordNet es una base de datos léxica del idioma inglés. Agrupa palabras en inglés en conjuntos de sinónimos llamados synsets, proporcionando definiciones cortas y generales, y almacena las relaciones semánticas entre los conjuntos de sinónimos. Su propósito es doble: producir una combinación de diccionario y tesauro cuyo uso sea más intuitivo, y soportar análisis automático de texto y a aplicaciones de Inteligencia Artificial. La base de datos y las herramientas del software se han liberado bajo una licencia BSD y pueden ser descargadas y usadas libremente. Además la base de datos puede consultarse en línea.   Sinónimos y significados[senses and Synonyms]: Consideremos las siguientes frases: 1) Raquel tuvo un accidente con el coche. [\*Ya que WordNet es para inglés sustituiremos coche por motorcar*/] 2) Raquel tuvo un accidente con el automovil. [\*Ya que WordNet es para inglés sustituiremos coche por automobile*/]   Las frases 1) y 2) tienen el mimos significado, por lo tanto podemos decir que son sinónimos. Gracias a NLTK y a su módulo de WordNet, podemos explorar la palabra "motorcar". Para ello iniciaremos como siempre nuestro querido python desde terminal e importaremos NLTK:   elmoyer@tutorial:~$ python Python 2.7.6 (default, Jun 22 2015, 17:58:13)  [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import nltk   Tras importar NLTK, ya solo nos queda importar también el módulo de WordNet para poder trabajar con él:   >>> from nltk.corpus import wordnet as wn    Ese "as wn" es para que no tengamos que escribir siempre wordnet cuando vayamos a usar el módulo y se puede sustituir por wn o por lo que queramos. Una vez importado ya podemos empezar a jugar con los synsets: >>> wn.synsets('motorcar') [Synset('car.n.01')]   Como vemos, motorcar solo tiene un significado posible que esta designado como "car.n.01", es decir el primer sustantivo con el significado coche. La entidad "car.n.01" se denomina "synset" o "set de sinónimos"(colección de palabras sinónimas o lemas). Para poder ver que palabras entran dentro de este synset, lo único que tenemos que escribir es:   >>> wn.synsets('dry') \\Cambiamos de ejemplo y usamos "dry" [Synset('dry.n.01'), Synset('dry.v.01'), Synset('dry.v.02'), Synset('dry.a.01'), Synset('dry.s.02'), Synset('dry.a.03'), Synset('dry.a.04'), Synset('dry.a.05'), Synset('dry.a.06'), Synset('dry.a.07'), Synset('dry.s.08'), Synset('dry.s.09'), Synset('dry.s.10'), Synset('dry.s.11'), Synset('dry.s.12'), Synset('dry.s.13'), Synset('dry.s.14'), Synset('dry.s.15'), Synset('dry.s.16')] >>> wn.synset('dry.n.01').lemma_names() \\Vemos que palabras están dentro de este synset [u'dry', u'prohibitionist']     Cada synstes de una palabra puede tener distintos significados. Sin embargo a nosotros lo que nos interesa es el significado de cada palabra que forma el synstet. Estaría bien saber que significa cada palabra, ¿no?:   >>> wn.synset('dry.n.01').definition() u'a reformer who opposes the use of intoxicating beverages'   ¿Y qué tal un ejemplo también?:   >>> wn.synset('dry.v.01').examples() [u'dry clothes', u'dry hair']   Como veís he tenido que migrar al synster de "dry" como verbo(v) y que el synset "dry.n.01" no tenía ejemplos: >>> wn.synset('dry.n.01').examples() []   Otra posibilidad que nos ofrece el módulo de WordNet, es obtener todos los lemas de un synset:   >>> wn.synset('dry.n.01').lemmas() [Lemma('dry.n.01.dry'), Lemma('dry.n.01.prohibitionist')]   O incluso buscar un lema en concreto: >>> wn.lemma('dry.n.01.dry') Lemma('dry.n.01.dry')   O obtener el synset correspondiente a un lema:   >>> wn.lemma('dry.n.01.dry').synset() Synset('dry.n.01')   U obtener el "nombre"/"designación" de un lema:   >>> wn.lemma('dry.n.01.dry').name() u'dry' Sin embargo, hay palabras que se podrían considerar ambiguas. En el campo de la lingüística, para ser más concretos en la sintaxis, decimos que una frase es ambigua cuando tienes mas de un árbol(distintas formas en las que se puede anañizar una frase). Esto se puede extrapolar también en este caso a las palabras de WordNet, es decir, decimos que una palabra puede ser ambigua cuando tiene distintos synsets. Así que volvemos a cambiar de ejemplo y vamos otra vez con "car":   >>> wn.synsets('car') [Synset('car.n.01'), Synset('car.n.02'), Synset('car.n.03'), Synset('car.n.04'), Synset('cable_car.n.01')]   Como vemos, tenemos 5 synsets que se diferencian notablemente unos de otros. Llegados a este punto, podríamos pensar que nos hemos quedado atascados y que nos llevaría mucho tiempo saber cual es el synset con el que queremos trabajar. Sin embargo la solución es muy sencilla, lo único que tenemos qu hacer es ver que palabras están dentro de los synsets y de esta forma elegir aquel con el que queríamos trabajar:   >>> for synset in wn.synsets('car'): ...     print(synset.lemma_names()) ... ['car', 'auto', 'automobile', 'machine', 'motorcar'] ['car', 'railcar', 'railway_car', 'railroad_car'] ['car', 'gondola'] ['car', 'elevator_car'] ['cable_car', 'car']   La jerarquia de WordNet:                         WordNet intenta facilitar la navegación entre los conceptos. para ser más especificos estos conceptos pueden ser:   Sustantivos: hiperonimia (hypernymy, can hiperónimo de perro). hiponimia (hyponymy, perro es un hipónimo de can). términos coordinados (coordinate terms, lobo y perro son términos coordinados puesto que ambos son cánidos). holonimia (holonymy, edificio es un holónimo de ventana).   Verbos: hiperonimia (hypernymy) troponimia (troponym) consecuencia lógica (entailment) términos coordinados (coordinate terms)   Adjetivos: sustantivos relacionados similar a participios de verbos   Adverbios La raíz de los adjetivos   Un ejemplo de hyponyms con NLTK sería:   >>> wn.synsets('sky') [Synset('sky.n.01'), Synset('flip.v.06')] >>> sky = wn.synset('sky.n.01') >>> types_of_sky = sky.hyponyms() >>> types_of_sky[0] Synset('blue_sky.n.01') >>> sorted(lemma.name() for synset in types_of_sky for lemma in synset.lemmas()) [u'blue', u'blue_air', u'blue_sky', u'mackerel_sky', u'wild_blue_yonder']   Un ejemplo de hypernyms con NLTK sería:   >>> sky.hypernyms() [Synset('atmosphere.n.05')] Como se puede ver en la imagen, WordNet tiene distintas jerarquía y el root sería la "entidad".  Pero podemos "navergar" por todos sus recorrido y ver el "largo" de la jerarquia de una palabra en concreto:   >>> paths = sky.hypernym_paths() >>> len(paths) 1 >>> [synset.name() for synset in paths[0]] [u'entity.n.01', u'physical_entity.n.01', u'matter.n.03', u'fluid.n.02', u'gas.n.02', u'atmosphere.n.05', u'sky.n.01'] También podemos ir al "root", que sería la entidad que encontramos arriba del todo en la imagen:   >>> sky.root_hypernyms() [Synset('entity.n.01')] Ahora vamos con meronimias y holonimias:   >>> wn.synset('sky.n.01').part_meronyms() [Synset('cloud.n.02'), Synset('rainbow.n.01')]   Por hoy eso es todo, espero poder hacer algo para la semana que viene con similitud semántica   Un saludo!
  3. Me Gusta
    elmoyer ha recibido reputación de portaro en Natural Language Toolkit Python   
    Después de la entrada de CCG, vamos a pasar hoy a las DRT(discourse representation theory). El discourse representation theory es un formalismo lingüístico que intenta explorar el significado de las frases desde un enfoque semántico. Lo curioso es que se realiza de una forma visual y por ello es más cómodo trabajar con las DRT en NLTK. 
     
    Vamos a comenzar. Como me imagino que sabéis, necesitamos abrir un terminal, escribir python e importar los módulos necesarios:
    >>> import nltk >>> from nltk.sem.drt import * >>> from nltk.sem import logic >>> from nltk.inference import TableauProver Una vez importado todo, vamos a centrarnos en nuestra frase de ejemplo: "If a farmer owns a donkey, he beats it". Podríamos decir que la frase se puede dividir en dos partes:
    If a farmer owns a donkey he beats it. Una vez que tenemos claro que podemos dividir la frase en dos, comenzamos a trabajar con NLTK. Importados los módulos necesarios, comenzamos a definir las propiedades o características de las palabras que contiene nuestra frase. Pero antes tenemos que decirle a NLTK que la DRT se leerá mediante un string: 
    >>> dexpr = DrtExpression.fromstring #Comienza la declaración de las propiedades de las palabras >>> farmer_x=dexpr('farmer(x)') #granjero definido >>> donkey_y=dexpr('donkey(y)') #burro definido >>> owns_xy=('owns(x, y)') #posesión definida >>> x = dexpr('x') #x = nombre de entidad (granjero) >>> y = dexpr('y') #y = nombre de entidad (burro) Tenemos que tener en cuenta que en las DRT "sólo" nos interesan los sustantivos, verbos, adjetivos y adverbios. Por lo tanto podríamos decir que tenemos una serie de "bag of words list"(bolsa de lista de palabras?) que son nuestras stop words o palabras que carecen de importancia. Por lo tanto ni el condicional "if", ni los determinantes "un" y artículos nos sirven para nada.    Una vez definido todo, podríamos obtener el DRT de la primera parte de la frase, "si un granjero tiene un burro". Es algo tan sencillo como añadir un print y ya lo tenemos:   >>> print(DRS([x, y], [farmer_x, donkey_y, owns_xy])) ([x, y],[farmer(x), donkey(y), owns(x, y)]) Para que nos sea más fácil el trabajar con la frase, vamos a dividirla en 2. Ya tenemos la primera parte, así que vamos a guardarla en la variable drs1:
    >>> drs1 = dexpr('([x, y], [farmer(x), donkey(y), owns(x, y)])') Sin embargo muchas veces, cuando se habla de DRT, solemos referirnos a la función que acabamos de imprimir en pantalla pero en una caja. Y resulta bastante curioso el método usado por NLTK para incrustarlo en la caja, ya que la función que se encarga de eso es pretty_format() o sea imprimir en un formato bonito:
    >>> print(drs1.pretty_format()) ___________ | x y | |-----------| | farmer(x) | | donkey(y) | | owns(x,y) | |___________| Vamos ahora a por la segunda parte de la frase!. La segunda parte es la de "lo golpea". Tenemos que tener en cuenta 2 cosas: 1) con he nos estamos refiriendo a farmer. 2) con it nos estamos refiriendo a donkey.     Sin embargo tenemos que darle otros valores que no sean X e Y para que en la caja no ponga en la parte superio "X Y" ya que si pusiese eso, la DRT sería incorrecta. Comenzamos con lo mismo, definimos valores: >>> he_z= dexpr('(x=z)') >>> it_u = dexpr('(y=u)') >>> beats_zu = ('beats(z, u)') Ahora definimos los nombres de las nuevas entidades:
    >>> z = dexpr('z') >>> u = dexpr('u') Imprimimos para comprobar si esta bien y para poder guardarlo como drs2:
    >>> print (DRS([z, u], [he_z, it_u, beats_zu])) ([u,z],[(x = z), (y = u), beats(z, u)]) Guardamos el resultado como la variable drs2:
    >>> drs2 = dexpr('([u,z],[(x = z), (y = u), beats(z, u)])') Imprimimos para ver si tiene algún fallo con el método pretty_format():
    >>> print(drs2.pretty_format()) ____________ | u z | |------------| | (x = z) | | (y = u) | | beats(z,u) | |____________| Ahora solo queda unir las dos DRS que tenemo, por lo tanto lo lógico sería pensar que algo como esto uniría la frase y serviría:   >>> drs3 = drs1 + drs2 >>> print(drs3.pretty_format()) ___________ ____________ | x y | | u z | (|-----------| + |------------|) | farmer(x) | | (x = z) | | donkey(y) | | (y = u) | | owns(x,y) | | beats(z,u) | |___________| |____________| Sin embargo al ser todo una misma frase tiene que estar dentro de otra caja que recoja las dos cajas. Además tendremos que quitar el mas y sustituirlo por un simbolo de implicacion. Para ello haremos lo siguiente:   >>> drs_final = dexpr(r"([],[([x, y], [farmer(x), donkey(y), owns(x, y)]) -> ([u,z],[(x = z), (y = u), beats(z, u)])])").pretty_print() ___________________________________ | | |-----------------------------------| | ___________ ____________ | | | x y | | u z | | | (|-----------| -> |------------|) | | | farmer(x) | | (x = z) | | | | donkey(y) | | (y = u) | | | | owns(x,y) | | beats(z,u) | | | |___________| |____________| | |___________________________________| Y fin de la historia, no hay mas que hacer
     
  4. Me Gusta
    elmoyer ha recibido reputación de portaro en Natural Language Toolkit Python   
    Un poco de español en NLTK, para ser un poco mas exacto algo relacionado con CCG(Combinatory Categorial Grammar). Para poneros un poco en situación, CCG es un formalismo gramatical que nos permite ver la estructura sintáctica y semántica de una frase. La teoría aburre un poco, sobre todo si no se es muy fan de la sintaxis o semánticas así que vamos a lo practico :
     
    Como sabéis todo esto funciona con NLTK, por lo tanto lo primero que tenemos que hacer abrir un terminal y escribir python e importar los módulos necesarios:
    elmoyer@laptop: python Python 2.7.3 (default, Mar 13 2014, 11:03:55) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import nltk >>> from nltk.ccg import chart, lexicon >>> from nltk.ccg.chart import printCCGDerivation Tecleado esto, ya podemos introducir las reglas gramaticales que queramos para poder parsear la frase posteriormente. Así que vamos a ello:
    >>> lex = lexicon.parseLexicon(u''' ... :- S, N, NP, PP ... ... AdjI :: N\\N ... AdjD :: N/N ... AdvD :: S/S ... AdvI :: S\\S ... Det :: NP/N ... PrepNPCompl :: PP/NP ... PrepNAdjN :: S\\S/N ... PrepNAdjNP :: S\\S/NP ... VPNP :: S\\NP/NP ... VPPP :: S\\NP/PP ... VPser :: S\\NP/AdjI ... ... auto => N ... bebidas => N ... cine => N ... ley => N ... libro => N ... ministro => N ... panadería => N ... presidente => N ... super => N ... ... el => Det ... la => Det ... las => Det ... un => Det ... ... Ana => NP ... Pablo => NP ... ... y => var\\.,var/.,var ... ... pero => (S/NP)\\(S/NP)/(S/NP) ... ... anunció => VPNP ... compró => VPNP ... cree => S\\NP/S[dep] ... desmintió => VPNP ... lee => VPNP ... fueron => VPPP ... ... es => VPser ... ... interesante => AdjD ... interesante => AdjI ... nueva => AdjD ... nueva => AdjI ... ... a => PrepNPCompl ... en => PrepNAdjN ... en => PrepNAdjNP ... ... ayer => AdvI ... ... que => (NP\\NP)/(S/NP) ... que => S[dep]/S ... ''') Vocabulario y gramática introducido en la variable lex. Si se trabaja con una lengua que requiera soporte de unicode se tiene que escribir una "u" cuando se vaya a definir el lex, tal y como hemos hecho:
    lex = lexicon.parseLexicon(u''' ... #Reglas gramaticales ... #Diccionario Una vez que hemos definido todo, creamos nuestro parser:
    >>> parser = chart.CCGChartParser(lex, chart.DefaultRuleSet) Como podéis ver, el parser el llama al modulo chart y específicamente al método "CCGChartParser" que toma como valores el diccionario creado anteriormente(lex) y las reglas por defecto del chart.
    Una vez definido el parser, nos tocará decirle a NLTK que trabaje con la frase de la que queramos obtener la información semántica y sintáctica. Para ello haremos referencia al la variable parser(recordad que únicamente es el CCGchartParser) y también al método parse:
    >>> for parse in parser.parse(u"el ministro anunció pero el presidente desmintió la nueva ley".split()): Y tras escribir esto ya sólo nos faltaría hacer un print para que nos devolviese la frase con las anotaciones semánticas y sintácticas:
    ... printCCGDerivation(parse) ... break Y obtenemos como resultado:
    el ministro anunció pero el presidente desmintió la nueva ley (NP/N) N ((S\NP)/NP) (((S/NP)\(S/NP))/(S/NP)) (NP/N) N ((S\NP)/NP) (NP/N) (N/N) N --------Leaf (NP/N) ----------Leaf N ------------------> NP ------------------>T (S/(S\NP)) -------------Leaf ((S\NP)/NP) --------------------------Leaf (((S/NP)\(S/NP))/(S/NP)) --------Leaf (NP/N) ------------Leaf N --------------------> NP -------------------->T (S/(S\NP)) -------------Leaf ((S\NP)/NP) --------------------------------->B (S/NP) -----------------------------------------------------------> ((S/NP)\(S/NP)) --------Leaf (NP/N) -------Leaf (N/N) -----Leaf N ------------> N --------------------> NP --------------------<T (S\(S/NP)) -------------------------------------------------------------------------------<B (S\(S/NP)) --------------------------------------------------------------------------------------------<B (S/NP) --------------------------------------------------------------------------------------------------------------> S Os pongo otro ejemplo con la frase el "el ministró compró la panadería":
     
    Es todo igual, lo único que hay que cambiar es la frase a parsear.
    >>> parser = chart.CCGChartParser(lex, chart.DefaultRuleSet) >>> for parse in parser.parse(u"el ministro compró la panadería".split()): ... printCCGDerivation(parse) ... break ... Obteniendo como resultado:
    el ministro compró la panadería (NP/N) N ((S\NP)/NP) (NP/N) N --------Leaf (NP/N) ----------Leaf N ------------------> NP -------------Leaf ((S\NP)/NP) --------Leaf (NP/N) -----------Leaf N -------------------> NP --------------------------------> (S\NP) --------------------------------------------------< S Ya podéis poneros a parsear que se que lo estáis deseando
    Un saludo!
  5. Me Gusta
    elmoyer ha recibido reputación de portaro en Natural Language Toolkit Python   
    Por ahora creo que el siguiente comentario será sobre el módulo de WordNet, que me parece bastante interesante si se trabaja con textos en inglés 
  6. Me Gusta
    elmoyer ha recibido reputación de portaro en Básicamente GNU/Linux [Español]   
    y más lecturas! Necesito vacaciones para ponerme al día
  7. Me Gusta
    elmoyer ha recibido reputación de portaro en [Idea Feliz] GNU/Linux Vagos E "The Strange Penguin" [x86_64][Esp]   
    No se podía esperar menos del jefe, como siempre muy buen trabajo! descargando!!!
  8. Me Gusta
    elmoyer ha recibido reputación de portaro en Completísima guía de comandos Linux (1.527 páginas)   
    Muchas gracias por compartir!
     
    PD: el link de Dropbox se ha caído
  9. Me Gusta
    elmoyer ha recibido reputación de Mgbu en Como ayudar al compilador a generar mejor codigo   
    todo depende diría yo... no es lo mismo escribir un script en python que un script en C. Lo que yo me pregunto es si merece la pena escribir para el compilador o si con escribir código limpio bastaría. 
  10. Me Gusta
    elmoyer ha recibido reputación de Rohlling en Como ayudar al compilador a generar mejor codigo   
    todo depende diría yo... no es lo mismo escribir un script en python que un script en C. Lo que yo me pregunto es si merece la pena escribir para el compilador o si con escribir código limpio bastaría. 
  11. Me Gusta
    elmoyer ha recibido reputación de nasciiboy en Como ayudar al compilador a generar mejor codigo   
    todo depende diría yo... no es lo mismo escribir un script en python que un script en C. Lo que yo me pregunto es si merece la pena escribir para el compilador o si con escribir código limpio bastaría. 
  12. Me Gusta
    elmoyer ha recibido reputación de jalr980 en Bola Mágica 8 [python]   
    Buenos días compañeros,
     
    es una de estas mañanas que dices "pfff que pereza hacer algo en python realmente productivo, mejor algo un tanto estúpido!" :D
     
    Así que aquí va. Os acordáis de las películas americanas en las que salían esas bolas negras a las que se les preguntaba algo y te respondían? Para que comprarse una bola mágica 8 si tenemos un ordenador!
     
    Código:
    import sys import random answers = ["Es cierto","Buenas perspectivas","Puedes confiar en ello", "Pregunta de nuevo mas tarde", "Concentrate y volve a preguntar","No esta claro, intentalo de nuevo", "Mi respuesta es no", "Mis fuentes no dicen nada al respecto"] print "Presiona intro para salir" print 'Cuando hagas una pregunta, no olvides ponerla entre "" ' while True: question = input("Preguntale a la bola magica 8: ") if(question == ""): sys.exit() print(answers[random.randint(1, len(answers))]); Es ejecutarlo si seguir las instrucciones
     
                                                                               
     
     
    Espero que os riáis un rato!
  13. Me Gusta
    elmoyer ha recibido reputación de KaliMotxo en Películas / Documentales / Series recomendados   
    Hoy toca una recomendación de una serie!
     
    La serie se llama Halt and Catch Fire 
     
                                                       
                
     
     
    Situado en la década de los 80, la serie dramática trata del boom de la informática a través de los ojos de un visionario empresarial,Gordon, un ingeniero informático; y Cameron Howe, una joven prodigio de la programación. Las innovaciones de este trío se enfrentarán directamente con los gigantes corporativos de la época. Su asociación profesional y personal serán desafiados por la avaricia y el ego mientras cambien la cultura de Silicon Prairie, Texas.
     
    Yo empecé a verla ayer y he tenido que parar... a este paso me tragaba la primera temporada y hasta el 31 de mayo de este año no empezarán a retransmitir la segunda temporada
     
    Espero que la encontréis tan buena como yo!
  14. Me Gusta
    elmoyer ha recibido reputación de portaro en Hola! qué tal tod@s   
    Bienvenido!! 
  15. Me Gusta
    elmoyer ha recibido reputación de pacoeloyo en Subforo "compra-venta/intercambio"   
    Yo personalmente no lo veo, hay muchos sitios de compra-venta por internet. Creo que somos una muy buena comunidad que se entiende con bastante facilidad, y porque no decirlo, con buen rollo. Seguramente el crear una sección de compra venta de lugar a que se registren una cantidad de usuarios que únicamente se dirijan a esa sección y de ahí no les saca nadie. 
    Pero a ver que dice el resto
  16. Me Gusta
    elmoyer ha recibido reputación de Rohlling en ARC Welder   
    Viene de lujo para cuando se desempaqueta la APK y la modificas! Así no tienes que estar buscando el maldito cable!!!!  
    Aprovecho para preguntar, alguien sabe donde esta mi cable? XD XD  Usad vuestro poder de la fuerza   
  17. Me Gusta
    elmoyer ha recibido reputación de ice en Bash vs. Python   
    Buenos días compañeros!
     
    Estoy comparando código en bash y en python, así que he decidido compartirlo con vosotros. Iré publicando algunos scripts cuya comparación me ha gustado
     
                                                                              VS.     
     
     
    Empezamos con algo simple:
     
    Listado del contenido de un directorio:
    ## Bash: ls -l /tmp/ ## Python: import subprocess subprocess.call(["ls", "-l", "/tmp"]) Obtener información del sistema:
    ## Bash ---------- #!/usr/bin/env bash function uname_funct { UNAME="uname -a" printf "Obteniendo informacion del sistema con el comando $UNAME : \n\n" $UNAME } function disk_funct { DISKSPACE="df -h" printf "Obteniendo informacion del disco duro con el comando $DISKSPACE : \n\n" $DISKSPACE } ----------- ## Python: ----------- #!/usr/bin/env python import subprocess def funcion_uname(): uname = "uname" uname_arg = "-a" print "Obteniendo informacion del sistema con el comando %s :\n" % uname subprocess.call([uname, uname_arg]) def funcion_disco(): diskspace = "df" diskspace_arg = "-h" print "Obteniendo informacion del sistema con el comando %s :\n" % diskspace subprocess.call([diskspace, diskspace_arg]) def main(): funcion_uname() funcion_disco() main() Utilidad en Python: Autocompletado!!
    ## Iniciar python desde el terminal y escribir: import rlcompleter, readline readline.parse_and_bind('tab : complete') Cuando vaya avanzando, iré completándolo
     
    Espero que os guste y os sirva de algo
  18. Me Gusta
    elmoyer ha recibido reputación de portaro en Hola !! :3   
    Bienvenida compañera! La mejor escuela es abrir esa venta mágica llamada terminal, empezar con los mas comunes e ir probando
  19. Me Gusta
    elmoyer ha recibido reputación de portaro en Películas / Documentales / Series recomendados   
    Hoy toca una recomendación de una serie!
     
    La serie se llama Halt and Catch Fire 
     
                                                       
                
     
     
    Situado en la década de los 80, la serie dramática trata del boom de la informática a través de los ojos de un visionario empresarial,Gordon, un ingeniero informático; y Cameron Howe, una joven prodigio de la programación. Las innovaciones de este trío se enfrentarán directamente con los gigantes corporativos de la época. Su asociación profesional y personal serán desafiados por la avaricia y el ego mientras cambien la cultura de Silicon Prairie, Texas.
     
    Yo empecé a verla ayer y he tenido que parar... a este paso me tragaba la primera temporada y hasta el 31 de mayo de este año no empezarán a retransmitir la segunda temporada
     
    Espero que la encontréis tan buena como yo!
  20. Me Gusta
    elmoyer ha recibido reputación de portaro en Películas / Documentales / Series recomendados   
    Otra recomendación marchando... "Her". Hacía tiempo que la había visto y la verdad es que me gusto bastante.
     
    Está ambientada en Shanghái, en el futuro cercano, la película muestra a Theodore Twombly, un complejo hombre que vive escribiendo conmovedoras cartas a los demás. Con el corazón roto después de terminar una larga relación, se siente intrigado por un nuevo y avanzado sistema operativo, el que promete ser una entidad intuitiva con cada usuario. Después de inicializarlo, Theodore queda encantado de conocer a «Samantha», una brillante voz femenina que es perspicaz, sensible y sorprendentemente divertida. Mientras los deseos y las necesidades de ambos crecen, su amistad se transforma finalmente en una relación de amor.
     
    Al principio de la película seguro que pensáis yo quiero uno de esos! Cuando lo cosa empieza a ponerse turbia se nos quitan las ganas! xD
  21. Me Gusta
    elmoyer ha recibido reputación de portaro en Películas / Documentales / Series recomendados   
    Vamos a intentar comentar un poco por encima de que tratan las películas así el usuario que lo lee no tiene que ir a buscarlo pero sin hacer spoilers!!
  22. Me Gusta
    elmoyer ha recibido reputación de portaro en Películas / Documentales / Series recomendados   
    @ tranquilo yo tampoco la he visto pero esta noche o mañana cae xD
  23. Me Gusta
    elmoyer ha recibido reputación de portaro en Películas / Documentales / Series recomendados   
    Ayer tocó un poco de Millenium y hoy se seguirá con la trilogía
     
                                                                                             
     
    Así que vamos a ello por si alguno no conoce mucho sobre las películas. Las películas están basadas en las novelas de Stieg Larsson y están protagonizadas por Mikael Blomkvist y Lisbeth Salander.
     
    Primera parte: "Los hombres que no amaban a las mujeres":
     
    El periodista Mikael Blomkvist es acusado de difamación y sentenciado a pasar tres meses en la cárcel. En ese momento recibe la llamada del anciano industrial Henrik Vanger (Sven-Bertil Taube) y un interesante trabajo: si en el plazo de un año descubre cual de sus familiares mató a su sobrina Harriet, que desapareció sin dejar rastro en 1966, recibirá la información que prueba que él es inocente y podrá recuperar su prestigio profesional. Así será como, con la ayuda de la excelente hacker Lisbeth Salander, Mikael Blomkvist se embarque en una investigación que cambiará su vida para siempre.
     
    Segunda parte: "La chica que soñaba con una cerilla y un bidón de gasolina":
     
    Han pasado dos años de lo ocurrido en Hedestad y Mikael Blomkvist, que goza de cierto prestigio profesional, trabaja mano a mano junto al freelance Dag Svensson en un libro sobre el tráfico de mujeres en Suecia. Todo cambia cuando él, su pareja y el administrador Nils Bjurman aparecen asesinados y todas las pistas apuntan a que la autora de los tres crímenes es, nada más y nada menos que, Lisbeth Salander. Entonces, Mikael Blomkvist decidirá investigar los crímenes por su cuenta para demostrar la inocencia de la que un día fue su amiga ¿O, realmente, es Lisbeth Salander una asesina?
     
    Tercera parte: "La Reina en el palacio de las corrientes de aire":
     
    Lisbeth Salander ha sobrevivido y permanece en la UCI de un hospital. Su vida pende de un hilo, pero quiere venganza. Quiere demostrar que ella no cometió los tres asesinatos por los que va a ser juzgada si sobrevive y quiere vengarse de su propio padre y las instituciones gubernamentales que le han destruido la vida. Con la ayuda de Mikael Blomkvist y la redacción de la revista Millenium, Lisbeth tendrá que encontrar ese hilo del que tirar antes de que sus enemigos consigan matarla.
     
     
    Personalmente la trilogía me parece bastante buena, eso si, la versión sueca! no la americana
    Nunca me han gustado mucho los escritores suecos pero ahora me estoy leyendo los libros y me parece que merecen la pena . Así que si alguno no ha visto nunca ninguna de las películas se la recomiendo(aun que para gusto los colores!) para cuando tenga unas cuantas horas libres y no sepa que hacer!
  24. Me Gusta
    elmoyer ha recibido reputación de portaro en Películas / Documentales / Series recomendados   
    @@Pepegnu pues agárrate ya que hay segunda parte aun que segundas partes nunca fueron buenas xD
  25. Me Gusta
    elmoyer ha recibido reputación de portaro en Películas / Documentales / Series recomendados   
    Por si acaso quito el trailer
×
×
  • Crear Nuevo...