Рубрики
Без рубрики

Автоматическая отчетность в Python – часть 3: Упаковка его

Как указано в моих предыдущих постах (Часть I и Часть II доступна на этом прекрасном веб-сайте), цель этого … Помечено с Python, Git, начинающим, планированием.

Автоматическая отчетность в Python (3 части серии)

Как описано в моих предыдущих постах (Часть I и Часть II, доступная на этом прекрасном веб-сайте), целью этого проекта является создание автоматического инструмента отчетности.

В этой серии руководств, результат, которого я стреляю, – это одна страница HTML, которая позволяет мне допросить и сравнивать вывод моделей машинного обучения.

На Заключение предыдущего учебника Инструмент отчетности фактически показывал некоторое подлинное использование! Это может принять ряд .csv Резюме аннотации машинного обучения файлов и вывод одного .html Страница, которая представлена информация, это форма, которая была … функциональной.

Есть три основных функция, которые я хотел бы добавить в инструмент на данный момент:

  1. Отчет выглядит невероятно скучно. Читаемость считается! Нам нужно улучшить E S T Х, T I C S отчета.
  2. Трудно копать в таблицы – в настоящее время это всего лишь 100 строк, представленные без инструментов для поиска. Некоторые основные функции поиска будут тарены.
  3. Наборы данных, которые мы хотим запустить отчет, в настоящее время жестко закодированы в скрипт. Это должно быть разделено, чтобы сделать инструмент немного более гибким.

Краткий комментарий

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

Но без дальнейшего ADO давайте возьмем трещину при совершенствовании эстетики.

Шаг семь – улучшение эстетики

Те из вас, что с вами с пониманием HTML-страниц могут знать, что на следующем: простыни каскадных стилей, известные чаще, как CSS.

Принимая ваши первые шаги вниз по пути

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

Итак, если это ваше первое реальное введение в CSS, позвольте мне снять то же путь, который я бы порекомендовал в изучении любых новых технологий:

  • Сделайте некоторое чтение фона на основах CSS. Ударить Википедия Отказ Если вы увлекаетесь, нажмите стандарт CSS! Никогда не бойся Google «Простое введение в [тему]».
  • Как вы читаете и исследовать, обратите внимание на потенциальные хорошие ресурсы будущей информации. Я бы побудил всех взглянуть на “УДИВИТЕЛЬНЫЙ СПИСОК” Относится к вашей теме – и в случае, потрясающий список CSS – здесь Отказ
  • С базовым пониманием того, что, черт возьми, под вашим поясом, играйте в контент вашего сердца с локальными файлами и реализуйте столько, сколько можете в локальных нулях. В этом случае создайте маленький (или большой?) HTML-страницы и выясните, как аккуратно структурировать CSS. Я нахожу, что это действительно помогает познакомиться с некоторыми практическими реалиями и проблемами работы с языком, прежде чем начать погружение в рамки.

Быть немного больше наемным

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

Вместо этого мы можем хотеть быстро спрыгнуть от чужой CSS Framework. К счастью, есть ряд этих доступных, с большим количеством их сосредоточения на том, чтобы быть «минимальным». Быстрый Поиск Google Должен заставить вас начать этот путь.

Интеграция

Как файл CSS будет интегрирован наш отчет? Есть несколько вариантов, которые обычно в игре:

  • Загрузите файл CSS и сохраните его в качестве внешнего файла. Преимущество в том, что у нас есть наш .html и .css Файлы аккуратно разделены, и у нас полный контроль над обоими; Гораздо более значительный недостаток заключается в том, что теперь, если мы хотим переместить наш отчет вокруг, мы должны перетащить кучу .css Файлы вокруг с ним.
  • Используйте Сеть доставки контента (CDN) Копия файла CSS Отказ Большинство рамки будут предлагать ссылку CDN для их файла: это, по сути, это связано с эффективной, легко доступной копией данных. Преимущество заключается в том, что вы можете получить CSS и идущий на вашей странице, просто бросая одну ссылку в Раздел вашего .html , нет мусора и суета с местными файлами. Недостатком является то, что у вас нет контроля файла, а требуется подключение к Интернету.
  • Слегка более сложный вариант – иметь локальные копии файла CSS, а затем напишите их в .html файл. Это, вероятно, может быть сделано относительно легко и устойчиво, если у нас умно с нашей шаблоном. Преимущество заключается в том, что у нас будет наш отчет в одном файле, и Это не требует использования интернет-соединения; Недостатком заключается в том, что он потребует немного больше усилий для настройки. (Это обычно используется подход при создании автономных версий интерактивных страниц. Написать Jupyter ноутбук к .html Проверьте файл, и вы найдете все CSS и JavaScript Magic, упакованные в раздел.)

На этом ранней стадии прототипирования я предпочитаю использовать CDNS, если это возможно. Преимущество возможности помешать каркасам CSS, просто изменив единую строку кода и не надо надо надоедать локальные файлы, стоит того, чтобы не могли играть и редактировать рамки. Оптимизация (в форме возможности автоматически интегрировать CSS в файл .html ) может прийти немного позже.

Начать с того, я собираюсь использовать Миллиграмм легкий маленький каркас. Чтобы начать использование метода CDN, я просто следую прилагаемым инструкциям для интеграции в CDN. Под нашей Шаблоны/доклады .html Файл, я добавлю реквизитные ссылки в раздел:

Report.html.





    
    {{ title }}
    
    
    


И вдруг, наша равнина, в начале 90-х гляжа веб-страница была преобразована во что-то более приятнее глаз:

Но мы отмечаем, что здесь что-то еще не совсем прямо здесь – прежде всего, почему страница (и таблица в частности) всегда занимает всю ширину окна? Почему это не выглядит прямо на мобильном?

Оказывается, просто добавляя кучу .css Файлы не достаточно. Нам нужно убедиться, что макет наших .html Страницы соответствуют тому, что ожидается от .css макет.

HTML-макеты

Как и большинство тем в этом пространстве, макет вашей HTML-страницы является разумно Интуитивно понятная концепция, в то время как одновременно является проблемой, в которой вы проводите лет. Что делает его немного более сложным, это то, что, несмотря на то, что есть ряд несколько фрагментарный объяснения Я изо всех сил пытался найти простой и/или целостный на поле (хотя Это объяснение в настоящее время мое любимое нежное введение, а Mozilla Mozilla , кажется, довольно тщательно).

Для краткости я собираюсь оставить большую часть дальнейшего чтения для вас, читателя (извините!), А вместо этого сосредоточиться на том, что миллиграмма ожидает.

Если мы Осмотрите код из Страница миллиграмма , мы увидим, что в , мы видим HTML сайта структурирована примерно как:


    

Теперь, основываясь на некоторых из показаний в вышеуказанных ссылках, и предполагая, что это структура, которую миллиграмма ожидается, мы можем применить ту же структуру для нашего собственного доклада, давая нам что-то вроде следующее:

Report.html.





    
     
    
    {{ title }}
    
    
    


    

{{ title }}

This report was automatically generated.

{% for section in sections %} {{ section }} {% endfor %}

Summary_section.html.

Quick summary

Accuracy

{% for model_results in model_results_list %}

{{ model_results.model_name }} analysed {{ model_results.number_of_images }} image(s), achieving an accuracy of {{ "{:.2%}".format(model_results.accuracy) }}.

{% endfor %}

Trouble spots

{% for model_results in model_results_list %}

{{ model_results.model_name }} misidentified {{ model_results.number_misidentified }} image(s).

{% endfor %}

{{ number_misidentified }} misidentified image(s) were common to all models.

table_section.html.

{{ model }} - Model Results

Results for each image as predicted by model '{{ model }}', as captured in file '{{ dataset }}'.

{{ table }}

Мы уже структурировали этот отчет, чтобы стать коллекцией в значительной степени независимой коллекции разделов – мы даже использовали эту терминологию! – Так что это не огромная драма, чтобы добавить <Раздел> Теги к системе.

Доказательство того, что это работает

Беги Autoreporting.py и проверьте отчет – попробуйте оба на полноэкранном, так и на Имитация мобильного экрана Отказ

Прогресс! Это преимущество использования хорошо выполненного макета.

Статус GitHub

Oooft. Это было много чтения фона для не огромного количества кода. Все равно, проект должен выглядеть как Это Отказ

Шаг восьмерка – сделание наших таблиц интерактивных

Хорошо. Так что теперь у нас есть наши столы, и они выглядят довольно хорошо – вызов – это то, что они не интерактивны. Например, было бы замечательно иметь функциональность фильтровать по категории или свернуть на определенное изображение.

Теперь, как при изучении CSS, у нас есть пара вариантов. Конечно, мы можем исследовать возможность создания всех этого самих – есть много примеров, и они не ужасно сложно Отказ Но, если мы будем прагматичны (или прессовать бизнес-потребности!) Мы, вероятно, можем найти предварительно построенный пакет того, что нам нужно.

После немного гутогола я наткнулся на Детали – Это плагин для Jquery , очень распространенная структура JavaScript. Детали выглядят так, как будто он охватывает большую часть функциональности, которые нам нужны, и обеспечивает богатство расширения и плагины Для любой из функций у нас нет. В целом, многообещающему кандидату.

Реализация источников данных

К счастью, получается, что реализующие источники данных относительно прямы. С ровной страницы Детали Сайт, мы видим, что общие принципы, которые нам нужно:

  • Хотя не прописано явно – DataTables – плагин jQuery – поэтому сначала нам нужно загрузить jQuery .js файл.
  • Затем мы загрузим таблицы данных .js и .css файлы.
  • Наконец, мы называем функцию данных данных, указывая на него на HTML я D таблицы, которую мы хотим добавить функциональность.

Это все относительно простые, с несколькими очень разрешимыми морщинами:

  1. Наши столы не имеют ID Теги, чтобы обратиться.
  2. Нам нужен способ вызвать функцию данных и указать его на ID таблицы, таким образом, который подходит с нашей системой шаблонов.

Давайте обратимся к этим за другим.

Импорт соответствующих файлов

Прежде чем мы доберемся до наших морщин, давайте ударим наши основы. Поскольку мы ранее импортировали наши файлы с CDNS, мы сделаем то же самое для jQuery.

Давайте обновим Раздел Шаблоны/доклады .html и добавьте ссылки:

Report.html.



    
    
    {{ title }}
    
    
    
    
    
    


Добавление тегов ID в таблицы

Нам нужно добавить ID Тег на <таблица> Объекты в нашем докладе. Как мы можем это сделать?

Ну, давайте на работу от Шаблоны/table_section.html файл. В этом файле отметим, что мы вставляем наши полностью сформированные таблицы HTML через {{таблица}} вставлять.

{{таблица}} Вставка генерируется в Autoreporting.py Когда мы называем get_results_df_as_html метод ModelResults класс. Этот метод занимает Пандас DataFrame и преобразует его в строку HTML, используя Dataframe.to_html функция .

Если мы осмотрим документы для этой функции, мы видим, что есть дополнительный аргумент table_id Отказ Ах, да, крутой человек! Если мы пройдем название модели в качестве этого аргумента, таблица HTML будет сгенерирована с помощью ID что мы хотим. ModelResults Класс уже имеет model_name в качестве атрибута, чтобы мы могли включить это:

class ModelResults:

    # ...

    def get_results_df_as_html(self):
        """
        Return the results DataFrame as an HTML object.
        :return: String of HTML.
        """
        html = self.df_results.to_html(table_id=self.model_name)
        return html

Вы можете запустить Autoreporting.py и проверьте таблицы, которые генерируются для подтверждения того, что они действительно имеют имя модели как ID Отказ

Легкий! Просто вопрос отслеживания его от конечного результата HTML к фактическому источнику в рамках кода.

Вызов функции данных

Нам нужно позвонить в таблицу данных, перечисленные выше, указывая на соответствующую ID Как мы только что сгенерировали. Фактический код для вызова функции довольно прост. Вопрос в том, куда мы его положили?

Эта задача имеет пару ограничительных ограничений на нее.

  • Нам нужно позвонить в функцию для генерации DataTable с использованием имени модели – что-то вроде этого:
$(document).ready( function () {
    $('#VGG19').DataTable();
} );
  • Традиционно JavaScript размещается либо в раздел, хотя это несколько Спорное обсуждение. Обратите внимание, что это традиция – На самом деле он будет везть где угодно.

Это вызов из-за структурирования нашего шаблона. Мы хотим разместить вызов JavaScript для DataTables в , что в Шаблоны/доклады .html. . Прямо сейчас, когда Report.html оказывается под Главная () Функция в Autoreporting.py , это ничего не знает о именах моделей: Визуализация () Вызов только имеет аргументы для заглавие , общий заголовок отчета, а Разделы , список предварительно отображаемых строк HTML готов к вставлению в документ. Нам просто нужно изменить Autoreporting.py пройти в названиях модели и настроить Report.html соответственно. Мы настраиваем наши файлы таким образом:

autoreporting.py

def main():

    # ...

    # Production and write the report to file
    f.write(base_template.render(
        title=title,
        sections=sections,
        model_results_list=[vgg19_results, mobilenet_results]
    ))

Report.html.


    
    

Бинго-Банко: Когда мы видим Report.html. Вызывы оказать функции DataTable для каждой существующей таблицы. Отлично!

И теперь, если мы бежим Autoreporting.py И проверьте вывод, мы получаем что-то подобное:

Теперь мы можем заказать наши таблицы, поиск категорий, фильтр по имена изображения – у нас есть некоторые богатые функциональные возможности, с помощью Более доступно через расширения .

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

Статус GitHub

Ваше репо должно выглядеть немного такое Это Отказ

Шаг девять – упаковка его

Ака шаг последнее.

Хорошая новость: у нас есть функциональность, которую мы хотим и нуждаются. Мы можем взять .csv Файл или два и ударить интерактивный отчет.

Плохая новость: Мы жестко заканчивали его двумя файлам, Vgg19_results.csv. и MOBILENET_RESULSS.CSV , который ограничивает функциональность.

Поэтому окончательный шаг для этой разведки для превращения этого жесткого кодированного сценария в инструмент, который можно назвать из командной строки. Мы хотим иметь возможность позвонить в отчет и произвольное количество .csv Файлы и имеют отчет. Так что, если мы позвонили нашему сценарию и указали соответствующие .csv Файлы, мы получим отчет успешно написано на /Выходы Папка – выглядит немного подобно этому в командной строке:

$ python autoreporting.py VGG19_results.csv MobileNet_results.csv
Successfully wrote "report.html" to folder "outputs".

Это может быть достигнуто, используя аргументы командной строки – или, чтобы поставить его просто просто, команды, которые следуют за вызовом Python. (В приведенном выше примере первого аргумента является AutoReporting.py , наш скрипт. Вторая и третья командная строка аргументов являются Vgg19_results.csv и MOBILENET_RESULSS.CSV , соответственно. ) У нас есть пара главных способов, которыми мы можем подойти к этому:

  • Мы можем свернуть аргументы вручную, используя sys.argv. . В этом подходе нет абсолютно ничего плохого, sys.argv. действительно довольно просто использовать.
  • Мы можем использовать анализатор, как argparse. , в первую очередь, чтобы помочь в создании сообщений о помощи и ошибках.

Потому что я не использовал argparse Раньше я заинтересован в том, чтобы пойти и тестировать его для этих целей.

Реализация Аргпарсе

Большинство всех, с которыми мы хотим работать в Argparse, обрабатывается в Главная () Позвоните в Autoreporting.py Отказ Чтобы сделать эту работу, мы собираемся:

  • Определите и разбирать аргументы, которые мы заинтересованы в (конкретно, FilePaths к результатам .csv файлы), используя argparse ;
  • Преобразуйте эти фийпаты в ModelResults объекты, которые мы можем использовать для создания наших отчетов;
  • Адаптировать наш существующий код для вывода отчетов, используя эти ModelResults объекты.

Итак, прежде всего, нам нужно убедиться, что argparse импортируется. Это была часть стандартной библиотеки, поскольку Python 3.2.

autoreporting.py

import argparse
# ...

Далее, внутри Главная () , мы определим парсер – мы говорим, как мы хотим интерпретировать аргументы командной строки. Этот код адаптирован довольно быстрым умным от Демо в argparse документы . У нас на самом деле есть только один аргумент, как argparse Определяет это – просто фийпаты нашим результатам .csv файлы. Ключевая вещь, которую следует отметить, что мы устанавливаем Наргс аргумент на "+" указывает на то, что мы можем иметь undefined Количество аргументов такого рода, но нам нужно хотя бы один Отказ

Когда мы называем parser.parse_args () Все аргументы аккуратно возвращаются как Пространство имен Объект, который делает входные данные очень простыми для доступа, как мы увидим в следующих шагах.

# ...

def main():
    """
    Entry point for the script.
    Render a template and write it to file.
    :return:
    """
    # Define and parse our arguments
    parser = argparse.ArgumentParser(description="Convert results .csv files into an interactive report.")
    parser.add_argument(
        "results_filepaths",
        nargs="+",
        help="Path(s) to results file(s) with filename(s) '_results.csv'."
    )
    args = parser.parse_args()

От args , Пространство имен Объект, мы можем вытащить фийпаты и использовать их для генерации ModelResults объекты.

args.result_filepaths Удерживает список наших файлов, которые мы указали, должен указывать на имена файлов в формате _results.csv . Мы используем OS.PATH Модуль для манипулирования этого FilePath, извлечь название модели и генерировать ModelResults Объект, добавляя его в список под названием Model_Results Как мы идем.

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

    # Create the model_results list, which holds the relevant information
    model_results = []
    for results_filepath in args.results_filepaths:
        results_root_name = os.path.splitext(os.path.basename(results_filepath))[0]
        model_name = results_root_name.split("_results")[0]
        model_results.append(
            ModelResults(model_name, results_filepath))

Логика для установленного пересечения – как мы выясним, какие изображения распространены во всех файлах результатов – было изменено для учетной записи того факта, что у нас сейчас есть произвольное количество ModelResults. Объекты в списке.

Чтобы сделать эту работу, мы быстро извлекаем missisefied_images Свойство каждого объекта, используя Понимание списка А затем рассчитайте пересечение множеств на основе этого результирующего списка. (Обратите внимание, что мы должны использовать ведущую Asterix ( * ), когда мы называем Set. Internersection () Так что каждый член списка передается как индивидуальный аргумент).

    # Create some more content to be published as part of this analysis
    title = "Model Report"
    misidentified_images = [set(results.misidentified_images) for results in model_results]
    number_misidentified = len(set.intersection(*misidentified_images))

Все ниже этой точки относительно согласуется с нашей предыдущей версией, но теперь мы используем тот факт, что у нас есть наш ModelResults Объекты, уже упакованные в Model_Results список.

    # Produce our section blocks
    sections = list()
    sections.append(summary_section_template.render(
        model_results_list=model_results,
        number_misidentified=number_misidentified
    ))
    for model_result in model_results:
        sections.append(table_section_template.render(
            model=model_result.model_name,
            dataset=model_result.dataset,
            table=model_result.get_results_df_as_html())
        )

    # Produce and write the report to file
    with open("outputs/report.html", "w") as f:
        f.write(base_template.render(
            title=title,
            sections=sections,
            model_results_list=model_results
        ))
    print('Successfully wrote "report.html" to folder "outputs".')

Oooft! Со всеми объяснениями это выглядит немного сложным. Однако, когда вы сравниваете этот код до предыдущего Commit, вы увидите, что здесь нет многое значение, которое на самом деле значительно отличается от здесь – мы действительно сохранили основные принципы одинаковы и просто играли с упаковкой.

Статус GitHub

Ваш проект должен выглядеть немного Как этот Отказ

Конец?

В самом начале первого поста я указал, что целью этого проекта состояла в том, чтобы создать автоматическую отчетную инструмент HTML, где результат был один автономный HTML-файл, с информацией и интерактивностью.

Ну, это сделано! У нас есть инструмент, который может принять произвольное количество стандартных файлов результатов и вымирает отчет, который вызывает их в интерактивный формат.

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

Это значит, что мы закончили? Это зависит, правда.

Что касается следующего?

На данный момент у нас есть инструмент, который работает для очень узкого использования, и предполагает Идеальные входы и Идеальная операция от пользователя. Теперь, если вы используете такой инструмент только для себя, и входы в инструмент вполне последовательны, то это действительно может быть совершенно удовлетворительным – поэтому больше не будет выполнено, у вас есть что-то подходящее для цель.

Но, конечно, есть какое-либо количество способов работать, чтобы продлить и укрепить этот инструмент. Как я писал этот урок, я сделал заметки на некоторых из них. Бег свободным от проще к более сложному, вот несколько заметок и идей:

  • Можем ли мы добавить аргумент командной строки по умолчанию с argparse Это позволяет нам указывать название отчета?
  • Наше .csv Входы должны быть названы в идеальном согласованном формате. Как мы можем реструктурировать наши входы, чтобы мы могли определить название модели, а не прочитать из имени файла?
  • Как мы можем сделать этот скрипт командной строки, который можно запускать в любой точке нашей машины – не только в папке сценарий? Если наши данные генерируются и хранятся в другом месте, это, безусловно, будет более полезным иметь возможность позвонить Авторепорт На терминале, а не отследить назад туда, где хранится скрипт.
  • В своей текущей форме мы анализируем изображения – можем ли мы добавить функциональность на Показать Изображения, которые мы анализируем? Это было бы здорово для создания гипотез для Почему Модель не удалась.
  • Наши отчеты требуют подключения к Интернету каждый раз, когда они открываются. В рамках процесса шаблонов, не могли бы мы снять файлы JavaScript и CSS и встроить их в наши файлы?

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

Благодарность и призыв к действию

Это был первый учебник этой области, который я когда-либо написал. У меня было очень весело, и перефразируя Сигур Рос, это было Хорошее начало Отказ

Но я действительно стремился слышать, какие части этого Вы С Учебник-ридер, наслаждался и какие части были сложные или неясные. Не стесняйтесь бросить комментарий или пришлите мне сообщение о том, что сработало и что не так.

Увидимся в следующий раз!

Автоматическая отчетность в Python (3 части серии)

Оригинал: “https://dev.to/goyder/automatic-reporting-in-python—part-3-packaging-it-up-1185”