pylab.hist (data, normed = 1).Нормализация, кажется, работает неправильно - PullRequest
41 голосов
/ 31 марта 2011

Я пытаюсь создать гистограмму с аргументом normed = 1

Например:

import pylab

data = ([1,1,2,3,3,3,3,3,4,5.1])    
pylab.hist(data, normed=1)
pylab.show()

Я ожидал, что сумма бинов будет равна 1. Но вместо этого один из бинов будет больше 1. Что сделала эта нормализация? А как создать гистограмму с такой нормализацией, чтобы интеграл гистограммы был бы равен 1?

enter image description here

Ответы [ 7 ]

45 голосов
/ 06 мая 2013

Смотрите мой другой пост о том, как сделать сумму всех бинов в гистограмме равной единице: https://stackoverflow.com/a/16399202/1542814

Копировать и вставить:

weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)

, где myarray содержит ваши данные

24 голосов
/ 31 марта 2011

В соответствии с документацией нормировано: если True, то результатом является значение функции плотности вероятности в ячейке, нормализованное таким образом, что интеграл по диапазону равен 1. Обратите внимание, что сумма значения гистограммы не будут равны 1, если не выбраны ячейки с единичной шириной; это не функция вероятности массы. Это от numy doc, но должно быть таким же для pylab.

In []: data= array([1,1,2,3,3,3,3,3,4,5.1])
In []: counts, bins= histogram(data, normed= True)
In []: counts
Out[]: array([ 0.488,  0.,  0.244,  0.,  1.22,  0.,  0.,  0.244,  0.,  0.244])
In []: sum(counts* diff(bins))
Out[]: 0.99999999999999989

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

In []: counts, bins= histogram(data, normed= False)
In []: counts
Out[]: array([2, 0, 1, 0, 5, 0, 0, 1, 0, 1])
In []: counts_n= counts/ sum(counts* diff(bins))
In []: counts_n
Out[]: array([ 0.488,  0.,  0.244,  0.,  1.22 ,  0.,  0.,  0.244,  0.,  0.244])
8 голосов
/ 31 марта 2011

Я думаю, вы путаете высоту бина с содержимым бина. Вам необходимо добавить содержимое каждой ячейки, то есть высоту * ширину для всех корзин. Это должно = 1.

6 голосов
/ 02 сентября 2015

Что сделала эта нормализация?

Чтобы нормализовать последовательность, вы должны принять во внимание размер корзины.В соответствии с документацией по умолчанию номер ячейки равен 10. Следовательно, размер ячейки равен (data.max() - data.min() )/10, то есть 0,41.Если normed=1, то высота столбца такова, что сумма, умноженная на 0,41, дает 1. Это то, что происходит при интеграции.

И как создать гистограмму с такой нормализациейчто интеграл гистограммы будет равен 1?

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

h = plt.hist(data)
norm = sum(data)
h2 = [i/norm for i in h[0]]
plt.bar(h[1],h2)
5 голосов
/ 18 февраля 2014

У меня была такая же проблема, и при ее решении возникла другая проблема: как построить нормированные частоты бинов в процентах с галочками на округленных значениях.Я выкладываю это здесь на случай, если это будет полезно для всех.В моем примере я выбрал 10% (0,1) в качестве максимального значения для оси Y и 10 шагов (один от 0% до 1%, один от 1% до 2% и т. Д.).Хитрость заключается в том, чтобы установить отметки на счетчиках data (которые являются выходным списком n из plt.hist), которые затем будут преобразованы в проценты с использованием класса FuncFormatter.Вот что я сделал:

import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

fig, ax = plt.subplots()

# The required parameters
num_steps = 10
max_percentage = 0.1
num_bins = 40

# Calculating the maximum value on the y axis and the yticks
max_val = max_percentage * len(data)
step_size = max_val / num_steps
yticks = [ x * step_size for x in range(0, num_steps+1) ]
ax.set_yticks( yticks )
plt.ylim(0, max_val)

# Running the histogram method
n, bins, patches = plt.hist(data, num_bins)

# To plot correct percentages in the y axis     
to_percentage = lambda y, pos: str(round( ( y / float(len(data)) ) * 100.0, 2)) + '%'
plt.gca().yaxis.set_major_formatter(FuncFormatter(to_percentage))

plt.show()

Графики

До нормализации: единица оси Y - это количество выборок в интервалах бина по оси x: Before normalisation: the y axis unit is number of samples within the bin intervals in the x axis

После нормализации: единица оси Y - это частота значений бина в процентах по всем выборкам After normalisation: the y axis unit is frequency of the bin values as a percentage over all the samples

3 голосов
/ 11 февраля 2014

Существует также аналог в NumPy - numpy.historgram: http://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html Одним из параметров является «плотность». Если вы установите density=True, выход будет нормализован.

нормированный: bool, опционально Это ключевое слово устарело в Numpy 1.6 из-за запутанного / глючного поведения. Он будет удален в Numpy 2.0. Вместо этого используйте ключевое слово плотности. Если False, результат будет содержать количество выборок в каждой ячейке. Если True, то результатом является значение функции плотности вероятности в ячейке, нормализованное так, что интеграл по диапазону равен 1. Обратите внимание, что это последнее поведение, как известно, глючит при неравной ширине ячейки; вместо этого используйте плотность.

плотность: bool, опционально Если False, результат будет содержать количество выборок в каждой ячейке. Если True, то результатом является значение функции плотности вероятности в ячейке, нормализованное таким образом, что интеграл по диапазону равен 1. Обратите внимание, что сумма значений гистограммы не будет равна 1, если не выбраны ячейки ширины единицы; это не функция вероятности массы. Переопределяет нормированное ключевое слово, если оно задано.

0 голосов
/ 29 июля 2017

Ваши ожидания неверны

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

Это так: вероятность (например, «вероятность того, что человеку от 20 до 40 лет составляет ...%») - это интеграл («от 20 до 40 лет») от плотности вероятности .Высота бинов показывает плотность вероятности, тогда как высота, умноженная на ширину, показывает вероятность (вы интегрируете постоянную предполагаемую функцию, высоту бина, от начала бина до конца бина) для определенной точки в этом бине.Сама высота - это плотность, а не вероятность .Это вероятность на ширину , которая, конечно, может быть выше единицы.

Простой пример: представьте функцию плотности вероятности от 0 до 1, которая имеет значение 0 от 0 до 0,9.Что может быть функция может быть между 0,9 и 1?Если вы объединяетесь с этим, попробуйте.Это будет выше, чем 1.

Кстати: по приблизительным оценкам, сумма высоты и ширины вашей истории, похоже, дает примерно 1, не так ли?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...