Предположим, что пользователь дает некоторые процентили распределения, подобного этому, и мы пытаемся найти параметры распределения.
# a list of (p,x) tuples, where P(X<x)=p
percentiles = [(0.2,8),(0.4,12),(0.5,16),(0.9,30)]
Пользователь указывает семейство распределения (например, Нормальное). Когда имеется более 2 процентилей, система уравнений переопределена, поэтому мы захотим найти параметры, которые лучше всего подходят для ввода, на основе наименьших квадратов.
У меня проблемы с реализацией этого. В этом минимальном примере ниже curve_fit
просто возвращает значение по умолчанию 1 для обоих параметров. Что я делаю не так?
from scipy import stats
from scipy import optimize
# a list of (p,x) tuples, where P(X<x)=p
percentiles = [(0.2,8),(0.4,12),(0.5,16),(0.9,30)]
fit = optimize.curve_fit(
lambda x,mu,sigma: stats.norm(mu,sigma).cdf(x),
xdata=[x[1] for x in percentiles],
ydata=[x[0] for x in percentiles])
print(fit[0])
Edit : Johan C указал, что мне важны первоначальные предположения. Вот (грубый) метод, который я использовал, чтобы получить начальное предположение о параметрах, введенных пользователем:
def percentiles_to_list(percentiles):
out =[]
i = 1
c = 1
for p,q in percentiles:
if c == len(percentiles):
number_to_append = int(100 - i)
else:
number_to_append = int(p*100-i)
out += [q]*number_to_append
i = p*100
c += 1
return out
def initial_guess(percentiles):
lis = percentiles_to_list(percentiles)
mean = np.mean(lis)
stdev = np.std(lis)
return mean,stdev