Skip to content

Commit 17f6eee

Browse files
authored
Merge pull request #163 from dmbates/REML
add REML estimation criterion
2 parents 544044b + 0320494 commit 17f6eee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4109
-3771
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ os:
77
julia:
88
- 0.7
99
- 1.0
10+
- 1.1
1011
- nightly
1112
matrix:
1213
allow_failures:

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ environment:
22
matrix:
33
- julia_version: 0.7
44
- julia_version: 1.0
5+
- julia_version: 1.1
56
- julia_version: nightly
67

78
platform:

docs/jmd/SimpleLMM.jmd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ For a linear mixed model, where all the conditional and unconditional distributi
336336
The optional second argument, `verbose`, in a call to `fit!` of a `LinearMixedModel` object produces output showing the progress of the iterative optimization of $\tilde{d}(\bf\theta|\bf y)$.
337337

338338
```{julia;term=true}
339-
mm1 = fit!(LinearMixedModel(@formula(Y ~ 1 + (1 | G)), dyestuff), true);
339+
mm1 = fit!(LinearMixedModel(@formula(Y ~ 1 + (1 | G)), dyestuff), verbose = true);
340340
```
341341

342342
The algorithm converges after 18 function evaluations to a profiled deviance of 327.32706 at $\theta=0.752581$. In this model the parameter $\theta$ is of length 1, the single element being the ratio $\sigma_1/\sigma$.
@@ -597,9 +597,9 @@ const ppt250 = ppoints(250)
597597
The kernel density estimate of $\sigma$ is more symmetric
598598

599599
```{julia;echo=false;fig_width=8}
600-
zquantiles = quantile(Normal(), ppt250);
601-
plot(x = zquantiles, y = quantile(mm1bstp[:β₁], ppt250), line)
602-
# Guide.xlabel("Standard Normal Quantiles"), Guide.ylabel("β₁"))
600+
zquantiles = quantile.(Normal(), ppt250);
601+
plot(x = zquantiles, y = quantile(mm1bstp[:β₁], ppt250), line,
602+
Guide.xlabel("Standard Normal Quantiles"), Guide.ylabel("β₁"))
603603
```
604604

605605
and the normal probability plot of $\sigma$ is also reasonably straight.

docs/jmd/SingularCovariance.jmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ As is customary (though not required) in Julia, a function whose name ends in `!
2525
An optional second argument of `true` in the call to `fit!` produces verbose output from the optimization.
2626

2727
```{julia;term=true}
28-
sleepm = fit!(LinearMixedModel(@formula(Y ~ 1 + U + (1+U|G)), dat[:sleepstudy]), true)
28+
sleepm = fit!(LinearMixedModel(@formula(Y ~ 1 + U + (1+U|G)), dat[:sleepstudy]), verbose=true)
2929
```
3030

3131
The variables in the optimization are the elements of a lower triangular matrix, $\Lambda$, which is the relative covariance factor of the random effects.
@@ -332,7 +332,7 @@ orthfm = fit!(LinearMixedModel(@formula(distance ~ 1 + age + (1 + age | Subject)
332332
```
333333

334334
```{julia;term=true}
335-
srand(1234123)
335+
Random.seed!(1234123)
336336
orthfmbtstrp = bootstrap(10000, orthfm);
337337
```
338338

docs/jmd/constructors.jmd

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,19 @@ Categorical covariates not suitable as grouping factors are named starting with
2828
The formula language in *Julia* is similar to that in *R* except that the formula must be enclosed in a call to the `@formula` macro.
2929
A basic model with simple, scalar random effects for the levels of `G` (the batch of an intermediate product, in this case) is declared and fit as
3030
```{julia;term=true}
31-
fm1 = fit(LinearMixedModel, @formula(Y ~ 1 + (1|G)), dat[:Dyestuff])
31+
fm1 = fit!(LinearMixedModel(@formula(Y ~ 1 + (1|G)), dat[:Dyestuff]))
3232
```
3333

3434
(If you are new to Julia you may find that this first fit takes an unexpectedly long time, due to Just-In-Time (JIT) compilation of the code.
3535
The second and subsequent calls to such functions are much faster.)
3636

3737
```{julia;term=true}
38-
@time fit(LinearMixedModel, @formula(Y ~ 1 + (1|G)), dat[:Dyestuff2]);
38+
@time fit!(LinearMixedModel(@formula(Y ~ 1 + (1|G)), dat[:Dyestuff2]));
39+
```
40+
41+
By default, the model fit is by maximum likelihood. To use the `REML` criterion instead, add the optional named argument `REML = true` to the call to `fit!`
42+
```{julia;term=true}
43+
fm1R = fit!(LinearMixedModel(@formula(Y ~ 1 + (1|G)), dat[:Dyestuff]), REML=true)
3944
```
4045

4146
### Simple, scalar random effects

docs/jmd/optimization.jmd

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,10 @@ Note that the first `ScalarFactorReTerm` in `fm4.trms` corresponds to grouping f
190190

191191
### Progress of the optimization
192192

193-
An optional `Bool` argument of `true` in the call to `fit!` of a `LinearMixedModel` causes printing of the objective and the $\theta$ parameter at each evaluation during the optimization.
193+
An optional named argument, `verbose=true`, in the call to `fit!` of a `LinearMixedModel` causes printing of the objective and the $\theta$ parameter at each evaluation during the optimization.
194194
```{julia;term=true}
195-
fit!(LinearMixedModel(@formula(Y ~ 1 + (1|G)), dat[:Dyestuff]), true);
196-
fit!(LinearMixedModel(@formula(Y ~ 1 + U + (1+U|G)), dat[:sleepstudy]), true);
195+
fit!(LinearMixedModel(@formula(Y ~ 1 + (1|G)), dat[:Dyestuff]), verbose=true);
196+
fit!(LinearMixedModel(@formula(Y ~ 1 + U + (1+U|G)), dat[:sleepstudy]), verbose=true);
197197
```
198198

199199
A shorter summary of the optimization process is always available as an

docs/make.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Documenter, MixedModels, StatsBase
22

33
makedocs(
4-
format = :html,
54
sitename = "MixedModels",
65
pages = ["index.md",
76
"constructors.md",

docs/src/GaussHermite.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ For a `k`th order normalized Gauss-Hermite rule the tridiagonal matrix has zeros
3333
julia> using LinearAlgebra, Gadfly
3434

3535
julia> sym3 = SymTridiagonal(zeros(3), sqrt.(1:2))
36-
3×3 SymTridiagonal{Float64,Array{Float64,1}}:
36+
3×3 LinearAlgebra.SymTridiagonal{Float64,Array{Float64,1}}:
3737
0.0 1.0
3838
1.0 0.0 1.41421
3939
1.41421 0.0
@@ -73,11 +73,11 @@ julia> gausshermitenorm(3)
7373

7474
The weights and positions are often shown as a *lollipop plot*.
7575
For the 9th order rule these are
76-
![Lollipop plot of 9th order normalized Gauss-Hermite rule](./assets//GaussHermite_4_1.svg)
76+
![Lollipop plot of 9th order normalized Gauss-Hermite rule](./assets/GaussHermite_4_1.svg)
7777

7878

7979
Notice that the magnitudes of the weights drop quite dramatically away from zero, even on a logarithmic scale
80-
![Lollipop plot of 9th order normalized Gauss-Hermite rule (logarithmic scale](./assets//GaussHermite_5_1.svg)
80+
![Lollipop plot of 9th order normalized Gauss-Hermite rule (logarithmic scale](./assets/GaussHermite_5_1.svg)
8181

8282

8383

@@ -136,7 +136,7 @@ julia> const contra = @transform(dat[:Contraception],
136136
a2 = abs2.(:a), urbdist = string.(:urb, :d));
137137

138138
julia> describe(contra)
139-
8×8 DataFrame. Omitted printing of 2 columns
139+
8×8 DataFrames.DataFrame. Omitted printing of 2 columns
140140
│ Row │ variable │ mean │ min │ median │ max │ nunique │
141141
│ │ Symbol │ Union │ Any │ Union │ Any │ Union
142142
├─────┼──────────┼────────────┼────────┼─────────┼─────────┼─────────┤
@@ -156,7 +156,7 @@ julia> describe(contra)
156156

157157

158158
Because a smoothed scatterplot of contraception use versus age
159-
![Scatterplot smooth of contraception use versus age](./assets//GaussHermite_9_1.svg)
159+
![Scatterplot smooth of contraception use versus age](./assets/GaussHermite_9_1.svg)
160160

161161

162162
shows that the proportion of women using artificial contraception is approximately quadratic in age,
@@ -170,8 +170,8 @@ julia> m1 = fit!(GeneralizedLinearMixedModel(form1, contra,
170170
Bernoulli()), fast=true)
171171
Generalized Linear Mixed Model fit by maximum likelihood (nAGQ = 1)
172172
Formula: use ~ 1 + a + a2 + l + urb + (1 | d)
173-
Distribution: Bernoulli{Float64}
174-
Link: LogitLink()
173+
Distribution: Distributions.Bernoulli{Float64}
174+
Link: GLM.LogitLink()
175175

176176
Deviance: 2372.7844
177177

@@ -232,7 +232,7 @@ This is primarily due to different sample sizes in the different districts.
232232
julia> using FreqTables
233233

234234
julia> freqtable(contra, :d)'
235-
1×60 Named Adjoint{Int64,Array{Int64,1}}
235+
1×60 Named LinearAlgebra.Adjoint{Int64,Array{Int64,1}}
236236
' ╲ d │ 1 2 3 4 5 6 7 … 55 56 57 58 59 60 61
237237
──────┼────────────────────────────────────────────────────────────────────────
238238
1 │ 117 20 2 30 39 65 18 … 6 45 27 33 10 32 42
@@ -266,12 +266,12 @@ end
266266
267267
268268
A plot of the deviance contribution versus $u_1$
269-
![Deviance contribution of u₁](./assets//GaussHermite_14_1.svg)
269+
![Deviance contribution of u₁](./assets/GaussHermite_14_1.svg)
270270
271271
272272
shows that the deviance contribution is very close to a quadratic.
273273
This is also true for $u_3$
274-
![Deviance contribution of u₃](./assets//GaussHermite_15_1.svg)
274+
![Deviance contribution of u₃](./assets/GaussHermite_15_1.svg)
275275
276276
277277
@@ -292,7 +292,7 @@ As shown below, this is an estimate of the conditional standard deviations of th
292292
julia> const s = inv.(m1.LMM.L.data[Block(1,1)].diag);
293293
294294
julia> s'
295-
1×60 Adjoint{Float64,Array{Float64,1}}:
295+
1×60 LinearAlgebra.Adjoint{Float64,Array{Float64,1}}:
296296
0.406889 0.713511 0.952164 0.627135 0.839679 0.654965 0.60326
297297

298298
````
@@ -316,9 +316,9 @@ end
316316

317317

318318

319-
![Scaled and shifted deviance contributions](./assets//GaussHermite_19_1.svg)
319+
![Scaled and shifted deviance contributions](./assets/GaussHermite_19_1.svg)
320320

321-
![Scaled and shifted deviance contributions](./assets//GaussHermite_20_1.svg)
321+
![Scaled and shifted deviance contributions](./assets/GaussHermite_20_1.svg)
322322

323323

324324

@@ -337,9 +337,9 @@ end
337337

338338

339339

340-
![Scaled and shifted conditional density](./assets//GaussHermite_22_1.svg)
340+
![Scaled and shifted conditional density](./assets/GaussHermite_22_1.svg)
341341

342-
![Scaled and shifted conditional density](./assets//GaussHermite_23_1.svg)
342+
![Scaled and shifted conditional density](./assets/GaussHermite_23_1.svg)
343343

344344

345345
and the function to be integrated with the normalized Gauss-Hermite rule is
@@ -357,6 +357,6 @@ end
357357

358358

359359

360-
![Function to be integrated with normalized Gauss-Hermite rule](./assets//GaussHermite_25_1.svg)
360+
![Function to be integrated with normalized Gauss-Hermite rule](./assets/GaussHermite_25_1.svg)
361361

362-
![Function to be integrated with normalized Gauss-Hermite rule](./assets//GaussHermite_26_1.svg)
362+
![Function to be integrated with normalized Gauss-Hermite rule](./assets/GaussHermite_26_1.svg)

docs/src/MultipleTerms.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ julia> const dat = Dict(Symbol(k)=>v for (k,v) in
1919

2020
julia> const ppt250 = inv(500) : inv(250) : 1.;
2121

22-
julia> const zquantiles = quantile(Normal(), ppt250);
22+
julia> const zquantiles = quantile.(Normal(), ppt250);
2323

2424
julia> function hpdinterval(v, level=0.95)
2525
n = length(v)
@@ -62,7 +62,7 @@ The data are derived from Table 6.6, p. 144 of Davies (), where they are descr
6262
6363
````julia
6464
julia> describe(dat[:Penicillin])
65-
3×8 DataFrame. Omitted printing of 1 columns
65+
3×8 DataFrames.DataFrame. Omitted printing of 1 columns
6666
│ Row │ variable │ mean │ min │ median │ max │ nunique │ nmissing │
6767
│ │ Symbol │ Union │ Any │ Union │ Any │ Union │ Nothing │
6868
├─────┼──────────┼─────────┼──────┼────────┼──────┼─────────┼──────────┤
@@ -122,7 +122,7 @@ Even when we apply each of the six samples to each of the 24 plates, something c
122122
A model incorporating random effects for both the plate and the sample is straightforward to specify — we include simple, scalar random effects terms for both these factors.
123123

124124
````julia
125-
julia> penm = fit(LinearMixedModel, @formula(Y ~ 1 + (1|G) + (1|H)), dat[:Penicillin])
125+
julia> penm = fit!(LinearMixedModel(@formula(Y ~ 1 + (1|G) + (1|H)), dat[:Penicillin]))
126126
Linear mixed model fit by maximum likelihood
127127
Formula: Y ~ 1 + (1 | G) + (1 | H)
128128
logLik -2 logLik AIC BIC
@@ -157,7 +157,7 @@ In chapter [chap:ExamLMM] we saw that a model with a single, simple, scalar ran
157157
The relative covariance factor, $\Lambda_\theta$, (Fig. [fig:fm03LambdaLimage], left panel) is no longer a multiple of the identity. It is now block diagonal, with two blocks, one of size 24 and one of size 6, each of which is a multiple of the identity. The diagonal elements of the two blocks are $\theta_1$ and $\theta_2$, respectively. The numeric values of these parameters can be obtained as
158158

159159
````julia
160-
julia> show(getθ(penm))
160+
julia> show(penm.θ)
161161
[1.53758, 3.21975]
162162
````
163163

@@ -201,7 +201,7 @@ A bootstrap simulation of the model
201201

202202
````julia
203203
julia> @time penmbstp = bootstrap(10000, penm);
204-
24.313179 seconds (83.13 M allocations: 2.532 GiB, 3.95% gc time)
204+
26.932617 seconds (77.19 M allocations: 2.076 GiB, 3.17% gc time)
205205

206206
````
207207

@@ -211,11 +211,11 @@ julia> @time penmbstp = bootstrap(10000, penm);
211211

212212
provides the density plots
213213

214-
![](./assets//MultipleTerms_8_1.svg)
214+
![](./assets/MultipleTerms_8_1.svg)
215215

216-
![](./assets//MultipleTerms_9_1.svg)
216+
![](./assets/MultipleTerms_9_1.svg)
217217

218-
![](./assets//MultipleTerms_10_1.svg)
218+
![](./assets/MultipleTerms_10_1.svg)
219219

220220
````julia
221221
julia> plot(penmbstp, x = :σ₂, density, xlabel("σ₂"))
@@ -281,7 +281,7 @@ The structure and summary of the data object are
281281

282282
````julia
283283
julia> describe(dat[:Pastes])
284-
4×8 DataFrame. Omitted printing of 1 columns
284+
4×8 DataFrames.DataFrame. Omitted printing of 1 columns
285285
│ Row │ variable │ mean │ min │ median │ max │ nunique │ nmissing │
286286
│ │ Symbol │ Union │ Any │ Union │ Any │ Union │ Nothing │
287287
├─────┼──────────┼─────────┼──────┼────────┼──────┼─────────┼──────────┤
@@ -403,13 +403,13 @@ confirm this impression in that all the prediction intervals for the random effe
403403
julia> Random.seed!(4321234);
404404

405405
julia> @time pstsbstp = bootstrap(10000, pstsm);
406-
17.509696 seconds (67.42 M allocations: 2.024 GiB, 4.36% gc time)
406+
21.205995 seconds (66.25 M allocations: 1.788 GiB, 3.44% gc time)
407407

408408
````
409409

410410

411411

412-
![](./assets//MultipleTerms_16_1.svg)
412+
![](./assets/MultipleTerms_16_1.svg)
413413

414414
````julia
415415
julia> plot(pstsbstp, x = , density, xlabel("σ"))
@@ -450,7 +450,7 @@ Plot(...)
450450

451451
````julia
452452
julia> count(x -> x < 1.0e-5, pstsbstp[:σ₂])
453-
3671
453+
3669
454454

455455
````
456456

@@ -522,7 +522,7 @@ is compared to model `pstsm` with
522522

523523
````julia
524524
julia> MixedModels.lrt(pstsm1, pstsm)
525-
2×4 DataFrame
525+
2×4 DataFrames.DataFrame
526526
│ Row │ Df │ Deviance │ Chisq │ pval │
527527
│ │ Int64 │ Float64 │ Float64 │ Float64 │
528528
├─────┼───────┼──────────┼──────────┼──────────┤
@@ -545,7 +545,7 @@ A bootstrap sample
545545

546546
````julia
547547
julia> @time psts1bstp = bootstrap(10000, pstsm1);
548-
6.902661 seconds (23.19 M allocations: 700.737 MiB, 4.32% gc time)
548+
9.347764 seconds (24.71 M allocations: 704.028 MiB, 3.37% gc time)
549549

550550
````
551551

@@ -555,13 +555,13 @@ julia> @time psts1bstp = bootstrap(10000, pstsm1);
555555

556556
provides empirical density plots
557557

558-
![](./assets//MultipleTerms_26_1.svg)
558+
![](./assets/MultipleTerms_26_1.svg)
559559

560560

561561

562562
and
563563

564-
![](./assets//MultipleTerms_27_1.svg)
564+
![](./assets/MultipleTerms_27_1.svg)
565565

566566

567567

@@ -631,7 +631,7 @@ Although the response, `Y`, is on a scale of 1 to 5,
631631

632632
````julia
633633
julia> freqtable(dat[:InstEval][:Y])'
634-
1×5 Named Adjoint{Int64,Array{Int64,1}}
634+
1×5 Named LinearAlgebra.Adjoint{Int64,Array{Int64,1}}
635635
' ╲ Dim1 │ 1 2 3 4 5
636636
─────────┼──────────────────────────────────
637637
1 │ 10186 12951 17609 16921 15754
@@ -648,7 +648,7 @@ At this point we will fit models that have random effects for student, instructo
648648
649649
````julia
650650
julia> @time instm = fit(LinearMixedModel, @formula(Y ~ 1 + A + (1|G) + (1|H) + (1|I)), dat[:InstEval])
651-
3.911847 seconds (2.74 M allocations: 323.059 MiB, 8.79% gc time)
651+
6.545960 seconds (680.61 k allocations: 218.683 MiB, 1.01% gc time)
652652
Linear mixed model fit by maximum likelihood
653653
Formula: Y ~ 1 + A + (1 | G) + (1 | H) + (1 | I)
654654
logLik -2 logLik AIC BIC

0 commit comments

Comments
 (0)