Home > front end >  Efficient way to sentence-tokenize and clean text
Efficient way to sentence-tokenize and clean text

Time:10-18

I have a dataframe consisting of two columns, one with dates and the other with a string of text. I'd like to split the text in sentences and then apply some preprocessing.

Here is a simplified example of what I have:

import nltk
from nltk.corpus import stopwords

example_df=pd.DataFrame({'date':['2022-09-01'],'text':'Europa tiene un plan. Son cosas distintas. Perdón, esta es imagen dentro, y el recorte a los beneficios los ingresos totales conocimiento del uso fraudulento Además, el riesgo ha bajado. de gases nocivos, como el CO2. -La justicia europea ha confirmado se ha dado acceso al público por lo menos, intentar entrar. para reducir los contagios, vestido de chaqué. Han tenido que establecer de despido según informa que podría pasar desapercibida El Tribunal Supremo confirma en nuestra página web'})

spanish_tokenizer = nltk.data.load('tokenizers/punkt/PY3/spanish.pickle')
example_df['sentence']=example_df['text'].parallel_apply(lambda x: spanish_tokenizer.tokenize(x))

As you can see, I rely on nltk tokenizer on the raw text to create a new column "sentences", that contains the list of sentences.

print(example_df['sentence'])
0    [Europa tiene un plan, Son cosas distintas, Perdón, esta es imagen dentro, y el recorte a los beneficios los ingresos totales conocimiento del uso fraudulento Además, el riesgo ha bajado, de gases nocivos, como el CO2, -La justicia europea ha confirmado se ha dado acceso al público por lo menos, intentar entrar, para reducir los contagios, vestido de chaqué, Han tenido que establecer de despido según informa que podría pasar desapercibida El Tribunal Supremo confirma en nuestra página web]
1                                                                                                                                                                                                                           [casi todas las restricciones, Socios como Esquerra le echan un servicio público; con terrazas llenas Los voluntarios piden a todos los cuatros juntos en una semana la sentencia de cárcel para Griñán que Griñán no conoció la trama, de las hipotecas, A las afueras de Westminster]
Name: sentence, dtype: object

# Since commas might be misleading:

example_df.sentence[1]
['casi todas las restricciones',
 'Socios como Esquerra le echan un servicio público; con terrazas llenas Los voluntarios piden a todos los cuatros juntos en una semana la sentencia de cárcel para Griñán que Griñán no conoció la trama, de las hipotecas',
 'A las afueras de Westminster']

My next goal is to clean those sentences. Since I need punctuation for the tokenizer to work, I believe I need to do this process ex-post which implies looping, for each date of text, to each sentence. First of all, I am not sure how to do this operation with the pandas structure, here is one of my trials to remove stopwords:

from nltk.corpus import stopwords

stop = stopwords.words('spanish')
example_df['sentence'] = example_df['sentence'].parallel_apply(lambda x: ' '.join(
    [word for word  in i.split()  for i in x if word not in (stop)]))

Which produces the following attribute error AttributeError: 'int' object has no attribute 'split'

Is there a more efficient/elegant wat to do this?

CodePudding user response:

Since the sentence column is tokenized text (a list of strings) the list comprehension logic needs to be changed.

Eg:

sentences = ['casi todas las restricciones', 'Socios como Esquerra le echan un servicio público; con terrazas llenas Los voluntarios piden a todos los cuatros juntos en una semana la sentencia de cárcel para Griñán que Griñán no conoció la trama, de las hipotecas', 'A las afueras de Westminster']
stopwords_removed = [word for word in sent.split() for sent in sentences if word not in stop]

sent being the sentences inside the list and each word being the individual words you obtain after splitting by whitespace.

Your error is most likely caused due to a missing axis parameter

df.Column.parallel_apply(func, axis=1)

where func is a function that returns your list comprehension result

CodePudding user response:

I think I managed to fix the list comprehension. I still have the efficiency issues once this is applied to a large corpus (sure, removing stop words can be done ex-ante, for removing punctuation should be done per each sentence of each row?)

example_df['sentence']=example_df['sentence'].parallel_apply(lambda x: [word for el in x for word in el.split() if word not in stop])

  • Related