Текстовые данные существуют во многих различных формах (от социальных сетей до электронной почты). Анализируя и визуализируя текстовые данные, вы можете отследить общие тенденции написания и восприятия текста.
Данное руководство поможет создать графики, отображающие частоту употребления слов в текстовом корпусе. Мы напишем программу, которая будет выполнять поиск по простому текстовому документу и подсчитывать частоту использования слов, а затем отображать результат в виде графика с помощью библиотеки matplotlib.
Требования
- Предварительно настроенная среда разработки и установленный Python 3.
- Базовые навыки работы с Python 3 и словарями (больше о словарях можно узнать здесь).
- Библиотека matplotlib (чтобы импортировать библиотеку, читайте это руководство).
Чтобы настроить среду разработки, обратитесь к статьям:
- Настройка локальной среды разработки для Python 3 в Ubuntu 16.04, CentOS 7, Windows 10, Mac OS X и Debian 8.
- Установка Python 3 и настройка среды разработки на сервере Ubuntu 16.04 или
1: Файл программы
Установив библиотеку matplotlib, вы можете приступать к созданию проекта.
При помощи любого удобного редактора создайте файл word_freq.py. Это будет главный файл программы.
Импортируйте в программу библиотеку matplotlib и класс pyplot (используйте псевдоним plt). В целом plt объявляется как глобальная переменная, которая будет использоваться в сценарии.
import matplotlib.pyplot as plt
Читайте также: Импорт модулей в Python 3
Далее нужно импортировать стандартные пакеты Python, с помощью которых можно настроить и принимать входные данные командной строки. Важно отметить пакет argparse: он позволяет собирать информацию командной строки и включает текст справки для пользователя.
Чтобы импортировать эти пакеты, добавьте в файл word_freq.py такие строки:
import matplotlib.pyplot as plt
import sys
import operator
import argparse
Затем создайте основной метод и вызов. В основном методе будет находиться большая часть кода программы.
import matplotlib.pyplot as plt
import sys
import operator
import argparse
def main():
if __name__ == "__main__":
main()
Базовый файл программы готов.
2: Настройка аргументов
Теперь нужно создать аргументы командной строки и сократить их в переменной для быстрого доступа.
Читайте также: Использование переменных в Python 3
В основном методе создайте переменную parser и присвойте ей конструктор argparse по умолчанию. Затем нужно присвоить ей аргументы – слова, которые нужно найти в файле, и файл, в котором нужно выполнить поиск (это будет файл .txt).
...
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"word",
help="the word to be searched for in the text file."
)
parser.add_argument(
"filename",
help="the path to the text file to be searched through"
)
if __name__ == "__main__":
main()
Первым аргументом в методе является слово, которое будет помещено в командную строку. Второй аргумент, help= “…”, предоставляет пользователю некоторую информацию о том, как должен выглядеть аргумент командной строки.
Сохраните эти аргументы в другую переменную, args:
...
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"word",
help="the word to be searched for in the text file."
)
parser.add_argument(
"filename",
help="the path to the text file to be searched through"
)
args = parser.parse_args()
if __name__ == "__main__":
main()
Входные данные всегда нужно проверять: аргументы командной строки могут содержать опечатки. Кроме того, так вы можете предотвратить резкие сбои сценария. Для обработки ошибок можно использовать оператор try.
...
def main():
...
args = parser.parser_args()
try:
open(args.filename)
except FileNotFoundError:
sys.stderr.write("Error: " + args.filename + " does not exist!")
sys.exit(1)
if __name__ == "__main__":
main()
Строка sys.exit(1) сообщит пользователю о проблемах в коде, из-за которых он не был выполнен.
Теперь программа может принимать аргументы командной строки.
3: Парсинг файла
Теперь нужно прочитать файл, подсчитать и зарегистрировать, сколько раз в нём встречается то или иное слово, и сохранить данные в словарь.
Добавьте в файл функцию word_freq(), которая принимает два аргумента командной строки (слово и имя файла), а затем вызовите эту функцию в main().
...
def main():
...
word_freq(args.word, args.filename)
def word_freq(word, filename):
if __name__ == "__main__":
main()
Прежде чем начать анализ файла, нужно создать словарь (назовём его doc), в котором будут храниться все найденные в файле слова, а также данные об их использовании. Добавьте в word_freq.py:
...
def word_freq( word, filename ):
doc = {}
if __name__ == "__main__":
main()
Далее нужно настроить итерацию файла. Для этого используйте вложенный цикл for.
Читайте также: Циклы for в Python 3
Первый цикл for открывает файл и берёт его первую строку. Затем он разделяет все его строки на слова, учитывая пробелы между словами, и хранит результат в массиве.
Второй цикл for рассматривает полученный массив и проверяет, есть он в словаре или нет. Если массив уже встречается в словаре, он добавляет к счётчику единицу. Если массива в словаре нет, цикл создаёт новую запись и ставит в счётчике 1.
...
def word_freq(word, filename):
doc = {}
for line in open(filename):
split = line.split(' ')
for entry in split:
if (doc.__contains__(entry)):
doc[entry] = int(doc.get(entry)) + 1
else:
doc[entry] = 1
if __name__ == "__main__":
main()
Напомним, что метод main() настраивает входные данные командной строки и передаёт их функции word_freq(). Функция word_freq() должна получать из командной строки слово и имя файла и сохранять каждое уникальное слово, найденное в файле.
4: Хранение и сортировка данных
Прежде чем приступить к построению графика, программа должна убедиться, что в файле вообще есть искомое слово. Для этого можно использовать условный оператор if.
...
def word_freq(word, filename):
...
else:
doc[entry] = 1
if (not word in doc):
sys.stderr.write("Error: " + word + " does not appear in " + filename)
sys.exit(1)
if __name__ == "__main__":
main()
Убедившись, что искомое слово присутствует в указанном файле, программа может начать сбор данных для создания графика.
Для начала нужно отсортировать данные в словаре по частоте употребления слова в порядке убывания и инициализировать переменные для дальнейшей работы. Сортировка данных необходима для построения графика.
...
def word_freq(word, filename):
...
if (not word in doc):
sys.stderr.write("Error: " + word + " does not appear in " + filename)
sys.exit(1)
sorted_doc = (sorted(doc.items(), key = operator.itemgetter(1)))[::-1]
just_the_occur = []
just_the_rank = []
word_rank = 0
word_frequency = 0
if __name__ == "__main__":
main()
Обратите внимание на переменные just_the_occur и just_the_rank. Первая содержит данные о том, сколько раз встречается то или иное слово, а вторая отображает место слова в рейтинге.
Теперь у вас есть упорядоченный словарь, который можно проанализировать, определить частоту употребления слова и его место в рейтинге, а затем построить график на основе этих данных.
...
def word_freq( word, filename ):
...
sortedDoc = (sorted(doc.items(), key = operator.itemgetter(1)))[::-1]
just_the_occur = []
just_the_rank = []
word_rank = 0
word_frequency = 0
entry_num = 1
for entry in sorted_doc:
if (entry[0] == word):
word_rank = entryNum
word_frequency = entry[1]
just_the_rank.append(entry_num)
entry_num += 1
just_the_occur.append(entry[1])
if __name__ == "__main__":
main()
Переменные just_the_occur и just_the_rank должны быть одной длины, иначе matplotlib не сможет построить график.
Также нужно добавить в цикл выражение if, чтобы найти слово и извлечь данные о нём.
5: Построение графика
Теперь можно использовать переменную plt, созданную ещё в начале руководства. Чтобы собрать график, нужно указать заголовок, метки осей x и y, масштаб и тип графика.
Метки осей должны быть описательными (хотя это, конечно, не обязательно, вы можете выбрать любые метки).
...
def word_freq( word, filename ):
...
just_the_rank.append(entry_num)
entry_num += 1
just_the_occur.append(entry[1])
plt.title("Word Frequencies in " + filename)
plt.ylabel("Total Number of Occurrences")
plt.xlabel("Rank of word(\"" + word + "\" is rank " + str(word_rank) + ")")
plt.loglog(
just_the_rank,
just_the_occur,
basex=10
)
plt.scatter(
[word_rank],
[word_frequency],
color="orange",
marker="*",
s=100,
label=word
)
plt.show()
if __name__ == "__main__":
main()
Функция plt.title определяет заголовок, функции plt.ylabel() и plt.xlabel() – метки осей.
Функция plt.loglog() принимает значения just_the_rank и just_the_occur и присваивает их осям х и у соответственно.
Нужная точка на графике будет отмечена оранжевой звёздочкой и подписана искомым словом.
Функция plt.show() отображает график.
Теперь код программы полностью готов.
6: Запуск программы
Чтобы проверить работу программы, нам понадобится тестовый файл. Для примера загрузите что-нибудь с сайта бесплатных электронных книг Project Gutenberg.
К примеру, загрузим роман A Tale of Two Cities; файл cities.txt можно загрузить с помощью curl в текущий каталог, в котором хранится сценарий Python.
curl http://www.gutenberg.org/files/98/98-0.txt --output cities.txt
Чтобы запустить программу, передайте в качестве параметров любое слово (например, fish) и имя файла.
python word_freq.py fish cities.txt
Если код не содержит ошибок, на экране вы увидите график, отображающий частоту использования каждого слова в файле; место слова fish в этом графике будет отмечено оранжевой звёздочкой.
Читайте также: Работа с текстовыми файлами в Python 3
Полный код программы и рекомендуемые улучшения
На данный момент у вас есть полностью рабочая программа для отслеживания частоты употребления слов в текстах.
Полный код программы выглядит так:
import matplotlib.pyplot as plt
import sys
import operator
import argparse
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"word",
help="the word to be searched for in the text file."
)
parser.add_argument(
"filename",
help="the path to the text file to be searched through"
)
args = parser.parse_args()
try:
open(args.filename)
except FileNotFoundError:
# Custom error print
sys.stderr.write("Error: " + args.filename + " does not exist!")
sys.exit(1)
word_freq(args.word, args.filename)
def word_freq(word, filename):
doc = {}
for line in open(filename):
# Assume each word is separated by a space
split = line.split(' ')
for entry in split:
if (doc.__contains__(entry)):
doc[entry] = int(doc.get(entry)) + 1
else:
doc[entry] = 1
if (word not in doc):
sys.stderr.write("Error: " + word + " does not appear in " + filename)
sys.exit(1)
sorted_doc = (sorted(doc.items(), key=operator.itemgetter(1)))[::-1]
just_the_occur = []
just_the_rank = []
word_rank = 0
word_frequency = 0
entry_num = 1
for entry in sorted_doc:
if (entry[0] == word):
word_rank = entry_num
word_frequency = entry[1]
just_the_rank.append(entry_num)
entry_num += 1
just_the_occur.append(entry[1])
plt.title("Word Frequencies in " + filename)
plt.ylabel("Total Number of Occurrences")
plt.xlabel("Rank of word(\"" + word + "\" is rank " + str(word_rank) + ")")
plt.loglog(just_the_rank, just_the_occur, basex=10)
plt.scatter(
[word_rank],
[word_frequency],
color="orange",
marker="*",
s=100,
label=word
)
plt.show()
if __name__ == "__main__":
main()
Этот код можно дополнить и улучшить. К примеру, программа могла бы сравнивать частоту использования двух слов. Тогда в командной строке появился бы ещё один аргумент.
Или же программа могла бы сравнивать длину двух слов и сохранять полученный результат в словарь.