Begrijpend lezen met Python en NLP ?>

Begrijpend lezen met Python en NLP

In een eerder blog schreef ik over de mogelijkheden van het analyseren van de inhoud van PDF bestanden met behulp van Python (zie http://blog.refine-it.nl/inhoud-pdf-bestanden-analyseren-met-python/).

Het uitlezen van de tekst uit dergelijke ongestructureerde databronnen is één ding. De volgende stap in het proces is dat je de ingelezen tekst ook moet begrijpen. Python heeft hier ook uitgebreide mogelijkheden voor. Hoewel deze functionaliteit het meest uitgebreid in het Engels is, zijn er ook goede mogelijkheden in het Nederlands. In deze blog leg ik de eerste stappen uit hoe je teksten kunt ontleden om een eerste inzicht in de inhoud te krijgen.

Benodigdheden

We maken in deze blog gebruik van:

  • Python versie 2.7
  • De volgende Python libraries:
    • Pandas
      Voor het makkelijk kunnen presenteren van de data in Pyhton
    • Nltk
      NLTK staat voor de  Natural Language Toolkit en wordt gebruikt voor het verwerken van de menselijke taal.
    • Spacy
      Dit zijn statistische modellen voor het voorspellen en toewijzen van taalkundige kenmerken. We gebruiken ook het Nederlandse model (nl_core_news_sm)

Importeren van de libraries

We starten het python script met het importeren van de benodigde libraries:


import spacy

from spacy import displacy

import pandas as pd

import nltk

import nl_core_news_sm

import unicodedata

from nltk.tokenize.toktok import ToktokTokenizer

Inlezen van de data

Als voorbeeld data maken we voor deze blog gebruik van een tekst bestand. We hebben een blog van deze website gekopieerd en geplakt in een txt bestand. In een andere blog zullen we ingaan op het webscrapen met behulp van Python.

Met de volgende code lezen we het bestand in:


myfile = open(u"blogtekst.txt")

tekst = myfile.read()

Opschonen van de data

Ongestructureerde data moet in de meeste gevallen eerst opgeschoond worden voordat deze goed gebruikt kan worden.

Als voorbeeld voeren we de volgende bewerkingen uit:

Verwijderen van karakters met accenten

In veel teksten komen karakters en letters voor met accenten. We moeten deze converteren naar standaard ASCII karakters om deze zo goed mogelijk te kunnen analyseren

Voor het verwijderen van accenten gebruiken we de volgende functie:


def remove_accented_chars(text):

text = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('utf-8', 'ignore')

return text

Verwijderen van speciale karakters

Speciale karakters en symbolen zijn vaak niet alfanumeriek en veroorzaken ruis in de ongestructureerde data. Ook deze tekens moeten we daarom converteren.
Voor het verwijderen van de speciale karakters gebruiken we de volgende functie:


def remove_special_characters(text, remove_digits=False):

pattern = r'[^a-zA-z0-9\s]' if not remove_digits else r'[^a-zA-z\s]'

text = re.sub(pattern, '', text)

return text

Verwijderen van stopwoorden

Woorden met weinig of geen belang noemen we stopwoorden. Voorbeelden zijn de, het en van. Deze woorden komen in veel teksten vaak voor en verstoren de analyse van de tekst. Het is dan ook meestal verstandig om deze woorden te verwijderen voor de analyse.

Voor het verwijderen van de stopwoorden gebruiken we de volgende code


tokenizer = ToktokTokenizer()

stopword_list = nltk.corpus.stopwords.words('dutch')

def remove_stopwords(text, is_lower_case=False):

tokens = tokenizer.tokenize(text)

tokens = [token.strip() for token in tokens]

if is_lower_case:

filtered_tokens = [token for token in tokens if token not in stopword_list]

else:

filtered_tokens = [token for token in tokens if token.lower() not in stopword_list]

filtered_text = ' '.join(filtered_tokens)

return filtered_text

Niet voor elke tekst hebben we al deze bewerkingen nodig. Met de volgende functie kunnen we flexibel de verschillende functies aanroepen:


def normaliseren_tekst(corpus, accented_char_removal=True, special_char_removal=True,

stopword_removal=True):

genormaliseerde_tekst = []

for doc in corpus:

# vervang karakters met accenten

if accented_char_removal:

doc = remove_accented_chars(doc)

# verwijder speciale karakters

if special_char_removal:

# insert spaces between special characters to isolate them

special_char_pattern = re.compile(r'([{.(-)!}])')

doc = special_char_pattern.sub(" \\1 ", doc)

doc = remove_special_characters(doc, remove_digits=remove_digits)

# verwijder stopwoorden

if stopword_removal:

doc = remove_stopwords(doc.decode('unicode-escape'), is_lower_case=text_lower_case)

genormaliseerde_tekst.append(doc)


return genormaliseerde_tekst

Normaliseren van de tekst

We kunnen nu de ingelezen tekst opschonen door de volgende functie aan te roepen:


tekst = normaliseren_tekst(tekst.decode('unicode-escape'), accented_char_removal=True,

special_char_removal=True, stopword_removal=True)

Taggen van de tekst

We hebben nu een opgeschoonde tekst die we met Spacy kunnen gaan ‘taggen’.
Kennis over de structuur en de syntax van de taal geeft veel informatie over de inhoud van de tekst. Er zijn diverse methodes om de syntax van tekst te analyseren. In deze blog gebruiken we de Parts Of Speech (POS) methode van tagging.
We gebruiken hier de library van Spacy.  Tagging kan ook met behulp van de nltk library, maar Spacy blijkt in de praktijk vaak betere resultaten op te leveren.

We starten met het inladen van het Nederlandse model van Spacy:


nlp = nl_core_news_sm.load()

Met de volgende code gaan we de ingeladen tekst vervolgens taggen en “ printen”  in de console:


doc = nlp(str(tekst.decode('unicode-escape')))

spacy_pos_tagged = [(word, word.tag_, word.pos_) for word in doc]

print(pd.DataFrame(spacy_pos_tagged, columns=['Word', 'POS tag', 'Tag type']))

Uitkomsten analyseren

De uitkomst van deze code is als volgt:

In de tabel zie je alle woorden vanuit de tekst en die worden met een POS Tag en een Tag Type aangeduid.
Een paar voorbeelden van deze toegevoegde tags zijn:

  • N(oun): zelfstandig naamwoorden.
  • V(erb): werkwoord
  • Adj(ective): bijvoeglijk naamwoord
  • Adv(erb): bijwoorden

Een complete lijst van alle Spacy POS tags is te vinden via deze link: https://spacy.io/api/annotation

Conclusie

We hebben in deze blog een nieuwe stap gemaakt in het proces van het begrijpen van de inhoud van een ongestructureerde databron zodat we de tekst verder kunnen analyseren.

Nu we de opbouw van de tekst kennen, kan een volgende stap zijn om de teksten te gaan classificeren en samenvatten.

Python en libraries zoals nltk en Spacy bieden vele functionaliteiten om deze analyses te kunnen uitvoeren.

 

Klik hier om naar onze site te gaan

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *