Визуализация данных с помощью Python
/Глава 12
  • Денис Вакарчук
    Автор
  • Александр Боровинский
    Автор
  • Денис Вакарчук
    Автор
  • Александр Боровинский
    Автор
Визуализация данных — это мощный инструмент для политолога-международника. Качественное графическое представление данных не только упрощает представление результатов анализа, но и раскрывает скрытые закономерности. В этой главе будет рассмотрена работа трех инструментов визуализации данных на языка программирования Python.

/01

Подготовка к визуализации данных в Python

В предыдущих главах авторы подробно рассмотрели применение методов искусственного интеллекта для анализа данных. Однако, несмотря на значительные достижения в этой области, искусственный интеллект все еще допускает неточности, а порой и явные ошибки. Для более глубокого понимания аналитических процессов и результатов необходимо обладать навыками самостоятельного анализа данных.
В профессиональной деятельности аналитика важно уметь представлять данные таким образом, чтобы они были понятны даже для лиц, не обладающих глубокими знаниями в конкретной области. Для достижения этой цели используются методы визуализации данных с использованием языка программирования Python.
Предполагается, что на вашем компьютере уже установлена среда Anaconda. Для начала работы необходимо открыть Jupyter Notebook и выполнить соответствующую команду:
 import pandas as pd
Pandas представляет собой специализированную библиотеку для обработки табличных данных, обладающую широким спектром встроенных функций. Эти функции необходимы для предварительной обработки и анализа данных.
Возможности Python будут продемонстрированы на основе работы с набором данных о голосовании государств в Генеральной Ассамблее ООН c 1946 по 2019 г. Эти данные были получены из работы авторского коллектива под руководством Эрика Воетена, видного исследователя голосования государств в международных организациях.
Набор данных состоит из трех таблиц (датафреймов):
  • Первая таблица (un_votes)
    Содержит историю голосования каждой страны. Каждая строка в этой таблице отражает участие конкретной страны в голосовании по определенному вопросу.
  • Вторая таблица (un_roll_calls)
    Содержит информацию о каждом голосовании. Она включает дату проведения голосования, описание и резолюцию, которая была предметом обсуждения.
  • Третья таблица (un_roll_call_issues)
    Представлена информация о категоризации каждого голосования в соответствии с одной из шести укрупненных повесток: «Колониализм», «Контроль над вооружениями и разоружение», «Экономическое развитие», «Права человека», «Палестинский вопрос» и «Ядерное оружие и ядерные материалы».

Предварительная обработка данных

Рассмотрим несколько примеров визуализации данных. Для этого необходимо предварительно обработать данные:
# Загружаем данные, выбирая только нужные столбцы
un_roll_call_issues = pd.read_csv('un_roll_call_issues.csv', usecols=['rcid', 'issue']) 
un_roll_calls = pd.read_csv('un_roll_calls.csv', usecols=['rcid', 'session', 'date'])
un_votes = pd.read_csv('un_votes.csv', usecols=['rcid', 'country', 'vote'])

# Объединяем датафреймы в одну цепочку
# Сначала un_roll_call_issues с un_roll_calls
# Затем результат с un_votes
UN = un_roll_call_issues.merge(un_roll_calls, on='rcid') \
    .merge(un_votes, on='rcid')
В качестве примера отберем только страны, входящие в «Большую двадцатку» (далее — G20). Для этого отфильтруем данные, не забывая, что в G20 входят 19 государств:
g20_members =[
   "Argentina", "Australia", "Brazil", "Canada", "China",
   "France", "Germany", "India", "Indonesia", "Italy",
   "Japan", "Mexico", "Russia", "Saudi Arabia", "South Africa",
   "South Korea", "Turkey", "United Kingdom", "United States"
]
 
G20 = UN.query("country in @g20_members")
Для начала посмотрим, какие вопросы и с какой частотой рассматривали страны, входящие в G20 с 1945 по 2019 гг.:
G20.groupby('issue').agg({'rcid':'nunique'}).reset_index()
Частота обсуждения странами G20 укрупненных повесток в Генеральной Ассамблее ООН
На этом этапе можно переходить к визуализации данных. Существует три базовых инструмента для визуализации данных:
  • функция plot() в библиотеке pandas
  • библиотека matplotlib
  • библиотека seaborn
В этой главе будет рассмотрена работа этих трех инструментов.

/02

Функция plot () в библиотеке pandas

В первую очередь необходимо понять, каким образом информация будет демонстрироваться зрителю. На основе получившихся табличных данных графически представим распределение частоты обсуждения странами G20 укрупненных повесток:
G20.groupby('issue').agg({'rcid':'nunique'}).reset_index().plot()
Распределение частоты обсуждения странами G20 укрупненных повесток в ГА ООН (версия 1)
Прежде чем делать выводы, целесообразно оценить восприятие информации человеком, который впервые знакомится с представленным графическим изображением.
Следует отметить, что на графике отсутствует возможность определить конкретные темы повесток, по которым проводились голосования, поскольку тематика каждой из них зашифрована числовыми индексами.
G20.groupby('issue').agg({'rcid':'nunique'}).reset_index().plot(x='issue',
     rot=45, figsize=(10,5))
Распределение частоты обсуждения странами G20 укрупненных повесток в ГА ООН (версия 2)
После удаления индексов они были заменены на укрупнённые темы повесток. Чтобы предотвратить пересечение названий, был использован параметр figsize, который позволил изменить размер текста. Параметр rot обеспечил поворот надписей под углом 45 градусов, что улучшило их читаемость. Кроме того, необходимо добавить подписи осей на графике.
G20.groupby('issue').agg({'rcid':'nunique'}).reset_index().plot(x='issue', 
    rot=45, figsize=(10,5), xlabel=Укрупненная повестка', 
    ylabel='Кол-во упоминаний', legend=False)
Распределение частоты обсуждения странами G20 укрупненных повесток в ГА ООН (версия 3)
Однако существует ещё один аспект, который можно квалифицировать как серьёзное искажение данных. В представленном виде график может быть использован исключительно с целью сокрытия определённой информации.
При детальном анализе графика становится очевидным, что страны G20 чаще всего принимали решения в Генеральной Ассамблее ООН по следующим вопросам: «Контроль над вооружениями и разоружение», «Права человека» и «Палестинский конфликт». В то же время резолюции по повестке «Экономическое развитие» рассматривались странами G20 значительно реже. Однако этот вывод является ошибочным и может привести к искажению восприятия данных. Причина — на оси Y графика присутствует смещение отсчёта.
Для устранения этой проблемы необходимо внести коррективы в график, добавив в функцию параметр ylim, которому будут присвоены значения 0 и 1100, соответствующие началу и концу отсчёта.
G20.groupby('issue').agg({'rcid':'nunique'}).reset_index().plot(x='issue', 
     rot=45, figsize=(10,5), xlabel='Укрупненная повестка',
     ylabel='Кол-во упоминаний', legend=False, ylim=(0,1100))
Распределение частоты обсуждения странами G20 укрупненных повесток в ГА ООН (версия 4)
  • /важно

    Для успешного решения задачи недостаточно просто визуализировать те или иные данные. Необходимо предварительно определить цель исследования и выбрать соответствующий тип графического представления.
/важно
Для успешного решения задачи недостаточно просто визуализировать те или иные данные. Необходимо предварительно определить цель исследования и выбрать соответствующий тип графического представления.
Линейная диаграмма не подходит для решения поставленной нами задачи, так как она, как правило, предназначена для отображения временных рядов. Кроме того, первоначальный правильный выбор подходящего типа графика может устранить проблему отсчёта от нуля. Верным решением в нашем случае является замена параметра ylim на параметр, указывающий на тип графика: kind = 'bar'. В результате мы получим столбчатую диаграмму.
G20.groupby('issue').agg({'rcid':'nunique'}).reset_index().plot(x='issue', 
    rot=45, figsize=(10,5), xlabel='Укрупненная повестка', 
    ylabel='Кол-во упоминаний', legend=False, kind='bar')
Распределение частоты обсуждения странами G20 укрупненных повесток в ГА ООН (версия 5)

/03

Библиотека Matplotlib

Рассмотрим, какая страна из группы G20 чаще всего воздерживается от принятия решения. Для этого отфильтруем данные, оставив только случаи голосования «воздержался», и создадим новый график с использованием библиотеки matplotlib.
# Импорт библиотеки matplotlib
import matplotlib.pyplot as plt

# Фильтрация данных и сохранение результата в новую переменную
G20_abstain = G20.query('vote == "abstain"')

# Подсчет количества голосований типа «воздержался» по странам
abstain_counts = G20_abstain['country'].value_counts()

# Создание круговой диаграммы
plt.figure(figsize=(10, 8))
plt.pie(abstain_counts, labels=abstain_counts.index,
        autopct='%1.1f%%', startangle=140)
plt.title('Соотношение стран по кол-ву воздержавшихся', pad=20)

# Чтобы диаграмма была круглой
plt.axis('equal')

# Демонстрация круговой диаграммы
plt.show()
Распределение стран по доле голосов «воздержался»
Следует отметить, что встроенный в pandas инструмент визуализации данных предоставляет возможность непосредственного написания кода после выполнения манипуляций с табличными данными. Matplotlib, в свою очередь, является отдельной библиотекой, и принимает уже готовую предобработанную таблицу в качестве аргумента. Библиотека Matplotlib предоставляет широкий спектр инструментов и возможностей для настройки графиков, отличающихся от pandas высокой степенью гибкости и функциональности.
Анализ получившегося графика показывает, что шесть государств из девятнадцати занимают более половины круговой диаграммы. Это свидетельствует о том, что значительная часть стран-участниц G20 довольно редко воздерживается при голосовании по резолюциям в Генеральной Ассамблее ООН.

/04

Библиотека Seaborn

Существуют графические инструменты, которые позволяют выявить данные, не всегда поддающиеся интерпретации при анализе значительных объемов данных. Одним из таких инструментов является диаграмма рассеивания, которая предоставляет возможность визуально оценить, по каким вопросам и в какие периоды времени различные государства принимали решение воздержаться от участия в голосовании.
Для иллюстрации представим результаты голосования Советского Союза/Российской Федерации в рамках Генеральной Ассамблеи Организации Объединенных Наций посредством диаграммы рассеивания. Хотя эту диаграмму можно построить с использованием встроенных функций библиотеки pandas, для получения желаемой разбивки точек по годам с цветовой кодировкой в зависимости от укрупненной повестки потребуется написать относительно громоздкий код.
Для решения этой задачи оптимальным выбором будет использование библиотеки seaborn. Импортируем библиотеку при помощи следующей команды:
import seaborn as sns
Перед построением диаграммы рассеивания необходимо провести предварительную обработку данных. В исходной таблице данные о дате представлены в строковом формате. Для корректного анализа требуется преобразовать их в формат даты и выделить год в отдельный столбец.
G20_abstain['date'] = pd.to_datetime(G20_abstain['date'])
 
G20_abstain['year'] = G20_abstain['date'].dt.year
Выявим, в каких случаях рассматриваемая страна воздерживалась от принятия решений при голосовании, а также определим периоды с минимальным количеством воздержаний.
# Фильтрация данных по рассматриваемой стране
Russia_abstain = G20_abstain.query('country = "Russia"')

# Группировка данных по году и повестке; подсчет количества голосов
votes_by_year_issue = Russia_abstain.groupby(['year', 'issue']).size().
reset_index(name='count')
После этого перейдем к непосредственному процессу построения графика.
# Создание диаграммы рассеивания
plt.figure(figsize=(12, 8))
sns.scatterplot(data=votes_by_year_issue, x='year', y='count', hue='issue', 
palette='viridis', s=100)

# Настройка параметров диаграммы рассеивания
plt.xlabel('Год', fontsize=14)
plt.ylabel('Количество голосов', fontsize=14)
plt.legend(title='Вопрос', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.grid(True, linestyle='--', alpha=0.7)
plt.tight_layout()

# Демонстрация диаграммы рассеивания
plt.show()
Распределение голосов «воздержался» СССР/РФ по укрупненным повесткам в ГА ООН
Для анализа представленного графика необходимо определить моду выборки. Мода является мерой центральной тенденции и представляет собой наиболее часто встречающееся значение во множестве наблюдений. В данном случае мода выборки соответствует ситуации, когда рассматриваемая страна наиболее часто воздерживалась от голосования по повестке «Палестинский конфликт» в начале 1990-х годов.
Таким образом, после распада Советского Союза вопросы разоружения и ядерного оружия часто становились причиной воздержания Российской Федерации от голосования в Генеральной Ассамблее ООН. В то же время по повестке «Экономическое развитие» Российская Федерация чаще всего принимала решения по существу.
Материал настоящей главы не претендует на всеобъемлющий характер. За рамками остались многие важные аспекты визуализации данных такие как продвинутые методы визуализации, интеграция с BI-платформами. Тем не менее, освоение рассмотренных инструментов Python для графического представления данных станет основой для дальнейшего профессионального роста в области количественного анализа политических процессов.
Практикум
Выполните задания для закрепления материала

Хотите больше узнать по теме? Ознакомьтесь с данной литературой

Читайте также:
Работа в Google Colab и генерация кода с помощью ИИ
Тематическое моделирование в Google Colab