Русский
Русский
English
Статистика
Реклама

Machine-learning

ML не в радость что может провалить проект по внедрению machine learning

26.03.2021 18:19:00 | Автор: admin

Эксперты направления аналитических решений ГК КОРУС Консалтинг
Алена Гайбатова и Екатерина Степанова.

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

Machine learning всего 5% от ресурсов проекта. Но усложнение логики ML может привести к увеличению сроков внедрения, а неправильное планирование сбора данных к неточному анализу, который может стать бесполезным и дорогим. Почему так происходит?

Проблема ожиданий

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

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

Поэтому результаты проекта должны быть полезными, легко интерпретируемыми и подтвержденными метриками и экспертами бизнеса.

Ложные предпосылки

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

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

Завышенное доверие к системе

Представьте, вы разработали и сдали в эксплуатацию систему поддержки и принятия решений, например, для прогноза продаж в сфере здравоохранения. Компания даже успела в ней поработать: платформа показывала отличные результаты и точные расчёты. Сотрудники стали понимать, что система работает лучше и быстрее людей, поэтому использовали её решения не глядя. Так появились завышенные ожидания от платформы, и за ее работой перестали следить. Качество внедренной системы в 2020 году из-за пандемии сильно упало и, если бы не подсистема мониторинга, компания могла понести убытки. Без оценки доверия к технологии нет.

Решение: делать подсистему мониторинга текущей оценки качества, работы системы и сотрудников.

Проблема изменений

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

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

Как минимизировать подобные риски

Научитесь задавать правильные вопросы.

1. Какую проблему решаете? Точно ли болит то, на что жалуются? Сколько стоит решение проблемы?

Ответы на эти вопросы помогут собрать информацию и посчитать value для бизнеса. Так вы сможете понять, к какой точности прогнозирования стоит стремиться. К примеру, если данный параметр близок к 100%, значит, что модель переобучилась и доверия к ней нет. Тот же принцип по обратную сторону: точность ниже 50% говорит о том, что модель недоучилась.

2. В какой процесс встраивается ML? Кто стейкхолдер процесса? Кто несёт ответственность за техническую составляющую системы, а кто её конечный пользователь?

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

3. Кто эксперт в предметной области в компании?

Экспертиза это данные, а они питают ML-продукт. Лучше всего помочь вычленить нужные сведения может тот, кто знает в них каждую точку. Чем больше качественных данных, тем выше вероятность получения желаемой модели и ожидаемого бизнес-результата.

4. Как будет проходить прием результатов?

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


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

Подробнее..

Перевод Двумерные тестовые функции для оптимизации

31.03.2021 22:18:24 | Автор: admin

Оптимизация функций это область исследований, где поставлена задача найти некое входное значение [аргумент функции], результат которого максимум или минимум данной функции. Алгоритмов оптимизации много, поэтому важно развивать алгоритмическое чутьё и исследовать алгоритмы на простых и легко визуализируемых тестовых функциях.


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

Обзор туториала

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

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

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

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

  1. Унимодальные функции.

  1. Унимодальная функция 1.

  2. Унимодальная функция 2.

  3. Унимодальная функция 3.

  1. Мультимодальные функции.

  1. Мультимодальная функция 1.

  2. Мультимодальная функция 2.

  3. Мультимодальная функция 3.

Реализация каждой целевой функции будет представлена на Python в выведена в виде поверхности.

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

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

Унимодальные функции

Унимодальность означает, что функция имеет единственный глобальный оптимум.

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

Унимодальная функция 1

Диапазон ограничен промежутком -5,0 и 5,0 и одним глобальным оптимумом в точке [0,0, 0,0].

# unimodal test functionfrom numpy import arangefrom numpy import meshgridfrom matplotlib import pyplotfrom mpl_toolkits.mplot3d import Axes3D# objective functiondef objective(x, y):return x**2.0 + y**2.0# define range for inputr_min, r_max = -5.0, 5.0# sample input range uniformly at 0.1 incrementsxaxis = arange(r_min, r_max, 0.1)yaxis = arange(r_min, r_max, 0.1)# create a mesh from the axisx, y = meshgrid(xaxis, yaxis)# compute targetsresults = objective(x, y)# create a surface plot with the jet color schemefigure = pyplot.figure()axis = figure.gca(projection='3d')axis.plot_surface(x, y, results, cmap='jet')# show the plotpyplot.show()

Код создаёт поверхность согласно графику функции.

График поверхности на основе унимодальной функции оптимизации 1График поверхности на основе унимодальной функции оптимизации 1

Унимодальная функция 2

Диапазон ограничен значениями -10,0 и 10,0 и одним глобальным оптимумом в точке [0,0, 0,0].

# unimodal test functionfrom numpy import arangefrom numpy import meshgridfrom matplotlib import pyplotfrom mpl_toolkits.mplot3d import Axes3D# objective functiondef objective(x, y):return 0.26 * (x**2 + y**2) - 0.48 * x * y# define range for inputr_min, r_max = -10.0, 10.0# sample input range uniformly at 0.1 incrementsxaxis = arange(r_min, r_max, 0.1)yaxis = arange(r_min, r_max, 0.1)# create a mesh from the axisx, y = meshgrid(xaxis, yaxis)# compute targetsresults = objective(x, y)# create a surface plot with the jet color schemefigure = pyplot.figure()axis = figure.gca(projection='3d')axis.plot_surface(x, y, results, cmap='jet')# show the plotpyplot.show()

Код создаёт поверхность согласно графику функции.

График унимодальной функции оптимизации 2График унимодальной функции оптимизации 2

Унимодальная функция 3

Диапазон ограничен -10,0 и 10,0 и одним глобальным оптимумом при [0,0, 0,0], функция известна как функция Изома.

# unimodal test functionfrom numpy import cosfrom numpy import expfrom numpy import pifrom numpy import arangefrom numpy import meshgridfrom matplotlib import pyplotfrom mpl_toolkits.mplot3d import Axes3D# objective functiondef objective(x, y):return -cos(x) * cos(y) * exp(-((x - pi)**2 + (y - pi)**2))# define range for inputr_min, r_max = -10, 10# sample input range uniformly at 0.01 incrementsxaxis = arange(r_min, r_max, 0.01)yaxis = arange(r_min, r_max, 0.01)# create a mesh from the axisx, y = meshgrid(xaxis, yaxis)# compute targetsresults = objective(x, y)# create a surface plot with the jet color schemefigure = pyplot.figure()axis = figure.gca(projection='3d')axis.plot_surface(x, y, results, cmap='jet')# show the plotpyplot.show()

Код создаёт поверхность согласно графику функции.

График унимодальной функции оптимизации 3График унимодальной функции оптимизации 3

Мультимодальные функции

Мультимодальная функция это функция с более чем одной модой или оптимумом (например долиной на графике).

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

Вот несколько примеров мультимодальных функций.

Мультимодальная функция 1

Диапазон ограничен -5,0 и 5,0 и одним глобальным оптимумом при [0,0, 0,0]. Эта функция известна как функция Экли.

# multimodal test functionfrom numpy import arangefrom numpy import expfrom numpy import sqrtfrom numpy import cosfrom numpy import efrom numpy import pifrom numpy import meshgridfrom matplotlib import pyplotfrom mpl_toolkits.mplot3d import Axes3D# objective functiondef objective(x, y):return -20.0 * exp(-0.2 * sqrt(0.5 * (x**2 + y**2))) - exp(0.5 * (cos(2 * pi * x) + cos(2 * pi * y))) + e + 20# define range for inputr_min, r_max = -5.0, 5.0# sample input range uniformly at 0.1 incrementsxaxis = arange(r_min, r_max, 0.1)yaxis = arange(r_min, r_max, 0.1)# create a mesh from the axisx, y = meshgrid(xaxis, yaxis)# compute targetsresults = objective(x, y)# create a surface plot with the jet color schemefigure = pyplot.figure()axis = figure.gca(projection='3d')axis.plot_surface(x, y, results, cmap='jet')# show the plotpyplot.show()

Код создаёт поверхность согласно графику функции.

Мультимодальная функция оптимизации 1Мультимодальная функция оптимизации 1

Мультимодальная функция 2

Диапазон ограничен [-5,0 и 5,0], а функция имеет четыре глобальных оптимума при [3,0, 2,0], [-2,805118, 3,131312], [-3,779310, -3,283186], [3,584428, -1,848126]. Эта функция известна как функция Химмельблау.

# multimodal test functionfrom numpy import arangefrom numpy import meshgridfrom matplotlib import pyplotfrom mpl_toolkits.mplot3d import Axes3D# objective functiondef objective(x, y):return (x**2 + y - 11)**2 + (x + y**2 -7)**2# define range for inputr_min, r_max = -5.0, 5.0# sample input range uniformly at 0.1 incrementsxaxis = arange(r_min, r_max, 0.1)yaxis = arange(r_min, r_max, 0.1)# create a mesh from the axisx, y = meshgrid(xaxis, yaxis)# compute targetsresults = objective(x, y)# create a surface plot with the jet color schemefigure = pyplot.figure()axis = figure.gca(projection='3d')axis.plot_surface(x, y, results, cmap='jet')# show the plotpyplot.show()

Код создаёт поверхность согласно графику функции.

Мультимодальная функция оптимизации 2Мультимодальная функция оптимизации 2

Мультимодальная функция 3

Диапазон ограничен промежутком [-10,0 и 10,0] и функцией с четырьмя глобальными оптимумами в точках [8,05502, 9,66459], [-8,05502, 9,66459], [8,05502, -9,66459], [-8,05502, -9,66459]. Эта функция известна как табличная функция Хольдера.

# multimodal test functionfrom numpy import arangefrom numpy import expfrom numpy import sqrtfrom numpy import cosfrom numpy import sinfrom numpy import efrom numpy import pifrom numpy import absolutefrom numpy import meshgridfrom matplotlib import pyplotfrom mpl_toolkits.mplot3d import Axes3D# objective functiondef objective(x, y):return -absolute(sin(x) * cos(y) * exp(absolute(1 - (sqrt(x**2 + y**2)/pi))))# define range for inputr_min, r_max = -10.0, 10.0# sample input range uniformly at 0.1 incrementsxaxis = arange(r_min, r_max, 0.1)yaxis = arange(r_min, r_max, 0.1)# create a mesh from the axisx, y = meshgrid(xaxis, yaxis)# compute targetsresults = objective(x, y)# create a surface plot with the jet color schemefigure = pyplot.figure()axis = figure.gca(projection='3d')axis.plot_surface(x, y, results, cmap='jet')# show the plotpyplot.show()

Код создаёт поверхность согласно графику функции.

График мультимодальной функции оптимизации 3График мультимодальной функции оптимизации 3

Резюме

Если вы хотите глубже погрузиться в тему обратите внимание на сопутствующие материалы ниже.

Узнайте, как прокачаться в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

HMM ловим мошеннические транзакции

09.04.2021 14:13:02 | Автор: admin

Три года я проработал в Сербии iOS-евангелистом - было два профильный проекта и один Machine Learning-овый.

Если вам стало интересно - добро пожаловать в мир HMM.

Постановка задачи

Австрийский банк. У него много клиентов, у клиентов открыт счет в этом банке. В течении года клиент тратит средства со своего счета. Ходит в магазины, гасит коммунальные платежи и пр. Каждое списание денег со счета назовем транзакцией. Дана последовательность транзакций за определенное время (скажем год). Надо обучить машину, чтобы она начала проверять новые транзакции как достоверные или подозрительные. И выдавала предупреждение в последнем случае. Для решения задачи надо использовать Hidden Markov Model.

Введение в HMM

Я болею коронавирусом каждый год 10 дней подряд. Остальные дни здоров, как бык.

Представим эту последовательность из 365 символов в виде массива. h означает здоров, l - болен.

days{365} = {hhhhhhhhhhllllllllllhhhhhhhhhhhhhhhhhhhhhhhh...hhhhh}

Вопрос - Какова вероятность, что я сегодня болен?

\frac{10}{365}= 3 процента

Если вам понятен ответ, то читайте дальше, через 15 минут вы станете экспертом по HMM. Если нет - ставьте плюс и идите ужинать.

Изменим вопрос - Какова вероятность, что я завтра буду больным?

Вы резонно уточните: -А сегодня я болен или здоров?

Если болен (смотрите на последовательность - таких больных дней всего 10), то с вероятностью \frac{9}{10} = 90 процентов завтра я продолжу болеть и с вероятностью 10 процентов стану здоров.

А если я сегодня здоров? - то с вероятностью

\frac{1}{355}= 0.3 процента я завтра заболею и с вероятностью 99.7% буду здоров.

Если вы сегодня больны, то с вероятностью 10% завтра вы будете здоровы и 90% продолжите болеть.

Получили 4 числа, которые красиво вписываются в матрицу 2 на 2 - вуаля! эта матрица и есть Марковский слой. Уберем проценты, оставим чистые вероятности в диапазоне от 0 до 1, как того требует наука.

здоров

болен

здоров

0.997

0.003

болен

0.10

0.90

Еще раз взглянем на матрицу и прочитаем слева направо, что если ты сегодня здоров, завтра с вероятностью 0.997 ты останешься здоров, а с вероятностью 0.003 заболеешь и так далее.

Формализуем транзакции

Чем отличается последовательность транзакций от череды болен/здоров? Ничем.

Для доказательства этого возьмем список транзакций, который мне предоставил Сбережении по моей просьбе.

27.10.2020 00:00 GAZPROMNEFT AZS 219    2507,43 118 753,95 28.10.2020 / 298380 Автомобиль 26.10.2020 14:45 SPAR 77                319,73 121 261,38 27.10.2020 / 220146 Супермаркеты 26.10.2020 14:38 ATM 60006475           4800,00 121 581,11 26.10.2020 / 213074 Выдача наличных 25.10.2020 17:52 EUROSPAR 18            970,02 126 381,11 26.10.2020 / 259110 Супермаркеты 25.10.2020 00:00 Tinkoff Card2Card      20000,00 127 351,13 26.10.2020 / 253237 Перевод с карты 22.10.2020 14:22 SBOL перевод 4276      7000,00 147 351,13 22.10.2020 / 276951 Перевод с карты 22.10.2020 12:18 STOLOVAYA              185,00 154 351,13 23.10.2020 / 279502 Рестораны и кафе 21.10.2020 16:46 MEGAFON R9290499831    500,00 154 536,13 21.10.2020 / 224592 Комунальные платежи, связь, интернет. 21.10.2020 14:17 SPAR 77                987,03 155 036,13 22.10.2020 / 219015 Супермаркеты 21.10.2020 13:42 PYATEROCHKA 646        289,93 156 023,16 22.10.2020 / 294539 Супермаркеты 21.10.2020 00:00 MEBEL                  75,00 156 313,09 22.10.2020 / 279935 Прочие расходы 19.10.2020 14:54 SPAR 77                552,92 132 044,80 20.10.2020 / 208987 Супермаркеты 19.10.2020 00:00 MOBILE FEE             60,00 132 597,72 20.10.2020 / - Прочие операции 16.10.2020 14:19 SPAR 77                579,39 132 657,72 17.10.2020 / 229627 Супермаркеты 12.10.2020 13:33 STOLOVAYA              185,00 133 237,11 13.10.2020 / 261374 Рестораны и кафе 12.10.2020 00:00 OOO MASTERHOST         1000,00 133 422,11 13.10.2020 / 268065 Прочие расходы 11.10.2020 12:09 SPAR 77                782,87 134 422,11 12.10.2020 / 275816 Супермаркеты 10.10.2020 14:52 SBOL перевод           400,00 135 204,98 10.10.2020 / 276925 Перевод с карты 09.10.2020 13:29 SBOL перевод 5484*     1000,00 135 604,98 09.10.2020 / 229184 Перевод с карты 09.10.2020 11:55 MAGNIT MK KRYUCHYA     274,00 136 604,98 10.10.2020 / 209914 Супермаркеты

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

def readtrans():    with open ("assets/trans.txt", "r") as file:        grades = file.read()    pattern = '(\d{2,5}),\d\d'    result = re.findall(pattern, grades)    r = list(map(int, result[0::2]))    return rdata = readtrans()t = list(range(len(data)))df = pd.DataFrame({'number':t, 'amount':data})ax1 = df.plot.bar(x='number', y='amount', rot=0, width=1.5)

Упростим картину - дешевые транзакции (менее 10$) обозначим буквой l, дорогие свыше 100$ буквой h, остальные - буквой m.

Наша последовательность стала выглядеть подозрительно знакомо

print(observations[:20])trans[] = ['m', 'm', 'm', 'l', 'm', 'm', 'h', 'm', 'l', 'l', 'm', 'l', 'l', 'l', 'l', 'l', 'l', 'm', 'l', 'l']

Теперь напишем Марковский слой для транзакций. Это будет матрица 3 на 3, поскольку у нас 3 возможных типа транзакций = {l,m,h}

[[0.5 0.3 0.2] [0.6 0.3 0.1] [0.7 0.3 0.0]]

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

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

-Так просто?! - воскликнет читатель. Да, но за построение такой простой модели банк много денег не заплатит. Надо ввести еще один Марковский слой (невидимый), и алгоритм сразу станет красивее, сложнее и наукоёмчее. И потянет на кандидатскую диссертацию.

Скрытый Марковский слой

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

То есть существует набор периодических однотипных событий, число которых мы не знаем и Марковский слой для которых невозможно построить. Как построишь, если ничего не знаешь конкретно?! Вот именно. Но мы знаем, что эти события происходят и их примерно 4-6 штук. Поход в магазин. Столовая. Еще что-то. И так далее. И что мы точно знаем, что после похода в столовую мы никогда не опустошаем свой кошелек на сумму более 300 рублей.

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

[[a1 a2 a3 a4 a5] [b1 b2 b3 b4 b5] [c1 c2 c3 c4 c5] [x1 x2 x3 x4 x5] [y1 y2 y3 y4 y5]]

Именно 20, а не 25 (отвечать будет Ягуар). Это точно такой же Марковский слой, что мы строили раньше, но основанный на 5 событиях.

И чтобы связать два слоя (видимый с платежами и невидимый с событиями) мы заведем матрицу перехода размера 5 на 3.

В чем смысл матрицы перехода? В том, что после невидимого события a (поход в столовую)

у нас произойдет с разной степенью вероятности либо l-платеж, либо m-платеж, либо h-платеж. Скорее всего после похода в столовую эта строка будет такая

[0.96 0.04 0.0]

Что означает невозможность потратить более 100 долларов в нашей технопарковской столовой. Даже с приглашенной девушкой.

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

И мы можем найти эти 20+10 неизвестных величин, потому что у нас есть история платежей!

Это прекрасно и это называется обучить систему!

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

Обучение

В питоне есть библиотека hmm, в которой существует метод обучения - ему надо подать ваши три матрицы, и серию последовательностей из транзакций. Алгоритм такой, что вы разбиваете историю ваших транзакций порциями штук по 15-20 и скармливаете ее, пока система не обучится.

Процесс сходимости хорошо виден на графике.

После этого вы обученной системе подаете новую транзакцию и она по выбранному вами критерию отбраковывает ее или одобряет.

Питон против Сишарпа

Работодатель обязал меня использовать библиотек Accord и язык C#

using Accord.MachineLearning;using Accord.Statistics.Models.Markov;using Accord.Statistics.Models.Markov.Learning;using Accord.Statistics.Models.Markov.Topology;using Comtrade.FMS.Common;

Согласно контракту я не могу разглашать код, поэтому написал аналог на Питоне (я не знаю оба языка) и частично смог повторить результат. Но по скорости обучения Питон сильно проигрывает Си-шарпу. Правда, я run-ил программу на разного класса компьютерах)) В Словении это был сервер работодателя. Питон для Хабра пыхтел на 2010 года макбуке.

Приведу одну строку кода, в которой зашифрован метод обучения.

var teacher = new BaumWelchLearning(hmm)

Детали метода Баум-Уэлша вы поймете, прочитав соответствующую литературу и настроив свои мозги на стат. процессы.

Успехов и хорошей карьеры в банковских IT структурах!

Подробнее..

Распознавание дорожных знаков

24.04.2021 18:16:03 | Автор: admin

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

Набор данных дорожных знаков

В рамках этой статьи используется общедоступный набор данных, доступный вKaggle:GTSRB это мультиклассовая задача классификации одного изображения, которая проводилась на Международной совместной конференции по нейронным сетям (IJCNN) 2011. Набор данных содержит более 50 000 изображений различных дорожных знаков и классифицируется на 43 различных класса. Он весьма разнообразен: некоторые классы содержат много изображений, а некоторые классы - несколько изображений.

Изучение набора данных

В начале импортируем все необходимые библиотеки.

import osimport matplotlibimport numpy as npfrom PIL import Imagefrom tensorflow.keras.preprocessing.image import img_to_arrayfrom sklearn.model_selection import train_test_splitfrom keras.utils import to_categoricalfrom keras.models import Sequential, load_modelfrom keras.layers import Conv2D, MaxPool2D, Dense, Flatten, Dropoutfrom tensorflow.keras import backend as Kimport matplotlib.pyplot as pltfrom sklearn.metrics import accuracy_score

Для тренировки нейронной сети будем использовать изображения из папки train, которая содержит 43 папки отдельных классов. Инициализируем два списка:dataи labels. Эти списки будут нести ответственность за хранение наших изображений, которые мы загружаем, вместе с соответствующими метками классов.

data = []labels = []

Далее, с помощью модуля os мы перебираем все классы и добавляем изображения и их соответствующие метки в списокdataиlabels. Для открытия содержимого изображения используется библиотекаPIL.

for num in range(0, classes):    path = os.path.join('train',str(num))    imagePaths = os.listdir(path)    for img in imagePaths:      image = Image.open(path + '/'+ img)      image = image.resize((30,30))      image = img_to_array(image)      data.append(image)      labels.append(num)

Этот цикл просто загружает и изменяет размер каждого изображения до фиксированных 3030 пикселей и сохраняет все изображения и их метки в спискахdataиlabels.

Затем нужно преобразовать список в массивыnumpyдля подачи в модель.

data = np.array(data)labels = np.array(labels)

Форма данных - (39209, 30, 30, 3), означает, что имеется 39 209 изображений размером 3030 пикселей, а последние 3 означают, что данные содержат цветные изображения (значение RGB).

print(data.shape, labels.shape)(39209, 30, 30, 3) (39209,)

Из пакета sklearn мы используем метод train_test_split() для разделения данных обучения и тестирования, используя 80% изображений для обучения и 20% для тестирования. Это типичное разделение для такого объема данных.

X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, random_state=42)print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)(31367, 30, 30, 3) (7842, 30, 30, 3) (31367,) (7842,) 

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

def cnt_img_in_classes(labels):    count = {}    for i in labels:        if i in count:            count[i] += 1        else:            count[i] = 1    return countsamples_distribution = cnt_img_in_classes (y_train)def diagram(count_classes):    plt.bar(range(len(dct)), sorted(list(count_classes.values())), align='center')    plt.xticks(range(len(dct)), sorted(list(count_classes.keys())), rotation=90, fontsize=7)    plt.show()diagram(samples_distribution)
Диаграмма распределенияДиаграмма распределения

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

def aug_images(images, p):    from imgaug import augmenters as iaa    augs =  iaa.SomeOf((2, 4),          [              iaa.Crop(px=(0, 4)),               iaa.Affine(scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}),              iaa.Affine(translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}),              iaa.Affine(rotate=(-45, 45))              iaa.Affine(shear=(-10, 10))])        seq = iaa.Sequential([iaa.Sometimes(p, augs)])    res = seq.augment_images(images)    return resdef augmentation(images, labels):    min_imgs = 500    classes = cnt_img_in_classes(labels)    for i in range(len(classes)):        if (classes[i] < min_imgs):            add_num = min_imgs - classes[i]            imgs_for_augm = []            lbls_for_augm = []            for j in range(add_num):                im_index = random.choice(np.where(labels == i)[0])                imgs_for_augm.append(images[im_index])                lbls_for_augm.append(labels[im_index])            augmented_class = augment_imgs(imgs_for_augm, 1)            augmented_class_np = np.array(augmented_class)            augmented_lbls_np = np.array(lbls_for_augm)            imgs = np.concatenate((images, augmented_class_np), axis=0)            lbls = np.concatenate((labels, augmented_lbls_np), axis=0)    return (images, labels)X_train, y_train = augmentation(X_train, y_train)

После увеличения наш обучающий набор данных имеет следующую форму.

print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)(36256, 30, 30, 3) (7842, 30, 30, 3) (36256,) (7842,)

Давайте еще раз проверим распределение данных.

augmented_samples_distribution = cnt_img_in_classes(y_train)diagram(augmented_samples_distribution)
Диаграмма распределения после аугментацииДиаграмма распределения после аугментации

На графика видно, что наш набор стал более сбалансирован. Далее из пакета keras.utils мы используем метод to_categorical для преобразования меток, присутствующих вy_trainиt_test, в one-hot encoding.

y_train = to_categorical(y_train, 43)y_test = to_categorical(y_test, 43)

Построение нейронной сети

Для создания нейронной сети будет использоваться библиотекаKeras]. Чтобы классифицировать изображения по соответствующим категориям, мы построим модель CNN (сверточная нейронная сеть). CNN лучше всего подходит для целей классификации изображений.

Архитектура нашей модели:

  • 2 Conv2D слоя (filter=32, kernel_size=(5,5), activation=relu)

  • MaxPool2D слой ( pool_size=(2,2))

  • Dropout слой (rate=0.25)

  • 2 Conv2D слоя (filter=64, kernel_size=(3,3), activation=relu)

  • MaxPool2D слой ( pool_size=(2,2))

  • Dropout слой (rate=0.25)

  • Flatten слой, чтобы сжать слои в 1 измерение

  • Dense слой (500, activation=relu)

  • Dropout слой (rate=0.5)

  • Dense слой (43, activation=softmax)

class Net:  @staticmethod  def build(width, height, depth, classes):    model = Sequential()    inputShape = (height, width, depth)    if K.image_data_format() == 'channels_first':      inputShape = (depth, heigth, width)    model = Sequential()    model.add(Conv2D(filters=32, kernel_size=(5,5), activation='relu', input_shape=inputShape))    model.add(Conv2D(filters=32, kernel_size=(5,5), activation='relu'))    model.add(MaxPool2D(pool_size=(2, 2)))    model.add(Dropout(rate=0.25))    model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))    model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))    model.add(MaxPool2D(pool_size=(2, 2)))    model.add(Dropout(rate=0.25))    model.add(Flatten())    model.add(Dense(500, activation='relu'))    model.add(Dropout(rate=0.5))    model.add(Dense(classes, activation='softmax'))    return model

Обучение и проверка модели

Мы строим нашу модель вместе с оптимизатором Adam, а функция потерь это categorical_crossentropy, потому что у нас есть несколько классов для категоризации. Затем обучаем модель с помощью функции model.fit().

epochs = 25model = Net.build(width=30, height=30, depth=3, classes=43)model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])history = model.fit(X_train, y_train, batch_size=64, validation_data=(X_test, y_test), epochs=epochs)

Как вы можете видеть, наша модель обучалась в течении 25 эпох и достигла 93% точности на тренировочном наборе данных. С помощью matplotlib мы строим график для точности и потерь.

plt.style.use("plot")plt.figure()N = epochsplt.plot(np.arange(0, N), history.history["loss"], label="train_loss")plt.plot(np.arange(0, N), history.history["val_loss"], label="val_loss")plt.plot(np.arange(0, N), history.history["accuracy"], label="train_acc")plt.plot(np.arange(0, N), history.history["val_accuracy"], label="val_acc")plt.title("Training Loss and Accuracy")plt.xlabel("Epoch")plt.ylabel("Loss/Accuracy")plt.legend(loc="lower left")plt.show()
Training Loss and AccuracyTraining Loss and Accuracy

Тестирование модели на тестовом наборе

Набор данных содержит папку Test, а в файле Test.csv есть сведения, связанные с путем к изображению и метками классов. Мы извлекаем путь к изображению и метки из файла Test.csv с помощью фреймворка Pandas. Затем, мы изменяем размер изображения до 3030 пикселей и делаем массив numpy, содержащий все данные изображения. С помощью accuracy_score из sklearn metrics проверяем точность предсказаний нашей модели. Мы достигли 96% точности на этой модели.

y_test = pd.read_csv('Test.csv')labels = y_test["ClassId"].valuesimgs = y_test["Path"].valuesimages=[]for img in imgs:    image = Image.open(img)    image = image.resize((30,30))    images.append(img_to_array(image))X_test=np.array(images)pred = model.predict_classes(X_test)print(accuracy_score(labels, pred))0.958590657165479
Подробнее..

Mushrooms (Machine Learning)

14.06.2021 12:13:27 | Автор: admin

Всем привет! Рассмотрим данные о грибах, предскажем их съедобность, построим корреляцию и многое другое.

Воспользуемся данными о грибах с Kaggle (исходный датафрейм) сhttps://www.kaggle.com/uciml/mushroom-classification, 2 дополнительных датафрейма приложу к статье.

Все операции проделаны наhttps://colab.research.google.com/notebooks/intro.ipynb

# Загружаем библиотекeу для работы с даннымиimport pandas as pd# для построения леса деревьев решений, обучения моделей и построения confusion_matrix:from sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import GridSearchCVfrom sklearn.metrics import confusion_matrix# для работы с графикой:import matplotlib.pyplot as pltimport seaborn as sns# Загружаем наш датафреймmushrooms = pd.read_csv('/content/mushrooms.csv')#Просматриваем наши данныеmushrooms.head()# Что будет изображено после выполнения кода можете увидеть на картинке внизу:
#Краткая сводка данныхmushrooms.info()
#Информация о количестве строк и столбцовmushrooms.shape# Используем кодировщик данных LabelEncoder для преобразования наших категоральных или текстовых данных в числа (обязательно перед heatmap)# Если мы этого не сделаем, при обучении дерева у нас возникнет ошибка на этапе его обученияfrom sklearn.preprocessing import LabelEncoderle=LabelEncoder()for i in mushrooms.columns:    mushrooms[i]=le.fit_transform(mushrooms[i])# Посмотрим как преобразовались наши данныеmushrooms.head()
# Просмотрим корреляцию наших данных с помощью heatmapfig = plt.figure(figsize=(18, 14))sns.heatmap(mushrooms.corr(), annot = True, vmin=-1, vmax=1, center= 0, cmap= 'coolwarm', linewidths=3, linecolor='black')fig.tight_layout()plt.show()

Положительно коррелирующие значения: Сильная корреляция (veil-color,gill-spacing) = +0.9 Средняя корреляция (ring-type,bruises) = +0.69 Средняя корреляция (ring-type,gill-color) = +0.63 Средняя корреляция (spore-print-color,gill-size) = +0.62 Отрицательно коррелирующие значения Средняя корреляция (stalk-root,spore-print-color) = -0.54 Средняя корреляция (population,gill-spacing) = -0.53 Средняя корреляция (gill-color,class) = -0.53 Если в нашем исследование возьмем максимально тесно связанные коррелирующие значения, то получим максимально точные значения и точно обученную модель. В нашей задаче мы будем обучать модель по классу, представляя, что аналитик не воспользовался таблицей корреляции.

# Отбросим колонку, которую будем предсказывать.X = mushrooms.drop(['class'], axis=1)# Создадим переменную, которую будем предсказывать.y = mushrooms['class']# Создаем модель RandomForestClassifier.rf = RandomForestClassifier(random_state=0)# Задаем параметры модели, изначально когда мы не знаем оптимальных параметров для обучения леса задаем так#{'n_estimators': range(10, 51, 10), 'max_depth': range(1, 13, 2),#             'min_samples_leaf': range(1,8), 'min_samples_split': range(2,10,2)}parameters = {'n_estimators': [10], 'max_depth': [7],              'min_samples_leaf': [1], 'min_samples_split': [2]}# Обучение Random forest моделей GridSearchCV.GridSearchCV_clf = GridSearchCV(rf, parameters, cv=3, n_jobs=-1)GridSearchCV_clf.fit(X, y)# Определение наилучших параметров, и обучаем с ними дерево для получения лучшего уровня обучаемостиbest_clf = GridSearchCV_clf.best_params_# Просмотр оптимальных параметров.best_clf
# Создание confusion matrix (матрицу ошибок) по предсказаниям, полученным в прошлом шаге и правильным ответам с нового датасета.y_true = pd.read_csv ('/content/testing_y_mush.csv')sns.heatmap(confusion_matrix(y_true, predictions), annot=True, cmap="Blues")plt.show()

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

Далее мы проделаем операции для определения модели наилучшей точности нашем дф

# определим точность нашей модели from sklearn.metrics import accuracy_scoremr = accuracy_score(y_true, predictions)#Данные для тренировки и тестировки датафреймаfrom sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)#Логистическая регрессия#Тренируем модельfrom sklearn.linear_model import LogisticRegressionlr = LogisticRegression(max_iter = 10000)lr.fit(x_train,y_train)#Строим матрицу ошибокfrom sklearn.metrics import confusion_matrix,classification_reporty_pred = lr.predict(x_test)cm = confusion_matrix(y_test,y_pred)#Делаем проверку точностиlog_reg = accuracy_score(y_test,y_pred)#K ближайших соседей#Тренируем модельfrom sklearn.neighbors import KNeighborsClassifierknn = KNeighborsClassifier(n_neighbors = 5, metric = 'minkowski',p = 2)knn.fit(x_train,y_train)#Создаем матрицу ошибокfrom sklearn.metrics import confusion_matrix,classification_reporty_pred = knn.predict(x_test)cm = confusion_matrix(y_test,y_pred)#Делаем проверку точностиfrom sklearn.metrics import accuracy_scoreknn_1 = accuracy_score(y_test,y_pred)#Дерево решений#Тренируем модельfrom sklearn.tree import DecisionTreeClassifierdt = DecisionTreeClassifier(criterion = 'entropy')dt.fit(x_train,y_train)#Создаем матрицу ошибокfrom sklearn.metrics import confusion_matrix,classification_reporty_pred = dt.predict(x_test)cm = confusion_matrix(y_test,y_pred)#Делаем проверку точностиfrom sklearn.metrics import accuracy_scoredt_1 = accuracy_score(y_test,y_pred)#Простой вероятностный классификатор#Тренируем модельfrom sklearn.naive_bayes import GaussianNBnb = GaussianNB()nb.fit(x_train,y_train)#Создаем матрицу ошибокfrom sklearn.metrics import confusion_matrix,classification_reporty_pred = nb.predict(x_test)cm = confusion_matrix(y_test,y_pred)#Делаем проверку точностиfrom sklearn.metrics import accuracy_scorenb_1 = accuracy_score(y_test,y_pred)#Осущевстляем проверку точностейplt.figure(figsize= (16,12))ac = [log_reg,knn_1,nb_1,dt_1,mr]name = ['Логистическая регрессия','К ближайших соседей','Простой вероятностный классификатор','Дерево решений', 'Случайные деревья']sns.barplot(x = ac,y = name,palette='colorblind')plt.title("График точностей моделей", fontsize=20, fontweight="bold")

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

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru