Как рассчитать вероятность подбора кривой в scipy?

У меня есть нелинейная модель, которая выглядит так:

Подбор кривой

Темная сплошная линия — это соответствие модели, а серая часть — необработанные данные.

Краткая версия вопроса: как мне получить вероятность соответствия этой модели, чтобы я мог выполнить тест отношения логарифмического правдоподобия? Предположим, что невязка нормально распределена.

Я относительно новичок в статистике, и мои текущие мысли таковы:

  1. Получите остаток от подгонки кривой и рассчитайте дисперсию остатка;

  2. Используйте это уравнение Логарифмическое правдоподобие для нормальных распределенийи подставьте дисперсию остатка в сигма-квадрат, x_i в качестве эксперимента и мю как модель подходит;

  3. Рассчитайте логарифмическое отношение правдоподобия.

Может ли кто-нибудь помочь мне с этими двумя вопросами полной версии?

  1. Верен ли мой метод? (Я так думаю, но было бы здорово убедиться!)

  2. Есть ли готовые функции в python/scipy/statsmodels, чтобы сделать это за меня?


person Yuxiang Wang    schedule 11.04.2014    source источник
comment
Если ваши остатки распределены нормально, вам просто нужно использовать метод наименьших квадратов, чтобы получить модель с наибольшей вероятностью. Можете показать, что вы уже пробовали? Просто знать, что это не домашнее задание?   -  person usethedeathstar    schedule 11.04.2014
comment
@usethedeathstar 0) Lol - Это не домашнее задание, просто попытка ответить на комментарий к обзору исследовательской работы; 2) подбор модели уже выполнен методом наименьших квадратов остатка, я пытаюсь выполнить тест отношения правдоподобия; 3) чтобы выполнить любую работу, основанную на правдоподобии, мне нужно сначала получить вероятность, что является моей проблемой 4) я написал, что я пробовал в соответствии с моими текущими мыслями.... Наконец, извините за действительно наивную статистику: (   -  person Yuxiang Wang    schedule 11.04.2014
comment
Хотя вопрос хорошо написан и сформулирован, возможно, стоит перенести его на stats.stackexchange.com, так как это сайт программирования.   -  person Hooked    schedule 11.04.2014
comment
@Hooked Спасибо за предложение! Не могли бы вы проинструктировать, как...? Мне вручную скопировать и вставить это туда?   -  person Yuxiang Wang    schedule 11.04.2014
comment
Вы можете просто удалить этот вопрос и опубликовать его повторно (форматирование уже выполнено!). Не мешало бы включить комментарии в новый вопрос. Удачи!   -  person Hooked    schedule 11.04.2014


Ответы (2)


Ваша функция правдоподобия

введите здесь описание изображения

который представляет собой просто сумму логарифма функции плотности вероятности распределения Гаусса.

введите здесь описание изображения

это вероятность подгонки мю и сигмы для вашего остатка, а не вероятность вашей модели с учетом ваших данных. Одним словом, ваш подход неправильный.

Поскольку вы выполняете нелинейный метод наименьших квадратов, следуя тому, что уже упоминал @usethedeathstar, вы должны идти прямо к F-test. . Рассмотрим следующий пример, измененный с http://www.walkingrandomly.com/?p=5254, и мы проводим F-test с помощью R. И мы обсудим, как перевести его в python в конце.

# construct the data vectors using c()
> xdata = c(-2,-1.64,-1.33,-0.7,0,0.45,1.2,1.64,2.32,2.9)
> ydata = c(0.699369,0.700462,0.695354,1.03905,1.97389,2.41143,1.91091,0.919576,-0.730975,-1.42001)
# some starting values
> p1 = 1
> p2 = 0.2
> p3 = 0.01

# do the fit
> fit1 = nls(ydata ~ p1*cos(p2*xdata) + p2*sin(p1*xdata), start=list(p1=p1,p2=p2))
> fit2 = nls(ydata ~ p1*cos(p2*xdata) + p2*sin(p1*xdata)+p3*xdata, start=list(p1=p1,p2=p2,p3=p3))

# summarise
> summary(fit1)

Formula: ydata ~ p1 * cos(p2 * xdata) + p2 * sin(p1 * xdata)

Parameters:
   Estimate Std. Error t value Pr(>|t|)    
p1 1.881851   0.027430   68.61 2.27e-12 ***
p2 0.700230   0.009153   76.51 9.50e-13 ***
---
Signif. codes:  0 ?**?0.001 ?*?0.01 ??0.05 ??0.1 ??1

Residual standard error: 0.08202 on 8 degrees of freedom

Number of iterations to convergence: 7 
Achieved convergence tolerance: 2.189e-06

> summary(fit2)

Formula: ydata ~ p1 * cos(p2 * xdata) + p2 * sin(p1 * xdata) + p3 * xdata

Parameters:
   Estimate Std. Error t value Pr(>|t|)    
p1  1.90108    0.03520  54.002 1.96e-10 ***
p2  0.70657    0.01167  60.528 8.82e-11 ***
p3  0.02029    0.02166   0.937     0.38    
---
Signif. codes:  0 ?**?0.001 ?*?0.01 ??0.05 ??0.1 ??1

Residual standard error: 0.08243 on 7 degrees of freedom

Number of iterations to convergence: 9 
Achieved convergence tolerance: 2.476e-06

> anova(fit2, fit1)
Analysis of Variance Table

Model 1: ydata ~ p1 * cos(p2 * xdata) + p2 * sin(p1 * xdata) + p3 * xdata
Model 2: ydata ~ p1 * cos(p2 * xdata) + p2 * sin(p1 * xdata)
  Res.Df Res.Sum Sq Df     Sum Sq F value Pr(>F)
1      7   0.047565                             
2      8   0.053813 -1 -0.0062473  0.9194 0.3696

здесь у нас две модели, fit1 имеет 2 параметра, поэтому остаток имеет 8 степеней свободы; fit2 имеет один дополнительный параметр, а остаток имеет 7 степеней свободы. Модель 2 значительно лучше? Нет, значение F равно 0,9194 при (1,7) степенях свободы и не имеет значения.

Получить таблицу ANOVA: Residue DF легко. Остаточная сумма квадратов: 0.08202*0.08202*8=0.05381 и 0.08243*0.08243*7=0.04756293 (примечание: 'Стандартная ошибка невязки: 0,08243 при 7 степенях свободы' и т. д.). В python можно получить по (y_observed-y_fitted)**2, так как scipy.optimize.curve_fit() не возвращает остатки.

F-ratio равно 0.0062473/0.047565*7, а чтобы получить P-значение: 1-scipy.stats.f.cdf(0.9194, 1, 7).

Складываем их вместе, у нас есть python эквивалент:

In [1]:

import scipy.optimize as so
import scipy.stats as ss
xdata = np.array([-2,-1.64,-1.33,-0.7,0,0.45,1.2,1.64,2.32,2.9])
ydata = np.array([0.699369,0.700462,0.695354,1.03905,1.97389,2.41143,1.91091,0.919576,-0.730975,-1.42001])
def model0(x,p1,p2):
    return p1*np.cos(p2*x) + p2*np.sin(p1*x)
def model1(x,p1,p2,p3):
    return p1*np.cos(p2*x) + p2*np.sin(p1*x)+p3*x
p1, p2, p3 = 1, 0.2, 0.01
fit0=so.curve_fit(model0, xdata, ydata, p0=(p1,p2))[0]
fit1=so.curve_fit(model1, xdata, ydata, p0=(p1,p2,p3))[0]
yfit0=model0(xdata, fit0[0], fit0[1])
yfit1=model1(xdata, fit1[0], fit1[1], fit1[2])
ssq0=((yfit0-ydata)**2).sum()
ssq1=((yfit1-ydata)**2).sum()
df=len(xdata)-3
f_ratio=(ssq0-ssq1)/(ssq1/df)
p=1-ss.f.cdf(f_ratio, 1, df)
In [2]:

print f_ratio, p
0.919387419515 0.369574503394

Как отметил @usethedeathstar: когда остаток нормально распределен, нелинейный метод наименьших квадратов IS является максимальной вероятностью. Следовательно, F-критерий и критерий отношения правдоподобия эквивалентны. Потому что F-ratio — это монотонное преобразование отношения правдоподобия λ.

Или в описательной форме см.: http://www.stata.com/support/faqs/statistics/chi-squared-and-f-distributions/

person CT Zhu    schedule 14.04.2014
comment
Большое спасибо! Это сэкономило мне неделю. Очень быстрый дополнительный вопрос: если невязка аппроксимации не распределена нормально (хотя при аппроксимации использовался метод наименьших квадратов), будет ли действителен f-критерий? - person Yuxiang Wang; 14.04.2014
comment
Люди на stats.stackexchange.com лучше скажут об этом. Теоретически это может выглядеть так, но на самом деле F-тест довольно надежен в отношении предположения о нормальности, поэтому вы все равно сможете использовать его большую часть времени. Надеюсь это поможет. Удачи вам в доработке! - person CT Zhu; 14.04.2014
comment
Понятно. Еще раз большое спасибо! - person Yuxiang Wang; 14.04.2014

Ваша формула кажется мне правильной. Это должно дать вам те же результаты, что и scipy.stats.norm.logpdf(x, loc=mu, scale=sigma)

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

Если у вас есть оценки двух моделей, где одна вложена в другую, то вы можете легко рассчитать ее самостоятельно.

http://en.wikipedia.org/wiki/Likelihood-ratio_test

Вот часть метода в statsmodels, который вычисляет LR-тест для сравнения двух вложенных линейных моделей https://github.com/statsmodels/statsmodels/blob/master/statsmodels/regression/linear_model.py#L1531

person Josef    schedule 13.04.2014