Практика EDA. Часть 1 | Анализ и обработка данных

Практика EDA. Часть 1

Все курсы > Анализ и обработка данных > Занятие 4 (часть 1)

На прошлом занятии мы изучали различные классификации данных, задачи EDA, а также познакомились с основными библиотеками для создания визуализаций. Сегодня мы свяжем эти концепции в практической работе по анализу датасета «Титаник» и датасета Tips.

Откроем ноутбук к этому занятию

В первую очередь подготовим датасеты.

Подготовка данных

Датасет «Титаник»

Скачаем обучающий датасет Титаник, подгрузим его в сессионное хранилище Google Colab и импортируем в ноутбук.

Как мы уже знаем, посмотреть на первые или последние несколько (по умолчанию, пять) значений можно с помощью методов .head() и .tail() соответственно.

датасет Titanic, первые три значения с помощью метода .head()

Иногда для получения более объективного представления о данных удобно использовать метод .sample(), который по умолчанию выдает одно случайное наблюдение.

датасет Titanic, пять случайных наблюдений с помощью метода .sample()

Метод .info() для каждого столбца выводит количество непустных (not-null) значений и тип данных. Кроме того, этот метод считает количество столбцов каждого типа и общий объем памяти, занимаемый датасетом.

Конечно, посмотреть количество пропусков удобнее, например, с помощью последовательного применения методов .isnull() и .sum().

Теперь выполним несложную предобработку данных.

Более сложные методы обработки данных мы рассмотрим в третьем и четвертом разделах курса.

Датасет Tips

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

датасет Tips библиотеки Seaborn

Вновь воспользуемся методом .info().

Пропущенных значений в этом датасете нет.

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

Описание данных

способы описания данных в EDA

Категориальные переменные

Методы .unique() и .value_counts()

Применение этих методов аналогично использованию метода библиотеки Numpy np.unique() с параметром return_counts = True. Применим его.

Теперь воспользуемся методами библиотеки Pandas.

При этом для нахождения относительной частоты делить на общее количество строк не нужно. Достаточно указать параметр normalize = True.

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

df.describe()

Исследование качественных переменных удобно начать с метода .describe(). Его применение к категориальным столбцам выдаст:

  • общее количество значений (count)
  • количество уникальных значений (unique)
  • наиболее часто встречающееся значение (top)
  • и количество таких значений (freq)

Применим метод .describe() к столбцам Sex и Embarked.

метод .describe(): категориальные данные

Перейдем к графическим методам.

countplot и barplot

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

Проще всего countplot и barplot построить с помощью библиотеки Seaborn.

функция countplot() библиотеки Seaborn
функция barplot() библиотеки Seaborn
функция barplot() библиотеки Seaborn: относительное количество наблюдений

В библиотеке Matplotlib мы можем построить только barplot (функция bar()). Отдельного инструмента для построения countplot в ней нет. Количество наблюдений мы можем найти с помощью метода .value_counts().

функция bar() библиотеки Matplotlib

Горизонтальную столбчатую диаграмму (horizontal barplot) можно построить с помощью функции barh().

функция barh() библиотеки Matplotlib

Снова воспользуемся параметром normalize = True метода .value_counts() для нахождения относительной частоты каждой категории признака.

функция bar() библиотеки Matplotlib: относительная частота наблюдений

Для того чтобы построить такой график в библиотеке Pandas, вначале необходимо сгруппировать данные по столбцу Survived, затем выбрать один столбец (например, PassengerId), посчитать количество наблюдений в каждой группе через метод .count() и наконец построить столбчатую диаграмму с помощью метода .plot.bar().

столбчатая диаграмма в библиотеке Pandas: метод .groupby() и метод .count()

Код можно упростить, если сначала выбрать желаемый признак (столбец), затем воспользоваться методом .value_counts() и наконец применить метод .plot.bar().

столбчатая диаграмма в библиотеке Pandas: метод .value_counts()

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

Количественные данные

df.describe()

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

метод .describe(): количественные данные

Как мы видим метод выдает:

  • count — количество наблюдений
  • mean — среднее арифметическое
  • std или standard deviation — среднее квадратическое отклонение
  • min и max — минимальное и максимальное значения, а также
  • 25%, 50% и 75% — первый, второй (он же медиана) и третий квартили

Здесь будет полезно сделать небольшое отступление и ближе познакомиться с новыми для нас способами оценки данных.

Среднее арифметическое и СКО

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

Квантили и робастная статистика

В этом смысле медиана дает более надежную оценку среднего при наличии выбросов.

Статистические методы и алгоритмы, устойчивые к выбросам и менее зависимые от предположений (assumptions) модели, еще называют робастными (robust statistics).

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

пример расчета медианы: нечетное количество чисел

Если количество чисел четное — два срединных значения складываются и делятся на два.

пример расчета медианы: четное количество чисел

Медиану можно также определить как значение, которое наши данные (или случайная величина) не превышают с вероятностью 50 процентов (отсюда знак % в выводе метода .describe()).

Аналогично можно найти, например, значение, которое величина не будет превышать с вероятностью 25 или 75 процентов. Такие значения будут называться первым и третьим квартилями (quartile, от латинского — quarta, «четверть»), потому что они делят распределение на четыре части. По-английски первый, второй и третий квартили принято обозначать как Q1, Q2 и Q3.

первый, второй (медиана) и третий квартили

Кроме этого, можно найти децили (deciles, делят распределение на десять частей). Наконец, если мы хотим найти конкретное значение, то будем искать квантиль (quantile). Если вероятность выражена в процентах, то квантиль принято называть процентилем или перцентилем (percentile).

Вывести конкретный процентиль в методе .describe() можно с помощью параметра percentiles.

метод .describe() с параметром percentiles, примененный к количественным данным

Закрепим полученные знания, проанализировав приведенные выше метрики.

  • Медианное значение обоих признаков чуть ниже среднего арифметического
  • 40 процентов чаевых были ниже 2,48 доллара
  • 99 процентов чеков были ниже 48,23 доллара

Рассмотрим еще одну очень полезную меру разброса.

Межквартильный размах

Межквартильный размах (interquartile range) — робастная (устойчивая к выбросам) альтернатива среднему квадратическому отклонению. Рассчитывается как разница между третьим (Q3) и первым (Q1) квартилями.

пример расчета межквартильного размаха

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

Гистограмма

С гистограммой мы уже знакомы.

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

Построим несколько графиков с использованием рассматриваемых нами библиотек.

гистограмма в библиотеке Matplotlib
гистограмма в библиотеке Pandas
гистограмма в библиотеке Seaborn
построение гистограммы с помощью функции displot() в Seaborn

Обратите внимание, что функция называется именно displot(), а не distplot()⧉, которая объявлена устаревшей и не рекомендуемой к использованию (deprecated).

гистограмма в библиотеке Plotly Express

Что можно сказать после изучения этих графиков? Распределение скошено вправо (skewed right или positively skewed), т.е. в нем есть несколько чеков на достаточно большую сумму, которые и создают правый «хвост».

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

Когда медиана меньше среднего арифметического, мы наблюдаем скошенное вправо распределение.

В целом соотношение скошенности распределения со средним арифметическом, медианой и модой приведено на графике ниже.

среднее арифметическое, медиана и мода в симметричном и скошенных распределениях

График плотности

С графиком плотности (density plot) мы столкнулись при изучении нормального распределения и модуля random.

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

Построим такой график с помощью библиотеки Seaborn.

график плотности в библиотеке Seaborn

Добавлю, для справки, что в Seaborn значение параметра kde расшифровывается как kernel density estimation (ядерная оценка плотности), непараметрический способ оценки плотности случайной величины.

boxplot

После знакомства с квантилями и робастной статистикой понимание графика box plot или как его еще называют box-and-wisker plot (ящик с усами) не вызовет сложностей.

анатомия графика boxplot

В первую очередь замечу, что boxplot строится на проранжированных по возрастанию данных. Теперь обратим внимание на сам «ящик» (box):

  • его левый край отражает первый квартиль (Q1) или 25-тый процентиль (25%)
  • вертикальная полоса посередине — медиана, второй квартиль (Q2) или 50-тый процентиль (50%)
  • правый край, соответственно, третий квартиль (Q3) или 75-тый процентиль (75%)
  • ширина ящика равна межквартильному размаху (IQR)

Усы (whiskers), то есть линии с ромбами на концах, отражают разброс данных за пределами IQR и рассчитываются как функция от этого значения. Данные, которые находятся за пределами этого диапазона, считаются выбросами (outliers).

Давайте построим этот график с помощью Seaborn.

boxplot в библиотеке Seaborn

Проверим расчет межквартильного размаха и усов. Вновь посмотрим на результат метода .describe().

результат метода .describe() в библиотеке Pandas

Первый и третий квартили (13,35, 24,13), а также медиана (17,80) соответствуют графику. Рассчитаем IQR.

$$ \text{IQR} = \text{Q3}-\text{Q1} = 24,13-13,35 = 10,78 $$

Теперь определим длину «усов».

$$ \text{left} = \text{Q1}-1,5 \times \text{IQR} = 13,35-1,5 \times 10,78 = -2,82 $$

$$ \text{right} = \text{Q3}+1,5 \times \text{IQR} = 24,13+1,5 \times 10,78 = 40,3 $$

Как мы видим, значения на графике совпадают с нашими расчетами. Аналогично мы можем воспользовать библиотекой Plotly.

горизонтальный boxplot в библиотеке Plotly
вертикальный boxplot в библиотеке Plotly

Также приведу код для библиотек Matplotlib и Pandas.

Гистограмма и boxplot

Гистограмма, с одной стороны, и boxplot, с другой, имеют свои достоинства и недостатки. В частности,

  • Гистограмма хорошо выявляет полимодальность (то есть несколько мод, «горбиков» в данных), при этом она сильно зависит от выбранного количества интервалов и не показывает выбросы.
  • boxplot наоборот, показывает выбросы, но не справляется с полимодальностью.

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

Вначале построим совмещенный график с помощью двух библиотек: Matplotlib и Seaborn. Первую мы будем использовать для создания подграфиков (рассмотрены ниже) и подписей, вторую — для самих визуализаций.

совмещенный график: гистограмма и boxplot, библиотеки Matplotlib и Seaborn

В Plotly такой график можно построить с меньшим количеством кода.

гистограмма + boxplot в Plotly

Прежде чем перейти к нахождению различий между признаками, еще раз приведу график плотности и boxplot нормального распределения c показателями среднего арифметического, СКО ($\sigma$, сигма), медианы и остальных квартилей, межквартильного размаха (IQR) и других метрик.

нормальное распределение: график плотности и boxplot
Источник: Википедия

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

Перейдем ко второй части занятия.