Правильная обработка необработанного текста

Обработка естественного языка, сокращенно НЛП, — это область искусственного интеллекта, которая занимается лингвистикой и человеческим языком. НЛП имеет дело с взаимодействием между компьютерами и человеческими языками. Он позволяет и программирует компьютеры для понимания человеческих языков и их анализа для выполнения таких задач, как классификация, обобщение, распознавание именованных объектов и т. д.

Но прежде чем компьютерная программа сможет проанализировать человеческий язык, необходимо выполнить множество шагов по очистке и предварительной обработке. Предварительная обработка и очистка текстовых данных оказывают огромное влияние на производительность моделей. Следовательно, очистка и обработка текста имеют огромное значение в жизненном цикле проекта НЛП.

В этой статье мы рассмотрим некоторые методы очистки и обработки текста и реализуем их с помощью языка программирования Python.

Удаление тегов HTML

Необработанный текст может содержать теги HTML, особенно если текст извлекается с использованием таких методов, как очистка веб-страниц или экрана. HTML-теги шумят и не добавляют ценности для понимания и анализа текста. Следовательно, их следует удалить. Мы будем использовать библиотеку BeautifulSoup для удаления тегов HTML.

from bs4 import BeautifulSoup
def remove_html_tags(text):
    return BeautifulSoup(text, 'html.parser').get_text()
remove_html_tags( ‘<p>A part of the text <span>and here another part</span></p>’)
#output
>> A part of the text and here another part

Стандартизация регистра

Это один из наиболее распространенных этапов предварительной обработки в НЛП, когда текст преобразуется в тот же регистр, чаще всего в нижний регистр.

def to_lowercase(text):
    return text.lower()
print("Learning NLP is Fun....")
>> learning nlp is fun

Но этот шаг может привести к потере информации в некоторых задачах НЛП. Например, в задаче анализа настроений слова, написанные заглавными буквами, могут обозначать сильные эмоции, такие как гнев, волнение и т. д. В таких случаях мы можем захотеть выполнить этот шаг по-другому или даже избежать его.

Стандартизация знаков ударения

Иногда люди используют символы с ударением, такие как é, ö и т. д., чтобы обозначить акцент на определенной букве во время произношения. В некоторых случаях знаки ударения также поясняют семантику слов, которая без знаков ударения может быть другой. Хотя символы с диакритическими знаками могут встречаться очень редко, рекомендуется преобразовать эти символы в стандартные символы ASCII.

import unicodedata
def standardize_accented_chars(text):
 return unicodedata.normalize(‘NFKD’, text).encode(‘ascii’, ‘ignore’).decode(‘utf-8’, ‘ignore’)
print(standardize_accented_chars('Sómě words such as résumé, café, prótest, divorcé, coördinate, exposé, latté.'))
>> Some words such as resume, cafe, pretest, divorce, coordinate, expose, latte.

Работа с URL-адресами

Часто люди используют URL-адреса, особенно в социальных сетях, чтобы предоставить дополнительную информацию в контексте. URL-адреса не распространяются на выборки и, следовательно, являются шумом. Мы можем удалить URL-адреса с помощью регулярных выражений.

impor re 
def remove_url(text):
 return re.sub(r’https?:\S*’, ‘’, text)
print(remove_url('using https://www.google.com/ as an example'))
>> using as an example

Примечание. В некоторых задачах URL-адреса могут добавлять к данным дополнительную информацию. Например, в задаче классификации текста, целью которой является определение того, является ли комментарий в социальной сети рекламой или нет, наличие URL-адресов в комментарии может предоставить полезную информацию. В таком случае мы можем заменить URL-адреса пользовательским токеном, например ‹URL›, или добавить в вектор признаков дополнительную бинарную функцию, которая соответствует наличию URL-адреса.

Расширение сокращений

Сокращения — это сокращенные версии слов или слогов. Они создаются путем удаления одной или нескольких букв из слов. Иногда несколько слов объединяются для создания сокращения. Например, I will сокращается на I’ll, do not на don’t. Учет я и я по-разному может привести к снижению производительности модели. Следовательно, хорошей практикой является преобразование каждого сокращения в его расширенную форму. Мы можем использовать библиотеку сокращений для преобразования сокращений в их расширенную форму.

import contractions
def expand_contractions(text):
    expanded_words = [] 
    for word in text.split():
       expanded_words.append(contractions.fix(word)) 
    return ‘ '.join(expanded_words)
print(expand_contractions("Don't is same as do not"))
>> Do not is same as do not

Удаление упоминаний и хэштегов

Этот шаг вступает в силу при работе с текстовыми данными социальных сетей, например, Tweets. Упоминания и хэштеги не распространяются на образцы и являются шумом в большинстве задач НЛП. Следовательно, лучше удалить их.

import re
def remove_mentions_and_tags(text):
    text = re.sub(r’@\S*’, ‘’, text)
    return re.sub(r’#\S*’, ‘’, text)
#testing the function on a single sample for explaination
print(remove_mentions_and_tags('Some random @abc and#def'))
>> Some random and 

Приведенный выше вывод может иметь большое значение для людей, но помогает повысить производительность моделей.

Примечание. На этом шаге мы удаляем текст, который идет после «@» и «#». Кроме того, этот шаг следует выполнить перед удалением специальных символов (шаг, который мы рассмотрим далее) из текста.

Удаление специальных символов

Специальные символы не являются буквенно-цифровыми символами. Такие символы, как %, $, & и т. д., являются специальными. В большинстве задач НЛП эти символы не добавляют значения для понимания текста и вносят шум в алгоритмы. Мы можем использовать регулярные выражения для удаления специальных символов.

import re
def remove_special_characters(text):
    # define the pattern to keep
    pat = r'[^a-zA-z0-9.,!?/:;\"\'\s]' 
    return re.sub(pat, '', text)
 
print(remove_special_characters(“007 Not sure@ if this % was #fun! 558923 What do# you think** of it.? $500USD!”))
>> '007 Not sure if this  was fun! 558923 What do you think of it.? 500USD!'

Удаление цифр

Цифры в тексте не добавляют лишней информации к данным и не вносят шума в алгоритмы. Следовательно, рекомендуется удалять цифры из текста. Опять же, мы можем использовать регулярное выражение для решения этой задачи.

# imports
import re 
def remove_numbers(text):
    pattern = r'[^a-zA-z.,!?/:;\"\'\s]' 
    return re.sub(pattern, '', text)
 
print(remove_numbers(“You owe me 1000 Dollars”))
>> You owe me Dollars

Удаление пунктуации

Опять же, знаки препинания не добавляют дополнительную информацию к данным в НЛП, поэтому мы их удаляем.

import string
def remove_punctuation(text):
    return ''.join([c for c in text if c not in string.punctuation])
    
remove_punctuation('On 24th April, 2005, "Me at the zoo" became the first video ever uploaded to YouTube.')
>> On 24th April 2005 Me at zoo became the first video ever uploaded to Youtube

Лимматизация

Лемматизация порождает корневую форму слов из их флективных форм. Например, для корневого слова ‘play’, ‘playing будет его изменяемой формой. Обратите внимание, что слова играть и играть означают почти одно и то же, и было бы лучше, если бы наша модель рассматривала воспроизведение так же, как воспроизведение. Для достижения таких преобразований мы используем лемматизацию. Лемматизация использует словарный запас и морфологический анализ слов для создания корневой формы слова. Мы будем использовать библиотеку spaCy для выполнения лемматизации.

import spacy
def lemmatize(text, nlp):
   doc = nlp(text)
   lemmatized_text = []
   for token in doc:
     lemmatized_text.append(token.lemma_)
   return “ “.join(lemmatized_text)
print(lemmatize('Reading NLP blog is fun.' ,nlp ))
>> Read NLP blog is fun.

До лемматизации стемпинг использовался для приведения флективных слов к их корневым формам. Но стемминг не учитывает словарный запас языка и удаляет из слов словоизменения, используя некоторый подход, основанный на правилах. Во многих случаях стемминг дает слова, не входящие в словарь языка. Следовательно, лемматизация почти всегда предпочтительнее стемминга. Тем не менее, я предоставляю код для выполнения стемминга.

import nltk
def get_stem(text):
    stemmer = nltk.porter.PorterStemmer()
    return ' '.join([stemmer.stem(word) for word in text.split()])
print(get_stem("Sharing and caring is a good habit"))
>> Shar and car is a good habit

Обратите внимание, что забота стала автомобильной, а Общий доступ стал Общий доступ.

Удаление стоп-слов

Такие стоп-слова, как I, am, me и т. д., не добавляют никакой информации, которая может помочь в моделировании. Их сохранение добавляет шума и увеличивает размеры векторов признаков, что сильно влияет на стоимость вычислений и точность модели. Поэтому желательно их удалить. Мы будем использовать библиотеку spacy для удаления стоп-слов. Spacy имеет 326 слов в наборе стоп-слов. В некоторых случаях мы можем захотеть добавить некоторые пользовательские стоп-слова, то есть слова, которые являются стоп-словами для наших задач, но могут не входить в набор стоп-слов spacy. Также в некоторых задачах NLP нам может понадобиться удалить некоторые слова из набора стоп-слов spacy. Например, в задачах на определение тональности мы хотели бы сохранить в тексте слова отрицания, такие как ‘not, ни, ни, и т. д.’, поэтому мы удалим их из набора стоп-слов spacy.

def remove_stopwords(text,nlp):       
    filtered_sentence =[] 
    doc=nlp(text)
    for token in doc:
        
        if token.is_stop == False: 
          filtered_sentence.append(token.text)   
    return “ “.join(filtered_sentence)
nlp = spacy.load("en_core_web_sm", disable=["parser", "ner"])
print(remove_stopwords('I love going to school',nlp))
>> love going school

Заключение

Мы обсудили некоторые распространенные и полезные методы очистки и обработки текста. Вы могли заметить, что я реализовал эти функции по отдельности, а некоторые функции можно комбинировать для повышения производительности кода. Я сохранил все шаги отдельно для лучшего объяснения отдельных шагов. При реализации этих шагов в проекте некоторые шаги можно комбинировать. Кроме того, некоторые из них могут не потребоваться в определенных задачах НЛП. Я попытался объяснить, какие шаги можно игнорировать в каких ситуациях. Но решение о включении этих шагов во многом зависит от постановки задачи. Кроме того, могут быть и другие библиотеки, выполняющие те же шаги с минимальным кодом, но я попытался объяснить шаги с помощью кода, который позволяет подумать о том, что происходит за кулисами. Имея представление об этих шагах, миграция на эти библиотеки не будет сложной задачей. Спасибо!!! Увидимся в следующей статье.

Ссылки

  1. https://spacy.io/
  2. https://www.w3schools.com/python/python_regex.asp
  3. https://pypi.org/project/contracts/