Как тщательно очистить набор данных, состоящий из очищенных веб-сайтов HTML

Самым важным шагом в любом проекте, основанном на данных, является получение качественных данных. Без этих шагов предварительной обработки результаты проекта могут быть легко искажены или полностью неправильно поняты. Здесь мы сосредоточимся на очистке данных, состоящих из очищенных веб-страниц.
Получение данных
Есть много инструментов для очистки Интернета. Если вы ищете что-то быстрое и простое, модуль обработки URL-адресов в Python под названием urllib может помочь вам. В противном случае я рекомендую scrapyd из-за возможных настроек и надежности.
Важно убедиться, что очищаемые страницы содержат данные в формате RTF, которые подходят для вашего варианта использования.
От HTML к тексту
Как только мы получили наши очищенные веб-страницы, мы начинаем с извлечения текста из каждой веб-страницы. На веб-сайтах есть множество тегов, не содержащих полезной информации о НЛП, таких как <script> и <button>. К счастью, есть модуль Python под названием котелpy3, который упрощает извлечение текста.
Мы используем ArticleExtractor для извлечения текста. Этот экстрактор был настроен для новостных статей, что хорошо работает с большинством HTML. Вы можете попробовать другие экстракторы, перечисленные в документации для котелpy3, и посмотреть, что лучше всего подходит для вашего набора данных.
Затем мы уплотняем все символы новой строки (\n и \r) в один символ \n. Это сделано для того, чтобы, когда мы разбиваем текст на предложения по \n и точкам, мы не получаем предложения без слов.
Если экстракторы из котелpy3 не работают для ваших веб-страниц, вы можете использовать beautifulsoup для создания своего собственного экстрактора текста. Ниже приведен пример замены метода parse_html.
Очистка больших N-грамм
После извлечения текста мы хотим продолжить процесс очистки. Веб-страницы часто содержат повторяющуюся информацию, особенно если вы очищаете несколько статей из одного домена. В проанализированном тексте могут присутствовать такие элементы, как заголовки веб-сайтов, слоганы компаний и нижние колонтитулы страниц. Чтобы обнаружить и удалить эти фразы, мы анализируем наш корпус, глядя на частоту появления больших n-граммов.
N-граммы - это концепция из НЛП, где «грамм» - это непрерывная последовательность слов из основной части текста, а «N» - размер этих последовательностей. Это часто используется для создания языковых моделей, которые могут помочь в решении самых разных задач - от обобщения текста до предсказания слов. Ниже приведен пример триграмм (3 грамма):
input = 'It is quite sunny today.' output = ['It is quite', is quite sunny', 'quite sunny today.']
Когда мы читаем статьи, есть много повторяющихся слов (униграмм), таких как «the» и «a». Однако по мере увеличения размера n-грамма вероятность повторения n-грамма уменьшается. Триграммы становятся все более редкими, и статьи практически не могут содержать одну и ту же последовательность из 20 слов. Путем поиска больших n-граммов, которые встречаются часто, мы можем обнаруживать повторяющиеся элементы на веб-сайтах в нашем корпусе и вручную их отфильтровывать.
Мы начинаем этот процесс с разбиения нашего набора данных на предложения, разбивая фрагменты текста на символы новой строки и точки. Затем мы токенизируем наши предложения (разбиваем предложение на строки из отдельных слов). С помощью этих токенизированных предложений мы можем генерировать n-граммы определенного размера (мы хотим начать с большого, около 15). Мы хотим отсортировать n-граммы по частоте, используя функцию FreqDist, предоставляемую nltk. Когда у нас есть частотный словарь, мы печатаем первые 10 н-граммов. Если частота выше 1 или 2, возможно, вы захотите удалить это предложение из корпуса. Чтобы удалить предложение, скопируйте все предложение и добавьте его как одну строку в массив filter_strs. Копирование всего предложения может быть выполнено путем увеличения размера n-грамма до тех пор, пока все предложение не будет записано в один n-грамм и напечатано на консоли, или просто распечатав parsed_texts и ища предложение. Если есть несколько нежелательных предложений с немного разными словами, вы можете скопировать общую подстроку в filter_strs, и регулярное выражение отфильтрует все предложения, содержащие эту подстроку.
Если вы запустите приведенный выше код в своем наборе данных без добавления каких-либо фильтров в filter_strs, вы можете получить график, аналогичный приведенному ниже. В моем наборе данных вы можете видеть, что есть несколько 15-граммов, которые повторяются 6, 3 и 2 раза.

Как только мы пройдем через процесс заполнения filter_strs ненужными предложениями, наш 15-граммовый график выровняется.

Имейте в виду, что не существует оптимального порога для размера n-граммов и частоты, определяющего, следует ли удалять предложение, поэтому поиграйте с этими двумя параметрами. Иногда вам нужно уменьшить размер н-граммов до 3 или 4, чтобы выбрать повторяющийся заголовок, но будьте осторожны, чтобы не удалить ценные данные. Этот блок кода разработан как итеративный процесс, в котором вы медленно создаете массив filter_strs после множества различных экспериментов.
Пунктуация, капитализация и токенизация
После того, как мы очистим корпус, следующим шагом будет обработка слов нашего корпуса. Мы хотим удалить знаки препинания, строчные все слова и разбить каждое предложение на массивы отдельных слов (токенизация). Для этого мне нравится использовать метод библиотеки simple_preprocess от gensim. Эта функция выполняет все три задачи за один раз и имеет несколько параметров, которые позволяют выполнять некоторую настройку. При установке deacc=True акценты будут удалены. Когда пунктуация удаляется, сама пунктуация обрабатывается как пробел, а две подстроки с каждой стороны пунктуации обрабатываются как два отдельных слова. В большинстве случаев слова будут разбиты на одну подстроку длиной один. Например, не превратится в не и т. В результате значение по умолчанию min_len равно 2, поэтому слова с одной буквой не сохраняются. Если это не подходит для вашего варианта использования, вы также можете создать текстовый процессор с нуля. Класс string Python содержит атрибут punctuation, в котором перечислены все часто используемые знаки препинания. Используя этот набор знаков препинания, вы можете использовать str.maketrans, чтобы удалить все знаки препинания из строки, но сохраняя те слова, в которых они были, как одно слово (не превращается в не). Имейте в виду, что при этом не учитываются знаки препинания, а также simple_preprocess gensim. Например, существует три типа тире ("-" длинное тире, - "короткое тире," - "дефис), и хотя simple_preprocess удаляет их все, string.punctuation не содержит длинного тире и, следовательно, не удаляет его.
Стоп-слова
Как только наш корпус будет хорошо размечен, мы удалим из него все стоп-слова. Стоп-слова - это слова, которые не придают особого значения предложению. Слова в английском словаре включают «the», «a» и «in». nltk содержит список запрещенных слов на английском языке, поэтому мы используем его для фильтрации наших списков токенов.
Лемматизация и стемминг
Лемматизация - это процесс объединения различных форм одного и того же слова и замены этих экземпляров леммой слова (словарной формой). Например, «функции» сокращаются до «функции». Основание - это процесс сокращения слова до его корневого слова (без каких-либо суффиксов или префиксов). Например, «бег» сокращается до «бегать». Эти два шага уменьшают размер словарного запаса, облегчая машине понимание нашего корпуса.
Теперь, когда вы знаете, как извлекать и предварительно обрабатывать текстовые данные, вы можете приступить к анализу данных. Удачи в ваших приключениях в НЛП!
Примечания
- Если вы помечаете корпус тегами частей речи, стоп-слова должны храниться в наборе данных, а лемматизация не должна выполняться перед тегированием.
- Репозиторий GitHub для Jupyter Notebook можно найти здесь.