Identificación nombres propios

Forums

Buenas tardes,

en una de las entradas publicadas he observado que se puede identificar nombres propios de un texto en Python. He seguido los pasos importando NLTK(import nltk) pero me da error cuando aplico las funciones que vienen expresadas en el artículo. ¿A qué es debido? Necesito identificar los personajes (nombres propios) en una obra de texto e ordenarlos alfabéticamente. 

Espero respuesta. Gracias de antemano. Saludos.

>>> import os
>>> os.listdir('/')
['$GetCurrent', '$Recycle.Bin', '$SysReset', 'Archivos de programa', 'Boot', 'bootmgr', 'Config.Msi', 'Documents and Settings', 'hiberfil.sys', 'Intel', 'MSOCache', 'OneDriveTemp', 'pagefile.sys', 'PerfLogs', 'Program Files', 'Program Files (x86)', 'ProgramData', 'Recovery', 'setup.log', 'swapfile.sys', 'System Volume Information', 'Users', 'Windows', 'Windows10Upgrade']
>>> with open('C:\\Users\\pablo\\Desktop\\macbeth.txt','r',encoding='utf8') as f:
    texto=f.read()
    len(texto)

    
116578
>>> import nltk
>>> tags=nltk.pos_tag(word_tokenize(s))
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    tags=nltk.pos_tag(word_tokenize(s))
NameError: name 'word_tokenize' is not defined
>>> tags=nltk.pos_tag(texto(s))
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    tags=nltk.pos_tag(texto(s))
NameError: name 's' is not defined
>>> 

Le explico: como ves, primero abro el archivo y calculo su longitud para verificar que está bien cargado mediante len(texto).

Después importo nltk y le añado los pasos que he encontrado en el artículo que tienen ustedes subidos pero como observa, me da ese error. 

Por probar, he cambiado "word_tokenize" por texto (ya que mi archivo se encuentra almacenado en la variable texto) pero me sigue dando error. ¿Sabría solucionarlo?

Quedo a la espera de su respuesta. Gracias.

Hola,

en el código en cuestión, además de importar nltk, hay algunas funciones que se importan de dicha librería de forma explícita, por ejemplo, word_tokenize. En tu caso tienes dos opciones:

  • O bien haces referencia a dicha función precediéndola del nombre de la librería: nltk.word_tokenize
  • O importas dicha función con from nltk import word_tokenize

En el primer caso te quedaría algo como

tags = nltk.pos_tag(nltk.word_tokenize(texto))

Tienes que usar la variable "texto" (y no "s") pues es así cómo has llamada al texto que has leído.

Inténtalo y me dices...

Un saludo

Daniel

Hola de nuevo, me da el siguiente error siguiendo ambas opciones:

>>> from nltk import word_tokenize
>>> tags=nltk.pos_tag(word_tokenize(texto))
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    tags=nltk.pos_tag(word_tokenize(texto))
  File "C:\Users\pablo\AppData\Roaming\Python\Python38\site-packages\nltk\tokenize\__init__.py", line 144, in word_tokenize
    sentences = [text] if preserve_line else sent_tokenize(text, language)
  File "C:\Users\pablo\AppData\Roaming\Python\Python38\site-packages\nltk\tokenize\__init__.py", line 105, in sent_tokenize
    tokenizer = load('tokenizers/punkt/{0}.pickle'.format(language))
  File "C:\Users\pablo\AppData\Roaming\Python\Python38\site-packages\nltk\data.py", line 868, in load
    opened_resource = _open(resource_url)
  File "C:\Users\pablo\AppData\Roaming\Python\Python38\site-packages\nltk\data.py", line 993, in _open
    return find(path_, path + ['']).open()
  File "C:\Users\pablo\AppData\Roaming\Python\Python38\site-packages\nltk\data.py", line 701, in find
    raise LookupError(resource_not_found)
LookupError: 
**********************************************************************
  Resource [93mpunkt[0m not found.
  Please use the NLTK Downloader to obtain the resource:

  [31m>>> import nltk
  >>> nltk.download('punkt')
  [0m
  For more information see: https://www.nltk.org/data.html

  Attempted to load [93mtokenizers/punkt/english.pickle[0m

  Searched in:
    - 'C:\\Users\\pablo/nltk_data'
    - 'C:\\Program Files\\Python38\\nltk_data'
    - 'C:\\Program Files\\Python38\\share\\nltk_data'
    - 'C:\\Program Files\\Python38\\lib\\nltk_data'
    - 'C:\\Users\\pablo\\AppData\\Roaming\\nltk_data'
    - 'C:\\nltk_data'
    - 'D:\\nltk_data'

No sé si es un tema ya que no tiene que ver con esto, pero no lo entiendo... No sé si usted sabe identificar este error. 

Un saludo

Vale, Daniel. Creo que ya lo tengo. Tenía que descargarme el paquete para aplicar las funciones de NLTK. Ahora bien, cuando ya introduzco todos los códigos incluido el último de nouns = [word for word, tag in tags if tag in ['NN','NNS', 'NNP', 'NNPS'] ], qué debería hacer para que me devuelva una lista con todos los nombres desglosados (en este caso yo solo usaría ['NNP'] porque busco nombres propios. Imagino que será usando el código print. ¿Puede ser?

Efectivamente, hay recursos que, por su tamaño, no se descargan al instalar la librería nltk y hay que usar el "downloader" en cuestión.

En el código del artículo al que hacías referencia en tu mensaje inicial, terminas con una lista de tuplas:

Extracción de palabras con un cierto tag

Si quieres extraer de esta estructura un subconjunto de palabras, puedes usar una "comprehension list". Por ejemplo, si quieres las palabras cuyo tag contenga "NN", sería así:

[word for (word, tag) in tags if "NN" in tag]

(es decir, extrae todas las "word" de las tuplas (word, tag) que hay en tags, si tag contiene "NN"):

Palabras cuyo tag contiene "NN"

 

De acuerdo pero, al extraerlo, evidentemente son muchas palabras las que se extraen. Pero he comprobado que ha extraído con el código NN demasiadas palabras, creo que las que empiezan por mayúscula. Si solamente me gustaría extraer nombres propios (de personajes), sabría decirme cómo debería continuar?

Gracias por la ayuda.

No tienes más que cambiar la condición que se aplique en la "comprehension list". En el ejemplo que comenté, uso if "NN" in tag (para extraer todas las palabras que contengan esa cadena de texto en su tag). Tienes que llevar ahí la condición que te interese a ti. Si te interesan las palabras cuyo tag sea exactamente NNP, tendrás que usar la condición if tag == "NNP".

Y tendrás que asignar la salida de esa expresión a una variable para poder utilizarla posteriormente, claro.

Enviado por pablolozano00 el Mié, 01/04/2020 - 11:39