Корреляции между парами данных

Часто нужно исследовать отношения между соответствующими элементами двух переменных в наборе данных. Скажем, есть две переменные, x и y, с равным количеством элементов, n. Пусть x_1 из x соответствуют y_1 из y, x_2 из x соответствуют y_2 из y т.д. Затем можно сказать, что существует n пар соответствующих элементов: (x_1, y_1), (x_2, y_2) и т.д.

Вы увидите следующие показатели корреляции между парами данных:

  • Положительная корреляция существует, когда большие значения x соответствуют большим значениям y и наоборот.
  • Отрицательная корреляция существует, когда большие значения x соответствуют меньшим значениям y и наоборот.
  • Слабая или отсутствует корреляция, если нет такой очевидной связи.

На следующем рисунке показаны примеры отрицательной, слабой и положительной корреляции:

Положительная, отрицательная и слабая корреляции
Положительная, отрицательная и слабая корреляции

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

Примечание:

Одна важная вещь, которую вы всегда должны иметь в виду при работе с корреляцией между парой переменных, и это то, что корреляция не является мерой или показателем причинности, а только ассоциации!

Есть две статистические меры, которые характеризуют корреляцию между наборами данных — ковариация и коэффициент корреляции. Давайте определимся для работы с этими мерами. Создадим два списка Python и будете использовать их для получения соответствующих массивов NumPy и серии Pandas:

>>> x = list(range(-10, 11))
>>> y = [0, 2, 2, 2, 2, 3, 3, 6, 7, 4, 7, 6, 6, 9, 4, 5, 5, 10, 11, 12, 14]
>>> x_, y_ = np.array(x), np.array(y)
>>> x__, y__ = pd.Series(x_), pd.Series(y_)

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

Ковариации

Выборочная ковариация — это мера, которая количественно определяет силу и направление взаимосвязи между парой переменных:

  • Если корреляция положительная, то и ковариация тоже положительная. Более сильное отношение соответствует более высокой ценности ковариации.
  • Если корреляция отрицательна, то и ковариация также отрицательна. Более сильное отношение соответствует более низкому (или более высокому абсолютному) значению ковариации.
  • Если корреляция слабая, то ковариация близка к нулю.

Ковариация двух переменных x и y математически записывается следующим образом:

s_{xy} = \frac{\sum_{i}{(x_i - mean(x))(y_i - mean(y))}}{(n - 1)},

где i = 1, 2, …, ?, mean(x) среднеарифметическое x и mean(y) среднеарифметическое y. Откуда следует, что ковариация двух одинаковых переменных на самом деле является дисперсией:

s_{xx} = \frac{\sum_{i}{(x_i - mean(x))^2}}{(n - 1)} = \sigma_x^2 и s_{yy} = \frac{\sum_{i}{(y_i - mean(y))^2}}{(n - 1)} = \sigma_y^2.

Вот как вы можете рассчитать ковариацию в чистом Python:

>>> mean_x, mean_y = sum(x) / n, sum(y) / n
>>> cov_xy = (sum((x[k] - mean_x) * (y[k] - mean_y) for k in range(n))
...           / (n - 1))
>>> cov_xy
19.95

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

NumPy имеет функцию cov(), которая возвращает ковариационную матрицу:

>>> cov_matrix = np.cov(x_, y_)
>>> cov_matrix
array(38.5       , 19.95      ],
       [19.95      , 13.91428571)

Обратите внимание, cov() имеет необязательные параметры bias (по умолчанию False) и ddof (по умолчанию None). Их значения по умолчанию подходят для получения образца ковариационной матрицы. Верхний левый элемент ковариационной матрицы — это ковариация x и x или дисперсия x. Точно так же нижний правый элемент — y и y или дисперсия y. Вы можете проверить, что это правда:

>>> x_.var(ddof=1)
38.5
>>> y_.var(ddof=1)
13.914285714285711

Как видите, дисперсии x и y равны cov_matrix[0, 0] и cov_matrix[1, 1] соответственно.

Два других элемента ковариационной матрицы равны и представляют фактическую ковариацию между x и y:

>>> cov_xy = cov_matrix[0, 1]
>>> cov_xy
19.95
>>> cov_xy = cov_matrix[1, 0]
>>> cov_xy
19.95

Вы получили то же значение ковариации с np.cov(), что и с чистым Python.
Объект Series Pandas имеет метод .cov(), который вы можете использовать для вычисления ковариации:

>>> cov_xy = x__.cov(y__)
>>> cov_xy
19.95
>>> cov_xy = y__.cov(x__)
>>> cov_xy
19.95

Здесь для одного объекта Series вызывается .cov() и передаете другой объект в качестве первого аргумента.

Коэффициент корреляции

Коэффициент корреляции или коэффициент корреляции Пирсона — произведение, обозначается символом ?. Коэффициент является еще одним показателем корреляции между данными. К нему надо относиться как к стандартизированной ковариации. Вот несколько важных замечаний:

  • ? > 0 указывает на положительную корреляцию.
  • ? < 0 указывает на отрицательную корреляцию.
  • r = 1 является максимально возможным значением ?. Это свидетельство полной линейной зависимости между переменными.
  • r = −1 является минимально возможным значением ?. Это свидетельство полного отсутствия линейной зависимости между переменными.
  • r ≈ 0 или когда around около нуля, означает, что корреляция между переменными отсутствует.

Математическая формула для коэффициента корреляции:

r = \frac{s_{xy}}{\sigma_x\sigma_y}.

где \sigma_x и \sigma_y — стандартные отклонения x и y соответственно. Если у вас есть средние значения (mean_x и mean_y) и стандартные отклонения (std_x, std_y) для наборов данных x и y, а также их ковариация cov_xy, то вы можете рассчитать коэффициент корреляции с помощью чистого Python:

>>> var_x = sum((item - mean_x)**2 for item in x) / (n - 1)
>>> var_y = sum((item - mean_y)**2 for item in y) / (n - 1)
>>> std_x, std_y = var_x ** 0.5, var_y ** 0.5
>>> r = cov_xy / (std_x * std_y)
>>> r
0.861950005631606

Есть переменная r, которая представляет коэффициент корреляции.

В scipy.stats есть функция pearsonr(), которая вычисляет коэффициент корреляции и p-value:

>>> r, p = scipy.stats.pearsonr(x_, y_)
>>> r
0.861950005631606
>>> p
5.122760847201171e-07

Верхний левый элемент — это коэффициент корреляции между x_ и x_. Нижний правый элемент — это коэффициент корреляции между y_ и y_. Их значения равны 1,0. Два других элемента равны и представляют фактический коэффициент корреляции между x_ и y_:

>>> r = corr_matrix[0, 1]
>>> r
0.8619500056316061
>>> r = corr_matrix[1, 0]
>>> r
0.861950005631606

Конечно, результат такой же, как с чистым Python и pearsonr().

Вы можете получить коэффициент корреляции с помощью scipy.stats.linregress():

>>> scipy.stats.linregress(x_, y_)
LinregressResult(slope=0.5181818181818181, intercept=5.714285714285714, rvalue=0.861950005631606, pvalue=5.122760847201164e-07, stderr=0.06992387660074979)

linregress() принимает x_ и y_, вычисляет линейную регрессию и возвращает результаты — наклон и точка пересечения определяют уравнение прямой регрессии, а rvalue — коэффициент корреляции. Чтобы получить доступ к определенным значениям из результата linregress(), включая коэффициент корреляции, используйте точечную запись:

>>> result = scipy.stats.linregress(x_, y_)
>>> r = result.rvalue
>>> r
0.861950005631606

Вот так можно сделать линейную регрессию и получить коэффициент корреляции.

Объект Series Pandas имеет метод .corr() для расчета коэффициента корреляции:

>>> r = x__.corr(y__)
>>> r
0.8619500056316061
>>> r = y__.corr(x__)
>>> r
0.861950005631606

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

Работа с данными 2D (таблицы)

В статистике очень часто работают с 2D данными. Вот несколько примеров форматов данных 2D:

  • Таблицы базы данных
  • CSV файлы
  • Таблицы Excel, Calc и Google

NumPy и SciPy предоставляют комплексные средства для работы с 2D-данными. Pandas имеет класс DataFrame специально для обработки 2D данных.

Axes

Начните с создания 2D массива NumPy:

>>> a = np.array(1, 1, 1],
...               [2, 3, 1],
...               [4, 9, 2],
...               [8, 27, 4],
...               [16, 1, 1)
>>> a
array( 1,  1,  1],
       [ 2,  3,  1],
       [ 4,  9,  2],
       [ 8, 27,  4],
       [16,  1,  1)

Теперь у вас есть набор 2D данных, который мы будем использовать в этом разделе. Можно применять к нему статистические функции и методы Python так же, как к данным 1D (последовательности):

>>> np.mean(a)
5.4
>>> a.mean()
5.4
>>> np.median(a)
2.0
>>> a.var(ddof=1)
53.40000000000001

Как видите, здесь получены статистики (например, среднее значение, медиана или дисперсия) по всем данным в массиве a. Иногда, нужно именно это, а часто эти величины надо рассчитать для каждой строки или столбца вашего 2D-массива.

Функции и методы, которые вы использовали до сих пор, имеют один необязательный параметр, называемый осью, который необходим для обработки 2D-данных. Ось может принимать любое из следующих значений:

  • axis = None — расчет статистики по всем данным в массиве, как в приведенном выше примере. Такое поведение часто используется по умолчанию в NumPy.
  • axis = 0 — расчет статистики для каждого столбца массива. Такое поведение часто используется по умолчанию для статистических функций SciPy.
  • axis = 1 — расчет статистики для каждой строки массива.

Давайте посмотрим ось = 0 в действии с np.mean ():

>>> np.mean(a, axis=0)
array([6.2, 8.2, 1.8])
>>> a.mean(axis=0)
array([6.2, 8.2, 1.8])

Два приведенных выше оператора возвращают новые массивы NumPy со средним значением для каждого столбца a. В этом примере среднее значение первого столбца равно 6,2. Второй столбец имеет среднее значение 8,2, а третий столбец имеет 1,8.

Если вы укажете axis = 1, то функция mean() выдаст результаты для каждой строки:

>>> np.mean(a, axis=1)
array([ 1.,  2.,  5., 13.,  6.])
>>> a.mean(axis=1)
array([ 1.,  2.,  5., 13.,  6.])

Как видите, первая строка имеет среднее значение 1.0, вторая 2.0 и так далее.

Примечание:

Эти правила можно распространить на многомерные массивы, но это выходит за рамки данного руководства. Не стесняйтесь погрузиться в эту тему самостоятельно!

Параметр axis работает аналогично c другими функциям и методами NumPy:

>>> np.median(a, axis=0)
array([4., 3., 1.])
>>> np.median(a, axis=1)
array([1., 2., 4., 8., 1.])
>>> a.var(axis=0, ddof=1)
array([ 37.2, 121.2,   1.7])
>>> a.var(axis=1, ddof=1)
array([  0.,   1.,  13., 151.,  75.])

Здесь получены медианы и вариация для всех столбцов (axis = 0) и строк (axis = 1) массива a.

Это очень похоже на работу со статистическими функциями SciPy. Но помните, что в этом случае значение по умолчанию для axis равно 0:

>>> scipy.stats.gmean(a)  # Default: axis=0
array([4.        , 3.73719282, 1.51571657])
>>> scipy.stats.gmean(a, axis=0)
array([4.        , 3.73719282, 1.51571657])

Если вы опустите axis или зададите axis = 0, то расчёт делается для каждого столбца. Например, первый столбец матрицы a имеет среднее геометрическое значение 4,0 и т. Д.

Если вы укажете axis = 1, то получите результат для каждой строки:

>>> scipy.stats.gmean(a, axis=1)
array([1.        , 1.81712059, 4.16016765, 9.52440631, 2.5198421 ])

В этом примере среднее геометрическое для первой строки матрицы a равно 1.0. Для второго ряда это примерно 1,82 и так далее.

Если вы хотите получить статистику для всего набора данных, то вы должны указать axis = None:

>>> scipy.stats.gmean(a, axis=None)
2.829705017016332

Среднее геометрическое значение всех элементов в массиве a составляет приблизительно 2,83.

Можно получить сводную статистику по Python за один вызов функции для двумерных данных с помощью scipy.stats.describe(). Он работает аналогично 1D массивам, но нужно быть осторожным с параметром axis:

>>> scipy.stats.describe(a, axis=None, ddof=1, bias=False)
DescribeResult(nobs=15, minmax=(1, 27), mean=5.4, variance=53.40000000000001, skewness=2.264965290423389, kurtosis=5.212690982795767)
>>> scipy.stats.describe(a, ddof=1, bias=False)  # Default: axis=0
DescribeResult(nobs=5, minmax=(array([1, 1, 1]), array([16, 27,  4])), mean=array([6.2, 8.2, 1.8]), variance=array([ 37.2, 121.2,   1.7]), skewness=array([1.32531471, 1.79809454, 1.71439233]), kurtosis=array([1.30376344, 3.14969121, 2.66435986]))
>>> scipy.stats.describe(a, axis=1, ddof=1, bias=False)
DescribeResult(nobs=3, minmax=(array([1, 1, 2, 4, 1]), array([ 1,  3,  9, 27, 16])), mean=array([ 1.,  2.,  5., 13.,  6.]), variance=array([  0.,   1.,  13., 151.,  75.]), skewness=array([0.        , 0.        , 1.15206964, 1.52787436, 1.73205081]), kurtosis=array([-3. , -1.5, -1.5, -1.5, -1.5]))

При axis = None получаем сводку по всем данным. Большинство результатов являются скалярами. Если вы установите axis = 0 или вообще не укажете, то возвращаемое значение является сводкой для каждой строки. Таким образом, большинство результатов — это массивы с тем же количеством элементов, что и количество столбцов. Если вы установите axis = 1, тогда метод description() возвращает сводку для всех столбцов и количество элементов равно количеству строк.

Вы можете получить конкретное значение из сводки с точечной нотацией:

>>> result = scipy.stats.describe(a, axis=1, ddof=1, bias=False)
>>> result.mean
array([ 1.,  2.,  5., 13.,  6.])

Вот так вы можете увидеть статистическую сводку для двумерного массива с помощью одного вызова функции.

DataFrames

Класс DataFrame является одним из основных типов данных Pandas. С ним очень удобно работать, потому что в нем есть метки для строк и столбцов. Используйте массив a и создайте DataFrame:

>>> row_names = ['first', 'second', 'third', 'fourth', 'fifth']
>>> col_names = ['A', 'B', 'C']
>>> df = pd.DataFrame(a, index=row_names, columns=col_names)
>>> df
         A   B  C
first    1   1  1
second   2   3  1
third    4   9  2
fourth   8  27  4
fifth   16   1  1

На практике имена столбцов имеют значение и должны быть описательными. Имена строк иногда указываются автоматически как 0, 1 и т. Д. Вы можете указать их явно с помощью параметра index, хотя вы можете свободно опускать index, если хотите.

Методы DataFrame очень похожи на методы Series, хотя их поведение отличается. Если вы вызываете методы статистики Python без аргументов, то DataFrame будет возвращать результаты для каждого столбца:

>>> df.mean()
A    6.2
B    8.2
C    1.8
dtype: float64
>>> df.var()
A     37.2
B    121.2
C      1.7
dtype: float64

То, что вы получаете, это новый объект Series, который содержит результаты. В этом случае ряд содержит среднее значение и дисперсию для каждого столбца. Если вы хотите получить результаты для каждой строки, просто укажите параметр axis = 1:

>>> df.mean(axis=1)
first      1.0
second     2.0
third      5.0
fourth    13.0
fifth      6.0
dtype: float64
>>> df.var(axis=1)
first       0.0
second      1.0
third      13.0
fourth    151.0
fifth      75.0
dtype: float64

Результатом является объект Series с желаемым количеством для каждой строки. Метки «первый», «второй» и т.д. относятся к разным строкам.

Вы можете изолировать каждый столбец DataFrame следующим образом:

>>> df['A']
first      1
second     2
third      4
fourth     8
fifth     16
Name: A, dtype: int64

Теперь у вас есть столбец «A» в форме объекта Series, и вы можете применить соответствующие методы:

>>> df['A'].mean()
6.2
>>> df['A'].var()
37.20000000000001

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

Иногда вам может понадобиться использовать DataFrame в качестве массива NumPy и применить к нему некоторую функцию. Все данные можно получить из DataFrame с помощью .values или .to_numpy():

>>> df.values
array( 1,  1,  1],
       [ 2,  3,  1],
       [ 4,  9,  2],
       [ 8, 27,  4],
       [16,  1,  1)
>>> df.to_numpy()
array( 1,  1,  1],
       [ 2,  3,  1],
       [ 4,  9,  2],
       [ 8, 27,  4],
       [16,  1,  1)

df.values и df.to_numpy() дают вам массив NumPy со всеми элементами из DataFrame без меток строк и столбцов. Обратите внимание, что df.to_numpy() более гибок, потому что вы можете указать тип данных элементов и хотите ли вы использовать существующие данные или скопировать их.

Как и Series, объекты DataFrame имеют метод .describe(), который возвращает другой DataFrame со сводкой статистики для всех столбцов:

>>> df.describe()
              A          B        C
count   5.00000   5.000000  5.00000
mean    6.20000   8.200000  1.80000
std     6.09918  11.009087  1.30384
min     1.00000   1.000000  1.00000
25%     2.00000   1.000000  1.00000
50%     4.00000   3.000000  1.00000
75%     8.00000   9.000000  2.00000
max    16.00000  27.000000  4.00000

В итоге получаем следующие результаты:

  • count: количество элементов в каждом столбце;
  • mean: среднее значение каждого столбца;
  • std: стандартное отклонение;
  • min и max: минимальное и максимальное значения;
  • 25%, 50% и 75%: процентили.

Если хотите, чтобы результирующий объект DataFrame содержал другие процентили, следует указать значение необязательного параметра процентили.

Вы можете получить доступ к каждому элементу описательной статистики следующим образом:

>>> df.describe().at['mean', 'A']
6.2
>>> df.describe().at['50%', 'B']
3.0

Вот так можно получить описательную статистику Python в одном объекте Series с помощью одного вызова метода Pandas.

Визуализация данных

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

matplotlib.pyplot — очень удобная и широко используемая библиотека, хотя это не единственная библиотека Python, доступная для этой цели. Вы можете импортировать это так:

>>> import matplotlib.pyplot as plt
>>> plt.style.use('ggplot')

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

Примечание:

В этом разделе основное внимание уделяется представлению данных и минимальным стилевым параметрам. Вы увидите ссылки на официальную документацию по используемым подпрограммам из matplotlib.pyplot, так что вы можете изучить варианты, которых вы не увидите здесь.

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

В NumPy 1.17 появился еще один модуль для генерации псевдослучайных чисел. Чтобы узнать об этом больше, посмсотрите официальную документацию.

Box Plots

Ящик с усами является отличным инструментом для визуального представления описательной статистики данного набора данных. Он может показывать диапазон, межквартильный диапазон, медиану, моду, выбросы и все квартили. Во-первых, создайте некоторые данные для представления в виде графика:

>>> np.random.seed(seed=0)
>>> x = np.random.randn(1000)
>>> y = np.random.randn(100)
>>> z = np.random.randn(10)

Первый оператор инициализирует генератора случайных чисел NumPy с помощью seed(). Поэтому при каждом запуске скрипта могут получаться одинаковые результаты. Не нужно устанавливать начальное значение и, если его не указывать, то каждый раз будут получаться разные результаты.

Другие операторы создают три массива NumPy с нормально распределенными псевдослучайными числами. x относится к массиву с 1000 элементами, y имеет 100, а z содержит 10 элементов. Теперь, когда у вас есть данные для работы, вы можете применить .boxplot() для отрисовки ящика с усами:

fig, ax = plt.subplots()
ax.boxplot((x, y, z), vert=False, showmeans=True, meanline=True,
           labels=('x', 'y', 'z'), patch_artist=True,
           medianprops={'linewidth': 2, 'color': 'purple'},
           meanprops={'linewidth': 2, 'color': 'red'})
plt.show()

Параметры .boxplot():

  • х ваши данные.
  • vert устанавливает горизонтальную ориентацию графика, когда False. Ориентация по умолчанию - вертикальная.
  • showmeans показывает среднее значение ваших данных, когда True.
  • meanline представляет среднее в виде линии, когда истина. Представлением по умолчанию является точка.
  • labels: метки ваших данных.
  • patch_artist определяет, как рисовать график.
  • medianprops обозначает свойства линии, представляющей медиану.
  • meanprops указывает свойства линии или точки, представляющей среднее значение.

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

Приведенный выше код создает изображение, подобное этому:

Box plots
Box plots

Вы можете увидеть три сюжета. Каждый из них соответствует одному набору данных (x, y или z) и показывает следующее:

  • Среднее значение — это красная пунктирная линия.
  • Медиана — это фиолетовая линия.
  • Первый квартиль — левый край синего прямоугольника.
  • Третий квартиль — это правый край синего прямоугольника.
  • Межквартильный диапазон — это длина синего прямоугольника.
  • Диапазон — всё слева направо.
  • Выбросы — точки слева и справа.

Сюжетная диаграмма может показать столько информации на одном рисунке!

Гистограммы

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

Частота представляет собой одно значение, которое соответствует каждому бину. Это количество элементов набора данных со значениями между краями корзины. По договоренности, все корзины, кроме самой правой, наполовину открыты. Они включают значения, равные нижним границам, но исключают значения, равные верхним границам. Крайняя правая корзина закрыта, так как включает обе границы. Если вы разделите набор данных с ребрами 0, 5, 10 и 15, то есть три элемента:

  • Первый и самый левый столбец содержит значения, большие или равные 0 и меньшие 5.
  • Второй контейнер содержит значения, большие или равные 5 и меньшие 10.
  • Третий и самый правый контейнер содержит значения, большие или равные 10 и меньшие или равные 15.

Функция np.histogram() — это удобный способ получить данные для гистограмм:

>>> hist, bin_edges = np.histogram(x, bins=10)
>>> hist
array([  9,  20,  70, 146, 217, 239, 160,  86,  38,  15])
>>> bin_edges
array([-3.04614305, -2.46559324, -1.88504342, -1.3044936 , -0.72394379,
       -0.14339397,  0.43715585,  1.01770566,  1.59825548,  2.1788053 ,
        2.75935511])

Он берет массив с вашими данными и количеством (или ребрами) бинов и возвращает два массива NumPy:

  • hist содержит частоту или количество элементов, соответствующих каждому бину.
  • bin_edges содержит ребра или границы корзины.

Что рассчитывает histogram(), граф .hist() может показать графически:

fig, ax = plt.subplots()
ax.hist(x, bin_edges, cumulative=False)
ax.set_xlabel('x')
ax.set_ylabel('Frequency')
plt.show()

Первый аргумент .hist() — это последовательность с вашими данными. Второй аргумент определяет края бинов. Третий отключает возможность создания гистограммы с накопленными значениями. Приведенный выше код создает такую фигуру:

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

Вы можете видеть края корзины на горизонтальной оси и частоты на вертикальной оси.

При значении аргумента cumulative = True в .hist() можно получить гистограмму с совокупным количеством элементов:

fig, ax = plt.subplots()
ax.hist(x, bin_edges, cumulative=True)
ax.set_xlabel('x')
ax.set_ylabel('Frequency')
plt.show()

Результат выполнения кода посмотрите на рисунке:

Гистограмма с накоплением
Гистограмма с накоплением

Частота первого и самого левого лотка — это количество элементов в этом лотке. Частота второго бина — это сумма количества элементов в первом и втором бинах. Другие контейнеры отрисовываются аналогично. Наконец, частота последнего и самого правого бина — это общее количество элементов в наборе данных (в данном случае 1000). Вы также можете напрямую нарисовать гистограмму с помощью pd.Series.hist(), используя matplotlib в фоновом режиме.

Pie Charts круговые диаграммы

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

Давайте определим данные, связанные с тремя метками:

>>> x, y, z = 128, 256, 1024

Теперь создайте круговую диаграмму с помощью .pie():

fig, ax = plt.subplots()
ax.pie((x, y, z), labels=('x', 'y', 'z'), autopct='%1.1f%%')
plt.show()

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

Круговая диаграмма
Круговая диаграмма

Круговая диаграмма показывает x как наименьшую часть круга, y как следующую наибольшую, а затем z как самую большую часть. Проценты обозначают относительный размер каждого значения по сравнению с их суммой.

Bar Charts

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

Гистограмма показывает параллельные прямоугольники, называемые барами. Каждая полоса соответствует одной метке и имеет высоту, пропорциональную частоте или относительной частоте ее метки. Давайте создадим три набора данных, каждый из которых содержит 21 элемент:

>>> x = np.arange(21)
>>> y = np.random.randint(21, size=21)
>>> err = np.random.randn(21)

Вы используете np.arange(), чтобы получить x или массив последовательных целых чисел от 0 до 20. Вы будете использовать это для представления меток. y — это массив равномерно распределенных случайных целых чисел, также от 0 до 20. Этот массив будет представлять частоты. err содержит нормально распределенные числа с плавающей точкой, которые являются ошибками. Эти значения не являются обязательными.

Вы можете создать гистограмму с помощью .bar(), если вам нужны вертикальные столбцы или .barh(), если вам нужны горизонтальные столбцы:

fig, ax = plt.subplots())
ax.bar(x, y, yerr=err)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()

Результат вы видите на рисунке:

Bar Charts
Bar Charts

Высоты красных полос соответствуют частотам y, а длины черных линий показывают ошибки err. Если вы не хотите включать ошибки, пропустите параметр yerr в .bar().

X-Y участки

Диаграмма x-y или диаграмма рассеяния представляет пары данных из двух наборов данных. Горизонтальная ось x показывает значения из набора x, а вертикальная ось y показывает соответствующие значения из набора y. При желании вы можете включить линию регрессии и коэффициент корреляции. Давайте сгенерируем два набора данных и выполним линейную регрессию с помощью scipy.stats.linregress():

>>> x = np.arange(21)
>>> y = 5 + 2 * x + 2 * np.random.randn(21)
>>> slope, intercept, r, *__ = scipy.stats.linregress(x, y)
>>> line = f'Regression line: y={intercept:.2f}+{slope:.2f}x, r={r:.2f}'

Набор данных x снова является массивом с целыми числами от 0 до 20. y вычисляется как линейная функция x, искаженная некоторым случайным шумом.

linregress возвращает несколько значений. Вам понадобится наклон и точка пересечения линии регрессии, а также коэффициент корреляции r. Затем вы можете применить .plot(), чтобы получить график x-y:

fig, ax = plt.subplots()
ax.plot(x, y, linewidth=0, marker='s', label='Data points')
ax.plot(x, intercept + slope * x, label=line)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend(facecolor='white')
plt.show()

Вот результат:

Диаграмма рассеивания
Диаграмма рассеивания

Вы можете видеть точки данных (пары x-y) в виде красных квадратов, а также синюю линию регрессии.

Схемы Зоны активности

Тепловая карта может быть использована для визуального отображения матрицы. Цвета представляют числа или элементы матрицы. Тепловые карты особенно полезны для иллюстрации ковариационных и корреляционных матриц. Вы можете создать тепловую карту для ковариационной матрицы с помощью .imshow():

matrix = np.cov(x, y).round(decimals=2)
fig, ax = plt.subplots()
ax.imshow(matrix)
ax.grid(False)
ax.xaxis.set(ticks=(0, 1), ticklabels=('x', 'y'))
ax.yaxis.set(ticks=(0, 1), ticklabels=('x', 'y'))
ax.set_ylim(1.5, -0.5)
for i in range(2):
    for j in range(2):
        ax.text(j, i, matrix[i, j], ha='center', va='center', color='w')
plt.show()

Здесь тепловая карта содержит метки «x» и «y», а также числа из ковариационной матрицы. Вы получите такую фигуру:

Тепловая карта
Тепловая карта

Желтое поле представляет самый большой элемент из матрицы 130.34, а фиолетовое соответствует наименьшему элементу 38.5. Синие квадраты между ними связаны со значением 69,9.

Вы можете получить тепловую карту для матрицы коэффициентов корреляции, следуя той же логике:

matrix = np.corrcoef(x, y).round(decimals=2)
fig, ax = plt.subplots()
ax.imshow(matrix)
ax.grid(False)
ax.xaxis.set(ticks=(0, 1), ticklabels=('x', 'y'))
ax.yaxis.set(ticks=(0, 1), ticklabels=('x', 'y'))
ax.set_ylim(1.5, -0.5)
for i in range(2):
    for j in range(2):
        ax.text(j, i, matrix[i, j], ha='center', va='center', color='w')
plt.show()

Посмотрите на результат:

Ещё одна тепловая карта
Ещё одна тепловая карта

Желтый цвет представляет значение 1,0, а фиолетовый показывает 0,99.

Заключение

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

  • Используйте статистику Python для наиболее важных статистических функций Python.
  • Используйте NumPy для эффективной обработки массивов.
  • Используйте SciPy для дополнительных подпрограмм статистики Python для массивов NumPy.
  • Используйте Pandas для работы с помеченными наборами данных.
  • Для визуализации данных с помощью графиков, диаграмм и гистограмм рекомендую использовать:

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

Использованы материалы: Python Statistics Fundamentals: How to Describe Your Data

Опубликовано Вадим В. Костерин

ст. преп. кафедры ЦЭиИТ. Автор более 130 научных и учебно-методических работ. Лауреат ВДНХ (серебряная медаль).

Оставьте комментарий

Ваш адрес email не будет опубликован.