Data Science

Панель мониторинга сквозных данных с Plotly Dash и Heroku: данные по безработице в США

Существует множество экономических данных, которые публикуются различными департаментами, DOL, BEA, BLS, FRED, NBER, Бюро переписи населения США - как мы можем собрать данные воедино и увидеть людей, которые на самом деле стоят за этими цифрами?

За последние пару месяцев мы видели, как до неприличия большие числа показывались одинаково - на линейных диаграммах и гистограммах с большим скачком. Конечно, это хороший способ показать изменения, но сложно посочувствовать или действительно понять одну строчку. Линии заставляют сказать: «Ооо, вау, необычно», и все. Я считаю, что эти данные должны быть представлены личным образом (людям, местам и отраслям, которые они знают), чтобы помочь пользователям сравнивать статистику по США.

Для этого требуется панель данных, в частности такая, цель которой:

Чтобы пользователи могли легко сравнивать и видеть проблемы и закономерности в рабочей силе США, что в конечном итоге приводит к более глубоким вопросам "почему" и последующим исследованиям.

Репозиторий GitHub с некоторым используемым кодом и данными находится здесь, а панель управления можно найти по адресу usa-data-dashboard.herokuapp.com. Если вы пользуетесь мобильным телефоном, перейдите на сайт usa-data-dashboard-mobile.herokuapp.com, чтобы улучшить качество просмотра. В целом этот проект занял четыре дня и, вероятно, 1000 строк кода. Само приложение представляет собой 500 строк кода.

Это приложение было создано в три этапа

  1. Получение и очистка данных
  2. Создание графических диаграмм и приложения Dash
  3. Развертывание на Heroku и оптимизация

Получение и очистка данных

Чтобы увидеть людей, стоящих за этими данными, и то, как мы можем им помочь, нам нужны диаграммы, показывающие, где, кто и почему. Я решил действовать настолько детально, насколько мог, и остановился на использовании данных на уровне округов (переписных участков) США, показывающих безработицу, социально-демографические данные и зависимость от отрасли. В переписи населения США зарегистрировано более 3000 округов. Как и следовало ожидать, это была самая длинная и сложная часть упражнения, примерно 2,5 дня из 4, и она может быть немного сухой. Наборы данных, на которых я остановился, были обусловлены точностью и согласованностью обновлений:

  1. Полный набор идентификаторов, соответствующих следующим: Федеральные стандарты обработки информации (FIPS), статистическая область на основе ядра (CBSA), название столичной области, название округа, название штата Примерно 2020
  2. Уровень безработицы в BLS по округам 2010–2020
  3. Занятость в BLS по отраслям (штат и район метро) 2019–2020
  4. Данные Бюро переписи населения США: демографические данные и средний доход 2018

Начало проекта было очень запутанным, учитывая огромное количество источников схожих данных, согласование идентификаторов, а также частоту обновления. Мне потребовалось около полдня, чтобы прочесать каждый из сайтов, перечисленных в моем подзаголовке, чтобы увидеть, где я могу извлечь наиболее согласованные данные и идентификаторы. Хотя он указан как номер один в моих наборах данных, я действительно не собирал все вместе до конца. Это было сложно по трем причинам:

  1. Округа и мегаполисы часто сгруппированы или написаны немного по-разному от источника данных к источнику данных.
  2. Как наборы данных, так и ключи, которые я обнаружил, относятся к разным датам, поэтому незначительные изменения в сопоставлении привели к дополнительным четырем-пяти часам проверки имени по имени на листах, чтобы найти комбинацию, которая работает лучше всего.
  3. Названия округов в США не уникальны.

По сути, все это связано с кодами Бюро переписи населения США, где FIPS совпадает с названием округа, CBSA совпадает с метрополитеном, а FIPS совпадает с CBSA (если округ является частью столичного района). Вы можете найти это сопоставление в моем FIPS to CBSA.xlsx файле. Это было создано с помощью комбинации клавиш NBER и BLS. Все это используется USCB, который разбивает это так:

Вот как это связано: я начал с данных идентификатора серии Local Area Unemployment ID из их базы данных (это было 3200 запросов / 200 макс. На запрос = 16 запросов) и использовал их преобразование area_code в area_text, чтобы получить названия округов и столбцов. (это в моем US BLS Codes.xlsx файле). Они восходят к 1990 году, но я извлек только из 2010 без корректировок.

Затем я взял страницы с обзором экономики штата и метрополитена, чтобы получить ежемесячные данные о занятости в отрасли. Это вернулось только к декабрю 2019 года. Я смог получить отраслевую разбивку с каждой страницы EAG как эта.

Данные переписи USCB также было трудно найти на уровне округа, поэтому я использовал файлы данных, найденные на Карте правосудия на уровне тракта, который представлял собой файл дампа postgreSQL text размером 1,2 ГБ. Мне пришлось загрузить postgreSQL, установить postGIS надстройку, а затем pd_dump файл в базу данных. Я прочитал таблицу базы данных в Python с помощью psycopg2 library, а затем взял среднюю разбивку по округам, используя этот метод. При сверке данных для проверки процентов с картой справедливости я исключил другие расы, поскольку это поле, похоже, не было включено в общую численность населения.

Если вам интересно, как я чистил файлы, посмотрите репо и конкретно этот скрипт. Я не очищал скрипт, но думаю, что он довольно простой, все прочитанные файлы находятся в репозитории. Не обращайте внимания на строки 18–21, я не стал использовать этот файл кода из-за несоответствия имен.

Создание графических диаграмм и приложения Dash

Теперь мы перейдем к коду, а именно к тому, как был сделан макет приложения. Для справки вот код приложения по состоянию на 16.06.2020. Я удалил около 150 строк, которые касались чтения и обработки данных, на которые было бы непросто смотреть, мы поговорим об этом позже. Реализация Dash начинается со строки 83.

Я предполагаю, что вы имеете базовое представление о макетах и ​​обратных вызовах, в противном случае, пожалуйста, ознакомьтесь с документацией по Plotly Dash, чтобы начать работу.

Напоминаем, что в Plotly Dash можно перенести любую диаграмму - она ​​будет статичной. Для этой панели я использовал четыре типа графиков:

Объекты графического изображения: go.Choropleth для режима определения местоположения "США-штаты"

В этом случае использовались три обратных вызова: один для выбора типа отрасли для отображения, а затем два для выбора дат. Ползунки пока не используют datetime объектов, поэтому это единственный обходной путь.

Plot_unemploy_choro_state () - это функция, которую я определил ранее в скрипте, в строке 64.

Plotly Express: px.choropleth_mapbox для графика уровня округа (FIPS)

Теперь мы немного усложняем задачу. Я использовал связанный обратный вызов, чтобы выбрать набор данных (данные переписи или данные о безработице округа BLS) в одном раскрывающемся списке, а затем во втором раскрывающемся списке, чтобы отобразить значение для построения графика.

Выглядит устрашающе, но все просто, если идти медленно. Первый обратный вызов - это то, что выбирает метки для отображения во втором раскрывающемся списке, а второй обратный вызов фильтрует соответствующий набор данных df по «типу данных» и устанавливает его как fig для возврата.

Графический экспресс: px.line и px.bar

Хорошо, теперь вся правая сторона. По сути, то, что здесь происходит, - выбор округа заботится обо всех диаграммах. Когда у меня есть округ, я строю линейный график с данными округа по безработице BLS, извлекаю демографические данные этого округа из данных Бюро переписи населения США за 2018 год, затем обновляю занятость в отрасли, используя данные штата (из диаграммы 1) и данные CBSA Metropolitan Area. (оба они взяты из источника данных EAG).

Округ - это обратный вызов штата, поскольку названия округов не уникальны в США. Поскольку у меня была настройка файла сопоставления, я мог легко использовать dict для извлечения из всех других листов на бэкэнде.

При пошаговом рассмотрении первый обратный вызов устанавливает раскрывающийся список округов. Второй обратный вызов вызывает предупреждение, если не выбран округ. Третий, четвертый и пятый обратные вызовы одинаково используют px.bar. Последний обратный вызов - это исторический линейный график. Здесь происходит множество операций, но не беспокойтесь о них слишком много.

Вторая вкладка: сравнение

Я проектировал вторую вкладку только после того, как создал первую. Я хотел, чтобы первое помогло пользователям находить необычные округа и штаты, а второе - чтобы сравнить их столько, сколько вы захотите, после того, как найдете интересные штаты / округа.

Сравнение состояний выглядит так:

А сравнение графств выглядит так:

На изображении обрезана диаграмма дохода, но вы можете посмотреть сами. По сути, это тот же код, но я использовал другой вариант px.bar и включил multi=True в раскрывающемся списке, чтобы можно было заполнить столько строк или полосок, сколько необходимо.

Вам не обязательно этого делать, но я использовал Dash Bootstrap Components вместо стандартной таблицы стилей для макетов, вкладок и карточек (устанавливая границы в определенных областях). У них отличная документация, и они действительно помогают упростить организацию кода приложения, поэтому я рекомендую попробовать их, если вы еще этого не сделали. Сначала я создал пустые вкладки и макет карточек, а затем начал их заполнять. Вы увидите, что мой app.layout довольно короткий, в строках 297–304.

Развертывание на Heroku и оптимизация

Если вы зашли так далеко, то поздравляю! Разобраться в том, как обрабатывать данные и строить информационную панель занимались кем-то другим, - непростая задача. Я скажу это, чтобы избавить вас от боли - как только у вас будет одна или две базовых диаграммы, работающие локально, разверните в Heroku. Heroku имеет то, что называется лимитом R15, что в основном означает ваш приложение выйдет из строя, если оно превысит 512 МБ X 2 рабочих = 1024 МБ используемой памяти (проверьте сбои с помощью heroku logs --tail). Эта ссылка содержит пошаговое руководство внизу для развертывания базового приложения. Если вы работаете в Windows, используйте venv\Scripts\activate вместо команды source.

По мере продвижения вы можете добавлять больше диаграмм и тестировать функции - это особенно важно, если вы добавляете больше, чем просто базовые пакеты dash / pandas / numpy, поскольку вы могли сделать что-то необычное, но по какой-то причине пип не работает или другой при нажатии на героку. Это действительно похоже на совет при использовании любого программного обеспечения: «сохраняйте раньше, сохраняйте часто».

Для большинства простых приложений вам не нужно заботиться об оптимизации, но для этого у меня было более 1 ГБ данных и несколько дорогостоящих операций в скриптах. Чтобы обойти это, я попытался ограничить такие операции, как .unstack(), чтобы сэкономить строки и разделить файлы большего размера на несколько CSV, а затем выполнил большинство операций, которые находились в Labor Data Prep.py file в app.py file. Вот почему есть почти 200 строк, прежде чем даже попасть в приложение Dash, некоторые файлы меняются с 3000 строк в CSV до 1600000 строк после операций в файле app.py.

Я часто сталкивался с ошибкой R15, постоянно используя около 1100+ МБ памяти, даже когда в приложении было только две диаграммы. Я изменил procfile , чтобы включить "preload" и сэкономить память за счет некоторой производительности.

web: gunicorn app:server --preload

Также он помогает узнать о различных типах дино (веб, рабочий, часы и т. Д.) И масштабировании по горизонтали и вертикали. Вам может потребоваться платный тариф для приложений с большим объемом памяти.

Также существует целый набор надстроек, стоимость которых варьируется от 5 долларов в месяц до 1000 долларов США для предприятий. Я потратил некоторое время на изучение кеширования, чтобы увидеть, будет ли производительность выше, но в конечном итоге решил, что в этом нет необходимости. Я кэшировал как можно больше переменных перед обратными вызовами - старайтесь избегать слишком большого количества операций с фреймами данных (например, df [df [column] == var]), особенно если это для связанных обратных вызовов.

После множества тестов и изменений (если быть точным, 40 версий) мое приложение стабильно работало на 600 Мбайт.

Окончательная приборная панель

Готово! Подводя итог, можно сказать, что панель данных не должна быть вашим вариантом для анализа данных, но когда существует слишком много просмотров, чтобы показать или изучить себя, тогда это хороший вариант.

Что следует помнить:

  1. Начните с одной ключевой цели / задачи панели инструментов.
  2. Не торопитесь, собирая и согласовывая данные, и посмотрите, что уже было сделано.
  3. Тщательно выбирайте диаграммы и дизайн обратных вызовов, заранее составьте план макета!
  4. Развертывайте по мере продвижения, а не массово в конце. Будет сложно оптимизировать все сразу.

В то время, когда у нас появляется все больше и больше открытых данных, я призываю всех начать изучать данные с более человечной точки зрения, а не просто сосредотачиваться на том, что вы можете или не можете предсказать. Удачи!

Все высказанные здесь мнения принадлежат мне и не отражают точку зрения тех, с кем я связан.