Python >> Tutoriel Python >  >> Python Tag >> NLTK

Résolution de coréférence en python nltk à l'aide de Stanford coreNLP

Comme mentionné par @Igor, vous pouvez essayer le wrapper python implémenté dans ce référentiel GitHub :https://github.com/dasmith/stanford-corenlp-python

Ce référentiel contient deux fichiers principaux :corenlp.pyclient.py

Effectuez les modifications suivantes pour que coreNLP fonctionne :

  1. Dans corenlp.py, modifiez le chemin du dossier corenlp. Définissez le chemin où votre ordinateur local contient le dossier corenlp et ajoutez le chemin à la ligne 144 de corenlp.py

    if not corenlp_path: corenlp_path = <path to the corenlp file>

  2. Le numéro de version du fichier jar dans "corenlp.py" est différent. Réglez-le en fonction de la version corenlp que vous avez. Changez-le à la ligne 135 de corenlp.py

    jars = ["stanford-corenlp-3.4.1.jar", "stanford-corenlp-3.4.1-models.jar", "joda-time.jar", "xom.jar", "jollyday.jar"]

Dans ce cas, remplacez 3.4.1 par la version jar que vous avez téléchargée.

  1. Exécutez la commande :

    python corenlp.py

Cela va démarrer un serveur

  1. Exécutez maintenant le programme client principal

    python client.py

Cela fournit un dictionnaire et vous pouvez accéder au coref en utilisant 'coref' comme clé :

Par exemple :John est informaticien. Il aime coder.

{
     "coref": [[[["a Computer Scientist", 0, 4, 2, 5], ["John", 0, 0, 0, 1]], [["He", 1, 0, 0, 1], ["John", 0, 0, 0, 1]]]]
}

J'ai essayé ceci sur Ubuntu 16.04. Utilisez Java version 7 ou 8.


stanfordcorenlp, le wrapper relativement nouveau, peut fonctionner pour vous.

Supposons que le texte soit "Barack Obama est né à Hawaï. Il est le président. Obama a été élu en 2008. "

Le code :

# coding=utf-8

import json
from stanfordcorenlp import StanfordCoreNLP

nlp = StanfordCoreNLP(r'G:\JavaLibraries\stanford-corenlp-full-2017-06-09', quiet=False)
props = {'annotators': 'coref', 'pipelineLanguage': 'en'}

text = 'Barack Obama was born in Hawaii.  He is the president. Obama was elected in 2008.'
result = json.loads(nlp.annotate(text, properties=props))

num, mentions = result['corefs'].items()[0]
for mention in mentions:
    print(mention)

Chaque "mention" ci-dessus est un dict Python comme celui-ci :

{
  "id": 0,
  "text": "Barack Obama",
  "type": "PROPER",
  "number": "SINGULAR",
  "gender": "MALE",
  "animacy": "ANIMATE",
  "startIndex": 1,
  "endIndex": 3,
  "headIndex": 2,
  "sentNum": 1,
  "position": [
    1,
    1
  ],
  "isRepresentativeMention": true
}

Le CoreNLP de Stanford a maintenant une liaison Python officielle appelée StanfordNLP, comme vous pouvez le lire sur le site Web de StanfordNLP.

L'API native ne semble pas encore prendre en charge le processeur coref, mais vous pouvez utiliser l'interface CoreNLPClient pour appeler le CoreNLP "standard" (le logiciel Java d'origine) à partir de Python.

Ainsi, après avoir suivi les instructions pour configurer le wrapper Python ici, vous pouvez obtenir la chaîne de coréférence comme celle-ci :

from stanfordnlp.server import CoreNLPClient

text = 'Barack was born in Hawaii. His wife Michelle was born in Milan. He says that she is very smart.'
print(f"Input text: {text}")

# set up the client
client = CoreNLPClient(properties={'annotators': 'coref', 'coref.algorithm' : 'statistical'}, timeout=60000, memory='16G')

# submit the request to the server
ann = client.annotate(text)    

mychains = list()
chains = ann.corefChain
for chain in chains:
    mychain = list()
    # Loop through every mention of this chain
    for mention in chain.mention:
        # Get the sentence in which this mention is located, and get the words which are part of this mention
        # (we can have more than one word, for example, a mention can be a pronoun like "he", but also a compound noun like "His wife Michelle")
        words_list = ann.sentence[mention.sentenceIndex].token[mention.beginIndex:mention.endIndex]
        #build a string out of the words of this mention
        ment_word = ' '.join([x.word for x in words_list])
        mychain.append(ment_word)
    mychains.append(mychain)

for chain in mychains:
    print(' <-> '.join(chain))