Подтвердить что ты не робот

Pylab.hist(данные, normed = 1). Нормализация, похоже, работает некорректно

Я пытаюсь создать гистограмму с аргументом 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

4b9b3361

Ответ 1

См. мой другой пост, как сделать сумму всех ящиков в гистограмме равной единице: fooobar.com/questions/100270/...

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

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

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

Ответ 2

В соответствии с документация нормирована: если True, результатом является значение функции плотности вероятности в ящике, нормированное так, что интеграл по диапазон равен 1. Обратите внимание, что сумма значений гистограммы не будет равна 1, если не выбраны единицы ширины единицы; это не функция массы вероятности. Это от numpy 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])

Ответ 3

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

Ответ 4

У меня была та же проблема, и при ее решении возникла еще одна проблема: как построить нормализованную частоту bin в процентах с тиками по округленным значениям. Я отправляю его здесь, если это полезно для всех. В моем примере я выбрал 10% (0,1) в качестве максимального значения для оси y и 10 шагов (один от 0% до 1%, один от 1% до 2% и т.д.). Хитрость заключается в том, чтобы установить тики на количество данных (которые являются выходным списком 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

Ответ 5

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

Чтобы нормализовать последовательность, вы должны учитывать размер корзины. Согласно документации, номер по умолчанию для бункера равен 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)

Ответ 6

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

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

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

Ответ 7

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

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

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

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

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