Transcription
видно. Ага. Значит, поехали. У нас сегодня большая достаточно лекция. Первая часть её такая больше теоретическая. Мы ещё чуть-чуть поговорим про то, что же такое машинное обучение, и потом уже посмотрим на конкретную реализацию одного из первых алгоритмов машинного обучения.
Итак, само по себе машинное обучение, да? То есть, если вы помните прошлую лекцию, то, э, эпоха восьмидесятых у нас показательна тем, что мы используем так называемый искусственный интеллект, основанный на знаниях. То есть мы самостоятельно извлекаем знания, их каким-то образом в машину записываем, и машина с ними работает. Но как раз-таки зима, вторая зима искусственного интеллекта показала, что знания из данных извлекать достаточно сложно. Поэтому к нашему текущему моменту, значит, основная такая работающая концепция, наибольшее количество алгоритмов искусственного интеллекта связано с таким направлением, как машинное обучение.
Соответственно, машинное обучение - это, опять же, так же, как и искусственный интеллект, не какая-то одна технология. Это целый набор самых разных технологий, да, математических алгоритмов, какой-то статистики, анализа данных. Основная идея этих алгоритмов в том, что мы строим какие-то алгоритмы, которые автоматически извлекают знания из данных как бы за нас, да, и уже потом с этими данными работают.
А, то есть, если как бы сравнивать машинное обучение с программированием, да, то в программировании у нас есть изначально какие-то, а, правила, да, то есть наше понимание того, как эти данные должны быть обработаны. Мы эти правила э даём программисту и также мы ему даём данные. он эти правила записывает на каком-то компьютерном языке, получается программа, и, соответственно, давая подавая данные на вход программы, мы в итоге получаем необходимые нам ответы. Но проблема этого в том, что существует огромное количество интеллектуальных задач, где, э, формализовать алгоритм крайне сложно.
Ну, условно говоря, алгоритм определения кошки на фотографии, да? То есть, если у нас кошка сфотографирована всегда как на паспорт, да, смотрит на нас прямо, если это одни и те же типы кошек, да, то мы можем попытаться описать какой-то алгоритм, где мы выделяем на фотографии там какой-то круг. От этого круга должны торчать вверх два треугольника. Внутри этого круга должны быть две окружности на определённом расстоянии. И тогда мы можем предположить, что это кошка. Да. Но если у нас какая-то нечёткая фотография, она сделана на каком-то контрастном фоне, если кошка повернулась спиной или мы сфотали лапку или хвостик или кошка лысая, да, то для всех этих исключений придётся писать отдельные условия, отдельные правила прописывать. И в итоге мы выясняем, что количество правил превышает какие-то все адекватные лимиты, да? Поэтому решать обычным алгоритмическим способом подобные задачи практически невозможно.
И здесь как раз нам на помощь приходит машинное обучение, когда мы, э, значит, как работает машинное обучение? У нас есть какие-то данные, скажем, те же самые фотографиями с животными, и есть ответы на эти данные. То есть то, что мы хотим получить в результате обработки этих данных. Ну, например, ответ: есть ли на изображение кошка, собака, лошадь или что-то ещё другое. Мы, соответственно, даём эти данные вместе с ответами специальному алгоритму, который, э, анализирует данные, пытается как-то связать между собой данные с ответами, построить какую-то взаимосвязь. И вот эту вот полученную взаимосвязь, она сохраняется в виде некоторой, ну, скажем так, математической модели, которая, естественно, то есть не сама по себе просто формулой записана. Мы, конечно, можем её и формулой записать, но основная идея в том, что это просто какие-то э ячейки данных как каким-то образом взаимосвязаные, да? То есть у нас есть формализованная в программном языке модель взаимосвязи данных с ответами. И используя эти то есть по сути на за нас э как бы алгоритм машинного обучения как бы написал программу, да, то есть получил некоторые правила обработки. И после этого мы даём данные вот этой модели какие-то данные на вход. И на основании полученных взаимосвязей модель нам даёт ответы, да? То есть именно таким образом она извлекает знания из данных. То есть знания в данном случае - это как бы набор законов, связывающих между собой входные данные и ответы на них.
А здесь стоит вспомнить такое понятие, как глубокое обучение, которое на самом деле является больше маркетинговым термином. А почему я так говорю? Несмотря на то, что по факту действительно такая область сейчас существует. Но если мы посмотрим на то, как она развивалась, то по факту глубокое обучение - это всего лишь дальнейшее развитие машинного обучения, да, где мы, э, то есть машинное обучение как концепция появилась в девяностые. Отдельные алгоритмы машинного обучения были открыты ещё в пятидесятых и восьмидесятых годах, да. Но вот в конечном итоге, именно к девяностым годам у нас сложилась такая отрасль. И, но даже когда она сложилась в девяностые, э, мы не могли, то есть мы не очень хорошо понимали эти алгоритмы, да, условно говоря, тот же самый такой алгоритм, как машинные, ээ, господи, нейронные сети. Мы примерно понимали, как они работают, но не могли обучать нейронные сети глубиной больше, чем в два слоя, да, и не особенно понимали, а что там за информация сохраняется в нейронных сетях. К нулевым годам мы научились обучать большее количество нейронных слоёв, да, лучше стали понимать, как эти слои между собой взаимосвязаны и как их организовать, чтобы научиться решать те или иные виды разных задач. И вот как раз-таки вот это вот новый вид построения мм нейронных сетей, для того, чтобы продать их инвесторам, было придуман такой термин, как глубокое обучение.
Соответственно, если вообще в целом посмотреть на взаимосвязь этих понятий, да, то мы опять же видим, что у нас есть огромная прорва самых разных алгоритмов искусственного интеллекта, из которых некоторую часть занимает машинное обучение. Но опять же не надо думать, что мы забыли про другие алгоритмы. Например, активно до сих пор развивается такой вид такие виды алгоритмов, как генетические алгоритмы или эволюционные алгоритмы, которые не являются классическим машинным обучением, но тем не менее хорошо с ним взаимодействуют, да. Соответственно, у машинного обучения также есть огромное количество самых разных алгоритмов. И некоторые из них, да, называются нейронные сети, но далеко не все. И это не значит, что нейронные сети - это, что называется, silвер буllт, да? То есть какой-то универсальный алгоритм, который мы должны использовать во всех ситуациях. То есть, с одной стороны, нейронные сети, они действительно достаточно гибкие, то есть они могут впитывать себя в самые разные взаимосвязи, но эта свобода в э как бы поиске, в построении как бы каких-то взаимосвязей, она, э, значит, окупается высокой ценой за вычисление, да? То есть, например, есть такой ресурс, как KGL. Это, скажем так, такая соревновательная платформа, где выкладываются какие-то датасеты, наборы данных и предлагается что-то из них решить. И, соответственно, различные датасатисты разными алгоритмами пробуют получить наиболее эффективное решение. Так вот, э в топе алгоритмов, которые сейчас решают большинство задач, два алгоритма. Один называется, ну, один - это, собственно говоря, нейронные сети, разные их виды. А второй называется XGR Boost, который является на самом деле достаточно старым, достаточно примитивным несколько доработанным алгоритмом, э, обхода дерева, да? То есть это вот такие алгоритмы, как случайный лес и так далее, да? То есть это достаточно примитивный алгоритм, который на самом деле достаточно э вычислительно простой. То есть, в отличие от нейронной сети, мы можем этот алгоритм запихать в какую-нибудь микроволновку или холодильник. А в микроволновке и в холодильник устанавливаются не полноценные компьютеры, а так называемые микроконтроллеры. То есть это компьютер с там, условно говоря, 2 Мбми оперативной памяти или даже полкилобай оперативной памяти, там 32 Мб флэш-память, ну, что-то такое. То есть что-то очень слабенькое. И запихнуть туда полноценную нейронку, ээ, во-первых, сложно, а, во-вторых, для большинства задач не нужно. То есть зачем это делать, если есть более простые алгоритмы, которые могут сделать то же самое с той же самой эффективностью, да? Поэтому вы, как инженеры, должны понимать, что, э, выбор вашего алгоритма для решения той или иной задачи - это не просто выбор самого модного алгоритма, а это выбор алгоритма, который по разным критериям удовлетворяет этоговому решению, да.
Соответственно, у нас опять же сами нейронные сети бывают разных видов, часть из которых это глубокие нейронные сети, то есть нейронные сети от двух слоёв и, условно говоря, до бесконечности. То есть сейчас для нас 50 слоёв - это уже не очень глубокая нейронная сеть, да? Там в каком-нибудь GPT там там сотни слоёв. А и на самом деле я здесь ещё не нарисовал. Есть ещё одно подразделение в части глубокого обучения. У нас вот современные большие языковые модели или диффузионные модели относятся к так называемому генеративному искусственному интеллекту, да? То есть это модели, которые не просто предсказывают что-то, а могут ещё и создать что-то. Причём надо понимать, что генеративный искусственный интеллект, несмотря на то, что он сейчас в первую очередь относится к машинному обучению, включает в себя не только алгоритмы, основанные на машинном обучении, да, это могут быть опять же и эволюционные алгоритмы, и какие-то другие алгоритмы, они также могут генерировать контент.
Вот, соответственно, давайте быстренько пробежимся по видам машинного обучения. И условно их можно разделить на несколько направлений. А и деление это происходит в первую очередь по тому, как наши алгоритмы работают с данными, на которых они обучаются.
Первый вид - это обучение с учителем. Это вот буквально то, что я вам уже приводил в пример, когда у нас есть набор данных, набор ответов на эти данные и алгоритм э пытается найти взаимосвязь между данными и ответами. То есть учителям в данном случае выступают именно ответы к данным, да, то есть они как бы дают обратную связь. На основании этих ответов нейронная сеть, когда обучается, понимает, правильный она вывод сделала или неправильный.
А полная противоположность этому методу - это обучение без учителя. То есть, исходя из этого определения, мы понимаем, что теперь нам даются данные, но при этом не даются ответы на эти данные. И алгоритм должен самостоятельно найти по каким-то своим критериям, которые он сам найдёт, э, какие-то взаимосвязи в данных, да, ну, условно говоря. То есть мы дали те же самые изображения с животными. И там нейронная сеть должна отличать, допустим, кошек от собак. То есть она не знает, что кошка, а что собака, но она просто на основании анализа изображений видит, что там есть какой-то класс изображений, где кто-то есть там с острыми ушками и определённой мордочкой, а есть кто-то другой, да, и она вот разделяет это на разные, что называется, кластеры, да. Соответственно, когда мы даём ей какие-то новые данные, она может их, соответственно, отнести к тому или иному виду в зависимости от того, как она эти данные разделила.
И два оставшихся направления - это на самом деле подразделение первых двух. А одно из них так называемое обучение с частичным привлечением учителя, оно решает проблему дороговизны данных, да? То есть надо понимать, что, э, машинное обучение не существует без большого объёма качественных данных. И что называется разметка этих данных, то есть обработка, подготовка к дальнейшему использованию в алгоритмах, она стоит каких-то человека часов. То есть даже просто а указать, что на фотографии есть код или нет кота, оно требует какого-то времени. Конечно, для каких-то задач мы можем а там привлечь там парсеры автоматические, скачать из интернета данные там фотографии по по запросу там в кошки, да, но опять же не факт, что у нас именно в скачанном материале все фотографии будут с кошками. А, но что, например, делать, если у нас какая-то более сложная обработка? Например, у нас есть изображение интерьеров, и мы должны научить алгоритм различать различные виды мебели и, э, выделять их разными цветами. Чтобы показать пример подобных данных алгоритму, мы должны дать эти необработанные данные там какому-нибудь исполнителю, да, то есть там фйлансеру, и он там на каждую картинку будет тратить, ну, минимум 5 минут, чтобы быстро-быстро обвести все эти виды мебели разным цветом, да, соответственно, э стоимость там датасета из там тысячи фотографий может перева валивать там за сотни тысяч рублей, а, соответственно, 1тыся фотографий - это на самом деле не такой уж и большой датасет. Поэтому, что мы делаем? Мы стараемся совместить лучшие стороны первого и второго метода. То есть мы для начала просим э нашего фрилансера э разметить данные, но не все, а какую-то их небольшую часть, например, всего лишь там 100 изображений. После того, как он произвёл разметку небольшой части, мы говорим алгоритму с обучения без учителя, да, что вот посмотри на то, что сделано на этих примерах, и разметь оставшийся датасет, там сотни тысяч фотографий по аналогии. И, соответственно, после того, как первая нейронная сеть разметила по аналогии эти данные, да, на чём мы несколько сэкономили, мы уже применяем обучение с учителем, чтобы полноценно обучить нейронную сеть, там различать различные виды, э, там интерьера.
И последний вид - это обучение с подкреплением, да? То есть это такой вид обучения, где, то есть это, по сути, обучение с учителем, но в качестве данных выступают не какие-то заранее подготовленные статические наборы данных, а в качестве учителя выступает динамическая среда, например, какой-нибудь эмулятор, да? То есть, например, мы можем подключить нейронную сеть к эмулятору там игровой приставки, скажем, игра в Mario, да, подавать на вход изображение, подавать на вход, то есть давать возможность как бы нажимать на кнопки, да, то есть нейронная сеть будет давать какие-то команды, и мы будем в ответ выдавать ей снова изображение и, условно говоря, ставим задачу, чтобы Марио любым способом добежал до конца как можно быстрее. рее, да, чтобы уровень не закончился где-то в перерыве из-за того, что мы погибли. Соответственно, перебирая различные варианты, взаимодействие с этой интерактивной средой, а наша модель как раз-таки обучается. Ну и ярчайший пример подобного вида обучения. Это, например, машины там вида Tтеesla, которые изначально обучались на эмуляторах городов, где было сэмулировано там вот целые города с дорожным движением, с работающими светофорами, с пешеходами, с другими ездящими машинами. И нейронная сеть сначала накручивала миллионы часов в вот этом эмуляторе, чтобы в дальнейшем его под присмотром инженеров уже смогли выпустить в реальный город.
Соответственно, под эти задачи, под эти виды машинного обучения есть разные виды задач. Да, мы разберём очень кратенько лишь некоторые из них, просто чтобы вы имели понимание, что мы можем делать с этим машинным обучением.
И самая первый, самый известный, так задача обучения, которая относится к обучению с учителем - это задача классификации. То есть классификация, она же раньше называлась задача распознавания образов. Это когда мы делим входные данные по каким-то заранее известным признакам на некоторые группы, да, условно говоря, там делим яблоки, отделяем их от груш, да, причём это не обязательно должны быть изображения, это могут быть какие-то, например, там числовые данные, то есть есть табличка, где записаны измерения яблок и груш, там вес яблока, цвет, ээ там, э диаметр, насколько оно приближено к кругу, да? И основная идея как раз-таки классификации в том, чтобы алгоритм каким-то образом эти данные разместил в какой-то координатной плоскости и научился отделять одни данных от других по каким-то признакам. Ну, самая такая первое, что напрашивается как пример - это, например, спам-фильтры, да, которые решают по содержимому письма, а по его тексту, а иногда даже вложенному изображению, к чему отнести, к спаму или не спаму, да, в какую папочку положить, а, пришедшее письмо. Это и определение языка, и анализ тональности, когда мы хотим понять вот комментарии, которые нам написал пользователь на какой-то товар, это позитивные комментарии, негативные или нейтральные, да, чтобы, например, на позитивный поставить лайк, на нейтральный никак не отреагировать, а негативный подать на обработку живому человеку, да, чтобы он написал какой-то фидбэк, как-то отработал с негативом. Ну и мы видим, что на самом деле для решения этой задачи применяется достаточно большой количество различных алгоритмов, да, не только нейронные сети. Некоторые из них мы с вами в ближайшее время изучим.
Другой вид обучения с учителем - это, соответственно, ээ так называемая регрессия. Регрессия - это такой вид выявления взаимосвязи, когда у нас есть какой-то набор, ну, скажем, числовых данных. А, и то есть, допустим, есть какая-то гипотетическая взаимосвязь, да, например, стоимость дома, как она зависит от площади дома. Ну, как бы логика нам подсказывает, что по идее, чем больше площадь дома, тем больше должна быть стоимость. Понятно, что есть ещё какие-то параметры, но сначала назмём для начала вот эти вот два самые примитивные, да, поэтому мы как бы строим различные ээ эти данные по этим проданным дома на каком-то графике, получаем какую-то взаимосвязь. Будет идеально, если она будет линейная. И, соответственно, задача алгоритмом найти эту самую взаимосвязь, да, понять, насколько сильно, а, стоимость дома зависит от площади. И по данному произвольному числу площади дома, он должен нам выдать число, соответствующее э как бы стоимости, да? То есть понятно, это будет приблизительная оценка, э, но тем не менее, да? То есть, в чём вообще отличается регрессия от классификации? Классификация у нас в качестве ответа даёт отношение к какому-то классу, там кошки, собаки, лошади или скорее 0, 1 там 2. А регрессия даёт чаще всего какие-то дробные числа, которые соответствуют, ну, скажем так, примерно реальным значениям. То есть сколько бы мог стоить этот дом. Соответственно, это у нас и, э, использование для прогноза стоимости ценных бумаг, да, построение каких-то медицинских диагнозов, условно говоря, там, какой процент холестерина будет при таком-то весе и таком-то росте. Ну, и вообще любые взаимосвязи каких-то чисел, в том числе взаимосвязи числа от времени.
А дальше мы посмотрим на обучение без учителя. И здесь у нас есть, что называется, злой брат-близнец классификации - это задача кластеризации, да? Она на самом деле концептуально похожа на задачу классификации. То есть у нас также есть а какой-то набор входных данных, которые мы должны разделить на какие-то группы, но при этом количество групп заранее неизвестно, да? То есть алгоритм должен сам разделить данные по каким-то признакам, да, и выделить там отделить кошек от собак либо собак различных э пород между собой, да, и сделать их группировку, чтобы в дальнейшем э для новых данных он мог предсказывать, к какой группе относятся эти данные. Соответственно, это у нас и сегментация рынка, да? То есть по вашим там покупкам или по тем товарам, которые вы смотрели, определяются ваши, э, скажем так, профили, да, то есть к какой целевой аудитории вы относитесь. Ну, в частности, была уже даже такая такой скандал, когда девушка подала в суд на Google, э, думая о том, что Google за ней следит, да, потому что она сдавала анализы в частную клинику. А и, э, до того, как анализы ей пришли непосредственно, да, о том, что она беременна, а Google стал предлагать ей товары для беременных. Но здесь ирония ситуации в том, что Google, конечно, следит за нами, но не в том виде, как мы думаем, да. В частности, девушка сама своими действиями, э, слила свои как бы интересы, да, и ещё достаточно как бы доказано известно, что, условно говоря, например, когда, э, скажем так, беременные женщины, они ведут себя несколько другим образом. не, нежели не беременные, да, и это можно статистически показать, статистически различить. И вот эту вот статистическую разницу увидел автоматически алгоритм сегментации рынка и предложил товары, ну, для той категории э покупателей, которые обычно этим интересуются. Ну, на самом деле, применения кстеризации достаточно много, в частности, и сжатие изображений, это тоже алгоритмы искусственного интеллекта и детекторы аномального поведения. Всё это у нас относится к кластеризации.
Ну и, наконец, последний на сегодня теоретический примерчик. Это задача снижения размерности, да? Ну, в частности, вот такой наиболее яркий пример. Это когда мы, например, опять же анализируем изображение с кошками и собаками. И, допустим, нам нужно отличать кошек от собак. Но если мы просто скормим эти данные алгоритму кластеризации, он не просто отделит кошек и собак, но и заметит, что собаки очень сильно разные между собой. Поэтому, наверное, он для собак повыделяет много различных их ээ м пород. Да. Нас же, если нас интересует именно различие кошек от собак, не интересует различия различных пород, да? Поэтому мы можем сказать, ну, условно говоря, использовать этот алгоритм для снижения размерности. То есть сказать, что вот эти данные нас не особенно интересуют, да? Нас не интересуют, что там у собаки висячие уши или стоящие, длинная морда или короткая. Нас просто интересует, что это собака, да, игнорируй, да, там как-то сусь данные, то есть сделай их более чистыми для получения более точного ответа для нашей задачи.
Так, какие-то вопросы по первой части есть? >> Да, проти. >> Ну, о'кей, тогда давайте непосредственно перейдём чуть-чуть уже к практике.
А, соответственно, а для практики мы с вами возьмём самый вообще примитивный из всех, что есть алгоритм классификации, да? То есть, ещё раз, это у нас обучение ээ с учителем, когда у нас есть данные и ответы на эти данные. Аа причём, обратите внимание, классификация, она тоже бывает самая разная. То есть у нас есть классификация, э, так называемая бинарная и мультиклассовая, да? Бинарная, когда у нас классов всего лишь два, мультиклассовая, когда классов намного больше, чем то есть три и больше. Вот. И этот алгоритм, он достаточно универсален. То есть он может выполнять как бинарную, так и мультиклассовую классификацию, то есть разделение данных на несколько видов групп. Этот алгоритм называется алгоритм к ближайших соседей.
Значит, э что для нас важно знать? Первое - это то, что этот алгоритм является так называемым алгоритмом ленивого обучения. Да, то есть эта фраза означает, что у него нет специализированной фазы обучения, да? И это такой важный моментик, что касается машинного обучения, потому что абсолютное большинство алгоритмов в своей работе делятся на две фазы. Первая фаза такая наиболее сложная, наиболее сложная по вычислениям, по стоимости - это фаза обучения, когда мы вводим данные в алгоритм, и он, соответственно, строит эти самые взаимосвязи между собой, между данными и ответами. И второй, вторая фаза - это использование или чаще можно услышать такое слово, как infence, да? То есть вот infence нейронной сети. Что это значит? Это значит, что мы уже берём готовую нейронную сеть, она обучена, и мы говорим ей там: "Сгенерируй картинку". И она её нам генерирует, да? То есть мы уже используем обученный алгоритм. Так вот, у алгоритмак ближайших соседей как таковой фазы обучения ну не то чтобы прямо нет, но она, скажем так, минимальна. А в чём она состоит, мы посмотрим чуть попозже, да? То есть основные его, а, вычисления происходят именно в фазе использования, да, то есть, но в этом есть и минус, да? То есть фаза использования, э, это когда мы даём какие-то новые данные и говорим: "Отнеси, э, эти данные к какому-то классу", да? И почему он называется ленивый? Потому что он буквально как бы оттягивает момент -э выдачи класса на самый последний момент, то есть когда мы уже непосредственно его спросили, только тогда он занялся вычислениями, занялся классификацией, да? То есть, как и мы все, в последний момент он выполнил свою работу.
А значит, вторым важным важной особенностью этого алгоритма является то, что он является непараметрическим алгоритмом обучения, а то есть его не особенно беспокоит распределение этих данных. И здесь я хочу особенно акцентировать ваше внимание, потому что это один из ключевых вообще моментов в любых алгоритмов машинного обучения, да? То есть машинное обучение у нас всё-таки вышло изначально из статистики и активно использует его статистический аппарат, да? И, в частности, в статистике мы знаем, что не все методы статистики можно использовать для одних и тех же данных, для самых разных данных, да? Например, у нас есть такой базовый метод, который ещё и в школе проходит, но потом и на уроках статистики. Это среднее арифметическая. Кто-нибудь не может назвать, в чём проблема среднего арифметического? Для чего оно не подойдёт? Ну, оно удобно, как будто только для, ну, есть контрпример, его приводят всегда про среднее по больнице. То есть мы не всегда можем брать среднее арифметическое, потому что оно не даст нам средний результат по всем. Вот могут быть какие-то выбросы. >> Верно. Верно. Действительно. То есть, если у нас есть условные выбросы, например, там зарплаты в организации и там директор получает миллион руб., а все остальные 20.000, да, то средняя зарплата будет, условно говоря, полмиллиона рублей, но она будет совершенно не отражать, да. Соответственно, статистика нас учит, что перед тем, как использовать какой-то метод, мы должны оценить как-то эти данные и, э, понять, э, применим ли тот или иной метод к, мм, к этим данным, да? То есть мы в первую очередь смотрим распределение данных, да? Соответственно, если данные нормально распределены, да, то есть имеют колоколообразную форму, то это, соответственно, одни методы. Если они ненормально распределены, то мы возьмём какое-нибудь там сведение гармоническое или медиану или моду, да, они все немножко разные вещи показывают, хотя вроде бы похожи на одно и ну как будто бы вроде про одно и то же. Так вот, KNN является непараметрическим алгоритмом, то есть нас не особенно беспокоит, как именно
Данные распределены. Поэтому, в общем-то, если у вас достаточно какая-то простая задачка классификации, можно попробовать начать с него, да, соответственно, какие у него есть преимущественные недостатки.
В первую очередь он очень просто реализуется. То есть мы буквально сейчас с вами посмотрим, как это реализуется. Он не требует предварительного обучения. То есть, по сути, весь вообще суть процесса обучения этого алгоритма - это, ну, скажем так, расставление точек на график, да? Ну, даже оно не выполняется. То есть это всё-таки расставление точек на график - это человеческая операция, а машине не нужны графики для того, чтобы оперировать с числами, да? То есть, то есть, ей нужно просто загрузить набор данных с которые как-то между собой, э, взаимосвязаны. А, соответственно, новые данные могут быть добавлены достаточно быстро. И для настройки этого алгоритма у нас требуется всего лишь два параметра. Это, собственно говоря, значение k и функция расстояния, которые мы чуть попозже рассмотрим.
Э-э, значит, к недостаткам этого алгоритма относится то, что этот алгоритм очень плохо работает с многомерными данными, да, потому что мм он, чем больше у нас будет мерность этих данных, то есть, условно говоря, там что такое мерность? Это, ну, скажем так, количество осей или количество колонок в таблице. Вот чем больше будет этих колонок, тем больше алгоритму при добавлении новой какой-то точки. Вот мы хотим узнать, вот болеет у нас сейчас человек или не болеет. Чем чем больше параметров у нас есть, тем больше вычислений нам нужно производить. Чем больше у нас точек до этого было проанализировано, тем больше, опять же, нам нужно вычислений производить. Поэтому, а, со временем этот алгоритм начинает работать всё медленнее и медленнее, когда мы накапливаем всё больше данных. То есть это тот уникальный случай в машинном обучении, когда увеличение количества данных со временем только ухудшает работу алгоритма, а не улучшает его. А, и самое такое мерзенькое, что этот алгоритм плохо работает с так называемыми категориальными признаками, да? То есть это, условно говоря, например, там цвет, а-а, там, я не знаю, кошка, собака, лошадь, да? То есть что-то, что нельзя измерить числом, а просто относится к какому-то вот э классу, да, вот эти вот признаки, их очень плохо, что называется, можно нанести на график. Они плохо между собой соотносятся, да. Поэтому KNN всё-таки лучше работает именно с мм числовыми данными в как бы натуральной природе.
Так, ну и для демонстрации этого алгоритма мы должны будем импортировать некоторые библиотеки. Я думаю, что вы уже частично на практике с ними познакомились. Это, в первую очередь, библиотека панс для работы с таблицами. библиотека нам пай для различных вычислений, ну и прочие библиотеки.
Значит, что мы делаем? Мы с вами для начала должны загрузить датасет, да? Я взял готовый датасет, причём как раз-таки с сайта KGE, да? То есть можно прямо открыть эту страничку этой задачей, посмотреть, как это всё выглядит. То есть как обычно даются задачи, да? То есть это какое-то описание датасета, что в нём находится. И плюс здесь есть даже некоторая детализация. То есть можно примерно посмотреть, что там содержится, как данные по тем или иным стовцам распределены, да? То есть мы уже на основании вот этой странички можем делать какие-то предварительные выводы о том, а какие алгоритмы мы можем использовать. Соответственно, это датасет, который содержит данные про рак молочной железы. А, и здесь что я делаю? То есть в первую очередь я просто при помощи read csv и указанию URL скачиваю эту таблицу, да, загружаю её в объект Pandas, который называется Dataфame. С этим объектом мы можем всячески манипулировать, да, и в частности у него есть такой столбец, как диагноз. И я этот диагноз значит преобразую. То есть у нас здесь есть две метки. Метка М - это злокачественные опухоли, да? То есть, соответственно, чем у нас злокачественные? Отличается доброкачественное. Доброкачественное - это какое-то новообразование, которое вот выросло само по себе, и если вы его вырежете, то больше у вас ничего не будет. А злокачественные, они, соответственно, создают свои копии по всему организму, через кровеносную систему распространяются. И то, что вы удалили с десяток, не гарантирует вам, что у вас не осталось в организме э очагов заболевания, да. Поэтому мы, условно говоря, доброкачественные метки относим к условно здоровым людям, да, которых достаточно просто вылечить. А злокачественные - это те, кто, соответственно, болеет раком, кого лечить сложно. Ну, и я просто делаю переименование всего этой истории в единицу и ноль.
А, значит, почему единица и ноль - это опять же отсылка к статистике. Вы это будете часто достаточно встречать в различных задачах машинного обучения, да? То есть у нас есть в статистике так называемая а нулевая гипотеза, да? Нулевая гипотеза она говорит о том, что а данные э между собой никак не взаимосвязаны, да? То есть у нас полнейший хаос в данных, и мы не можем не сможем никак вы, э, найти в них никакой зависимости, да? Соответственно, э гипотеза один или альтернативная - это как раз-таки когда мы пытаемся доказать, что в этих данных всё-таки есть какая-то взаимосвязь, и мы можем выделить ярко, например, какой-нибудь класс, например, ээ больных людей, да? Соответственно, мы как раз-таки классом ноль обозначаем здоровых, а а классом один - это вот то, что мы должны будем уметь находить, да, то есть заболевших раком.
А, значит, следующее, что нам нужно сделать - это разделить наш набор данных на тестовую и проверочную на обучающую и тестовую выборки, да? То есть, ну, в данном ситуации это, ээ, скажем так, не сильно критично, но, вообще говоря, это один из ключевых аспектов машинного обучения. То есть мы всегда датасеты разбиваем на несколько наборов. На одном из наборе мы обучаем, на другом мы проверяем, что, э, алгоритм правильно обучился. И для нас очень важно, э, не смешивать между собой данные из этих наборов. Потому что проверять, чтобы алгоритм обучился, мы должны на каких-то новых уникальных данных. Иначе у нас есть опасность, что алгоритм э получит какой-то закон, а просто зазубрит данные, да? То есть, условно говоря, он выучит, как выглядели какие-то конкретные яблоки. Поэтому на, если мы ему покажем яблоко, которое он до этого видел, он скажет: "Да, это яблоко". покажем другое яблоко, допустим, зелёное, а до этого было красное, он скажет: "Нет, это не яблоко". Да, потому что он просто зазубрил конкретные яблоки. И нам вот нужно, чтобы он научился обобщать. А для этого мы данные должны физически разделить. Есть много разных способов разделения данных. Мы на них потом в дальнейшем ещё посмотрим. Но я использую такой метод, который называется маска. Он достаточно простой, но изначально, когда его увидите, это выглядит как что-то страшное и непонятное.
Значит, основная суть работы происходит вот здесь. То есть, что мы здесь делаем? То есть у нас есть некоторый вот наш набор, э, dataфреймame, который имеет э определённый размер, да, то есть у него какое-то количество записей. И количество этих записей мы можем получить при помощи функции L длина. А, значит, что мы делаем? Мы при помощи библиотеки нампу а вызываем оттуда метод randм, который генерирует, э, точнее подключаем библиотеку ренм и оттуда вызываем метод rent, который генерирует псевдослучайные числа от нуля до ээ единицы, да? То есть это вот какое-то число от нуля до единицы. Сколько будет этих чисел? Столько, сколько мы передадим вот сюда как параметр, да? Соответственно, мы передаём длину нашего датафрейма, то есть он сгенерирует столько случайных чисел, сколько у нас содержится записей. А что мы делаем дальше? Мы используем операцию больше, точнее меньше, а для сравнения, но сравнения чего с чем, да? То есть здесь у нас на выходе вот эта вот история, это у нас получился массив, да, или точнее список из случайных элементов от нуля до единицы аа по длине как набор датасета, да? И мы говорим: "Сравни каждую из ячеек этого списка с числом, ну, в данном случае 0,7. Поскольку данные у нас генерировались случайно, они, скорее всего, будут распределены, ну, их распределение будет близко к нормальному, да, поэтому мы можем ожидать, что, ну, скажем так, количество, э, значит, чисел той или иной категории, да, вот, скажем, там чисел в диапазоне от нуля до 0,1, чисел в диапазоне от 0,1 до 0,2 и так далее, да, их будет Ну, примерно поровну. Понятно, что в серединке будет побольше, покм поменьше, да, но примерно поровну таких чисел. И когда мы сравниваем каждую из этих случайных чисел с 07, мы по сути говорим: "Попадают ли вот спрашиваем, попадает ли то или иное число вот в диапазон больше 0,7? Да, и это означает, что мы по-хорошему должны, то есть результатом сравнения будет true либо false, да, то есть какое-то логическое высказывание. То есть в результате вот этой операции у нас получится также список из отдельных элементов по количеству равному количеству записей в датасете, но только уже содержащих не случайные числа, а true либо false. И этих true либо fse будет по количеству примерно как соотношение а 0,7 к 03, да? То есть примерно ээ 70% этих случайных данных у нас будет отнесено к одному набору и 30 к другому, да? Таким образом, мы случайным образом э выделим какие-то индексы, какие-то номера в э вот этом датасете и разделим их на две группы, да? Эти группы будут разделены через true или false, да? То есть, если мы будем выполнять эту операцию как бы множество раз, то каждый раз у нас будет выполняться один и тот же алгоритм. То есть мы будем случайным образом распределять элис вот примерно в этом соотношении, да? Соответственно, если мы хотим там соотношение поменять, мы просто меняем число, и у нас получается новая маска.
После того, как у нас появился вот этот вот список, который называется маска, мы говорим, что мы хотим извлечь в датафрейм, который называется train из нашего исходного датафрейма все элементы из вот этого, э, списка датафрейм, для которых э значение будет равно true, да? То есть он в trй датасет поместит вот как раз 70% от нашего исходного датасета. То есть он будет знать конкретные номера, какие нужно поместить в датасет. Соответственно, в тестовый, на котором мы будем проверять, что мы делаем? Мы вот эту маску обращаем, да, то есть используем операцию не, которая преобразует вот этот вот набор, э, то есть вот этот список true false на противоположный. То есть тоже true false, но то, что стало было true, стало false и наоборот, да? Поэтому мы обратные элементы загоняем во второй список. Таким образом, мы будем каждый раз случайно разделять ээ исходный список на две различные части, да, в определённом соотношении, да, соответственно, разделили, получили вот примерно такое количество значений, да. Ну, и, соответственно, мы можем при помощи оператора Head посмотреть, да, как примерно выглядят эти данные. Ну, чтобы если мы, допустим, их до этого ещё не видели.
А, соответственно, как же работает алгоритм вот этот вот KNN, да? Вот представим, что у нас есть, э, допустим, две координатные оси, да? То есть откуда вообще берутся эти координатные оси? Сколько этих координатных осей есть у тех или иных данных? Ну, на самом деле, вот каждая точка у нас на графики, это, по сути, одна запись в таблице, да, э, один набор данных. И у этого набора данных мы видим большое количество параметров. Соответственно, то, какое положение эта точка будет занимать на графике, это буквально значение вот этих вот параметров. Поэтому по факту, сколько у нас столбцов с параметрами, столько у нас и должно быть осей. То есть в данном случае у нас осей ого-го сколько, да, вот сколько осей. Но поскольку для нас представить такой график будет крайне сложно, мы его вот в таком виде не выводим, а представим себе, что у нас есть всего лишь два параметра, по которым мы отображаем эти точки на графике. И вот у нас есть некоторое количество точек. Мы по двум параметрам их поставили на график. При этом у нас есть ещё и третий параметр. Этот параметр, ну, условно говоря, ответ, да, то есть к какому типу относятся э те или иные данные. Ну, и в данном случае у нас есть два ответа. Ну, условно назвём их класс треугольник и класс квадрат, да. Мы, соответственно, вот таким образом как бы добавили третью ось за счёт того, что раскрасили эти точки в разные формы. И вот как же работает этот алгоритм, да? Вот у нас есть изначальный набор данных, которые мы, условно говоря, наносим на эти оси. Ну, это нам для, чтобы так вот визуализировать. Понятно, что никакой алгоритм, ни на какие оси их не относит. Он данные просто хранит в таблице. Мы же их визуализируем. И вот у нас появляется новая точка. У этой точки есть вот этот вот набор параметров, да? То есть мы знаем, где её разместить на графике, но при этом у неё нет конечного ответа, к какому классу оно относится. И мы должны этот ответ узнать. Как мы будем его узнавать? Ну, для начала, поскольку у нас есть параметры, мы поставим эту точку, условно говоря, на график, то есть разместим её на осях. И после этого мы будем измерять расстояние, да, для до соседних ячеек, да? То есть тут нужно понимать, что опять же это мы у нас ээ смотрим на график и видим, да, какие ближе, какие дальше. Машина какие вижи какие ближе, какие дальше, она не видит. Единственное, что она может сделать - это буквально посчитать физически расстояние до каждой точки, да? В этом и состоит суть ленивых вычислений, что мы будем в последний момент, когда нас спросят, э, к чему относится эта точка, мы её возьмём и будем вычислять расстояние до, э, других точек. После того, как мы эти расстояния все вычислили, мы сортируем эти точки по расстоянию, то есть выстраиваем их, ну, какой из них ближе, какой дальше, и начинаем отбирать по количеству, да? То есть обратите внимание, мы здесь как бы вывели какой-то кружочек, чтобы в этот кружочек попало, ну, в данном случае три объекта. И наш вывод о том, к какому классу относится вот этот вот наш новый объект, он основывается на на том, больше всего объектов какого класса находится рядом, да? То есть обратите внимание, мы сначала сделали, сказали: "Посмотри, три ближайших соседа". И он сказал: "Ну, из трёх ближайших соседей один квадрат, там один класс один и два класса два или два класса ноль". Да. Поэтому мы делаем вывод, что наш новый объект - это, скорее всего, класс треугольник. Но, э, то есть вот как раз вот этот наш название алгоритма K ближайших соседей, да, вот это слово K, оно как разтаки и обозначает параметр, сколько именно ближайших соседей мы выберем для рассмотрения. Потому что вот обратите внимание, мы немножко меняем ситуацию. То есть мы говорим: "А теперь смотри, не три ближайших соседа, а пять ближайших соседей". Да? И в этот случае ситуация кардинально меняется, то теперь у нас уже больше квадратов. И мы говорим о том, что у нас скорее это квадрат, нежели треугольник. Поэтому подбор параметра параметров и, в частности, параметра K очень сильно может повлиять на ответ. Ну, понятно. В идеале у нас, конечно, должно быть так, чтобы ээ наши вот эти кластеры, они сбивались в какие-то групки. И вот прямо вот таких вот смешений всё-таки не было, да? То есть это именно учебный пример, где я вам демонстрирую, как оно может быть. Но в идеале, если бы у нас там были треугольники все сосредоточены вот в этом облаке, а квадраты вот в этом. И когда мы воткнули бы точку вот здесь, мы бы лучше понимали, что это скорее квадрат, чем треугольник, да? Но опять же, всякое всякие ситуации бывают.
Теперь следующий вопрос. Как мы будем вообще определять вот это расстояние? И для этого у нас существует несколько способов, да? То есть у нас всегда практически в математике есть несколько а способов сделать одно и то же. И одним из самых популярных методов определения расстояния является так называемое евклидово расстояние. Вот его страшная пристрашная формула. Посмотрите, пожалуйста, на эту формулу и попытайтесь вспомнить, не видели ли вы что-то похожее ранее. Я вам даже сразу подскажу, вы точно что-то похожее видели и даже активно использовали в школе на уроках геометрии. Кто может сказать, что это такое? Что за формула? Ну, это расстояние между точками, ну, на плоскости. Хотя, >> ну, какая теорема активно использует этовклидовое расстояние? >> А, ну вообще теорема Пифагора, >> да? Теорема Пифагора, да. Но мы на самом деле можем сказать, что теорема Пифагора является частным случаем определения Евклидового расстояния, да? То есть математики вообще в целом всё любят обобщать. Поэтому вот эта формула, она у нас записана длямерного пространства, да? То есть надо понимать, что мы здесь вот на плоскости, да, вычисляем расстояние для двухмерного пространства. >> Вот если мы скину мне, ну, пять яндексстанций, >> так? Кто-то мне тут мешает своим разговором. >> Вот так вот прямо хороший. >> Раз-раз, >> пожалуйста, микрофоны все выключите. Вот. Соответственно, у нас э здесь вычисляется расстояние для двухмерной плоскости, да, но, вообще говоря, у нас здесь именно вотмерное пространство, поэтому мы должны вычислять это всё дело в nмерном пространстве. И, в частности, теорема Пифагора, она как раз-таки является теоремой для двухмерного пространства, да? Мы же здесь, то есть, что мы, как мы вообще вычисляем расстояние, да? Давайте внимательно посмотрим на а вот эту формулу и попытаемся её разобрать по косточкам, да? Представим, что у нас даже не двухмерное, а одномерное пространство. То есть, что такое одномерное пространство? Это у нас, ну, буквально прямая линия. на которой мы можем откладывать различные отрезки. И вот нам нужно выяснить расстояние от одной точки до другой на этой одной прямой линии. Как мы это сделаем? Ну, на самом деле, очень просто. Просто возьмём и вычтем как бы координату одной точки из координаты другой точки и получим как раз-таки расстояние между этими точками. А в чём проблема этих вычислений? в том, что мы, когда подставляем вот эту координату в формулу, не знаем заранее, какая из этих точек больше, да, какую из какой мы вычитаем. Поэтому у нас может положиться получиться как положительное расстояние, так и отрицательное расстояние. Но отрицательное расстояние нас не устраивает, да? У него нету какого-то геометрического, скажем так, смысла. То есть это уже не расстояние, если оно отрицательное. Поэтому мы должны каким-то образом избавиться от минуса. И один из самых простых способов избавления от минуса - это возведение в квадрат, да? Поэтому мы возводим эту разницу в квадрат таким образом, то есть, условно говоря, там 2 возводим в квадрат, будет 4. -2 возводим в квадрат, тоже будет 4, да. Таким образом, мы избавляемся от минуса, да? Соответственно, чтобы потом избавиться от квадрата, мы, соответственно, извлекаем квадратный корень, чтобы сделать обратную операцию. Но поскольку наши поскольку наше вот это вот расстояние оно у нас не в одномерном пространстве, а вмерном, то мы должны, чтобы получить общее итоговое расстояние, да, по формуле вектора, мы знаем, что это на самом деле сумма всех вот этих вот расстояний на разных пространствах, да? Поэтому мы по сути берём каждое из этих ээ пространств, да, и в них находим расстояние между вот какими-то двумя точками, да. Но надо понимать, что вот в чём как раз-таки проблема к э вот этого алгоритма в том, что когда у нас появляется новая точка, мы должны теперь посчитать расстояние от этой точки до каждой точки, которая у нас есть в датасете, да, и более того, для каждого параметра это расстояние рассчитать, да. Поэтому у нас сложность этого алгоритма растёт с количеством параметров и с количеством новых точек. Вот поэтому у, как я уже говорил, да, у любого алгоритма есть свои плюсы, есть свои минусы, да, Silвер буlletт не существует. Поэтому, с одной стороны этот алгоритм достаточно прост, но с другой стороны вы должны контролировать количество данных, которые у него будут для вычисления, да? То есть, возможно, со временем какую-то часть данных придётся выкидывать, э, чтобы там, если вы вычисляете опять же этот классификацию, ну, допустим, вы, аэ, делаете ээ там информационную систему для распознавания продуктов в холодильнике, да, и у вас там не будет стоять сверхмощной платы с нейронным ускорителем. Это, опять же, будет стоять какой-то микроконтроллер, да? Поэтому мы должны будем явно контролировать количество данных, чтобы холодильник в какое-то разумное время на своём сверхслабом процессоре смог классифицировать, что это яблоко, да, ну, и там занести его куда-то в какую-то свою базу данных, если у нас умный холодильник.
Ну, соответственно, давайте посмотрим, как это реализуется на практике. То есть понятно, что чаще всего алгоритм этот вы не реализуете самостоятельно. Да что такое? Этот алгоритм вы не реализуете самостоятельно. Вы, э, просто используете уже готовые алгоритмы из библиотек, да, но тем не менее, чтобы понимать, как он лучше работал, давай давайте мы просто посмотрим на код. Итак, этот код, я вам честно скажу, я вот украл в интернете, он не самый оптимальный, но, в общем-то, достаточно понятный. Значит, первая функция - это непосредственно функция вычисления евклидового расстояния, да? То есть мы сюда передаём два списка. Каждый из этих списков это является, по сути, одна из точек, да? То есть вот одна запись. И у этой точки есть большое количество параметров, да? И вот мы, соответственно, передаём эту точку целиком в виде списка со всеми её параметрами. Соответственно, вот у нас есть точка один, точка 2 и LН - это, собственно говоря, размерность вот этого массива, ну, любого из этих массивов, потому что, по идее, они должны быть одинакового размера. Ну, и, соответственно, сам алгоритм очень прост. То есть мы просто в цикле по длине массива, да, то есть по количеству точек, находим разницу, возводим её в квадрат. Да, прибавляем к общей сумме, которая у нас называется общая дистанция, и возвращаем в итоге математический квадратный корень из вот этого общего расстояния. То есть, то есть мы буквально реализовали в этой функции вот эту формулу для, а произвольных точек, да, с с точек с произвольным количеством параметров.
А, значит, следующий алгоритм, он как раз-таки для как раз набора данных и для какой-то одной точки, да? То есть у нас есть вот итоговый набор как бы обученных данных и есть какая-то точку точка, которую мы хотим проверить, к какому из как бы классов она относится, да? Мы, соответственно, аа выполняем в цикле вычисления этого самого евклидового расстояния от нашей вот этой точки до каждой из точки в датасете. И после этого мы, соответственно, полученные расстояние складываем в специальный список, который называется distances, да, то есть расстояние, и сортируем их по убыванию, да, то есть находим самых ближайших соседей из всех, да? То есть в данном случае это мы как будто бы вот их выстроили. И после этого мы возвращаем, а, вот этот список, а причём именно в количестве К, то есть мы указываем, сколько именно соседей вернуть, да? То есть мы из асортированного списка возвращаем только те, которых находятся ближе всего, да, в необходимом нам количестве.
А, ну, и, соответственно, последнее действие - это уже непосредственно работа с вот этим отсортированным списком. То есть мы в этом списке смотрим, кто какой из классов обладает большим количеством, да? То есть буквально при помощи операции со словарём увеличиваем э количество элементов того или иного класса, когда мы их понимаем, что вот это класс там один, мы там увеличили его, да, или класс два. То есть таким образом мы считаем, каких из классов средей этих ближайших соседей больше всего. И, соответственно, делаем в итоге вывод, к какому же классу мы должны отнести эту точку, да? В этом, по сути, состоит вся работа алгоритма, да. Ну, и вот здесь у нас как раз-таки пример отработки этого алгоритма, да, на как он работает. Мы видим, да, что в итоге у нас получается, к какому классу у нас относятся те или иные данные. И здесь мы подходим к такой важной теме, как метрики, да? То есть дело в чём? Мы же работаем с машинным обучением. То есть мы стараемся сделать так, чтобы большую часть процесса обучения алгоритм выполнял самостоятельно, и мы минимально принимали в этом участие. Да. И одним из тех вещей, которые алгоритм по-хорошему должен э выдавать, да, это мы должны каким-то образом вот машина обучилась, да, вот она выдаёт какой-то результат, и пускай даже вот мы там два раза её запустили и результат, э, два раза положительный или два раза запустили и два раза он выдал нам ошибку, да? То есть как мы можем судить в целом о том, насколько же наш вот этот ээ в целом алгоритм правильно или хорошо работает? Вот то, что он нам дважды выдал ошибку или дважды выдал правильный ответ. Это общая закономерность, да? То есть это касается любых данных, либо нам просто повезло или не повезло, да? То есть
Мы должны иметь какой-то автоматический способ оценить э достоверность ответов. И метрика - это как раз-таки именно какая-то формула, какая-то числовая величина, которая должна нам показать то, насколько достовер достоверен результат, насколько мы ему вообще можем доверять.
Значит, э одним из ключевых параметров метрики, э, является, э, взаимосвязь, то есть некоторая корреляция между точностью и величиной метрики, да? То есть корреляция может быть как прямая, так и обратная. То есть, условно говоря, прямая корреляция - это чем более качественный у нас - решение, тем больше величина метрики, да, что такое, что происходит? А обратная корреляция - это когда, соответственно, э чем больше у нас качество, тем меньше величина ветрики. Но на самом деле нам здесь не принципиально важна сама по себе вот эта взаимосвязь, да, чтобы была взаимосвязь между качеством и величиной, да, мы в конечном итоге, если корреляция обратная, можем ещё и как бы инвертировать её. То есть это не сложно. Самое главное, чтобы была вот эта взаимосвязь.
Соответственно, какие же метрики у нас существуют? И первая метрика, которая на которую мы посмотрим, которая чаще всего используется просто потому, что она, казалось бы, самая понятная, но, как мы сейчас увидим, она не самая идеальная. Это метрика, которая, а, называется Acura. Дословно её на русский язык часто неправильно переводят как аккуратность, да? Сейчас скорее принято называть её меткость. Ну или, чтобы не путаться, обычно так её называют акюuracy. Соответственно, это метрика, которая показывает долю правильных ответов алгоритма, да, и, соответственно, она вычисляется как отношение количества правильных ответов кличеству вообще в целом сделанных предсказаний. Да. Как вы думаете, в чём проблема такого подхода? Есть у вас какие-то может быть три теста и 66% верности, а может быть 3.000 и 1.000 неправильных результатов, это всё же многовато.
>> А, ну, с одной стороны, правильно, с другой стороны, так можно сказать практически про каждую метрику. Это не проблема конкретно акюресе, как будто бы. Либо я вас не понял до конца. Ну ладно, хорошо. Тут, наверное, действительно стоит сразу постоять на примеры, да? То есть смотрите, а одна из самых главных проблем от Юриси, а это то, что она работает с некоторыми идеальными данными, которые идеально поделены, ну, условно говоря, там пополам, да? То есть у нас есть так называемый баланс классов. То есть у нас условно, допустим, половина данных - это здоровые люди, по другая половина это данных - это больные люди, да? И в этом случае акюреси показывает достаточно качественный результат. То есть в этой ситуации прямо отлично она работает. Но представим, что наши данные несколько более реальны. А в реальных данных вполне себе может встретиться такое, что, а, допустим, у нас абсолютное большинство, там девять из десяти - это у нас здоровые люди и только один из десяти - это, соответственно, больной человек. И если мы представим себе какой-нибудь беспечный алгоритм, да, который вот просто посмотрел на эти данные, такой: "Ну, в большинстве случаев ээ здесь у нас будут нули". А поэтому я буду просто, когда меня будут спрашивать, всегда говорить, что ответ ноль. Да, с точки зрения алгоритма он как бы абсолютно прав, а, и всё у него хорошо, да? То есть, если мы посчитаем accuracy, да, для этого алгоритма беспечного, мы увидим, что акюреси 90%, да? То есть он всего лишь один случай из десяти даёт нам неправильный ответ, да. Но если мы говорим, допустим, про людей, которые здоровы или больны, да, то в данном случае наш беспечный алгоритм буквально убьёт этого человека, да, потому что он скажет ему, что он здоров. А если же мы возьмём какой-нибудь другой алгоритм, какую-нибудь там, допустим, нейронную сеть, которая, скажем, правильно всегда определяет заболевание, но при этом иногда у неё есть ложные срабатывания, и она на здоровых людей говорит, что они больные. Да, с точки зрения вот этой метрики у неё акюрес намного хуже. уже порядка ноль, э, тут написано 0,8, он скорее 0,7, да, но при этом, а, она будет спасать жизнь, да. Поэтому это как раз вот ярчайший пример того, что в данном случае метрика у более плохого алгоритма более высокая, да, и она никак не показывает в данном случае качество алгоритма, да? То есть первое - это значит дисбаланс классов, да? А, и в целом она у нас не показывает как бы разницу для разных классов. Она показывает, сколько раз она угадала правильно для одного ну для вообще всех классов. Нам мы не можем понимать, э, сколько из этих правильно угаданных здоровые, а сколько из этих правильно угаданных больные. Мы в целом берём правильно угаданные ответы.
А, соответственно, здесь, да, что такое здесь? Мы приходим к э снова возвращаемся к статистике, и мы должны пару слов сказать про такую вещь, как ошибки классификации. Да, у нас на самом деле есть два типа ошибок. А первые называется ложноположительные. или false positive. Это, соответственно, ошибки, когда мы отвергаем верную, э, нулевую гипотезу, да? То есть в данном случае это когда мы диагностируем болезнь у здорового пациента. И вторая - это, соответственно, fse negative, когда мы наоборот принимаем неверное, да, решение за верное, да, то есть в данном случае, когда человек на самом деле болен, мы говорим, что он здоров. А лучше эти ошибки можно представить, если изобразить все наши данные на вот, условно говоря, каком-то вот таком графике, да? То есть у нас вот есть все данные. Это вот данные - это всё точки. И, э, в данном случае вот эти прямоугольники, они как раз обозначают, а-э, реальное распределение классов, да, условно говоря. Здесь у нас, э, злокачественные, да, то есть это вот все наши больные, а здесь у нас все здоровые люди. И мы накладываем на эти два класса некий круг, который показывает вот то, что внутри круга это тех, те, кого мы правильно распознали как здоровые, а здесь, соответственно, тех, кого мы неправильно распознали. То есть в данном случае мы говорим о том, что они, э, не больные, хотя они больные. Да, и здесь же у нас ситуация наоборот, да? То есть здесь у нас внутри круга вот на правой половине false positive. Так, да, да. Соответственно, false positive, а здесь, соответственно, false true negative, да? То есть, ээ, вот это вот график, он как раз-таки отлично показывает взаимосвязь между, в целом всеми данными, которые у нас существуют. То есть у нас всего существует четыре виданых. А, правильно распознанные больные, неправильно распознанные больные, правильно распознанные здоровые, неправильно распознанные здоровые, да? Соответственно, два вида этих данных относятся к правильным ответам, два относятся к ошибкам. И, э, как раз мы вот эти понятия используем для того, чтобы лучше понять, как считаются другие метрики.
Значит, вторая метрика, которую мы посмотрим - это точность. Она у нас показывает долю объектов, которые названы классификатором как положительные и при этом действительно являющихся >> при этом действительно являющихся положительными, да? То есть визуально это можно представить себе как-то вот так, да, вот с точки зрения вот этого графика, да? То есть мы, э, смотрим отношение правильно предсказанных к всем предсказанным как больные, да? И таким образом э этот эта метрика, она как раз-таки, почему она называется точность, да? Потому что она как раз-таки смотрит отношения для какого-то конкретного класса. То есть мы можем посчитать точность как для больных, так и для здоровых, да? и, ну, соответственно, выявить вот эту метрику, а для какого-то конкретного класса, что может быть для нас критично для определённых классов, да, для определённых типов задач.
А, значит, третья метрика, которая называется полнота, показывает, какую долю объектов положительного класса, а, из всех объектов положительного класса нашёл алгоритм, да? То есть мы смотрим на э-э то, что он предсказал как правильное. А и при этом мы смотрим на, в принципе, все правильные ответы, ну, в смысле, точнее, на все, э, там, всех людей, которые больные, да. Таким образом, вот этот вот показатель, эта метрика, она охватывает показывает, насколько мы своими правильными ответами охватываем все возможные варианты или не все, да? То есть мы таким образом смотрим вот это вот соотношение, да? То есть сколько мы угадали правильно, да? Соответственно, она хороша у нас также в медицине, да, для выявления каких-то опасных заболеваний, когда у нас там мало случаев заболеваний среди всех данных, да, и мы хотим, чтобы все эти случаи заболеваний были охвачены полностью, как можно более полно.
А, ну и самая такая итоговая общая мера, которая достаточно часто используется, то есть мы не всегда можем решить, а какая из мер точность или полнота является для нас более важной, да? Поэтому есть, на самом деле, мера, которая одновременно использует и точность, и полноту. Это так называемая F1 мера. И она как раз используется, для неё расчёта используется точность и полнота, да? То есть мы их перемножаем, умножаем на два и делим на их сумму. И вообще говоря, вот эта формула, она является формулой среднего как сейчас среднего среднего гармонического, да? То есть среднее гармоническое - это как раз-таки то среднее, которое используется для относительных величин. То есть относительные величины - это величины, которые рассчитаны как отношение чего-то одного и другого, да? То есть это безмерные величины. И вот как раз-таки для того, чтобы получить среднее эносительных величин и используется формула среднего гармонического, да? Вот, причём есть ещё и дополнительная формула сбалансированной F-меры, да, куда вместо двойки вводится параметр бета. И этот параметр позволяет нам настраивать, что для нас более важно. То есть, если для нас более важна точность, то мы должны установить вот эту бету в диапазоне от нуля до единицы. Если же, соответственно, более важна полнота, то, соответственно, устанавливаем бета больше единицы, да, и, соответственно, значение той или иной величины будет больше учитываться в итоговой оценке.
Так, ну, здесь у нас демонстрация работы, значит, нашего алгоритма. Тут это мы уже видели, да. Ну и последнее, значит, что я хотел вам показать, это такой визуальный способ оценки качества работы алгоритма. То есть, о'кей, мы посчитали вот эти вот некоторые числа, да, там отношения, вот эти вот метрики. А, и мы хотим понять вообще, насколько эти метрики вообще охватывают данные, да? То есть попытаться как-то визуализировать эту историю. И для этого используется такой общий метод визуализации, которая называется по-русски матрица несоответствий или матрица ошибок. По-английски она называется confusion matrix, да? Это, соответственно, вот те самые классы, э, правильные, неправильные, да? То есть false positive, false negative, true positive и true negative выведены в виде некоторой таблички. Да, мы могли бы, конечно, написать какой-то специальный код, но как бы обычно это не требуется. То есть вот нам не нужно понимание алгоритма. А поэтому мы просто воспользуемся библиотекой CIT Learn. У неё есть такоя подбиблиотека, которая называется METX. То есть мы просто из неё импортируем функцию, которая называется confusion matrix. И она нам, соответственно, строит, ну, в данном случае, в текстовой форме вот такую вот матрицу, да? То есть здесь мы видим как раз вот true positive, false positive, false negative и true negative, да? То есть у нас по вертикали располагаются реальные значения, а по горизонтали располагаются предсказанные значения. Ну и в данном случае мы видим, что у нас в целом алгоритм отработал неп неплохо, да? То есть у нас 111 true positive, то есть мы 111 раз правильно предсказали заболевание, 52 раза не правильно предсказали отсутствие заболевания. Ну и 6 и5 - это у нас количество ошибочных элементов, да? Соответственно, таким образом можно в числовом виде быстро оценить качество работы алгоритма, да? Ну и надо понимать, что в данном случае это у нас табличка для всего лишь двух классов, да? Если классов больше, то таблица разрастается в каком-то большем виде. Плюс чаще всеё всего её и рисуют в каком-то всё-таки именно визуальном виде в виде. Э то есть числа вот эти накладывают прямо сюда в график и рисуют как-то их цветами, да? То есть чем больше число, тем более глубокий цвет, чтобы мы чисто визуально сразу могли оценить качество работы алгоритма. Yeah.