Перевод и разбор доклада об обработке естественного языка для решения SEO задач. Рассматриваемый код в докладе доступен по ссылке seo_python. Это будет своего рода вводный курс по NLP, предполагающий некоторое знакомство с:PythonБиблиотеками data science, такими как Pandas и NumPyЗнакомство с Jupiter NotebooksЗнакомство с NLPМы будем использовать следующие Python библиотеки:import json #Чтобы обрабатывать данные в в формате json import pandas as pd #Для анализа табличных данных import re #Используем регулярные выражения import nltk #Для обработки естественного языка import numpy as np import string import spacy from scipy import stats from matplotlib import pyplotNatural Language Processing (NLP) – это способ, позволяющий компьютерам анализировать, понимать и получать смысл из человеческого языка удобным способом.Используя NLP, разработчики могут организовать и структурировать знания для выполнения таких задач, как автоматическая суммаризация, перевод, распознавание именованных сущностей, извлечение отношений, анализ тональностей, распознавание речи и сегментация тем.Это своего рода старый взгляд на обработку естественного языка, основанный на лингвистической эвристике и статистике. Новая модель обработки естественного языка в значительной степени опирается на машинное обучение, и, безусловно, обе они переплетаются друг с другом.Итак, рассмотрим текст на естественном языке. Часто это просто набор неструктурированных текстовых данных.Текст может быть в любом формате:Просто текстовые блокиТекстовые блоки в CSV или тексты, полученные по APIПримеры источников данных, которые вы могли бы использовать:Книги (в электронном формате)CSV, Excel, JSON, XMLWord, PDF-файлыВеб-страницы (наиболее применимый к SEO)Для примера мы будем использовать набор данных wocka.json. Он представлен в файле JSON. С помощью нескольких строк кода считаем файл, затем преобразуем его в датафрейм pandas и выведем в качестве примера.with open('wocka.json', 'r') as json_file: data = json.load(json_file) wocka = pd.DataFrame.from_dict(data)ТокенизацияПри работе с текстами, необходимо их токенизировать для дальнейшего анализа.Токенизация по словам – это процесс разделения предложений на более мелкие единицы (слова-компоненты).Предварительная обработка текста позволяет нам разобрать и подготовить текстовые данные для анализа, также помогает преобразовывать их в машиночитаемый формат. Для токенизации мы не используем библиотеку обработки естественного языка, а будем использовать для этой цели простые регулярные выражения. Для этого создали функцию, которая разбивает все по словам и затем возвращает каждое из них.def tokenize_words(text): tokens = re.split('\W+', text) text = [word for word in tokens] return text wocka['tokenize'] = wocka['body'].apply(lambda x: tokenize_words(x.lower()))Будем использовать лямбда-функцию tokenize_words. Создадим столбец tokenize со всеми словами.Для токенизации также можно использовать встроенную функцию библиотеки nltk sent_tokenize(text, language='english').Удаление мусора и стоп-словНа следующем шаге предварительной обработки текста мы будем удалять большое количество мусора из этих данных. Очистка данных иногда занимает большую часть времени.Удаление мусора:Пунктуация и специальные символыСтоп словаОбщие сокращенияи тд.Это лишь некоторые примеры. Чтобы показать как это работает, давайте посмотрим на Python код. Для этого создадим функцию, которая удаляет пунктуацию и возвращает результат.def remove_punctuation(text): removal = ' '.join(word.strip(string.punctuation) for word in text.split()) removal = removal.lower() return removal print('Before: ' + wocka['body'][0] + '\r\n') print('After: ' + remove_punctuation(wocka['body'][0]))Итак, мы собираемся удалить стоп-слова. Для этого мы используем NLTK. Данная библиотека имеет базу стоп-слов (Базу нужно будет скачать nltk.download(“stopwords”)).def remove_stop_words(text): text = ''.join([word for word in text if word not in string.punctuation]) tokens = re.split('\W+', text) text = [word for word in tokens if word not in stopwords] return textПример стоп-слов для русского языкаfrom nltk.corpus import stopwords print(stopwords.words("russian"))Расширенные аббревиатурыПредставьте, что вы работаете с данными Twitter или данными текстовых сообщений или любыми другими данными. Существует множество аббревиатур. Например, в Твиттере это может быть RT для ретвита.Для обработки естественного языка, можно создать своего рода карту: аббревиатуру и то, что она означает.abbreviation_map = { 'lol': 'laugh out loud', 'brb': 'be right back', 'serp': 'search engine results page' } def expand_abbreviations(text, abbreviations): for word in sorted(abbreviations.keys(), key = len, reverse=True): text = re.sub(word, abbreviations[word], text) return text sample_sentence = remove_punctuation("Hold my bear whie I check the serp one moment. brb.") print('Before: ' + sample_sentence) print('After: ' + expand_abbreviations(sample_sentence, abbreviation_map))Стемминг и лемматизацияВернемся к нормализации и стандартизации. Поговорим о процесс стемминга или лемматизации.Нормализация позволяет:ускорить процесс машинного обученияустранить неоднозначностьСтеммингНаиболее базовый метод сведения разных форм одного и того же слова к общей базеСтемминг – отсечение конца словаБолее быстрый методРезультаты не являются реальными словамиДля реализации стемминга используется PorterStemmer. Для каждого слова полученного в результате токенизации получаем стемму.ps = nltk.PorterStemmer() def stemming(text): text = [ps.stem(word) for word in text] return textТакже можно использовать SnowballStemmer. Для использования указываем в атрибутах язык: stemmer = SnowballStemmer('russian')SnowballStemmer поддерживает следующие языки: арабский, датский, голландский, английский, финский, французский, немецкий, венгерский, итальянский, норвежский, португальский, румынский, русский, испанский и шведский.ЛемматизацияЛемматизация – процесс приведения слова к его базовой (канонической форме). Этот процесс намного сложнее, поэтому требует больше времени. Для ускорения работы используется библиотека spacy. Предварительно необходимо скачать модель "en_core_web_sm".nlp = en_core_web_sm.load() def lemmatization(text): lemma = [word.lemma_ for word in nlp(' '.join(text))] return lemmaИзвлечение информации и группировкаПолучаем больше контекста:N-граммыТегирование словРаспознавание именованных сущностейWord Embeddings (преобразование языковой сущности в вектор)N-граммыИтак, что же такое n-грамма. Те, кто работает в SEO, вероятно, слышали, этот термин. N-грамма – в основном является переменной, обозначающей любое количество слов, сгруппированных вместе. Вы можете иметь биграммы, которые представляют собой два слова, триграммы – три слова, сгруппированные вместе, и так далее.Теги словТегирование слов (морфологический анализ) – это процесс определения части речи, является ли слово существительным, прилагательным или наречие и так далее.Тег - это набор граммем, характеризующих данное слово.Для тегирования будем использовать библиотеку spacy. Напишем лямбда-функцию, которая из двух списков сформирует список множеств следующего вида: (ключ, часть речи). Рассмотрим первое слово размеченное, как местоимение, второе, как глагол и так далее. Так что теперь для всех слов в предложении определена их часть речи.Это позволит нам использовать такие вещи, как визуализация. Визуализация позволяет посмотреть, как слова соединяются вместе.Распознавание именованных сущностейНам много приходится работать с сущностями. Например, мы знаем, что Саддам Хуссейн, Барак Обама или Дональд Трамп - являются людьми (персоны). С помощью NLP мы можем определить именованные сущности в тексте. Для этого возьмем предварительно обученную модель библиотеки spacy.Предварительно нужно будет установить библиотеку и скачать модель.$ pip install -U spacy $ python -m spacy download en_core_web_sm или $ python -m spacy download enЗагружаем модель, а затем создаем функцию для распознавания именованных сущностей, с помощью которой мы извлекаем каждый текстовый элемент и проверяем к какой сущности он принадлежит.Подготовленная модель spacy распознает следующие именованные сущности:PERSONNORPFACORGGPEи тд.С полным списком можно ознакомиться в документации. spacy.ioAnnotation Specifications · spaCy API DocumentationSchemes used for labels, tags and training dataWord Embeddings: word2vec, GloVeВекторное представление слова выводит нас на другой уровень. Для работы будем использовать библиотеку gensim. Разберем несколько примером эмбединга слов. Возьмем для примера слово "Cow". (В докладе разбирается на примере слова "Germany". Слово заменено, так как используется другой корпус слов).Видим следующие связанные слова: pig, bull и тд.Для слова "man" мы видим гораздо больше контекста.Пример сходства слов 'man' и 'woman'.Итак, на этом этапе мы перейдем к машинному обучению, а это значит, что нам нужно будет создавать функции машинного обучения, которые в основном являются аспектами нашего набора данных, которые мы используем для обучения модели. Для этого мы собираемся использовать некоторую личную эвристику для создания числовых представлений наших данных, просто чтобы понять, как работает машинное обучение, и попытаться применить его к идеям, представленным в анекдотах, и посмотреть, что может сработать.Будем использовать данные анекдотов, которые могут иметь значение: длину шутки и количество строк шутки. Также посмотрим, как ненормативная лексика влияет на то, насколько популярна шутка. Мы хотим посмотреть на содержание этих шуток и проверить, присутствует ли ненормативная лексика.Для этого будем использовать словарь ненормативных слов. Проведем проверку вхождения "плохих" слов в нашем наборе данными и добавим логический столбец, который является истинным или ложным, в случае если шутка "грязная".Теперь у нас есть множество функций, которые мы можем использовать в целях машинного обучения.Метод Бокса-КоксаБудем использовать алгоритм Box-Cox. Цель данного алгоритма в том, чтобы нормализовать набор данных. Визуализируем результат нормализации наших шуток в виде гистограммы.Распределение по длине шуткиРаспределение по количеству строк в шуткеЕсли мы проведем преобразование Бокса-Кокса данные становятся более нормализованными.ВекторизацияРазберем 3 типа векторизации:Count VectorizerN-Gram VectorizerTF-IDF VectorizerCount VectorizerРассмотрим Count Vectorizer. Воспользуемся библиотекой машинного обучения sklearn. Построим разреженную матрицу, где указано сколько раз слово встречается в указанном корпусе.N-Gram VectorizerN-Gram Vectorizer очень похож на Count Vectorizer, но вместо отдельных слов рассматриваются сочетания слов.TF-IDF VectorizerИтак, давайте поговорим о TF-IDF. Это понятие часто искажается в мире SEO. Изначально в tf-idf закладывалась идея поиска информации о наиболее значимых словах в наборе данных.Этот показатель позволять понять какие редкие слова считаются более важными. В нашем примере мы можем использовать это, чтобы отличать одни шутки от других. Basic Machine LearningТеперь имея все эти функции, мы можем обучать наши модели. Модель, которую мы будем обучать, очень проста. Она представляет собой дерево решений и, по сути, автоматически создает все эти деревья для решения проблемы.Рассмотрим пример для спортивной команды "Х". Мы принимаем решение в зависимости от статистики игроков, являются ли они успешными, или команды, с которой они играют. В данном случае мы используем то, что называется случайным лесом.Для реализации базового машинного обучения, мы будем использовать векторизатор tf-idf библиотеки sklearn. Проведем расчет для заголовков и тела шутки.Запустим простой случайный лес. Это всего лишь несколько строк кода, потому что большую часть сложной работы выполняет модель машинного обучения. Делаем перекрестную проверку, и видим, что эти данные являются абсолютным мусором.Это не очень хорошие показатели для того, чтобы предсказать, насколько популярной будет шутка. Но концепция верная, и таким образом с помощью простой модели, безусловно, мы могли бы добиться лучших результатов.Приложения для SEOПримеры еще нескольких приложений для обработки естественного языка для задач SEO:Создание качественного контентаПрогнозирование потенциала ссылокНаписание фрагментов контентаОптимизация контент, анализ ключевых слови тд.