2013-03-14 2 views
15

Я хочу построить приближение функции плотности вероятности на основе образца, который у меня есть; Кривая, которая имитирует поведение гистограммы. Я могу иметь образцы как большие, как я хочу.Функция плотности вероятности расслоения по образцу с matplotlib

+0

Какой у вас образец? Является ли это распределением или фактическими данными? – askewchan

+1

Я не понимаю, как кто-то мог проголосовать за этот вопрос ?! Я имею в виду, на основании чего ??? – Cupitor

+2

обычно на [SO] люди будут поднимать вопросы, которые сразу же становятся ясными, а также показывают некоторую попытку айзера ответить на их собственный вопрос. «Что ты пробовал?» Обычно downvotes сопровождаются комментариями, поэтому, я не уверен, почему этого не произошло в этом случае. – askewchan

ответ

25

Если вы хотите построить распределение, и вы это знаете, определить его как функцию и построить ее таким образом:

import numpy as np 
from matplotlib import pyplot as plt 

def my_dist(x): 
    return np.exp(-x ** 2) 

x = np.arange(-100, 100) 
p = my_dist(x) 
plt.plot(x, p) 
plt.show() 

Если у вас нет точного распределения в виде не аналитическая функция, возможно, вы можете создать большую выборку, возьмите гистограмма и как-то сгладить данные:

import numpy as np 
from scipy.interpolate import UnivariateSpline 
from matplotlib import pyplot as plt 

N = 1000 
n = N//10 
s = np.random.normal(size=N) # generate your data sample with N elements 
p, x = np.histogram(s, bins=n) # bin it into n = N//10 bins 
x = x[:-1] + (x[1] - x[0])/2 # convert bin edges to centers 
f = UnivariateSpline(x, p, s=n) 
plt.plot(x, f(x)) 
plt.show() 

вы можете увеличить или уменьшить s (коэффициент сглаживания) в UnivariateSpline е вызов для увеличения или уменьшения сглаживания. Например, используя два, которые вы получаете: dist to func

+0

, что не помогает в моем случае. Я уже написал свою функцию выборки, и она не является точной для образцов одного размера, скажем! – Cupitor

+0

Тогда я думаю, вы должны изменить свой вопрос, чтобы быть более ясным. Это отвечает на ваш вопрос, предполагая, что вы «имеете распределение». – askewchan

+0

Спасибо. Но я получаю следующую ошибку: raise ValueError («массивы x и y должны быть одинаковыми по длине». ValueError: массивы x и y должны быть одинаковыми по длине вдоль оси интерполяции. – Cupitor

18

Что вам нужно сделать, это использовать gaussian_kde из пакета scipy.stats.kde.

учитывая ваши данные, которые вы можете сделать что-то вроде этого:

from scipy.stats.kde import gaussian_kde 
from numpy import linspace 
# create fake data 
data = randn(1000) 
# this create the kernel, given an array it will estimate the probability over that values 
kde = gaussian_kde(data) 
# these are the values over wich your kernel will be evaluated 
dist_space = linspace(min(data), max(data), 100) 
# plot the results 
plt.plot(dist_space, kde(dist_space)) 

Плотность ядра могут быть сконфигурированы по желанию и может обрабатывать N-размерные данные с легкостью. Это также позволит избежать искажений сплайнов, которые вы можете увидеть в сюжете, заданном askewchan.

enter image description here

+0

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

+1

@SitzBlogz Предположим, что ваш набор данных называется 'data', а затем просто удалите строку' data = randn (1000) 'в ответ @EnricoGiampieri, и все готово! –

Смежные вопросы