Попытка понять синтаксис Джулии в коде линейной регрессии (пакет GLM) - PullRequest
3 голосов
/ 11 апреля 2020

Всего Джулия Нуб здесь (с основами c знание Python). Я пытаюсь сделать линейную регрессию, и вещи, которые я прочитал, предлагают пакет GLM. Вот пример кода, который я нашел здесь :

using DataFrames, GLM
y = 1:10 
df = DataFrame(y = y, x1 = y.^2, x2 = y.^3)
sm = GLM.lm( @formula(y ~ x1 + x2), df )
coef(sm)

Может кто-нибудь объяснить здесь синтаксис? Что значит @formula? Docs здесь скажем @foo означает макрос, который, я думаю, в основном просто функция, но где я могу найти функцию / макрос formula? Просто глядя на использование здесь, я бы подумал, что он может передавать y ~ x1 + x2 (что бы это ни было) в качестве аргумента formula для lm? (аналогично ключевым словам = в python?)

Далее, что здесь ~? Общие документы говорят, что ~ означает отрицание, но я не вижу, как это делает здесь.

Есть ли место в документации GLM, где все это объясняется? Я этого не вижу. Я вижу только несколько примеров, но не полную разбивку каждой функции и всех ее аргументов.

1 Ответ

3 голосов
/ 11 апреля 2020

Вы наткнулись на @ язык формул , который определен в пакете StatsModels.jl и реализован во многих пакетах, связанных со статистикой / эконометрикой, в экосистеме Julia.

Как вы говорите, @formula - это макрос, который преобразует данное ему выражение (здесь y ~ x1 + x2) в другое выражение Джулии. Если вы хотите выяснить, что происходит, когда макрос вызывается в Джулии, - который, как я признаю, часто выглядит как волшебный c для новых (а иногда и опытных!) Пользователей - макрос @macroexpand может вам помочь. В этом случае:

julia> @macroexpand @formula(y ~ x1 + x2)
:(StatsModels.Term(:y) ~ StatsModels.Term(:x1) + StatsModels.Term(:x2))

Результатом выше является выражение, построенное макросом @formula. Мы видим, что переменные в нашем макросе формулы преобразуются в StatsModels.Term объекты. Если бы мы использовали StatsModels напрямую, мы могли бы построить это сами, выполнив:

julia> Term(:y) ~ Term(:x1) + Term(:x2)
FormulaTerm
Response:
  y(unknown)
Predictors:
  x1(unknown)
  x2(unknown)

julia> (Term(:y) ~ Term(:x1) + Term(:x2)) == @formula(y ~ x1 + x2)
true

Теперь, что происходит с ~, который, как вы говорите, может использоваться для отрицания в Юлии? Здесь произошло то, что StatsModels определил методы для ~ (что в Юлии и инфиксный оператор , что означает, что по сути это функция, которая может быть записана между аргументами вместо необходимости вызываться с аргументами в скобках:

julia> (Term(:y) ~ Term(:x)) == ~(Term(:y), Term(:x))
true

Таким образом, написание y::Term ~ x::Term аналогично вызову ~(y::Term, x::Term), и этот метод для вызова ~ с терминами слева и справа определен StatsModels (см. метод № 6 ниже):

julia> methods(~)
# 6 methods for generic function "~":
[1] ~(x::BigInt) in Base.GMP at gmp.jl:542
[2] ~(::Missing) in Base at missing.jl:100
[3] ~(x::Bool) in Base at bool.jl:39
[4] ~(x::Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}) in Base at int.jl:254
[5] ~(n::Integer) in Base at int.jl:138
[6] ~(lhs::Union{AbstractTerm, Tuple{Vararg{AbstractTerm,N}} where N}, rhs::Union{AbstractTerm, Tuple{Vararg{AbstractTerm,N}} where N}) in StatsModels at /home/nils/.julia/packages/StatsModels/pMxlJ/src/terms.jl:397

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

Я согласен, что документы GLM.jl, возможно, не самые полные в мире, но одна из причин этого заключается в том, что весь механизм, стоящий за @formula, на самом деле не это не GLM.jl - так что посмотрите документы по StatsModels, ссылки на которые приведены выше, и я думаю, что они неплохие.

...