Школа данных Билайн. Как прошло мое 3-е занятие

Рассказываю о Школе данных Билайн, где слушаю курс "Введение в машинное обучение". Делюсь впечатлениями о третьем занятии. 



Как и предыдущие, третье занятие проходило весьма энергично. Начали с обсуждения домашнего задания. Мне оно показалось сложным, сказывается отсутствие знакомства с пакетами Pandas и Seaborn. Хотя потратил часов 15, так и не смог все задачи решить. Кроме того, некоторые задания были сформулированы так, что можно было трактовать их по-разному. Также участники высказали пожелания уделять меньше внимания теоретическим вопросам типа обзора задач Линейной алгебры и больше - практическим аспектам решения этих задач.

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



По нашей просьбе лектор еще раз "пробежался" по основным методам библиотеки Seaborn.

В Seaborn вместо гистограммы используется .distplot(dataframe_name['параметр'], kde=False)
Параметр отобразится по оси абсцисс.


Можно оси подписать .axlabel и задать стиль раскраски .set_style

sns.distplot(girls['Height'], kde=False)
sns.axlabel('Playboy girls height', 'Frequency')
sns.set_style('darkgrid')

Получим еще более симпатичный график


Еще одна удобная и распространенная визуализация - это .boxplot или "ящик с усами". Строится зависимость непрерывного признака от категориального.

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

def weight_category(weight):
    return 'heavier' if weight > 54\
            else 'lighter' if weight < 49 else 'median'

girls['weight_cat'] = girls['Weight'].apply(weight_category)
sns.boxplot(x='weight_cat', y='Height', data=girls)


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

Скачиваем data frame.
Можно посмотреть - в табличке всего 7 наблюдений, автор статьи усматривает в них некоторую зависимость.



Понятно, что 7 наблюдений маловато для того, чтобы строить какие-то модели, но нам для тренировки подойдет.

Выполним сортировку по Score

df.sort_values('Score', 
               ascending=False, 
               inplace=True) 

Посмотрим на статистику

df.describe().T 



Можно нарисовать boxplot методами Pandas.Пользуемся надстройкой над методом mathplotlib. Задаем аргумент box, чтобы боксплот нарисовать для признаков Drugs и Score. Можно наблюдать средние, медианные значения, выбросы.

df.plot(kind='box') 



Если изменить аргумент функции на 'bar', получим столбчатую диаграмму, где значения Score показаны в зависимости от признака Drugs.

df.plot(x='Drugs', y='Score', kind='bar') 


Лучше всего зависимость видна на скаттер графике, здесь тенденция вполне проявлена.

df.plot(x='Drugs', y='Score', kind='scatter') 


Pandas позволяет быстро строить различные графики, например, чтобы построить в Pandas гистограмму, достаточно будет строки:

df['Drugs'].gist()

Можно оценить корреляцию Пирсона, получаем весьма сильную корреляцию -0.93.

df.corr(method='pearson')


Возможен также JointPlot, но это уже, как говорится "подробности".

# sns.regplot(x='Drugs', y='Score', data=df)
sns.jointplot(x='Drugs', y='Score', 
              data=df, kind='reg')

Чтобы вы представляли себе темп, с которым идет занятие, на всю вступительную часть ушло порядка 13 минут.

Далее приступили к практике по визуализации и первичному анализу данных. Нужно было построить образцы гистограмм, боксплотов и т.п. картинки на основе датафрейма, созданного на основе известного соревнования Kaggle Titanic. Работать можно либо в облаке SageMathCloud, либо на своем ноуте, где установлена сборка Jupyter. Задания для работы в класса и домашку нам раздают через облако, также для локального использования данные дублируют на Yandex.Диск.

Итак, что же предлагалось сделать:


Считываю обучающую выборку в train_df , с этим pandas-датафреймом и буду теперь работать.

Смотрю, как оформлены данные в датафрейме - .head(10) извлекает из датафрейма первые 10 строк с заголовками столбцов.


Приглядимся к таблице подробнее, функция .describe(include='all') выдает краткую первичную статистику по базе данных. Поскольку видно, что признаки Age и Embarked содержат пропуски, заполняем их медианными значениями, используя функции .fillna и .median()  Медианные значения для Age берем из обучающей выборки. Для параметра Embarked заполняем пропуски значением 'S', как самым распространенным. 


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


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

Вначале я написал неправильный вариант кода, перепутав местами x и y.

sns.boxplot(x='Fare', y='Pclass', data=train_df)



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

sns.boxplot(x='Pclass', y='Fare', data=train_df)


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

Предлагаемое в тетрадке решение: создайте признак Fare_no_out - стоимости без выбросов, в котором исключаются стоимости, отличающиеся от средней по классу более чем на 3 стандартных отклонения. Важно: Надо исключать выбросы именно в зависимости от класса каюты. Иначе исключаться будут только самые большие (1 класс) и малые (3 класс) стоимости.

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

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


А я перешел к следующему пункту: Каково соотношение погибших и выживших в зависимости от пола? Отобразите c помощью Seaborn.countplot c аргументом hue.

Для визуализации соотношений удобно использовать "каунтплоты" .countplot(x='Параметр1', hue= 'Параметр2', data=имя_датафрейма), которые показывают зависимости по двум категориальным признакам, названия параметров указываются по осям и в "легенде".

Видно, что женщин в процентном отношении выжило существенно больше, чем мужчин.

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


На самом деле решение было простым, но это я уже дома доразобрался.

sns.countplot(x='Pclass', hue='Survived', data=train_df)

Видим, что в 3-м классе выживали намного меньше, чем во-втором, а наибольшую выживаемость демонстрируют пассажиры первого класса - они и к шлюпкам были ближе, и спасали их в первую очередь.

Графическая проверка зависимости выживания от возраста

train_df.plot(x='Survived', y='Age', kind='box')

или куда более наглядный вариант с Seaborn:

sns.boxplot(x='Survived', y='Age', data=train_df) 

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

С вычислением Fare_no_out я не справился.

Для понимания темпов - до этого места нужно было добраться за 33 минуты от начала занятия.

Далее Юрий Кашницкий, который читает нам этот блок лекций, быстро пробежался по решению задач.

с 37-й минуты. Начался разбор новой темы:

Обучение с учителем. Задачи классификации и регрессии
  • Практическое задание. Визуальный анализ данных пассажиров "Титаника"
  • Обзор библиотеки Scikit-learn
  • Дерево решений в задаче классификации
  • Дерево решений в соревновании Kaggle Inclass по автострахованию
  • Извлечение признаков. Пример с набором данных Titanic
  • Домашнее задание 3. Дерево решений и случайный лес в задаче предсказания выживания пассажиров "Титаника"
Дальше не буду подробно рассказывать о том, что происходило в следующие 2 часа. (Да, мы постоянно выходим за границы официальных 2 часов занятия на 20-30 минут, материалов действительно много, иногда возникают вопросы у обучаемых и в итоге задержка получается с завидным постоянством).

Поговорили об основных алгоритмах, поддерживаемых библиотекой Scikit-learn.
  • Линейные модели (Ridge, Lasso, Elastic Net, ...)
  • Ансамбли (случайный лес, бэггинг, градиентный бустинг, ...)
  • Машина опорных векторов (SVM)
  • k ближайших соседей (kNN)
И о шпаргалке, подсказывающей выбор алгоритма


О том, что в scikit-learn удобный API, что позволяет писать собственные классы - достаточно скормить алгоритму обучающую выборку

class Estimator(object):
    def fit(self, X, y=None):
        """Fits estimator to data."""
        # set state of ``self``
        return self

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

def predict(self, X):
        """Predict response of ``X``."""
        # compute predictions ``pred``
        return pred

Очень бегло нам рассказали об SVM, а заодно о наборах данных USI Machine Learning repositary  http://archive.ics.uci.edu/ml/ очень популярных в машинном обучении.

и далее совсем кратко.

с 43-й минуты. Пробежались по теме кросс-валидации результатов, опасности переобучения, вариантах выделения тестовой выборки, вот об этом всём, выборе k.

с 60-й минуты. Обсудили "дерево решений".  Почему они популярны. Кредитный скоринг. Игра в 20 вопросов. Энтропия Шеннона. Пример предсказания цвета шарика по координате. Интерпретируемость методов (случайный лес - не интерпретируемый).

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

с 88-й минуты. Пример применения алгоритма дерева решений к страхованию автомобилей. Подготовка данных. Навеска меток (scikit-learn не умеет работать с категориальными признаками). Добавление dummy-переменных. Проблема непопадания данных для ряда брендов. Добавление колонок с нулевыми данными. Глубина дерева. Как формировать данные для отсылки результатов на Kaggle. Фунция .gini (Джини импьюрити). Вывод дерева в формате .pdf  Отправка файла на Kaggle.

со 115-й минуты. Функция GridSearchCV и ее применение. Распараллеливание процессов. Приходим к дереву глубины 3. Обучение случайного леса. Параметры.

со 122-й минуты вернулись к примеру Титаник. Поговорили о составлении обучающей и тестовой выборок. Попробовали на выборке алгоритм Случайный лес. Что можно "вытащить" из исходных признаков? Создание нового категориального признака, заменяющего числовой признак.

с 127-й минута.  "Пробежались" по домашнему заданию. Нужно будет с теми же данными Титаника разобраться, как обучить дерево решений, как настроить его параметры, как обучить случайный лес. Проверили все ли зарегистрировались на Kaggle. Рассказали подробнее об устройстве соревнований Kaggle.

134-я минута. Занятие завершилось.

Надеюсь, вы получили неплохое представление о том, что происходит на занятиях по теме "Машинное обучение" в Школе Данных Билайн. Пожелайте мне успехов в прохождении курса!

+ +

Также по теме:

- Анонсы: Data-MBA для менеджеров и бизнесменов (c 16 февраля)
- Школа данных Билайн. Как прошло мое первое занятие
- Анонсы: Завтра у меня первое занятие в Школе данных Билайн

UPD:

Отправил свое домашнее задание на соревнования Kaggle




Комментариев нет:

Популярные сообщения

Желающие следить за новостями блога, могут подписаться на рассылку на follow.it (отписаться вы сможете в один клик). 

Еще можно подписаться на Telegram-каналы @abloud62 @abloudrealtime, где также дублируются анонсы практически всех новостей блога. 

 

Translate