2016-07-29 4 views
2

У меня есть данные (серия PD), который выглядит как (ежедневно доходности, п = 555):не удается получить у оси на Matplotlib гистограмме для отображения вероятностей

S = perf_manual.returns 
S = S[~((S-S.mean()).abs()>3*S.std())] 

2014-03-31 20:00:00 0.000000 
2014-04-01 20:00:00 0.000000 
2014-04-03 20:00:00 -0.001950 
2014-04-04 20:00:00 -0.000538 
2014-04-07 20:00:00 0.000764 
2014-04-08 20:00:00 0.000803 
2014-04-09 20:00:00 0.001961 
2014-04-10 20:00:00 0.040530 
2014-04-11 20:00:00 -0.032319 
2014-04-14 20:00:00 -0.008512 
2014-04-15 20:00:00 -0.034109 
... 

Я хотел бы, чтобы генерировать график распределения вероятности из этого. Использование:

print stats.normaltest(S) 

n, bins, patches = plt.hist(S, 100, normed=1, facecolor='blue', alpha=0.75) 
print np.sum(n * np.diff(bins)) 

(mu, sigma) = stats.norm.fit(S) 
print mu, sigma 
y = mlab.normpdf(bins, mu, sigma) 
plt.grid(True) 
l = plt.plot(bins, y, 'r', linewidth=2) 

plt.xlim(-0.05,0.05) 
plt.show() 

я получаю следующее:

NormaltestResult(statistic=66.587382579416982, pvalue=3.473230376732532e-15) 
1.0 
0.000495624926242 0.0118790391467 

graph

У меня есть впечатление, что ось у является граф, но я хотел бы иметь вероятности вместо этого. Как мне это сделать? Я пробовал много ответов StackOverflow и не могу понять это.

+0

Вы уверены, что эти счетчики? Я думаю, что они являются значениями плотности вероятности, так как ваш график нормализуется до 1, когда вы интегрируете его. Диапазон ваших x-значений очень мал. – jotasi

+0

Может быть, плотность вероятности не моя самая сильная точка. Как я могу сделать это в процентах? –

+0

Какие проценты вы хотите иметь? Для каждого бина вероятность попадания данных в этот бит? Плотность вероятности в основном означает, что интеграл по плотности для некоторого х-диапазона дает вам вероятность этого диапазона. – jotasi

ответ

2

Нет простого способа (что я знаю) сделать это с помощью plt.hist. Но вы можете просто записать данные с помощью np.histogram, а затем нормализовать данные любым способом. Если я правильно вас понял, вы хотите, чтобы данные отображали вероятность найти точку в данном бункере, а не распределение вероятности. Это означает, что вам нужно масштабировать свои данные, чтобы сумма по всем ячейкам равнялась 1. Это можно сделать, выполнив bin_probability = n/float(n.sum()).

Теперь у вас не будет должным образом нормализованной функции распределения вероятностей (pdf), что означает, что интеграл по интервалу не будет вероятностью! Именно по этой причине вам нужно перемасштабировать свой mlab.normpdf, чтобы иметь ту же норму, что и ваша гистограмма. Необходимым фактором является просто ширина бункера, потому что, когда вы начинаете с правильно нормированного биндинга pdf, сумма по всем ячейкам умножается на их соответствующую ширину: 1. Теперь вы хотите иметь только сумму ящиков, равную 1. Таким образом, коэффициент масштабирования равен ширина бункера.

Таким образом, код, который вы в конечном итоге с что-то вдоль линий:

import numpy as np 
import scipy.stats as stats 
import matplotlib.pyplot as plt 
import matplotlib.mlab as mlab 

# Produce test data 
S = np.random.normal(0, 0.01, size=1000) 

# Histogram: 
# Bin it 
n, bin_edges = np.histogram(S, 100) 
# Normalize it, so that every bins value gives the probability of that bin 
bin_probability = n/float(n.sum()) 
# Get the mid points of every bin 
bin_middles = (bin_edges[1:]+bin_edges[:-1])/2. 
# Compute the bin-width 
bin_width = bin_edges[1]-bin_edges[0] 
# Plot the histogram as a bar plot 
plt.bar(bin_middles, bin_probability, width=bin_width) 

# Fit to normal distribution 
(mu, sigma) = stats.norm.fit(S) 
# The pdf should not normed anymore but scaled the same way as the data 
y = mlab.normpdf(bin_middles, mu, sigma)*bin_width 
l = plt.plot(bin_middles, y, 'r', linewidth=2) 

plt.grid(True) 
plt.xlim(-0.05,0.05) 
plt.show() 

И результирующее изображение будет:

enter image description here

+0

Спасибо за это и развеяю мое замешательство :) –