Как понять «ящик с усами»
Непонятная большинству простых смертных штука под названием "диаграмма разброса" (или «ящик с усами» или боксплот) весьма полезна в статистике. Попробуем разобраться, что это за зверь, как его строить и читать.
Боксплот — это стандартизированный способ отображения распределения данных на основе сводки из пяти чисел: минимум, первый квартиль (Q1), медиана, третий квартиль (Q3) и максимум. «Ящик» может показать выбросы и их значения, симметричность данных, насколько плотно они сгруппированы, не перекошены ли, и если перекошены, то как.
Что такое «ящик с усами»
Для некоторых наборов данных вам понадобится чуть больше, чем просто меры центральной тенденции (медиана, среднее и мода).
Вам нужна информация об изменчивости или дисперсии данных. Боксплот — это график, который дает наглядное представление о распределении значений. Кому-то он может показаться сложным в сравнении с гистограммой или графиком плотности распределения, но он очень информативен.
Анатомия боксплота
Вот составляющие «ящика с усами»:
Медиана (Q2 или 50% процентиль) — среднее значение набора данных.
Первый квартиль (Q1 или 25% процентиль) — среднее число между наименьшим числом (не минимум) и медианой набора данных.
Третий квартиль (Q3 или 75% процентиль) — среднее значение между медианой и наибольшим значением (не максимум) набора данных.
Межквартильный размах (IQR) — диапазон от 25-го до 75-го процентиля.
«Усы» (показаны лиловым цветом).
Выбросы (показаны зелеными кружками).
Что такое выбросы, минимумы и максимумы, разберём дальше.
Боксплот на данных с нормальным распределением
На рисунке выше представлено сравнение боксплота почти нормального распределения и функции плотности вероятности для нормального распределения.
Плотность вероятности
Probability Density Function или PDF используется для определения вероятности того, что случайная величина попадет в определённый диапазон значений. Эта вероятность задается интегралом плотности вероятности этой переменной по заданному диапазону. Другими словами — это площадь под функцией до оси Х и между наименьшим и наибольшим значениями диапазона.
Не спешите закрывать вкладку и пить корвалол! Сейчас мы построим график функции плотности вероятности для нормального распределения, и всё станет понятнее.
Уравнение ниже — не что иное как функция плотности вероятности для нормального распределения:
Давайте упростим его, предположив, что у нас есть среднее значение (μ
), равное 0, и стандартное отклонение (σ
), равное 1.
Этот график можно построить с помощью чего угодно, но мы будем строить его с помощью Python.
# Импортируем все библиотеки from scipy.integrate import quad import numpy as np import matplotlib.pyplot as plt x = np.linspace(-4, 4, num = 100) constant = 1.0 / np.sqrt(2 * np.pi) pdf_normal_distribution = constant * np.exp((-x**2) / 2.0) fig, ax = plt.subplots(figsize=(10, 5)) ax.plot(x, pdf_normal_distribution) ax.set_ylim(0) ax.set_title('Normal Distribution', size = 20) ax.set_ylabel('Probability Density', size = 20)
Приведенный выше график показывает не вероятность событий, а их плотность вероятности. Чтобы получить вероятность события в заданном диапазоне, нам потребуется взять интеграл. Предположим, нас интересует вероятность попадания случайной точки в межквартильный размах 0.6745 стандартного отклонения от среднего значения — тогда нам нужно взять интеграл в диапазоне от -0.6745 до 0.6745. Давайте не будем мучиться и посчитаем всё с помощью библиотеки SciPy.
# Напишем функцию плотности вероятности для нормального распределения def normal_probability_density(x): constant = 1.0 / np.sqrt(2 * np.pi) return(constant * np.exp((-x**2) / 2.0)) # Берём интеграл в диапазоне от -0.6745 до 0.6745 result_50p, _ = quad(normal_probability_density, -.6745, .6745, limit = 1000) print(result_50p)
То же самое можно сделать для минимумов и максимумов.
# Напишем функцию плотности вероятности для нормального распределения def normal_probability_density(x): constant = 1.0 / np.sqrt(2*np.pi) return(constant * np.exp((-x**2) / 2.0) # Берём интеграл в диапазоне от -2.698 до 2.698 result_99_3p, _ = quad(normalProbabilityDensity, -2.698, 2.698, limit = 1000) print(result_99_3p)
Как упоминалось ранее, выбросы — это оставшиеся 0,7% данных.
Важно отметить, что для любого PDF площадь под кривой должна быть равна 1 (вероятность взятия любого числа из диапазона всегда равна 1).
Построение и интерпретация графиков
Мы рассмотрели «ящик» на нормальном распределении, но у вас же не всегда будет нормальное распределение, верно? Сейчас будем использовать боксплот на реальном примере. Для этого возьмём Висконсинский (диагностический) набор данных по раку молочной железы. Можно загрузить всё вот отсюда вот.
Загрузка данных
Приведенный ниже код считывает данные в датафрейм.
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # Тот самый датасет из ссылки df = pd.read_csv('https://raw.githubusercontent.com/obulygin/content/main/boxplots/BreastCancerWisconsin.csv')
Построение графика
Для анализа взаимосвязи между категориальным признаком (злокачественная или доброкачественная опухоль) и непрерывным признаком (area_mean
) используем график.
Существует несколько способов построения графиков с помощью Python, посмотрим на примере трех библиотек.
seaborn: пример кода для построения графика с помощью библиотеки seaborn.
sns.boxplot(x='diagnosis', y='area_mean', data=df)
matplotlib: эта библиотека чуть капризнее, зато тут настраивается и регулируется вообще всё.
malignant = df[df['diagnosis']=='M']['area_mean'] benign = df[df['diagnosis']=='B']['area_mean'] fig = plt.figure() ax = fig.add_subplot(111) ax.boxplot([malignant,benign], labels=['M', 'B'])
pandas: вы можете построить график с помощью метода .boxplot()
. Приведенный ниже код строит график столбца area_mean
относительно различных диагнозов.
df.boxplot(column = 'area_mean', by = 'diagnosis'); plt.title('')
Боксплоты с насечками
График с насечками позволяет оценить доверительные интервалы (по умолчанию 95% доверительный интервал) для медиан каждого графика.
malignant = df[df['diagnosis']=='M']['area_mean'] benign = df[df['diagnosis']=='B']['area_mean'] fig = plt.figure() ax = fig.add_subplot(111) ax.boxplot([malignant,benign], notch = True, labels=['M', 'B'])
Интерпретация графиков
Вы всегда можете сделать свои «ящики» симпатичнее, немного поработав над ними (код здесь).
Используя график, мы можем сравнить диапазон и распределение area_mean
для злокачественных и доброкачественных опухолей. Мы видим большой разброс значений area_mean
для злокачественных опухолей, а также много выбросов.
Кроме того, поскольку насечки на боксплотах не пересекаются, можно с 95% уверенностью сделать вывод, что истинные медианы действительно отличаются.
Вот еще пара моментов, которые следует иметь в виду при работе с диаграммами рассеивания:
- Вы всегда можете извлечь данные из боксплота, если хотите узнать, каковы числовые значения в различных частях графика.
- Matplotlib сам не оценивает распределение данных и вычисляет квартили по фактическим параметрам распределения (медиана и квартили вычисляются непосредственно из данных). Другими словами, ваш график может выглядеть по-разному в зависимости от распределения ваших данных и размера выборки, например, асимметрично, с большим или меньшим количеством выбросов.
Источник: Medium
Перевод и адаптация: Екатерина Прохорова
👉🏻Подписывайтесь на PythonTalk в Telegram 👈🏻