Документация Engee

Руководство

Введение в нелинейную регрессию

Предположим, что для -го наблюдения связь между независимой переменной и зависимой переменной выражается следующей формулой:

где  — нелинейная функция модели, которая зависит от независимой переменной и вектора параметров . Чтобы найти параметр , который лучше всего соответствует нашим данным, мы выбираем параметр так, чтобы свести к минимуму сумму квадратов остатков в данных, то есть решаем следующую задачу:

Учитывая, что функция нелинейная, задача нахождения оптимального значения не имеет аналитического решения. Для решения задачи наименьших квадратов необходимо использовать вычислительные инструменты, а именно LsqFit.jl в данном руководстве.

Одним из примеров нелинейной модели является экспоненциальная модель, которая принимает одноэлементную предикторную переменную . Функция модели имеет следующий вид:

Модель в этом случае описывается так:

Для подгонки данных с помощью LsqFit.jl передайте определенную функцию модели (m), данные (tdata и ydata) и начальное значение параметра (p0) в curve_fit(). В настоящее время LsqFit.jl поддерживает только алгоритм Левенберга-Марквардта.

julia> # t: массив независимых переменных
julia> # p: массив параметров модели
julia> m(t, p) = p[1] * exp.(p[2] * t)
julia> p0 = [0.5, 0.5]
julia> fit = curve_fit(m, tdata, ydata, p0)

Он возвращает составной тип LsqFitResult с рядом любопытных значений:

  • dof(fit): степени свободы

  • coef(fit): наиболее соответствующие параметры

  • fit.resid: вектор остатков

  • fit.jacobian: оцененный якобиан для решения

Вычисление якобиана

Якобиан векторной функции определяется как матрица со следующими элементами:

Таким образом, матрица имеет вид:

Якобиан экспоненциальной функции модели относительно :

По умолчанию с целью аппроксимации якобиана для алгоритма подгонки данных и вычисления ковариации используется метод конечных разностей (дополнительные сведения см. в описании модуля NLSolversBase.jl). Чтобы получить результаты быстрее и, возможно, с большей точностью, можно также передать функцию, вычисляющую якобиан, в curve_fit().

function j_m(t,p)
    J = Array{Float64}(length(t),length(p))
    J[:,1] = exp.(p[2] .* t)       #df/dp[1]
    J[:,2] = t .* p[1] .* J[:,1]   #df/dp[2]
    J
end

fit = curve_fit(m, j_m, tdata, ydata, p0)

Линейная аппроксимация

Нелинейную функцию можно аппроксимировать как линейную путем разложения в ряд Тейлора:

где  — это фиксированный вектор,  — вектор очень небольшой величины, а  — градиент при .

Рассмотрим векторную функцию остатков

с элементами:

Линейную аппроксимацию каждого элемента в таком случае можно записать в следующем виде:

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

Это линейная функция от , так как  — это фиксированный вектор.

Точность соответствия

Линейная аппроксимация нелинейной задачи наименьших квадратов приводит к аппроксимации ковариационной матрицы каждого параметра, что дает возможность выполнить регрессионный анализ.

Рассмотрим решение задачи наименьших квадратов , которое представляет собой локальный минимизатор нелинейной задачи:

Зададим как фиксированную точку в линейной аппроксимации: и . Вектор параметров в окрестности можно выразить как . Локальная аппроксимация для задачи наименьших квадратов имеет следующий вид:

Это, по сути, линейная задача наименьших квадратов:

где , и . Решим уравнение при частных производных, равных . Аналитическое решение выглядит так:

Ковариационная матрица для аналитического решения:

Обратите внимание, что  — это вектор остатков в точке наилучшего соответствия с элементами . Точка очень близка к , поэтому ее можно заменить .

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

где можно оценить как сумму остатков квадратов, деленную на количество степеней свободы:

В LsqFit.jl для вычисления ковариационной матрицы используется QR-разложение как обладающее большей вычислительной устойчивостью. Оно имеет следующую форму:

vcov() вычисляет ковариационную матрицу соответствия:

julia> cov = vcov(fit)
2×2 Array{Float64,2}:
 0.000116545  0.000174633
 0.000174633  0.00258261

Тогда среднеквадратичная погрешность равна корню квадратному из каждого диагонального элемента ковариационной матрицы. stderror() возвращает среднеквадратичную погрешность каждого параметра.

julia> se = stderror(fit)
2-element Array{Float64,1}:
 0.0114802
 0.0520416

margin_error() вычисляет произведение среднеквадратичной погрешности и критического значения каждого параметра на определенном уровне значимости (по умолчанию 5 %) из t-распределения. Допустимый предел погрешности на уровне значимости 10 % можно вычислить так:

julia> margin_of_error = margin_error(fit, 0.1)
2-element Array{Float64,1}:
 0.0199073
 0.0902435

confint() возвращает доверительный интервал каждого параметра на определенном уровне значимости, то есть, по сути, оценочное значение ± допустимый предел погрешности. Чтобы получить доверительный интервал на уровне значимости 10 %, выполните следующий код:

julia> confidence_intervals = confint(fit; level=0.9)
2-element Array{Tuple{Float64,Float64},1}:
 (0.976316, 1.01613)
 (1.91047, 2.09096)

Взвешенные наименьшие квадраты

curve_fit() также принимает весовой параметр (wt) для выполнения метода взвешенных наименьших квадратов и общих наименьших квадратов, где параметр минимизирует взвешенную сумму остатков квадратов.

Весовой параметр (wt) представляет собой массив или матрицу весов для каждой выборки. Для выполнения метода взвешенных наименьших квадратов передайте массив весов [w_1, w_2, ..., w_n] или матрицу весов W:

Задача нахождения взвешенных наименьших квадратов принимает вид:

Или в матричной форме:

где

 — векторная функция остатков со следующими элементами:

Алгоритм LsqFit.jl выдает решение задачи наименьших квадратов .

Если вес представляет собой вектор, то в LsqFit.jl функция остатков, передаваемая в levenberg_marquardt(), имеет другой формат:

r(p) = sqrt.(wt) .* ( model(xpts, p) - ydata )
lmfit(r, g, p0, wt; kwargs...)

Если вес задан матрицей, производится разложение Холецкого, то есть, по сути, из матрицы извлекается квадратный корень:

u = chol(wt)
r(p) = u * ( model(xpts, p) - ydata )
lmfit(r, p0, wt; kwargs...)

Решение будет таким же, как и для задачи наименьших квадратов, упомянутой в данном руководстве.

Если задать и , линейная аппроксимация задачи нахождения взвешенных наименьших квадратов принимает вид:

Аналитическое решение линейной аппроксимации:

Допустим, что погрешности в каждой выборке являются независимыми и имеют нормальное распределение с нулевым средним значением и разной дисперсией (гетероскедастическую погрешность), то есть , где:

Мы знаем дисперсию погрешности и задаем вес как величину, обратную дисперсии (оптимальный вес), то есть :

Ковариационная матрица теперь будет иметь следующий вид.

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

где является оценочным. Если в этом случае задать , результат будет таким же, как и в версии без веса. Однако curve_fit() в настоящее время не поддерживает такую реализацию. curve_fit() предполагает, что вес является матрицей, обратной ковариационной матрице погрешностей, а не отношением ковариационной матрицы погрешностей, то есть ковариация оценочного параметра вычисляется как covar = inv(J'*fit.wt*J).

Если в качестве весового вектора передать вектор единичных значений, при оценке ковариации будут возникать ошибки.

Передайте вектор 1 ./ var(ε) или матрицу inv(covar(ε)) в качестве весового параметра (wt) в функцию curve_fit():

julia> wt = inv(cov_ε)
julia> fit = curve_fit(m, tdata, ydata, wt, p0)
julia> cov = vcov(fit)

Если матрица весов не является диагональной, выполняется метод общих наименьших квадратов.

Общие наименьшие квадраты

Допустим, что погрешности в каждой выборке являются скоррелированными и имеют нормальное распределение с нулевым средним значением и разной дисперсией (гетероскедастическую и автокоррелированную погрешность), то есть .

Если задать матрицу весов как обратную ковариационной матрице погрешностей (оптимальный вес), то есть , то мы получим ковариационную матрицу параметров:

Передайте матрицу inv(covar(ε)) в качестве весового параметра (wt) в функцию curve_fit():

julia> wt = 1 ./ yvar
julia> fit = curve_fit(m, tdata, ydata, wt, p0)
julia> cov = vcov(fit)

Оценка оптимального веса

В большинстве случаев дисперсии погрешностей неизвестны. Для выполнения метода взвешенных наименьших квадратов необходимо сначала оценить дисперсии погрешностей, то есть квадрат остатка -й выборки:

Необходимые остатки возвращаются при невзвешенной подгонке (OLS), так как оценка OLS является несмещенной. Затем передайте обратную величину остатков в качестве оценочного оптимального веса для выполнения метода взвешенных наименьших квадратов:

julia> fit_OLS = curve_fit(m, tdata, ydata, p0)
julia> wt = 1 ./ fit_OLS.resid
julia> fit_WLS = curve_fit(m, tdata, ydata, wt, p0)
julia> cov = vcov(fit_WLS)

Справочные материалы

Hansen, P. C., Pereyra, V. and Scherer, G. (2013) Least squares data fitting with applications. Baltimore, Md: Johns Hopkins University Press, стр. 147—​155.

Kutner, M. H. et al. (2005) Applied Linear statistical models.

Weisberg, S. (2014) Applied linear regression. Fourth edition. Hoboken, NJ: Wiley (Wiley series in probability and statistics).