Глава 11. Обработка естественного языка (NLP)
вильно написанное слово с наибольшим уровнем достоверности (по данным проверки орфографии):
In [5]: word.correct() # Выбирает слово с наибольшим уровнем достоверности
Out[5]: 'they'
Вызов correct для объекта TextBlob или Sentence проверяет орфографию каждого слова. Для каждого неправильного слова correct заменяет его правильно написанным вариантом с наибольшим уровнем достоверности:
In [6]: from textblob import Word
In [7]: sentence = TextBlob('Ths sentense has missplled wrds.')
In [8]: sentence.correct()
Out[8]: TextBlob("The sentence has misspelled words.")
11.2.10. Нормализация: выделение основы и лемматизация
В результате выделения основы из слова удаляется префикс или суффикс и остается только основа, которая может быть реальным словом (но может и не быть). Лемматизация выполняется аналогичным образом, но ее результатом является осмысленная часть речи, то есть реальное слово.
Выделение основы и лемматизация относятся к операциям нормализации, готовящим слова для анализа. Например, перед вычислением статистики вхождения слов в корпусе текста все слова могут быть преобразованы к нижнему регистру, чтобы слова, начинающиеся с букв нижнего и верхнего регистра, обрабатывались одинаково. Иногда для представления разных форм слова приходится использовать только корень. Например, в некотором приложении все следующие слова могут рассматриваться как слово «program»: program, programs, programmer, programming и programmed (и, возможно, английские варианты написания — скажем, programmes).
У объектов Word и WordList для выделения основы и лемматизации используются методы stem и lemmatize. Попробуем использовать их с Word:
In [1]: from textblob import Word
In [2]: word = Word('varieties')
In [3]: word.stem()
Out[3]: 'varieti'
11.2. TextBlob 495
In [4]: word.lemmatize()
Out[4]: 'variety'
11.2.11. Частоты слов
Различные методы выявления сходства между документами основаны на частотах вхождения слов. Как вы вскоре узнаете, TextBlob подсчитывает частоты автоматически. Начнем с загрузки электронного текста пьесы Шекспира «Ромео и Джульетта» в TextBlob. Для этого будет использоваться класс Path из модуля pathlib стандартной библиотеки Python:
In [1]: from pathlib import Path
In [2]: from textblob import TextBlob
In [3]: blob = TextBlob(Path('RomeoAndJuliet.txt').read_text())
Используйте загруженный ранее файл RomeoAndJuliet.txt1. Предполагается, что вы запустили сеанс IPython из этой папки. Когда вы читаете файл методом read_text объекта Path, файл будет немедленно закрыт после завершения чтения файла.
Частоты вхождения слов в тексте TextBlob хранятся в словаре word_counts. Подсчитаем вхождения некоторых слов в пьесе:
In [4]: blob.word_counts['juliet']
Out[4]: 190
In [5]: blob.word_counts['romeo']
Out[5]: 315
In [6]: blob.word_counts['thou']
Out[6]: 278
Если вы уже разобрали TextBlob в список WordList, то для подсчета вхождений конкретных слов в список можно воспользоваться методом count:
In [7]: blob.words.count('joy')
Out[7]: 14
In [8]: blob.noun_phrases.count('lady capulet')
Out[8]: 46
1 Каждая электронная книга проекта «Гутенберг» включает дополнительный текст (в частности, лицензионную информацию), которая не является частью самой книги. В данном примере мы воспользовались текстовым редактором для удаления текста из нашей копии электронной книги.
496 Глава 11. Обработка естественного языка (NLP)
11.2.12. Получение определений, синонимов и антонимов из WordNet
WordNet1– база данных слов, созданная в Принстонском университете. Библиотека TextBlob использует интерфейс WordNet библиотеки NLTK, позволяющий искать определения слов, синонимы и антонимы. За дополнительной информацией обращайтесь к документации интерфейса NLTK WordNet по адресу:
https://www.nltk.org/api/nltk.corpus.reader.html#module-nltk.corpus.reader.wordnet
Получение определений
Начнем с создания объекта Word:
In [1]: from textblob import Word
In [2]: happy = Word('happy')
Свойство definitions класса Word возвращает список всех определений слова в базе данных WordNet:
In [3]: happy.definitions
Out[3]:
['enjoying or showing or marked by joy or pleasure',
'marked by good fortune',
'eagerly disposed to act or to be of service',
'well expressed and to the point']
База данных необязательно содержит все возможные словарные определения для заданного слова. Также имеется метод define, который позволяет передать в аргументе часть речи, с тем чтобы вы могли получить определения, соответствующие только этой части слова.
Получение синонимов
Наборы синонимов Word доступны в свойстве synsets. Результат представляет собой список объектов Synset:
In [4]: happy.synsets
Out[4]:
[Synset('happy.a.01'),
1 https://wordnet.princeton.edu/.
11.2. TextBlob 497
Synset('felicitous.s.02'),
Synset('glad.s.02'),
Synset('happy.s.04')]
Каждый объект Synset представляет группу синонимов. В записи happy.a.01:
ØØ
happy — лемматизированная форма исходного объекта Word (в данном случае они совпадают).
ØØ
a — часть речи: a — прилагательное, n — существительное, v — глагол, r — наречие, s — прилагательное-сателлит. Многие наборы синонимов прилагательных в WordNet имеют сателлитные наборы синонимов, представляющие похожие прилагательные.
ØØ
01 — индекс, начинающийся с 0. Многие слова обладают несколькими смыслами; значение является индексом соответствующего смысла в базе данных WordNet.
Также имеется метод get_synsets, который позволяет передать часть речи в аргументе, чтобы получить набор Synset только для указанной части речи.
Вы можете перебрать список synsets, чтобы найти синонимы исходного слова. Каждый объект Synset содержит метод lemmas, который возвращает список объектов Lemma, представляющих синонимы. Метод name объекта Lemma возвращает слово-синоним в виде строки. В следующем коде для каждого объекта Synset в списке synsets вложенный цикл for перебирает объекты Lemma из этого объекта Synset (при наличии). Затем синоним добавляется в множество с именем synonyms. Мы использовали множество, потому что оно автоматически устраняет все добавленные в него дубликаты:
In [5]: synonyms = set()
In [6]: for synset in happy.synsets:
...: for lemma in synset.lemmas():
...: synonyms.add(lemma.name())
...:
In [7]: synonyms
Out[7]: {'felicitous', 'glad', 'happy', 'well-chosen'}
Получение антонимов
Если слово, представленное объектом Lemma, имеет антонимы в базе данных WordNet, то вызов метода antonyms объекта Lemma возвращает список объектов Lemma, представляющих антонимы (или пустой список, если в базе данных
498 Глава 11. Обработка естественного языка (NLP)
нет ни одного антонима). Во фрагменте [4] показано, что для 'happy' было найдено четыре объекта Synset. Сначала найдем объекты Lemma для Synset с индексом 0 в списке synsets:
In [8]: lemmas = happy.synsets[0].lemmas()
In [9]: lemmas
Out[9]: [Lemma('happy.a.01.happy')]
В данном случае lemmas возвращает список из одного элемента Lemma. Мы можем проверить, содержит ли база данных какие-либо антонимы для этого объекта Lemma:
In [10]: lemmas[0].antonyms()
Out[10]: [Lemma('unhappy.a.01.unhappy')]
Результат является списком объектов Lemma, представляющих антоним (-ы). В данном случае мы видим, что база данных содержит для слова 'happy' один антоним 'unhappy'.
11.2.13. Удаление игнорируемых слов
Игнорируемые слова (стоп-слова) — часто встречающиеся в тексте слова, которые часто удаляются из текста перед анализом, поскольку обычно не несут полезной информации. Ниже приведен список игнорируемых слов английского языка из NLTK, возвращаемый функцией words1 модуля stopwords (которой мы вскоре воспользуемся на практике):
Список игнорируемых слов английского языка из NLTK
['a', 'about', 'above', 'after', 'again', 'against', 'ain', 'all', 'am', 'an', 'and', 'any', 'are', 'aren', "aren't", 'as', 'at', 'be', 'because', 'been', 'before', 'being', 'below', 'between', 'both', 'but', 'by', 'can', 'couldn', "couldn't", 'd', 'did', 'didn', "didn't", 'do', 'does', 'doesn', "doesn't", 'doing', 'don', "don't", 'down', 'during', 'each', 'few', 'for', 'from', 'further', 'had', 'hadn', "hadn't", 'has', 'hasn', "hasn't", 'have', 'haven', "haven't", 'having', 'he', 'her', 'here', 'hers', 'herself', 'him', 'himself', 'his', 'how', 'i', 'if', 'in', 'into', 'is', 'isn', "isn't", 'it', "it's", 'its', 'itself', 'just', 'll', 'm', 'ma', 'me', 'mightn', "mightn't", 'more', 'most', 'mustn', "mustn't", 'my', 'myself', 'needn', "needn't", 'no', 'nor', 'not',
1 https://www.nltk.org/book/ch02.html.
11.2. TextBlob 499
'now', 'o', 'of', 'off', 'on', 'once', 'only', 'or', 'other', 'our', 'ours', 'ourselves', 'out', 'over', 'own', 're', 's', 'same', 'shan', "shan't", 'she', "she's", 'should', "should've", 'shouldn', "shouldn't", 'so', 'some', 'such', 't', 'than', 'that', "that'll", 'the', 'their', 'theirs', 'them', 'themselves', 'then', 'there', 'these', 'they', 'this', 'those', 'through', 'to', 'too', 'under', 'until', 'up', 've', 'very', 'was', 'wasn', "wasn't", 'we', 'were', 'weren', "weren't", 'what', 'when', 'where', 'which', 'while', 'who', 'whom', 'why', 'will', 'with', 'won', "won't", 'wouldn', "wouldn't", 'y', 'you', "you'd", "you'll", "you're", "you've", 'your', 'yours', 'yourself', 'yourselves']
Библиотека NLTK также содержит списки игнорируемых слов для ряда других естественных языков. Прежде чем использовать списки игнорируемых слов NLTK, их необходимо загрузить при помощи функции download модуля nltk:
In [1]: import nltk
In [2]: nltk.download('stopwords')
[nltk_data] Downloading package stopwords to
[nltk_data] C:\Users\PaulDeitel\AppData\Roaming\nltk_data...
[nltk_data] Unzipping corpora\stopwords.zip.
Out[2]: True
В этом примере будет загружен список игнорируемых слов английского языка 'english'. Импортируйте stopwords из модуля nltk.corpus, а затем используйте метод words класса stopwords для загрузки списка игнорируемых слов 'english':
In [3]: from nltk.corpus import stopwords
In [4]: stops = stopwords.words('english')
Затем создадим объект TextBlob, из которого будут удаляться игнорируемые слова:
In [5]: from textblob import TextBlob
In [6]: blob = TextBlob('Today is a beautiful day.')
Наконец, чтобы удалить игнорируемые слова, используйте слова TextBlob в трансформации списка, которая добавляет каждое слово в полученный список только в том случае, если слово не входит в stops:
In [7]: [word for word in blob.words if word not in stops]
Out[7]: ['Today', 'beautiful', 'day']
500 Глава 11. Обработка естественного языка (NLP)
11.2.14. n-граммы
N-грамма1 представляет собой последовательность из n текстовых элементов, например букв в словах или слов в предложении. В обработке естественных языков n-граммы могут использоваться для выявления букв или слов, часто располагающихся рядом друг с другом. Для текстового ввода это поможет предсказать следующую букву или слово, вводимое пользователем, например при завершении элементов в IPython по нажатии клавиши Tab или при вводе текстового сообщения в вашем любимом месседжере для смартфона. При преобразовании речи в текст n-граммы могут использоваться для повышения качества текста. N-граммы представляют собой форму лексической солидарности, то есть расположения букв или слов рядом друг с другом.
Метод ngrams объекта TextBlob выдает список WordList n-грамм, которые по умолчанию имеют длину 3 (они называются триграммами). Передавая ключевой аргумент n, вы сможете получать n-граммы любой длины по своему усмотрению. Вывод показывает, что первая триграмма содержит первые три слова предложения ('Today', 'is' и 'a'.) Затем ngrams создает триграмму, начинающуюся со второго слова ('is', 'a' и 'beautiful'), и т. д. — до тех пор, пока не будет создана триграмма с тремя последними словами TextBlob:
In [1]: from textblob import TextBlob
In [2]: text = 'Today is a beautiful day. Tomorrow looks like bad weather.'
In [3]: blob = TextBlob(text)
In [4]: blob.ngrams()
Out[4]:
[WordList(['Today', 'is', 'a']),
WordList(['is', 'a', 'beautiful']),
WordList(['a', 'beautiful', 'day']),
WordList(['beautiful', 'day', 'Tomorrow']),
WordList(['day', 'Tomorrow', 'looks']),
WordList(['Tomorrow', 'looks', 'like']),
WordList(['looks', 'like', 'bad']),
WordList(['like', 'bad', 'weather'])]
Следующий пример строит n-граммы из пяти слов:
In [5]: blob.ngrams(n=5)
Out[5]:
[WordList(['Today', 'is', 'a', 'beautiful', 'day']),
1 https://en.wikipedia.org/wiki/N-gram.
11.3. Визуализация частот вхождения слов с использованием гистограмм 501
WordList(['is', 'a', 'beautiful', 'day', 'Tomorrow']),
WordList(['a', 'beautiful', 'day', 'Tomorrow', 'looks']),
WordList(['beautiful', 'day', 'Tomorrow', 'looks', 'like']),
WordList(['day', 'Tomorrow', 'looks', 'like', 'bad']),
WordList(['Tomorrow', 'looks', 'like', 'bad', 'weather'])]
11.3. Визуализация частот вхождения слов с использованием гистограмм и словарных облаков
Ранее мы получили частоты вхождения некоторых слов в пьесе «Ромео и Джульетта». В некоторых случаях визуализации частот слов повышают качество анализа текстового корпуса. Часто существует несколько возможных вариантов визуализации данных, и один из них оказывается лучше других. Например, вас могут интересовать частоты вхождения слов друг относительно друга или же данные относительного использования слов в корпусе. В этом разделе будут рассмотрены два способа наглядного представления частот слов:
ØØ
Гистограмма для наглядного количественного представления частот самых частых слов в пьесе «Ромео и Джульетта» в виде столбцов разной длины.
ØØ
Словарное облако для наглядного качественного представления частот: более частые слова выводятся более крупным шрифтом, а более редкие слова — шрифтом меньшего размера.
11.3.1. Визуализация частот вхождения слов средствами Pandas
Построим наглядное представление частот в тексте «Ромео и Джульетты» для 20 самых частых слов, которые не являются игнорируемыми словами. Для этого воспользуемся функциональностью TextBlob, NLTK и Pandas. Средства визуализации Pandas базируются на Matplotlib, поэтому в этом сеансе IPython следует запустить следующей командой:
ipython --matplotlib
Загрузка данных
Начнем с загрузки текста «Ромео и Джульетты». Прежде чем выполнять следующий код, запустите IPython из каталога ch11, чтобы вы могли обратиться к файлу электронной книги RomeoAndJuliet.txt, загруженному ранее в этой главе:
502 Глава 11. Обработка естественного языка (NLP)
In [1]: from pathlib import Path
In [2]: from textblob import TextBlob
In [3]: blob = TextBlob(Path('RomeoAndJuliet.txt').read_text())
Затем загрузите список игнорируемых слов NLTK:
In [4]: from nltk.corpus import stopwords
In [5]: stop_words = stopwords.words('english')
Получение частот слов
Чтобы построить визуализацию частот 20 слов, необходимо знать все слова и их частоты. Вызовем метод items словаря blob.word_counts, чтобы получить список кортежей «слово-частота»:
In [6]: items = blob.word_counts.items()
Исключение игнорируемых слов
Воспользуемся трансформацией списка для удаления кортежей, содержащих стоп-слова:
In [7]: items = [item for item in items if item[0] not in stop_words]
Выражение item[0] получает слово из каждого кортежа, чтобы проверить, входит ли оно в список stop_words.
Сортировка слов по частотам
Чтобы определить 20 наиболее частых слов, отсортируем кортежи в items по убыванию частоты. Мы можем воспользоваться встроенной функцией sorted с аргументом key для сортировки кортежей по элементу частоты в каждом кортеже. Чтобы задать элемент кортежа для выполнения сортировки, используйте функцию itemgetter из модуля operator стандартной библиотеки Python:
In [8]: from operator import itemgetter
In [9]: sorted_items = sorted(items, key=itemgetter(1), reverse=True)
В процессе упорядочения элементов items функция sorted обращается к элементу с индексом 1 в каждом кортеже с использованием выражения itemgetter(1). Ключевой аргумент reverse=True означает, что кортежи должны сортироваться по убыванию.
11.3. Визуализация частот вхождения слов с использованием гистограмм 503
Получение 20 самых частых слов
Затем сегмент используется для получения 20 самых частых слов из sorted_items. Когда объект TextBlob проводит разбиение корпуса на лексемы, он разбивает все сокращенные формы по апострофам и подсчитывает общее количество апострофов как одно из «слов». Текст «Ромео и Джульетты» содержит множество сокращенных форм. Если вывести sorted_items[0], вы увидите, что это самое часто встречающееся «слово» с 867 вхождениями1. Выводиться должны только слова, поэтому мы игнорируем элемент 0 и получаем сегмент с элементами с 1 по 20 списка sorted_items:
In [10]: top20 = sorted_items[1:21]
Преобразование top20 в DataFrame
Затем преобразуем список кортежей top20 в коллекцию DataFrame библиотеки Pandas для удобства его представления в визуальном виде:
In [11]: import pandas as pd
In [12]: df = pd.DataFrame(top20, columns=['word', 'count'])
In [13]: df
Out[13]:
word count
0 romeo 315
1 thou 278
2 juliet 190
3 thy 170
4 capulet 163
5 nurse 149
6 love 148
7 thee 138
8 lady 117
9 shall 110
10 friar 105
11 come 94
12 mercutio 88
13 lawrence 82
14 good 80
15 benvolio 79
16 tybalt 79
17 enter 75
18 go 75
19 night 73
1 В некоторых локальных контекстах этого не происходит, и элементом 0 становится слово 'romeo'.
504 Глава 11. Обработка естественного языка (NLP)
Визуализация DataFrame
Чтобы построить визуализацию данных, используем метод bar свойства plot коллекции DataFrame. Аргументы указывают, какие данные столбца должны выводиться по осям x и y, и что на диаграмме не должны выводиться условные обозначения:
In [14]: axes = df.plot.bar(x='word', y='count', legend=False)
Метод bar создает и выводит гистограмму Matplotlib.
Взглянув на исходную гистограмму, которая появляется на экране, можно заметить, что некоторые из ее столбцов усечены. Чтобы решить эту проблему, используйте функцию gcf (Get Current Figure) для получения рисунка Matlpotlib, выведенного pandas, а затем вызовите метод tight_layout. Вызов «сжимает» гистограмму, чтобы все ее компоненты поместились в окне:
In [15]: import matplotlib.pyplot as plt
In [16]: plt.gcf().tight_layout()
Окончательный вид гистограммы показан ниже:
11.3. Визуализация частот вхождения слов с использованием гистограмм 505
11.3.2. Визуализация частот слов в словарных облаках
Теперь построим словарное облако для визуализации наиболее частых 200 слов в тексте «Ромео и Джульетты». Мы можем воспользоваться для этого классом WordCloud модуля wordcloud 1 с открытым кодом для генерирования словарных облаков всего в нескольких строках кода. По умолчанию wordcloud создает прямоугольные словарные облака, но, как вы вскоре увидите, библиотека также может создавать словарные облака произвольной формы.
Установка модуля wordcloud
Чтобы установить wordcloud, откройте приглашение Anaconda (Windows), терминал (macOS/Linux) или командную оболочку (Linux), после чего выполните следующую команду:
conda install -c conda-forge wordcloud
Возможно, пользователям Windows придется запустить приглашение Anaconda с правами администратора для получения необходимых привилегий при установке программного обеспечения. Щелкните правой кнопкой мыши на команде Anaconda Prompt в меню Пуск и выберите команду MoreRun as administrator.
Загрузка текста
Сначала нужно загрузить текст пьесы «Ромео и Джульетты». Прежде чем выполнять следующий код, запустите IPython из каталога ch11, чтобы вы могли обратиться к файлу электронной книги RomeoAndJuliet.txt, загруженному ранее в этой главе:
In [1]: from pathlib import Path
In [2]: text = Path('RomeoAndJuliet.txt').read_text()
Загрузка маски, определяющей форму словарного облака
Чтобы создать словарное облако нужной формы, нужно инициализировать объект WordCloud изображением, которое называется маской. WordCloud за1
https://github.com/amueller/word_cloud.
506 Глава 11. Обработка естественного языка (NLP)
полняет текстом области изображения маски, цвет которых отличен от белого. В нашем примере будет использована форма сердца, определяемая файлом mask_heart.png из каталога примеров ch11. Более сложным маскам для создания словарного облака требуется больше времени.
Загрузим изображение маски функцией imread из модуля imageio, включенного в поставку Anaconda:
In [3]: import imageio
In [4]: mask_image = imageio.imread('mask_heart.png')
Функция возвращает изображение в виде коллекции array библиотеки NumPy, как того требует WordCloud.
Настройка объекта WordCloud
Затем создадим и настроим объект WordCloud:
In [5]: from wordcloud import WordCloud
In [6]: wordcloud = WordCloud(colormap='prism', mask=mask_image,
...: background_color='white')
...:
По умолчанию ширина и высота объекта WordCloud составляет 400 × 200 пикселов, если только другие значения не заданы ключевыми аргументами width и height или маской. При использовании маски размер WordCloud определяется размером изображения. WordCloud использует Matplotlib во внутренней реализации. WordCloud назначает словам случайные цвета с цветовой карты. Вы можете передать ключевой аргумент colormap и воспользоваться одной из именованных цветовых карт Matplotlib. Список имен цветовых карт и их цветов доступен по адресу:
https://matplotlib.org/examples/color/colormaps_reference.html
Ключевой аргумент mask задает загруженное ранее изображение mask_image. По умолчанию слова выводятся на черном фоне, но мы изменили цвет фона при помощи ключевого аргумента background_color и выбрали белый цвет ('white'). За полным списком ключевых аргументов WordCloud обращайтесь по адресу:
http://amueller.github.io/word_cloud/generated/wordcloud.WordCloud.html
11.3. Визуализация частот вхождения слов с использованием гистограмм 507
Генерирование словарного облака
Метод generate объекта WordCloud получает используемый текст в аргументе и строит словарное облако, которое возвращается в виде объекта WordCloud:
In [7]: wordcloud = wordcloud.generate(text)
Прежде чем строить словарное облако, generate сначала удаляет игнорируемые слова из аргумента text по встроенному списку игнорируемых слов модуля wordcloud. Затем generate вычисляет частоты для оставшихся слов. По умолчанию метод использует не более 200 слов для словарного облака, но это количество можно изменить при помощи ключевого аргумента max_words.
Сохранение словарного облака в файле
Наконец, воспользуемся методом to_file объекта WordCloud для сохранения изображения словарного облака в заданном файле:
In [8]: wordcloud = wordcloud.to_file('RomeoAndJulietHeart.png')
Откройте каталог примеров ch11 в своей системе и сделайте двойной щелчок на файле RomeoAndJuliet.png, чтобы просмотреть изображение, — вероятно, в вашей версии слова будут располагаться в других позициях и выводиться другим цветом:
508 Глава 11. Обработка естественного языка (NLP)
Генерирование словарного облака по словарю
Если у вас уже имеется словарь с парами «ключ-значение», представляющими счетчики слов, то их можно передать методу fit_words объекта WordCloud. Этот метод предполагает, что игнорируемые слова уже были удалены ранее.
Вывод изображения средствами Matplotlib
Для вывода изображения на экран используйте магическую команду IPython
%matplotlib
чтобы включить интерактивную поддержку Matplotlib в IPython, после чего выполните следующие команды:
import matplotlib.pyplot as plt
plt.imshow(wordcloud)
11.4. Оценка удобочитаемости с использованием Textatistic
Интересным применением обработки естественного языка является оценка удобочитаемости текста, которая зависит от используемого словаря, структуры предложений, длины предложений, темы и многих других факторов. При написании этой книги мы воспользовались платным инструментом Grammarly, чтобы улучшить текст и добиться того, чтобы он нормально воспринимался широкой аудиторией.
В этом разделе для оценки удобочитаемости будет использоваться библиотека Textatistic1,2. Существует много разных формул, используемых при обработке естественного языка для вычисления индекса удобочитаемости.
Установка Textatistic
Чтобы установить Textatistic, откройте приглашение Anaconda (Windows), терминал (macOS/Linux) или командную оболочку (Linux), после чего выполните команду:
pip install textatistic
1 https://github.com/erinhengel/Textatistic.
2 Другие библиотеки оценки удобочитаемости для Python — readability-score, textstat, readability и pylinguistics.
11.4. Оценка удобочитаемости с использованием Textatistic 509
Возможно, пользователям Windows придется запустить приглашение Anaconda с правами администратора для получения необходимых привилегий при установке программного обеспечения. Щелкните правой кнопкой мыши на команде Anaconda Prompt в меню Пуск и выберите команду MoreRun as administrator.
Вычисление статистики и индексов удобочитаемости
Загрузим текст «Ромео и Джульетты» в переменную text:
In [1]: from pathlib import Path
In [2]: text = Path('RomeoAndJuliet.txt').read_text()
Для вычисления статистики и индексов удобочитаемости потребуется объект Textatistic, инициализированный текстом, который вы хотите обработать:
In [3]: from textatistic import Textatistic
In [4]: readability = Textatistic(text)
Метод dict объекта Textatistic возвращает словарь с различными статистическими характеристиками и индексами удобочитаемости1:
In [5]: %precision 3
Out[5]: '%.3f'
In [6]: readability.dict()
Out[6]:
{'char_count': 115141,
'word_count': 26120,
'sent_count': 3218,
'sybl_count': 30166,
'notdalechall_count': 5823,
'polysyblword_count': 549,
'flesch_score': 100.892,
'fleschkincaid_score': 1.203,
'gunningfog_score': 4.087,
'smog_score': 5.489,
'dalechall_score': 7.559}
1 Каждая электронная книга проекта «Гутенберг» включает дополнительный текст (в частности, лицензионную информацию), которая не является частью самой книги. В данном примере мы воспользовались текстовым редактором для удаления текста из нашей копии электронной книги.
510 Глава 11. Обработка естественного языка (NLP)
Каждое значение в словаре также доступно через свойство Textatistic с именем, совпадающим с ключом в показанном выводе. Вот некоторые статистические показатели:
ØØ
char_count — количество символов в тексте.
ØØ
word_count — количество слов в тексте.
ØØ
sent_count — количество предложений в тексте.
ØØ
sybl_count — количество слогов в тексте.
ØØ
notdalechall_count — количество слов, не входящих в список Дейла — Челла (список слов, понятных 80 % пятиклассников1). Чем выше это число по сравнению с общим количеством слов, тем менее понятным считается текст.
ØØ
polysyblword_count — количество слов из трех и более слогов.
ØØ
flesch_score — индекс удобочитаемости Флеша, который может быть связан с уровнем образования. Считается, что тексты со значением индекса более 90 понятны пятиклассникам. При значениях ниже 30 для усвоения текста обычно требуется образование на уровне колледжа. Промежуточные диапазоны соответствуют другим образовательным уровням.
ØØ
fleschkincaid_score — индекс Флеша — Кинкейда, соответствующий уровню образования.
ØØ
gunningfog_score — индекс туманности Ганнинга, соответствующий уровню образования.
ØØ
smog_score — индекс SMOG (Simple Measure of Gobbledygook), соответствующий годам образования, необходимым для понимания текста. Эта метрика считается особенно эффективной для материалов по здравоохранению2.
ØØ
dalechall_score — индекс Дейла — Челла, который может быть связан с уровнями образования от 4 и ниже до выпускника колледжа (уровень 16) и выше. Этот индекс считается наиболее надежным для широкого диапазона типов текста3,4.
1 http://www.readabilityformulas.com/articles/dale-chall-readability-word-list.php.
2 https://en.wikipedia.org/wiki/SMOG.
3 https://en.wikipedia.org/wiki/Readability#The_Dale%E2%80%93Chall_formula.
4 http://www.readabilityformulas.com/articles/how-do-i-decide-which-readability-formula-to-use.php.
11.5. Распознавание именованных сущностей с использованием spaCy 511
За дополнительной информацией о каждом индексе удобочитаемости, представленном здесь, а также нескольких других обращайтесь по адресу:
https://en.wikipedia.org/wiki/Readability
В документации Textatistic приведены и использованные формулы индексов удобочитаемости:
http://www.erinhengel.com/software/textatistic/
11.5. Распознавание именованных сущностей с использованием spaCy
NLP может определить, о чем говорится в тексте. Ключевой аспект этого процесса — распознавание именованных сущностей в целях поиска и классификации таких элементов, как даты, время, количества, места, имена людей, названия предметов, организаций и т. д. В этом разделе для анализа текста используются средства распознавания именованных сущностей из NLP-библиотеки spaCy1,2.
Установка spaCy
Для установки spaCy откройте приглашение Anaconda (Windows), терминал (macOS/Linux) или командную оболочку (Linux), после чего выполните команду:
conda install -c conda-forge spacy
Возможно, пользователям Windows придется запустить приглашение Anaconda с правами администратора для получения необходимых привилегий для установки программного обеспечения. Щелкните правой кнопкой мыши на команде Anaconda Prompt в меню Пуск и выберите команду MoreRun as administrator.
Чтобы библиотека spaCy могла загрузить дополнительные необходимые компоненты для обработки английского (en) текста, по завершении установки необходимо выполнить команду,:
python -m spacy download en
1 https://spacy.io/.
2 Также стоит обратить внимание на Textacy (https://github.com/chartbeat-labs/textacy) — библиотеку NLP, построенную на базе spaCy и поддерживающую другие операции NLP.
512 Глава 11. Обработка естественного языка (NLP)
Загрузка языковой модели
Первый шаг использования spaCy — загрузка языковой модели, представляющей естественный язык анализируемого текста. Для этого следует вызвать функцию load модуля spacy. Загрузим ранее примененную модель английского языка:
In [1]: import spacy
In [2]: nlp = spacy.load('en')
Документация spaCy рекомендует использовать имя переменной nlp.
Создание объекта spaCy Doc
Затем объект nlp используется для создания объекта spaCy Doc 1, представляющего обрабатываемый документ. В данном случае используется предложение из вводного описания Всемирной паутины, встречающегося во многих наших книгах:
In [3]: document = nlp('In 1994, Tim Berners-Lee founded the ' +
...: 'World Wide Web Consortium (W3C), devoted to ' +
...: 'developing web technologies')
...:
Получение именованных сущностей
Свойство ents объекта Doc возвращает кортеж объектов Span, представляющих именованные сущности, встречающиеся в Doc. Каждый объект Span содержит многочисленные свойства2. Переберем объекты Span и выведем свойства text и label_:
In [4]: for entity in document.ents:
...: print(f'{entity.text}: {entity.label_}')
...:
1994: DATE
Tim Berners-Lee: PERSON
the World Wide Web Consortium: ORG
Свойство text каждого объекта Span возвращает сущность в виде строки, а свойство label_ возвращает строку, обозначающую классификацию сущ1
https://spacy.io/api/doc.
2 https://spacy.io/api/span.
11.6. Выявление сходства средствами spaCy 513
ности. В данном случае spaCy обнаруживает три сущности, представляющие дату (DATE — 1994), человека (PERSON — Tim Berners-Lee) и организацию (ORG — World Wide Web Consortium). За дополнительной информацией о spaCy и кратким руководством по Quickstart обращайтесь по адресу:
https://spacy.io/usage/models#section-quickstart
11.6. Выявление сходства средствами spaCy
Выявление сходства — процесс анализа документов для определения того, насколько они похожи друг на друга. Один из возможных методов выявления сходства — подсчет частот слов. Так, некоторые специалисты считают, что работы Уильяма Шекспира в действительности могли быть написаны сэром Фрэнсисом Бэконом, Кристофером Марло или другими людьми1. Сравнение частот слов в их работах с частотами слов в работах Шекспира может открыть сходство в авторском стиле.
Для анализа сходства документов могут применяться различные методы машинного обучения, которые будут рассмотрены в дальнейших главах. Тем не менее, как это часто бывает в Python, некоторые библиотеки, такие как spaCy и Gensim, могут сделать это за вас. Мы воспользуемся средствами выявления сходства spaCy для сравнения объектов Doc, представляющих пьесу Шекспира «Ромео и Джульетта», с работой Кристофера Марло «Эдуард II». Текст «Эдуарда II» можно загрузить с сайта проекта «Гутенберг» так же, как мы это сделали ранее для «Ромео и Джульетты»2.
Загрузка языковой модели и создание объекта spaCy Doc
Как и в предыдущем разделе, начнем с загрузки языковой модели для английского языка:
In [1]: import spacy
In [2]: nlp = spacy.load('en')
1 https://en.wikipedia.org/wiki/Shakespeare_authorship_question.
2 Каждая электронная книга проекта «Гутенберг» включает дополнительный текст (в частности, лицензионную информацию), которая не является частью самой книги. В данном примере мы воспользовались текстовым редактором для удаления текста из нашей копии электронной книги.
514 Глава 11. Обработка естественного языка (NLP)
Создание объекта spaCy Doc
Затем создаются два объекта Doc — для «Ромео и Джульетты» и для «Эдуарда II»:
In [3]: from pathlib import Path
In [4]: document1 = nlp(Path('RomeoAndJuliet.txt').read_text())
In [5]: document2 = nlp(Path('EdwardTheSecond.txt').read_text())
Сравнение сходства книг
Наконец, метод similarity класса Doc используется для получения значения в диапазоне от 0.0 (сходство отсутствует) до 1.0 (полная идентичность), которое показывает, насколько похожи документы:
In [6]: document1.similarity(document2)
Out[6]: 0.9349950179100041
spaCy считает, что два документа обладают высокой степенью сходства. Для чистоты эксперимента мы создали объект Doc для текста новостной заметки и сравнили его с «Ромео и Джульеттой». Как и предполагалось, spaCy возвращает низкое значение, свидетельствующее о незначительном сходстве между ними. Попробуйте скопировать текст заметки в текстовый файл и провести сравнение самостоятельно.
11.7. Другие библиотеки и инструменты NLP
В этой главе были представлены различные библиотеки NLP, но вам всегда стоит самостоятельно исследовать возможные варианты, чтобы выбрать оптимальный инструмент для ваших задач. Ниже перечислены некоторые (в основном бесплатные и распространяемые с открытым кодом) библиотеки NLP и API:
ØØ
Gensim — выявление сходства и тематическое моделирование.
ØØ
Google Cloud Natural Language API — облачный API для задач NLP (распознавание именованных сущностей, анализ эмоциональной окраски, анализ частей речи и визуализация, определение категорий контента и т. д.).
ØØ
Microsoft Linguistic Analysis API.
11.8. Машинное обучение и NLP-приложения с глубоким обучением 515
ØØ
Анализ эмоциональной окраски Bing — поисковая система Bing компании Microsoft использует эмоциональную окраску при выборе результатов поиска (на момент написания книги эта возможность была доступна только в США).
ØØ
PyTorch NLP — библиотека глубокого обучения для NLP.
ØØ
Stanford CoreNLP — NLP-библиотека для языка Java, которая также предоставляет обертку для Python. Включает разрешение кореференции, то есть поиск всех ссылок на один ресурс.
ØØ
Apache OpenNLP — другая NLP-библиотека на базе Java для выполнения распространенных операций, включая разрешение кореференции. Доступны обертки для Python.
ØØ
PyNLPl — NLP-библиотека для языка Python; включает как базовую, так и более сложную функциональность NLP.
ØØ
SnowNLP — библиотека Python, упрощающая обработку текста на китайском языке.
ØØ
KoNLPy — NLP для корейского языка.
ØØ
stop-words — библиотека Python с игнорируемыми словами для многих языков. В этой главе использовались списки игнорируемых слов NLTK.
ØØ
TextRazor — коммерческий облачный NLP API с бесплатным уровнем.
11.8. Машинное обучение и NLP-приложения с глубоким обучением
Существует множество областей обработки естественного языка, требующих применения машинного обучения и методов глубокого обучения. Некоторые из них рассмотрены в главах, посвященных машинному обучению и глубокому обучению:
ØØ
Ответы на вопросы на естественном языке — например, издатель Pearson Education использует IBM Watson в качестве виртуального преподавателя. Студенты задают Watson вопросы на естественном языке и получают ответы.
ØØ
Составление сводки документа — анализ документа и построение краткой сводки (также называемой конспектом), которая, например, может вклю516
Do'stlaringiz bilan baham: |