[ЗАСТАВКА] В этом модуле мы
продолжим изучать возможности библиотеки sklearn.
Напомню, что ранее мы уже успели обучить несколько линейных моделей,
но практически всегда мы использовали параметры, заданные по умолчанию.
Настало время это исправить и ответить на вопрос:
как же параметры модели влияют на ее качество?
И каким образом можно подбирать параметры, оптимальные для решаемой задачи?
В этом видео мы будем рассматривать модуль grid_search в библиотеке sklearn и
научимся подбирать параметры модели по сетке.
Для начала давайте импортируем необходимые модули.
И снова здесь только модуль grid_search, который мы будем рассматривать.
И теперь сгенерируем данные.
Воспользуемся датасетом «ирисы Фишера» и разобьем его на обучение и
тест с помощью функции train_test_split.
Теперь давайте выберем модель — пусть это будет
SGD-классификатор — и создадим объект с параметрами по умолчанию.
Теперь можно подбирать параметры.
Для начала давайте посмотрим, какие же степени свободы у нас есть,
какие параметры, вообще говоря, мы можем подобрать.
Для этого воспользуемся методом get_params, который вернет нам словарь,
и посмотрим, какие ключи у нас есть.
Так, ну мы видим, что доступен целый ряд параметров, который можно подбирать.
Ну, давайте будем подбирать только несколько.
С одной стороны, можно выбрать вид функции потерь, будем рассматривать hinge,
log, squared_hinge и squared_loss.
Также давайте выберем вид регуляризации — выберем между l1 и l2.
Также можем подобрать количество итераций — давайте подбирать от 5 до 10,
по умолчанию у нас 5 итераций.
И выберем коэффициент alpha — это множитель перед регуляризацией.
По умолчанию у нас доступно значение 0,0001.
Ну, вот давайте создадим отрезок от 0,0001 до 0,001,
бросим на него равномерно пять точек и будем использовать их в качестве весов.
Это можно сделать с помощью метода linspace.
Итак, создадим наш словарь.
В данном случае в качестве сетки мы будем использовать словарь,
у которого ключ — это название параметра, который мы подбираем.
Видите, что эти названия совпадают с названиями из get_params.
А в качестве значения идет набор значений, которые мы хотим проверить.
Таким образом, если мы построим декартово произведение на этих параметрах,
то мы получим точки со всеми возможными наборами параметров.
Собственно, это нам и хочется получить.
Мы хотим в каждой из этих точек измерить качество классификации, далее сравнить,
посмотреть, где качество максимальное, и сказать,
что вот это есть оптимальные параметры.
Это такой метод полного перебора на множестве параметров, и, в общем-то,
он и называется поиском по сетке.
Итак, давайте создадим стратегию кросс-валидации,
с помощью которой мы будем оценивать качество.
В данном случае я использую ShuffleSplit, буду делать 10 итераций,
и в тестовую выборку будет идти 20 % данных.
И теперь можно перейти непосредственно как бы к подбору параметров.
Для начала давайте создадим объект grid_search,
с помощью которого мы будем это делать.
Данному объекту нужно обязательно передать модель,
которую мы хотим оптимизировать — в данном случае наш SGD-классификатор.
Также нужно передать сетку с параметрами, по которой мы будем бегать.
Нужно указать метрику, которую мы будем проверять, и стратегию кросс-валидации.
Таким образом, мы будем искать модель, наилучшую с точки зрения метрики accuracy,
оцененную с помощью нашей стратегии кросс-валидации.
Итак, наша сетка-объект готов, теперь давайте обучим сетку.
Делается это с помощью метода fit.
В процессе обучения у нас будет оценено качество в каждой из точек,
и мы с вами потом сможем найти оптимальную.
Вот давайте запустим.
Работает это небыстро, потому что, смотрите,
мы с вами перебираем четыре варианта функции потерь, две регуляризации,
пять значений для количества итераций и пять значений для коэффициента alpha.
Если все это перемножить...
так, сколько мы получим?
Получим 200 комбинаций — ну, довольно много.
А еще мы делаем кросс-валидацию.
Так, ну вот видим, что в несколько секунд мы уложились.
Теперь давайте анализировать результаты.
Ну, прежде всего, нас интересует самый лучший классификатор — его можно найти с
помощью команды best_estimator.
Видим, что здесь нам возвращается модель с лучшими параметрами.
Отдельно можем попросить best_score,
или оценку на лучшем наборе параметров, и, собственно,
вывести лучшие наборы параметров в виде вот просто словаря параметров.
Давайте это сделаем.
Используются методы best_score и best_params.
Так, смотрим, что лучшая оценка — это 0,895 для accuracy.
И какие у нас наборы параметров получились?
Регуляризация — l1, а коэффициент alpha — 9 итераций, и функция потерь — hinge.
Так, ну, часто нам хочется посмотреть не только на лучший набор параметров,
но и увидеть оценки на всех возможных наборах.
Почему это полезно?
Ну мы хотим проанализировать, каким образом каждый из параметров или
комбинация параметров влияет на качество — собственно,
для этого можно посмотреть на все остальные значения.
И также можно узнать, насколько наша лучшая оценка лучше, чем, скажем,
следующая.
Вот получить весь набор доступных данных можно с помощью метода grid_scores.
Ну, давайте мы весь выводить не будем, для примера выведем первые 10 значений.
Ну, вот мы видим,
что нам доступна средняя оценка качества по кросс-валидации, доступно отклонение и,
конечно же, наборы параметров, на которых эта оценка была достигнута.
Теперь давайте ответим на вопрос: всегда ли для нас оптимально
использование такой стратегии поиска по сетке?
Ну что это значит?
В данном случае мы с вами работали с небольшим датасетом, обучение модели
занимало не очень много времени, поэтому мы уложились в несколько секунд.
Представьте себе обратную ситуацию.
Если бы мы работали с большим набором данных, где было бы много признаков и
много объектов, каждая модель обучалась бы значительное количество времени и мы бы
хотели действительно подобрать много параметров.
Тогда этот процесс занял бы существенное время,
и с точки зрения вычислительной эффективности, возможно,
нам было бы не так выгодно использовать полный перебор по сетке.
Какие есть альтернативы?
Можно использовать случайный поиск по сетке.
Почему это, в принципе, может быть выгодно?
Вот представьте, что мы с вами имеем большую сетку параметров.
Что, если мы возьмем и оценим качество в каких-то случайных точках по этой сетке?
Тогда мы сможем проанализировать полученный результат, посмотреть,
как некоторые сочетания, некоторые наборы параметров влияют на качество,
и на основе этого каким-то образом сузить область поиска.
Например, мы можем откинуть заведомо неоптимальные параметры — параметры,
которые...
на которых всегда достигается худшее качество модели.
После того как мы это сделаем,
мы можем сузить область поиска и снова провести некоторую оптимизацию — например,
опять запустить поиск по сетке или воспользоваться другим алгоритмом.
Таким образом, эта стратегия кросс-валидации, вернее,
стратегия подбора параметров также является очень полезной.
Вот давайте посмотрим, как это можно делать.
Для этого нам нужно создать другой объект, так называемый RandomizedSearchCV,
которому мы также передаем те же самые параметры — обязательно нужно сказать,
какую модель мы хотим оптимизировать.
Передаем сетку, говорим, какая метрика нас интересует,
указываем стратегию кросс-валидации, и дальше основное отличие в том,
что мы говорим, сколько итераций мы хотим сделать.
Фактически это означает, сколько точек из нашей полной сетки мы проверим.
Вот давайте для примера проверим в 10 раз меньше точек — всего лишь 20 —
и посмотрим, насколько сильно от этого ухудшится наше качество.
Понятно, что это некоторый случайный результат, потому что в зависимости
от того, каким образом мы инициализировали сетку, мы проверим разные точки,
но в целом можно сделать некоторое приближение и понять вообще,
насколько мы ухудшим качество за счет того, что сузим область поиска.
Вот давайте это сделаем.
Объект создан, теперь снова вызываем метод fit и заодно замерим,
как долго он будет работать.
Ну, вот видим, что работает он меньше секунды, очень быстро.
Теперь давайте также посмотрим на оценку качества лучшей точки и на
лучшие параметры.
Мы видим, что наша оценка изменилась в третьем знаке, не сильно ухудшилась.
И теперь давайте проанализируем параметры.
Видим, что изменился только коэффициент alpha, вид функции потерь,
вид регуляризации и количество итераций осталось прежним.
Теперь вы можете либо продолжить процесс оптимизации из этой точки,
либо остановиться на найденном наборе параметров.
А мы с вами на этом заканчиваем.
На этом видео мы научились подбирать параметры моделей с помощью поиска по
сетке и случайного поиска по сетке.
Это означает, что теперь вы умеете не только генерировать модельные данные,
строить модели и оценивать их качество, но также оптимизировать модели.
Это означает, что теперь мы можем собрать вместе все полученные знания и попробовать
решить настоящую задачу.
Именно этим мы и займемся на следующем видео.