PHP-Дайджест № 193 (16 – 30 ноября 2020)

Парад релизов: обновление языка — PHP 8.0, а также Xdebug 3, DBAL 3.0, Bref 1.0, Symfony 5.2, Flysystem 2.0. Первый принятый RFC для PHP 8.1, долгосрочная поддержка PHPUnit, порция полезных инструментов, подкасты, стримы, статьи.

Приятного чтения!

PHP 8

Новости и релизы

  • Xdebug 3 — Большое обновление популярного отладчика. Теперь он быстрее в работе и значительно проще в конфигурации.

    Для старта достаточно одной опции xdebug.mode, а дефолтный порт сменен на 9003, чтоб не было конфликта с PHP-FPM. Подробнее в руководстве по обновлению.

    Сравнительные бенчмарки Xdebug 2 и Xdebug 3 показывают значительный прирост производительности. Для сбора покрытия он даже быстрее, чем phpdbg, хоть и медленнее PCOV.

  • Bref 1.0 — Релиз инструмента, который облегчает создание serverless-приложений на PHP и AWS Lambda. Кстати, теперь с поддержкой WebSocket — удержание соединения берет на себя API Gateway.
  • doctrine/dbal 3.0 — После 10 лет с выхода DBAL 2.0 наконец-то мажорное обновление популярной библиотеки для работы с базами данных. Короткий обзор есть в анонсе релиза. Главные изменения касаются отвязки DBAL от PDO. Все fetch-методы перенесены из класса Statement в новый Result.
  • thephpleague/flysystem 2.0 — Обновление библиотеки, абстрагирующей работу с файловыми системами. Что нового в версии 2.
  • PHP 7.4.13
  • PHP 7.3.25
  • В твиттере продолжились споры о том, стоит ли поддерживать старые версии PHP в опенсорс инструментах. Никита написал, что инструменты, в которых минимальная версия PHP повышается слишком резко, в действительности приносят больше проблем на пути к обновлению PHP.

    .
    Ранее эта же проблема обсуждалась, когда Марко Ocramius бампнул версию в своем пакете Ocramius/PackageVersions до 7.4 (уже и до 8.0). В результате чего в Composer 2 пакет заменили на форк composer/package-versions-deprecated.

    Так или иначе, а PHPUnit 9 и PHPUnit 8.5 получат Life Support. Это значит, что в них будет гарантирована работа на PHP 7.3 (7.2 соответственно) и всех последующих версиях PHP.

PHP Internals

  • check [RFC] Explicit octal integer literal notation — Не успели выпустить PHP 8.0, а уже принят первый RFC для PHP 8.1! В следующей версии языка восьмеричные числа можно будет записывать с префиксом 0o.
    0o16 === 14; // true 016 === 0o16; // true 

Инструменты

  • phpsandbox.io — Аналог codepen/jsfiddle только для PHP. Веб-сайт для быстрого тестирования и демонстрации кода. Кроме голого PHP можно сделать код на Laravel, ReactPHP или импортировать любой проект с Гитхаба.
  • beyondcode/httpdump — Приложение на Laravel для отладки водящих HTTP-запросов (отладка веб-хуков и т.п.). Создает случайные URL и дампит в красивом виде все запросы к ним. Демо httpdump.app.
  • clue/php-socket-raw — Легковесная ООП-обертка для низкоуровневого расширения сокетов PHP (ext-sockets).
  • zenstruck/foundry — Фабрика для создания удобных фикстур с автодополнением в IDE для Symfony и Doctrine.
  • spatie/backtrace — Обертка над debug_backtrace() для удобной работы со стеком вызовов.
  • nette/tracy — Инструмент для отладки: дебагбар, красивые ексепшены, логирование, профилирование, все в одном.
  • JetBrains/phpstorm-attributes — В PhpStorm 2020.3 будут из коробки доступны несколько атрибутов PHP 8. Теперь они вынесены в отдельный пакет.

Symfony

Laravel

Разное

Аудио/Видео

Спасибо за внимание!

Если вы заметили ошибку или неточность — сообщите, пожалуйста, в личку хабра или телеграм.

Больше новостей и комментариев в Telegram-канале PHP Digest.

Прислать ссылку
Поиск ссылок по всем дайджестам
Предыдущий выпуск: PHP-Дайджест № 192

ссылка на оригинал статьи https://habr.com/ru/post/530562/

Spark 3.0: новые возможности и примеры их использования – часть 1

К нашей новой программе «Apache Spark для дата-инженеров» и вебинару о курсе, который пройдет 2 декабря, мы подготовили перевод обзорной статьи о Spark 3.0.

Spark 3.0 вышел с целым набором важных улучшений, среди которых: повышение производительности с помощью ADQ, чтение бинарных файлов, улучшенная поддержка SQL и Python, Python 3.0, интеграция с Hadoop 3, поддержка ACID. 

В этой статье автор постарался привести примеры использования этих новых функций. Это первый первый материал о функциональности Spark 3.0 и у этой серии статей планируется продолжение.

В этой статье освещены следующие функции Spark 3.0:

  • Структура адаптивного выполнения запросов (AQE)

  • Поддержка новых языков

  • Новый интерфейс для структурированной потоковой передачи

  • Чтение бинарных файлов

  • Рекурсивный просмотр папок

  • Поддержка многозначного разделителя данных (||)

  • Новые встроенные функции Spark

  • Переключение на пролептический григорианский календарь

  • Data Frame Tail

  • Функция Repartition в SQL запросах

  • Улучшенная совместимость с ANSI SQL

Адаптивное выполнение запросов

Функция адаптивной регулировки запросов (AQE) – это, пожалуй, одно из самых существенных улучшений Spark 3.0. Она повторно оптимизирует и корректирует планы запросов, основываясь на статистике времени их выполнения, собранной во время обработки запросов.

До выхода версии 3.0 оптимизация в Spark происходила путем создания плана до начала выполнения запроса, а как только запросы начинали обрабатываться, Spark не проводил дальнейшей оптимизации с использованием метрик, собираемых в процессе выполнения запросов. AQE восполняет этот пробел, применяя второй уровень оптимизации, основанный на метриках, получаемых на каждом этапе.  

По умолчанию, функция адаптивной регулировки запросов (AQE) отключена. Для включения необходимо переключить конфигурацию spark.sql.adaptive.enabled на true. С включенной функцией AQE, Spark демонстрирует двукратное ускорение по данным TPC-DS по сравнению с версией Spark 2.4 

AQE в Spark 3.0 выполняет 3 важных функции:

  • Динамически объединяет разделы, что позволяет оптимизировать их количество

  • Преобразует join sort-merge в broadcast соединение 

  • Оптимизирует джойны со скошенными данными

Поддержка новых языков

В Spark 3.0 расширилась библиотека языков, теперь поддерживаются: 

  • Python3 (Python 2.x)

  • Scala 2.12

  • JDK 11

Помимо поддержки новых языков также добавилась поддержка Hadoop до 3 версии, Kafka до 2.4.1 и много других обновлений.

Новый интерфейс для Spark Structured Streaming

В web-интерфейсе Spark появилась новая вкладка Структурированной потоковой передачи для мониторинга стриминговых приложений. В этой вкладке отображается идентификатор запуска, статус, время запуска, продолжительность обработки каждого микро-пакета, а также текущая статистика. Это позволяет разработчику видеть, что происходит с потоковыми запросами и вовремя выявлять ошибки.

Вкладка содержит 2 раздела:

  • Активные потоковые запросы

  • Завершенные потоковые запросы 

Источник: Databricks

Раздел «Active Streaming Queries» отображает все текущие запросы, а раздел «Completed Streaming Queries» – все неудавшиеся и завершенные

По ссылке Run ID представлена подробная статистика потоковых запросов по следующим параметрам: скорость поступления данных, скорость обработки, строки ввода, продолжительность каждого пакета, время, затраченное на выполнение различных операций. Вы можете найти примеры, как устранить проблемы структурированной потоковой передачи в Databricks.

Источник данных для чтения бинарных файлов 

Spark 3.0 поддерживает источник данных в формате “binaryFile”, который позволяет считывать бинарные файлы.

С помощью источника binaryFile, DataFrameReader считывает форматы image, pdf, zip, gzip, tar и многие другие бинарные файлы. Каждый файл будет преобразован в отдельную запись в датафрейме, содержащую метаданные файла.  

val df = spark.read.format("binaryFile").load("/tmp/binary/spark.png")

df.printSchema()

df.show()

Выдает следующий результат

root

 |-- path: string (nullable = true)

 |-- modificationTime: timestamp (nullable = true)

 |-- length: long (nullable = true)

 |-- content: binary (nullable = true) 

+--------------------+--------------------+------+--------------------+

|                path|    modificationTime|length|             content|

+--------------------+--------------------+------+--------------------+

|file:/C:/tmp/bina…|2020-07-25 10:11:…| 74675|[89 50 4E 47 0D 0...|

+--------------------+--------------------+------+--------------------+

Функция рекурсивного просмотра папок

В Spark 3.0 теперь есть функция recursiveFileLookup, которая позволяет читать и загружать файлы из рекурсивных подпапок. После установки значения true для этой опции, DataFrameReader рекурсивно загружает файлы, перебирая все папки и подпапки по указанному пути.

spark.read.option("recursiveFileLookup", "true").csv("/path/to/folder")

Поддержка многозначного разделителя данных 

В Spark 3.0 поддерживается функция многосимвольного разделителя (||) при чтении и записи CSV файлов. К примеру, если у вас есть CSV файл с подобным содержанием:

 col1||col2||col3||col4

val1||val2||val3||val4

val1||val2||val3||val4

Он может считываться следующим образом:

 val df  = spark.read

      .option("delimiter","||")

      .option("header","true")

      .csv("/tmp/data/douplepipedata.csv")

В Spark 2.x многозначный разделитель не поддерживался, поэтому нам приходилось преобразовывать двойной разделитель в одинарный с помощью препроцессора. Попытки считывать файлы напрямую без препроцессора заканчивались следующей ошибкой:

 throws java.lang.IllegalArgumentException: Delimiter cannot be more than one character: ||

Новые встроенные функции Spark

К внушительному списку из сотен встроенных функций Spark SQL, третья версия Spark добавила новые. 

sinh,cosh,tanh,asinh,acosh,atanh,any,bitand,bitor,bitcount,bitxor,

booland,boolor,countif,datepart,extract,forall,fromcsv,

makedate,makeinterval,maketimestamp,mapentries

mapfilter,mapzipwith,maxby,minby,schemaofcsv,tocsv

transformkeys,transform_values,typeof,version

xxhash64

Переключение на Пролептический Григорианский календарь 

Предыдущая версия Spark поддерживает даты в формате Юлианского и Григорианского календаря: для дат до 1582 года используется Юлианский календарь, а для более поздних дат – Григорианский.

В JDK 7 и более ранних версиях используется тот же принцип посредством java.sql.Date API. В JDK 8 представлен java.time.LocalDate API с опцией пересчета дат по Пролептическому Григорианскому календарю. 

Теперь в Spark 3.0 тоже есть опция переключения на Пролептический Григорианский календарь, который уже давно используется такими системами обработки данных как Pandas, R и Apache Arrow. Если вы оперируете датами в периоде после 15 октября 1582 г., то все функции Date&Timestamp, которые работали в Spark до версии 3.0, будут работать корректно. Ваши результаты могут отличаться, если вы используете даты в периоде до 15 октября 1582 г.

Вместе с опцией переключения на Пролептический Григорианский календарь в Spark 3.0 представлены новые Date & Timestamp функции: 

makedate(), maketimestamp(), makeinterval(). 

makedate(year, month, day) – эта функция возвращает дате из входных аргументов поля <год>, <месяц> и <число>. 

makedate(2014, 8, 13)

//returns 2014-08-13.

maketimestamp(year, month, day, hour, min, sec[, timezone]) – эта функция возвращает Timestamp из полей <год>, <месяц>, <час>, <мин>, <сек>, <часовой пояс>. 

maketimestamp(2014, 8, 13, 1,10,40.147)

//returns Timestamp 2014-08-13 1:10:40.147

maketimestamp(2014, 8, 13, 1,10,40.147,CET)

makeinterval(years, months, weeks, days, hours, mins, secs) создает интервал между значениями 

Отправка недопустимых дат в makedate() и make_timestam() возвращает 0.

Новая опция DataFrame.tail() 

В Spark есть действие head(), которое возвращает элементы из начала дата фрейма, но нет действия tail(), которое уже поддерживается Pandas в Python. В датафреймы Spark 3.0 действие tail() добавили и теперь есть возможность возвращать определенные элементы из его хвоста. Действие tail() возвращает scala.Array[T] в Scala. 

 

val data=spark.range(1,100).toDF("num").tail(5)

data.foreach(print)

//Returns

//[95][96][97][98][99]

Функция repartition в SQL запросах

В SQL запросах Spark отсутствовали некоторые actions, присутствующие в  Dataset/DataFrame, например, в Spark SQL не поддерживалась функция repartition() для датасета. Репартишен теперь доступен внутри SQL-выражения. Функция позволяет уменьшить или увеличить количество партиций. 

 

val df=spark.range(1,10000).toDF("num")

println("Before re-partition :"+df.rdd.getNumPartitions)

df.createOrReplaceTempView("RANGE¨C17CTABLE")

println("After re-partition :"+df2.rdd.getNumPartitions)

//Returns 

//Before re-partition :1

//After re-partition :20

Улучшенная совместимость с ANSI SQL 

Поскольку Spark часто используется data-инженерами, которые уже знакомы с ANSI SQL, в Spark 3.0 поработали над улучшением совместимости с ним. Вы можете активировать эту функцию, установив true в spark.sql.parser.ansi.enabled Spark конфигурации.


Програмы Newprolab по Apache Spark:

Apache Spark для дата-инженеров (Scala). Интенсивный практический курс из 11 занятий, 5 лабораторных.

Apache Spark (Python). Модуль в составе курса «Специалист по большим данным». 6 занятий, 5 лабораторных.

ссылка на оригинал статьи https://habr.com/ru/company/newprolab/blog/530568/

История презентаций: эпоха до появления Powerpoint (часть 1)

image

Рассказываем, как развивались способы создания презентаций до появления привычных нам сервисов.

Мы привыкли делать презентации в специальных программах или онлайн-редакторах: у нас есть Powerpoint, Google Slides, Keynote или Prezi. Среди них самым популярным изобретением стал именно Powerpoint: этот сервис верой и правдой служит нам уже более 30 лет. Но что было до его появления? Презентации тоже были. Давайте посмотрим, с помощью каких технологий их создавали.

Какими были первые презентации?

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

image
Alt: Витражи представляли собой серию последовательных изображений

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

image
Alt: В научных кругах доски активно использовали для презентации и обсуждения новых идей – на них показывали расчеты и схемы

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

Что изменилось с появлением проекторов?

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

Как работал кодоскоп?

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

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

image
Alt: Вот так выглядит кодоскоп. Это устройство увеличивало оригинал изображений в 10-20 раз

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

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

Как работал диапроектор?

Диапроектор или слайд-проектор – это устройство, в которое вставляли несколько цветных изображений размером 24х35 мм. Их изготавливали на фотопленке или на специальных стеклянных пластинах. Принцип действия устройства также строится на освещении – сначала использовали лампы накаливания, а с 1980-х годов – галогенные лампы.

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

image
Alt: Так выглядит диапроектор. Картинки для отображения вставляются в ячейки и поочередно сменяются

С помощью диапроектора появилась возможность показывать фотографии и цветные слайды. Эти слайды готовили художники, они были красиво оформлены, содержали иллюстрации и инфографику. В целом, возможности оформления таких презентаций были достаточными для полноценных выступлений. Кроме того, появилась возможность одновременно загружать в проектор до 80 слайдов – для этого были созданы карусельные диапроекторы.

image
Alt: В карусели можно было компактно разместить множество слайдов – с такими диапроекторами можно было делать длинные подробные презентации

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

Как проходили выступления?

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

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

image
Alt: Изображения, полученные с помощью кодоскопа, не отличаются красочностью

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

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

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

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

Как выглядели слайды?

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

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

image
Alt: Перед вами презентация General Electric, показанная в 1958

Конечно, дизайн середины прошлого века в чем-то уступал современным возможностям. О трехмерной инфографике или сложных фотоколлажах говорить не приходится: только цветные заливки, простые изображения и текст:

image
Alt: Это слайд с презентации IBM’s Premiere of Products (1959)

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

image
Alt: Такими были слайды в презентации Packing, a Recurring, Recursive Problem (1976)

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

image
Alt: Презентация IBM (1979)

Выводы

  • Презентация – более широкое понятие, чем набор привычных нам слайдов. Это способ передачи информации визуальными средствами. В широком смысле презентацией можно называть наскальные рисунки или даже церковные витражи.
  • Первым устройством для отображения слайдов на экране стал кодоскоп. Он позволял делать черно-белые слайды, состоящие преимущественно из текста.
  • Цветные слайды демонстрировали с помощью диапроектора, над их оформлением трудились художники.
  • С помощью нескольких диапроекторов можно было создавать незатейливую анимацию. Но эта технология стоила дорого и требовала тщательной подготовки к выступлению.
  • Возможности оформления слайдов уступали современным, но уже активно использовались иллюстрации, инфографика и обработка фотографий.

ссылка на оригинал статьи https://habr.com/ru/post/527162/

Аудит чат-ботов

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

В других сферах чат-боты также хорошо себя зарекомендовали: в медицине они могут провести опрос пациента, передать специалисту симптомы и записать на прием к врачу для установления диагноза. В логистических компаниях чат-боты помогут согласовать дату доставки, сменить адрес и выбрать удобный пункт выдачи. В крупных интернет-магазинах чат-боты частично взяли на себя сопровождение заказов, а в сфере сервисов каршеринга чат-бот выполняют до 90% задач оператора. Однако, претензионную работу чат-боты решать пока не умеют. Негативный фидбек и спорные ситуации по-прежнему ложатся на плечи операторов и специалистов.

Таким образом, большинство растущих бизнесов уже активно используют чат-боты для работы с клиентами. Однако, польза от внедрения чат-бота часто варьируется: в одних компаниях уровень автоматизации достигает 90%, в других компаниях он составляет лишь 30-40%. От чего это зависит? Насколько хорош этот показатель для бизнеса? Есть ли способы повысить уровень автоматизации чат-бота? В данной статье будут рассмотрены вопросы, которые помогут разобраться в этом.

Бенчмаркинг

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

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

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

Необходимо сформировать список вопросов для проверки (не менее 50 вопросов, разделённых на несколько тематик):

  • Вопросы по банковским услугам, например: «Какие у вас ставки по вкладам?», «Как перевыпустить карту?» и пр.
  • Справочная информация, например: «Какой сейчас курс валют?», «Как получить кредитные каникулы?» и пр.
  • Уровень понимания клиента. (Устойчивость бота к опечаткам, ошибкам восприятие разговорной речи), например: «Я поетря карту, чтро мне делаьь?», «Пополнить мобилу» и пр.
  • Разговор на отвлечённые темы, например: «Расскажи анекдот», «Чем заняться во время самоизоляции?» и пр.

Примечание: данные тематики вопросов приведены в качестве примера и могут быть расширены или изменены.

Эти вопросы следует задать своему чат-боту, а также чат-ботам конкурентов. После написания вопроса возможны 3 варианта результата (в зависимости от результата проставляется соответствующий балл):

  • бот не распознал вопрос клиента (0 баллов);
  • бот распознал вопрос клиента, но только после уточняющих вопросов (0,5 балла);
  • бот распознал вопрос с первой попытки (1 балл).

Если чат-бот перевел клиента на оператора, то вопрос также считается не распознанным (0 баллов).

Далее суммируется количество баллов, набранных каждым чат-ботом, после чего рассчитывается доля корректно распознанных вопросов по каждой тематике (низкая – менее 40%, средняя – от 40 до 80%, высокая – более 80%), и составляется финальный рейтинг. Результаты можно представить в виде таблицы:

Предположим, по результатам бенчмаркинга чат-бот банка занял второе место. Какие выводы можно сделать? Результат не самый лучший, но и не худший. Опираясь на таблицу, можно сказать о его не самых сильных сторонах: во-первых, требуется доработка алгоритмов для корректного распознания вопросов клиента (чат-бот не всегда понимает вопросы клиента, содержащие ошибки и опечатки), а также не всегда поддерживает диалог на отвлеченные темы. Более детальную разницу можно увидеть при сравнении с чат-ботом, занявший первое место.

Чат-бот, занявший третье место, проявил себя хуже: во-первых, требуется серьёзная доработка базы знаний по вопросам банковских услуг и справочной информации, во-вторых, он слабо обучен для диалога с клиентом на отвлеченные темы. Очевидно, что уровень автоматизации такого чат-бота находится на более низком уровне по сравнению с конкурентами, занявшие I и II места.

Таким образом, по результатам проведения бенчмаркинга были выявлены сильные и слабые стороны в работе чат-ботов, а также проведено сравнение конкурирующих чат-ботов между собой. Следующим шагом является выявление этих проблемных мест. Как этого достичь? Рассмотрим некоторые подходы, основанные на анализе данных: AutoML, Process-mining, DE-подход.

AutoML

В настоящее время искусственный интеллект уже проник и продолжает проникать по многие сферы бизнеса, что неминуемо влечет за собой повышенный спрос на компетенции в области DataScience. Однако, спрос на таких специалистов растет быстрее, чем уровень их квалификации. Дело в том, что разработка моделей машинного обучения занимает много ресурсов и требует не только большого объема знаний от специалиста, но и значительных временных затрат на построение моделей и их сравнение. Чтобы сократить давление, создаваемое дефицитом, а также сократить время на разработку моделей, многие компании начали создавать алгоритмы, способные автоматизировать процесс работы DataScientist’ов. Такие алгоритмы получили название AutoML.

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

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

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

Для начала произведем разметку диалогов клиента с чат-ботом. В каждом диалоге оставляем только сообщения от клиентов. Если в сообщении клиента прослеживается негатив в сторону чат-бота, или не понимание его ответов, ставим flag = 1, в остальных случаях = 0:


Разметка сообщений от клиентов

Далее объявляем модель AutoML, обучаем её на размеченных данных и сохраняем (все необходимые параметры модели также передаются, но в примере ниже они не приводятся).

automl = saa.AutoML res_df, feat_imp = automl.train('test.csv', 'test_preds.csv', 'classification', cache_dir = 'tmp_dir', use_ids = False) automl.save('prec')

Загружаем полученную модель, после чего производим предсказание целевой переменной для тестового файла:

automl = saa.AutoML automl.load('text_model.pkl') preds_df, score, res_df = automl.predict('test.csv', 'test_preds.csv', cache_dir = 'tmp_dir') preds_df.to_csv('preds.csv', sep=',', index=False)

Далее производим оценку полученной модели:

test_df = pd.read_csv('test.csv') threshold = 0.5 am_test = preds_df['prediction'].copy() am_test.loc[am_test>=threshold] = 1 am_test.loc[am_test<threshold] = 0 clear_output() print_result(test_df[target_col], am_test.apply(int))

Полученная матрица ошибок:

В процессе создания модели мы стремились минимизировать ошибку 1-го рода (отнесение хорошего диалога к плохому), поэтому для полученного классификатора остановились на f1-мере, равной 0,66. С помощью обученной модели удалось выявить 65 тыс. «плохих» сессий, что, в свою очередь, позволило выявить на 7 недостаточно эффективных сценариев.

Process Mining

Для выявления проблемных сценариев также применим инструменты, основанные на Process Mining — общее название ряда методов и подходов, предназначенных для анализа и усовершенствования процессов в информационных системах или бизнес-процессов на основании изучения журналов событий.

С помощью этого метода удалось выявить 7 сценариев, которые участвуют в длительных и нерезультативных диалогах:

18% диалогов имеют более 4-х сообщений от чат-бота

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

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

Выявленные сценарии фигурируют примерно в 15% всех диалогов

DE (Data Engineering) подход

Также был применен несложный аналитический подход для поиска проблемных сценариев: были выявлены диалоги, оценка обратной связи в которых (со стороны клиентов) составляла от 1 до 7 баллов, затем отобраны наиболее часто встречающиеся сценарии в этой выборке.

Так, комплексно применяя подходы, основанные на AutoML, Process Mining и DE были выявлены проблемные места в работе чат-бота компании, требующие доработки.

Теперь чат-бот станет лучше!

ссылка на оригинал статьи https://habr.com/ru/post/530570/

Самоучитель по WinCC OA. Часть 3. Глобальные скрипты (control scripts)

Запрограммированое в предыдущей части поведение задвижки… нелогично. В обработчике нажатия кнопки «Открыть» или «Закрыть» мы непосредственно задавали значение элемента под названием Position. При том, что в самом DPT у нас уже предусмотрены команды «Открыть» и «Закрыть».

Datapoint type «Flap»
Datapoint type «Flap»

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

Но для начала изменим обработчик нажатия на кнопки «Открыть» и «Закрыть».

Скрипт на нажатие кнопки «Open»
Скрипт на нажатие кнопки «Open»

Меняем на

main(mapping event) {   dpSet("System1:Flap1.Commands.Open", 1, "System1:Flap1.Commands.Close", 0); }
Измененный скрипт кнопки «Open»
Измененный скрипт кнопки «Open»

Обратите внимание, что этот скрипт задает значение двум DPE, но, как было сказано в конце прошлой части, это выполняется одним сообщением. Выставляется команда «Открыть» и сбрасывается команда «Закрыть», это своего рода «защита от дурака» (которая, в принципе, должна и так быть в прикладной программе контроллера, но мы перестраховываемся).

Аналогично поступаем со скриптом кнопки «Close»

Проверим выполнение скрипта нажатия кнопок, меняются ли переменные команд в модуле Para

Нажатие кнопки «Open»
Нажатие кнопки «Open»
Нажатие кнопки «Close»
Нажатие кнопки «Close»

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

Для создания скрипта мы должны в gedi найти в дереве проекта Scripts, нажать правую кнопку мыши и выбрать Add New CTRL Script

Дадим осмысленное имя файла скрипта, я его назвал Model

После нажатия ОК скрипт появляется в дереве проекта

Далее двойным кликом на файле открываем скрипт для редактирования. Теперь необходимо продумать поведение модели и структуру самого скрипта. С учетом ярко-выраженного событийного поведения всей системы WinCC OA, этот скрипт должен вызывает функцию dpConnect, завязанную на одну из переменных команд управления задвижкой. Разберемся по шагам.

  1. Вызываем dpConnect на изменение значения переменной команды. В данном случае у нас очень упрощенная модель, защита от дурака реализована в скриптах нажатия кнопки, поэтому достаточно будет привязаться и к одной команде.

  2. Создаем callback функцию на изменение значения команды в рамках модели поведения.

Другие варианты поведения модели неверны с точки зрения идеалогии WinCC OA. Если в самом «глобальном» скрипте вызывать dpGet для чтения значения переменной команды, то этот скрипт надо вызывать постоянно, с определенной периодичностью.

Напоминаю, что у функции dpConnect есть два аргумента. Первый аргумент — имя callback-функции (я назвал ее OnOpen_CB), второй — имя точки данных, на которую происходит подписка. Итого, в упрощенном виде, без каких-либо проверок функция main скрипта Model выглядит так:

main() { 	dpConnect("OnOpen_CB", "System1:Flap1.Commands.Open"); }

Далее напишем саму callback-функцию. У нее тоже два аргумента — имя точки данных (тип данных string) и «новое» значение этой точки данных (должно соответствовать типу данных «исходной» точки). Получается вот такая заготовка.

void OnOpen_CB(string dp1, bool bNewValue) { ; }

Дописываем обработчик, он очень простой. Если значение команды «открыть» равно «истина», то задаем положение задвижки, равное 90. Если значение равно «ложь», то значение — 0.

void OnOpen_CB(string dp1, bool bNewValue) { 	if (bNewValue) { 		dpSet("System1:Flap1.Inputs.Position", 90); 	} else { 		dpSet("System1:Flap1.Inputs.Position", 0); 	} }

Теперь этот созданный скрипт необходимо как-то вызвать. Для исполнения «глобальных» скриптов используется Control Manager. Следовательно, требуется добавить в список менеджеров системы вызов еще одного менеджера (Control), где в качестве параметра задается имя исполняемого скрипта. В системе есть уже один вызов Control. И его трогать не следует во избежание нехороших последствий. Разве что, вы работаете с системой на уровне эксперта, но тогда зачем вам читать эти заметки?

Существующий список менеджеров
Существующий список менеджеров

В консоли WinCC OA нажимаем кнопку Append new manager, выбираем в появившемся окне менеджер Control. Для первого запуска свежесозданного скрипта имеет смысл выбрать режим запуска (Start mode) ручной (manual), чтобы не наблюдать попытки перезапуска в случае ошибок в самом скрипте. В качестве параметров вызова менеджера необходимо указать его номер в системе. В нашем случае это будет номер 2. Почему 2? Потому что менеджер с номером 1 в системе уже существует. Менеджеры одного типа в системе должны запускаться со своим уникальным номером. Именно одного типа. Это значит, что в системе может быть ui с номером 1 и ctrl с номером 1, а вот два ui (или ctrl) с одним и тем же номером быть не должны. Поэтому в качестве агрумента запуска я указываю строку «-num 2». Кроме того, требуется передать имя исполняемого скрипта. Вызов нового менеджера выглядит следующим образом:

Свойства Control менеджера для симуляции задвижки
Свойства Control менеджера для симуляции задвижки

Остается нажать кнопку ОК и запустить менеджер вручную кнопкой Manager Start либо мышью через вспывающее меню (новый менеджер при этом должен быть выделен в списке). Если все сделано правильно, то добавленный менеджер позеленеет и примет статус 2.

Скрипт симуляции успешно запущен
Скрипт симуляции успешно запущен

Теперь остается проверить работу симуляции.

По нажатию кнопки Open визуализируется открытие
По нажатию кнопки Open визуализируется открытие
Кнопка Close визуализирует закрытие
Кнопка Close визуализирует закрытие

Следует обратить внимание на то, что Control Manager запускает скрипт (точнее, свою функцию main) один раз при старте. После выполнения функции main() необходимые callback функции продолжают находится в памяти ПК, они исполняются при выполнении условий, указанных в dpConnect (по изменению значения переменной). Однако, если в сам скрипт были внесены изменения, то необходимо вручную остановить соответствующий экземпляр control-менеджера и запустить его заново. Без останова-запуска изменения не будут приняты.

Сам control manager при запуске создает свой отдельный процесс. Его функция main выполняется в отдельной нитке (потоке, thread). Callback функция (в нашем случае OnOpen_CB) так же запускается в отдельном потоке. После выполнения функция main перестает работать, но callback продолжает находится в памяти ПК (в своем потоке) и вызывается при изменениях «подписанной» переменной.

ссылка на оригинал статьи https://habr.com/ru/post/530572/