Extraction des entités avec NER

Ce notebook utilise spacy.io pour identifier et collecter certains types d'entités: Personnes, GPE, NORP, ...

Voir https://spacy.io/docs/usage/entity-recognition pour la liste complète des entités identifiables par spacy

In [2]:
import pandas as pd
import numpy as np

import csv, re, string

import spacy
In [7]:
# load les données
df = pd.read_csv('../data/facebook_god_emperor_trump.csv', low_memory=False)

# échantillonage aléatoire des données ce qui permet 
# de faire tourner le script sur un subset du dataset
# frac = 0.5 => 50% du dataset original 

frac = 1
df = df.sample(frac = frac)

print("\n-- Le dataset a {0} rows".format(df.shape[0]))
print("\n-- columns")
print(df.columns)
print("\n-- head")
print(df.head())
--Le dataset a 172191 rows

-- columns
Index(['post_id', 'reaction_count', 'share_count', 'comment_count',
       'created_at', 'message'],
      dtype='object')

-- head
        post_id  reaction_count  share_count  comment_count  \
73862      1156             0.0          0.0            0.0   
49902      5390             1.0          0.0            0.0   
81677      4803             2.0          0.0            0.0   
156453     2704             1.0          0.0            0.0   
7789       2818             0.0          0.0            0.0   

                 created_at                                            message  
73862   2016-07-24 15:46:46  Bien Paolo Vargas Well, your a nasty little Cu...  
49902   2016-10-23 21:17:37       "and they are bringing those problems to us"  
81677   2016-09-15 00:40:10  This still does not fill the void in my life. ...  
156453  2016-09-20 17:44:09  why's real life moonman a deplorable now? that...  
7789    2016-11-18 11:35:33  She's been cut off from her daily dose of adre...  

Identification des entités

On s'intéresse surtout aux personnes, GPE (pays, villes, états), ORG (entreprises, marques) et NORP (nationalités, religions, ...). Le NER de spacy n'est pas 100% précis. Mais c'est cela qui nous sera utile pour identifier les détournements des noms de personnes, de pays (Murica pour America) ou d'autres entités (4chan, Fox News, ...)

Voir https://spacy.io/docs/usage/entity-recognition pour d'autres exemples d'utilisation du NER de spacy.io

In [ ]:
# charger le modele spacy en anglais

nlp     = spacy.load('en')

# Très simplement, ajouter stocker chaque entité dans une liste

persons = []
GPE     = []
ORG     = []
NORP    = []
entities = []  # pour toutes les autres entités hors date ou chiffre

# Parcourir tous les rows de la dataframe 

for i,d in df.iterrows():

    # parser chaque message avec spacy

    doc = nlp(d.message)
    
    # si spacy a identifié des entités:

    if len(doc.ents) > 0:
        for ent in doc.ents:
            if ent.label_ == 'PERSON':
                persons.append(str(ent))
            elif ent.label_ == 'GPE':
                GPE.append(str(ent))
            elif ent.label_ == 'NORP':
                NORP.append(str(ent))
            elif ent.label_ == 'ORG':
                ORG.append(str(ent))
            # Toutes les autres entités trouvées en dehors des dates et chiffres
            elif (ent.label_ not in ['CARDINAL', 'ORDINAL', 'PERCENT','DATE','TIME']) :
                entities.append((str(ent), ent.label_))

            
# mémoriser les différentes entités dans des fichiers

open('../data/persons.txt', 'w').write("\n".join( sorted(persons) ))
open('../data/gpe.txt', 'w').write("\n".join( sorted(GPE) ))
open('../data/norp.txt', 'w').write("\n".join( sorted(NORP) ))
open('../data/org.txt', 'w').write("\n".join( sorted(ORG) ))

# Sauvegarder les autres type d'entités ainsi que leur type

str_entities = [ "{0},{1}".format(e[1], str(e[0]).replace(',',' '))  for e in entities ]

open('../data/entities.csv', 'w').write("\n".join( str_entities ))