numpy.histogramdd
numpy.histogramdd(sample, bins=10, range=None, normed=None, weights=None, density=None)
Функция histogramdd() вычисляет N-мерную гистограмму N-го количества наборов данных.
Набор данных sample
должен состоять из n-го количества одномерных массивов одинаковой длинны, которые, в совокупности, представляют собой координаты точек в n-мерном пространстве. А функция histogramdd(), по сути, просто разбивает это пространство на "прямоугольные" подобласти (n-мерные параллелипипеды) и занимается подсчетом вхождений точек в каждую из них.
-
- sample - массив NumPy или подобный массиву объект.
- Входные данные в виде двумерного массива. Каждая строка в этом массиве представляет собой отдельную координату. Если в качестве данного параметра передан подобный массиву объект, то в этом случае каждый вложенный одномерный список представляет собой набор значений для одной координаты. Последний способ является менее предпочтительным.
- bins - последовательность Python, массив или целое число (необязательный параметр).
-
- Если указана последовательность массивов, то каждый массив описывает интервалы ячеек вдоль каждой оси ;
- Если указано одно число, то каждая ось разбивается на равное ему количество ячеек с одинаковыми интервалами;
- Если указана последовательность целых чисел, то каждая ось разбивается на равные интервалы, количество которых равно соответствующему числу в последовательности.
- range - последовательность Python или массив (необязательный параметр).
-
Последовательность кортежей с элементами вида
(v_min, v_max)
, которые определяют допустимые крайние значения по всем осям. Все значения изsamples
, которые не входят в данный интервал будут считаться недопустимыми (считаться выбросами) и не учитываться при расчете гистограммы. Данный параметр может не указываться, если границы заданы явно в параметреbins
. - density - True или False (необязательный параметр).
-
Если
density = True
, то результатом вычислений окажется функция (точнее ее значения) плотности вероятности -bin_count / sample_count / bin_area
, а интеграл по диапазону значенийrange
будет равен 1. Однако, интеграл не будет равен 1 если ширина ячеек не равна 1. Не путайте данную функцию плотности вероятности с функцией вероятности. Еслиdensity = False
, товозвращается обычное количество вхождений значений в каждую ячейку. - normed - True или False (необязательный параметр).
-
Является псевдонимом для
density
и считается устаревшим начиная с версии 1.6.0. - weights - массив NumPy или подобный массиву объект (необязательный параметр).
-
Массив весовых коэфициентов той же формы, что и
samples
. Каждое значение вweights
добавляет соответствующий вес к точке с координатами из соответствующих элементов изsamples
. Если параметрdensity = True
, то все коэфициенты вweights
нормализуются так, что интеграл плотности по диапазонуrange
будет равен 1.
-
- hist - массив NumPy
- Значения многомерной гистограммы для входного набора данных
samples
. - edges - список массивов NumPy
- Список массивов каждый из которых содержит границы ячеек по соответствующему измерению
len(edges[i]) = len(samples[i]) + 1
.
Примеры
Все примеры выполнены в Jupyter Notebook.
Рассмотрим набор 25000 точек в трехмерном пространстве:
import numpy as np
rng = np.random.RandomState(777)
X = np.random.randint(0, 100, size = 100)
Y = np.random.randint(0, 100, size = 100)
Z = np.random.randint(0, 100, size = 100)
Теперь давайте попробуем взглянуть на все это множество точек, расположенных в трехмерном пространстве:
# Магическая команда. Только для Jupyter Notebook:
%matplotlib inline
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X, Y, Z, s = 2)
ax.set_xlabel('X', fontsize = 20)
ax.set_ylabel('Y', fontsize = 20)
ax.set_zlabel('Z', fontsize = 20)
# Увеличим размер графика
fig.set_figwidth(15)
fig.set_figheight(15)
plt.show()
А заоодно посмотрим на проекции данных точек на плоскости:
fig, axes = plt.subplots(1, 3)
axes[0].scatter(X, Y, s = 1)
axes[0].set_title('X - Y')
axes[1].scatter(X, Z, s = 1)
axes[1].set_title('X - Z')
axes[2].scatter(Y, Z, s = 1)
axes[2].set_title('Y - Z')
fig.set_figwidth(18)
fig.set_figheight(6)
plt.show()
Как видите, анализировать визуально такие графики чрезвычайно трудно, и использование функции histogramdd()
во многом направленно именно на алгоритмический статистический анализ.
Следует отметить, что для некоторых алгоритмов машинного обучения анализ многомерных гистограмм, намного лучше, чем анализ самих многомерных данных.
Однако, мы все же можем попробовать вычислить трехмерную гистограмму нашего набора данных и попытаться хоть как-то его визуализировать. Для этого мы поступим следующим образом: разобьем оси X и Y на 100 равных интервалов:
sample = np.vstack((X, Y, Z)).T
hist, edges = np.histogramdd(sample, bins = (100, 100, 10))
print('Форма hist: ', hist.shape)
Форма hist: (100, 100, 10)
Теперь транспонируем массив, что бы ось Z стала первой:
hist = np.transpose(hist)
Визуализировать трехмерную гистограмму будем с помощью двумерных тепловых карт - разделим гистограмму по оси Z на 10 слоев и построим 10 графиков - по одной для каждого слоя:
i = 5
j = 2
k = 0
fig, axes = plt.subplots(5, 2)
X_edges, Y_edges = np.meshgrid(edges[0], edges[1])
for n in range(i):
for m in range(j):
hist_level = axes[n][m].pcolormesh(X_edges, Y_edges, hist[k],
cmap = 'nipy_spectral')
axes[n][m].set_title('Z_' + str(k))
fig.colorbar(hist_level, ax = axes[n][m])
k += 1
fig.set_figwidth(14)
fig.set_figheight(35)
plt.show()
Это не самая лучшая визуализация - можно поэкспериментировать с границами ячеек и не учитывать выбросы. В общем, все зависит от конкретной ситуации. В случае четырехмерных гистограмм, подобная визуализация так же возможна, по принципу от 4-х измерений к 3, а от 3-х к 2.