-
Notifications
You must be signed in to change notification settings - Fork 115
Fix handling of zero weights #638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2659,3 +2659,49 @@ end | |
| x -0.502451 0.675377 -0.74 0.4982 -2.3776 1.3727 | ||
| ─────────────────────────────────────────────────────────────────────────""" | ||
| end | ||
|
|
||
| @testset "nobs, deviance & stderror with zero weights" begin | ||
| X = [ones(10) 1:10] | ||
| y = [1, 4, 6, 2, 3, 5, 6, 7, 1, 6] | ||
| wts = [1, 0, 4, 0, 5, 2, 6, 4, 2, 6] | ||
|
|
||
| lmod = lm(X, y) | ||
| glmod = glm(X, y, Normal()) | ||
| @test nobs(lmod) == nobs(glmod) == 10 | ||
| @test dof_residual(lmod) == dof_residual(glmod) == 8 | ||
| @test deviance(lmod) ≈ deviance(glmod) ≈ 39.29696969696969 | ||
| @test coef(lmod) ≈ coef(glmod) ≈ [2.6666666666666665, 0.2606060606060606] | ||
| @test stderror(lmod) ≈ stderror(glmod) ≈ [1.51404201801774, 0.24400996532360475] | ||
|
|
||
| lmod = lm(X, y, wts=uweights(10)) | ||
| glmod = glm(X, y, Normal(), wts=uweights(10)) | ||
| @test nobs(lmod) == nobs(glmod) == 10 | ||
| @test dof_residual(lmod) == dof_residual(glmod) == 8 | ||
| @test deviance(lmod) ≈ deviance(glmod) ≈ 39.29696969696969 | ||
| @test coef(lmod) ≈ coef(glmod) ≈ [2.6666666666666665, 0.2606060606060606] | ||
| @test stderror(lmod) ≈ stderror(glmod) ≈ [1.51404201801774, 0.24400996532360475] | ||
|
|
||
| lmod = lm(X, y, wts=fweights(wts)) | ||
| glmod = glm(X, y, Normal(), wts=fweights(wts)) | ||
| @test nobs(lmod) == nobs(glmod) == sum(wts) | ||
| @test dof_residual(lmod) == dof_residual(glmod) == sum(wts) - 2 | ||
| @test deviance(lmod) ≈ deviance(glmod) ≈ 91.87804878048782 | ||
| @test coef(lmod) ≈ coef(glmod) ≈ [3.6707317073170724, 0.20731707317073195] | ||
| @test stderror(lmod) ≈ stderror(glmod) ≈ [0.9538283539174621, 0.13286974786560674] | ||
|
|
||
| lmod = lm(X, y, wts=aweights(wts)) | ||
| glmod = glm(X, y, Normal(), wts=aweights(wts)) | ||
| @test nobs(lmod) == nobs(glmod) == sum(!iszero, wts) | ||
| @test dof_residual(lmod) == dof_residual(glmod) == sum(!iszero, wts) - 2 | ||
| @test deviance(lmod) ≈ deviance(glmod) ≈ 91.87804878048782 | ||
| @test coef(lmod) ≈ coef(glmod) ≈ [3.6707317073170724, 0.20731707317073195] | ||
| @test stderror(lmod) ≈ stderror(glmod) ≈ [2.060504744176091, 0.2870314608599428] | ||
|
|
||
| lmod = lm(X, y, wts=pweights(wts)) | ||
| glmod = glm(X, y, Normal(), wts=pweights(wts)) | ||
| @test nobs(lmod) == nobs(glmod) == sum(!iszero, wts) | ||
| @test dof_residual(lmod) == dof_residual(glmod) == sum(!iszero, wts) - 2 | ||
| @test deviance(lmod) ≈ deviance(glmod) ≈ 24.500813008130084 | ||
| @test coef(lmod) ≈ coef(glmod) ≈ [3.6707317073170724, 0.20731707317073195] | ||
| @test stderror(lmod) ≈ stderror(glmod) ≈ [1.7617126628715203, 0.23455696986842048] | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gragusa I get slightly different standard errors with > X = 1:10
> y = c(1, 4, 6, 2, 3, 5, 6, 7, 1, 6)
> wts = c(1, 0, 4, 0, 5, 2, 6, 4, 2, 6)
> svyd <- svydesign(~1, weights=wts, data=data.frame(X=X, y=y, wts=wts))
> summary(svyglm(y ~ X, svyd))
Call:
svyglm(formula = y ~ X, design = svyd)
Survey design:
svydesign(~1, weights = wts, data = data.frame(X = X, y = y,
wts = wts))
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.6707 1.7371 2.113 0.079 .
X 0.2073 0.2313 0.896 0.405
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for gaussian family taken to be 3.500116)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gragusa I'd appreciate your input on this one too.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the late reply - I don't get the notifications from this repo (although I am subscribed). I think they match to 4 digits (the one used by R to print the coefficient): ## GLM is master/main
using GLM, DataFrames
X = 1:10
y = [1, 4, 6, 2, 3, 5, 6, 7, 1, 6]
wts = [1, 0, 4, 0, 5, 2, 6, 4, 2, 6]
df = DataFrame(y=y, X=X, wts=wts)
julia> lm1 = lm(@formula(y~X), df, weights=GLM.pweights(df.wts))
LinearModel
y ~ 1 + X
Coefficients:
───────────────────────────────────────────────────────────────────────
Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%
───────────────────────────────────────────────────────────────────────
(Intercept) 3.67073 1.73707 2.11 0.0675 -0.334964 7.67643
X 0.207317 0.231276 0.90 0.3962 -0.326007 0.740641
───────────────────────────────────────────────────────────────────────The variance returned by R> ss$cov.scaled
(Intercept) X
(Intercept) 3.0174195 -0.37802382
X -0.3780238 0.05348872which matches Julia's GMM: julia> @show vcov(ll);
vcov(lm1) = [3.0174195202295895 -0.378023819721369; -0.3780238197213689 0.05348872288847028]
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, the problem is that the deviance reported by Julia and R differs. I'm unable to view the code for syvglm for the license. However, the ratio between the two is exactly Let me try to fix this.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. The "problem" is that this PR changes the result. I get this: LinearModel
y ~ 1 + X
Coefficients:
───────────────────────────────────────────────────────────────────────
Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%
───────────────────────────────────────────────────────────────────────
(Intercept) 3.67073 1.76171 2.08 0.0823 -0.640024 7.98149
X 0.207317 0.234557 0.88 0.4108 -0.366623 0.781257
───────────────────────────────────────────────────────────────────────
julia> vcov(lm1)
2×2 Matrix{Float64}:
3.10363 -0.388825
-0.388825 0.055017
julia> deviance(lm1)
24.50081300813008This PR seems more correct to me as
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll try .... 🤞🏽
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PR open: #648
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm so this works but are we sure it's right? :-) Do you think EDIT: and 1: In summary.glm(g) :
observations with zero weight not used for calculating dispersion
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, difficult to say what
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is was my goal with this PR, but I don't think that's the case with #648 at the moment, right? julia> lm1 = lm(@formula(y~X), df, weights=GLM.pweights(df.wts))
[ Warning: pweights is defined in StatsBase and is not public in GLM
LinearModel
y ~ 1 + X
Coefficients:
───────────────────────────────────────────────────────────────────────
Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%
───────────────────────────────────────────────────────────────────────
(Intercept) 3.67073 1.76171 2.08 0.0823 -0.640024 7.98149
X 0.207317 0.234557 0.88 0.4108 -0.366623 0.781257
───────────────────────────────────────────────────────────────────────
julia> df2 = df[df.wts .> 0,:];
julia> lm1 = lm(@formula(y~X), df2, weights=GLM.pweights(df2.wts))
LinearModel
y ~ 1 + X
Coefficients:
───────────────────────────────────────────────────────────────────────
Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%
───────────────────────────────────────────────────────────────────────
(Intercept) 3.67073 1.76171 2.08 0.0823 -0.640024 7.98149
X 0.207317 0.234557 0.88 0.4108 -0.366623 0.781257
───────────────────────────────────────────────────────────────────────Current state of #648: julia> lm1 = lm(@formula(y~X), df, weights=GLM.pweights(df.wts))
[ Warning: pweights is defined in StatsBase and is not public in GLM
LinearModel
y ~ 1 + X
Coefficients:
───────────────────────────────────────────────────────────────────────
Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%
───────────────────────────────────────────────────────────────────────
(Intercept) 3.67073 1.73707 2.11 0.0790 -0.579731 7.92119
X 0.207317 0.231276 0.90 0.4046 -0.358596 0.77323
───────────────────────────────────────────────────────────────────────
julia> df2 = df[df.wts .> 0,:];
julia> lm1 = lm(@formula(y~X), df2, weights=GLM.pweights(df2.wts))
LinearModel
y ~ 1 + X
Coefficients:
───────────────────────────────────────────────────────────────────────
Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%
───────────────────────────────────────────────────────────────────────
(Intercept) 3.67073 1.76171 2.08 0.0823 -0.640024 7.98149
X 0.207317 0.234557 0.88 0.4108 -0.366623 0.781257
───────────────────────────────────────────────────────────────────────If that's useful I can look at the svyglm code for you and/or write to Thomas Lumley (I think he's responsive). Zero weights should be supported without a warning IMO as they can arise sometimes. For example I have a survey where we have two different definitions of who is in scope, and it's convenient to have two different weighting columns, with zero weights for those who are out of scope in a given definition. We simply need to skip observations with zero weights everywhere and everything should be fine. |
||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.