Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • New on SSC: lmtest -- Lagrange-multiplier test after constrained maximum-likelihood estimation

    Thanks to Kit Baum, a new package called lmtest is available on SSC.

    lmtest performs a Lagrange-multiplier (LM) test (Silvey, 1959), also referred to as score test, of the restrictions that were previously imposed on the most recently estimated model by specifying the option constraints(). lmtest complements test and lrtest that implement the Wald test and the likelihood-ratio test, respectively, which - together with the Lagrange-multiplier test - represent the three canonical approaches to testing hypotheses after maximum-likelihood (ML) estimation (cf. Greene, 2012, p. 564). lmtest requires that the preceding estimation command allows the option constraints() and the maximize_options iterate() and from(), and also requires that the constraints are saved in e(Cns) and the score vector is saved in e(gradient). Unlike test, the syntax of lmtest does not involve specifying the restrictions to be tested. The restrictions are rather specified by the option constraints() in the command syntax used for estimating the model. This corresponds to the logic of the Lagrange-multiplier test to estimate only the restricted version of a model. The LM-test statistic reads simply as score*inv(Info)*score', with the estimated score vector (score) and the estimated inverse information matrix (inv(Info)) being evaluated at the restricted maximum. lmtest calculates the estimated score vector and the coefficient variance-covariance matrix, which serves as estimator for inv(Info), at the restricted maximum by making use of the maximize_options iterate(0) and from(e(b)). For determining the number of degrees-of-freedom, lmtest considers all restrictions that are specified in e(Cns), except for base-level coefficients being restricted to the value of zero. indepvars that are automatically omitted due to collinearity may hence distort the result of the LM test. Specifying the option df(#) allows manually providing the appropriate number of degrees-of-freedom. Alternatively, one may specify the option noomitted to prevent lmtest from interpreting omitted variables as exclusion restrictions to be tested.

    References:
    Silvey, S. D. (1959). “The Lagrangian Multiplier Test. Annals of Mathematical Statistics 30, 389-407.
    Greene, W. H. (2012). Econometric Analysis, Pearson, 7th ed.

    Best wishes,
    Harald

    ________________________________________
    Harald Tauchmann
    Friedrich-Alexander-Universität Erlangen-Nürnberg
    Professur für Gesundheitsökonomie
    Findelgasse 7/9
    90402 Nürnberg
    Germany




  • #2
    . ssc inst lmtest
    checking lmtest consistency and verifying not already installed...
    file http://fmwww.bc.edu/repec/bocode/l/lmtest.ado not found
    could not copy http://fmwww.bc.edu/repec/bocode/l/lmtest.ado
    (no action taken)

    ssc install: apparent error in package file for lmtest; please notify [email protected],
    providing package name
    r(601);

    Sorry,I can not install this command
    Best regards.

    Raymond Zhang
    Stata 17.0,MP

    Comment


    • #3
      Dear Raymond,
      Kit Baum fixed this issue. Downloading lmtest from SSC now works.
      Best,
      Harald

      Comment


      • #4
        Nice!
        The scoretest program in the boottest package, can also do this. Some equivalent commands, I think:

        Code:
        webuse sysdsn1
        constraint 1 [Uninsure]
        constraint 2 [Prepaid]: 2.site 3.site
        mlogit insure age male nonwhite i.site, constr(1 2)
        lmtest
        
        mlogit insure age male nonwhite i.site
        scoretest, h0(1 2)
        scoretest ([Uninsure]) ([Prepaid]: 2.site 3.site)
        scoretest [Uninsure] ([Prepaid]: 2.site 3.site)
        ​​​​​​​
        Or one can replace "scoretest" with "boottest" to bootstrap the distribution of the score statistic, i.e., perform the "score bootstrap" of Kline and Santos (2012).

        These examples use boottest 4.4.4, which is not yet on SCC, but can be installed with "net install boottest, replace from(https://raw.github.com/droodman/boottest/v4.4.4)"

        Comment


        • #5
          Dear David, thank you very much for pointing me to the conventional LM test functionality of boottest, which I have not been aware of. Thought there was a gap to fill in Stata’s toolbox of classical methods, which, however, has already been filled by your package. At least, lmtest (more recent version lgrgtest; forthcoming Stata Journal) and scoretest – as one should expect - seem to generate identical results after popular Stata ML estimation commands. (After some less frequently used commands, e.g. [ME] (multilevel mixed effects), scoretest fails while lgrgtest still carries out a test; yet I am almost sure that one can find examples for the opposite pattern.)
          Best, Harald

          Comment


          • #6
            Oh that is a good point, about the [ME] commands. I think I have fixed it in the latest version, for scoretest as well as boottest. Please let me know if you find any other crashes.

            Comment


            • #7
              Dear David: I did some (mechanical) testing. In most of my applications, scoretest and lgrgtest yield the same results. Yet after several commands - at least in my applications - scoretest does not carry out a test, though lgrgtest does (nlogit, dsge, eprobit, meglm, gsem, frontier, mlexp, mprobit, slogit, truncreg, gamma, arch, arfima, arima, dfactor, mgarch, ucm, xtcloglog, xtfrontier, xtintreg, xtlogit, xtnbreg, xtpoisson, xtprobit, xttobit). There are also some estimation commands after which (in my applications) scoretest and lgrgtest yield very different test results (fracreg, ologit, oprobit, etpoisson). Best, Harald

              Comment


              • #8
                Wow. Very helpful.

                Comment


                • #9
                  Harald Tauchmann, thanks again for this thorough testing. There's nothing like an independent replication to surface bugs.

                  Inspired by this feedback I tested scoretest more thoroughly. I think I found a few issues in both scoretest and lmtest, which might pertain to lgrgtest.

                  The latest scoretest should be on SSC soon and is now available via
                  Code:
                  net install boottest, from(https://raw.github.com/droodman/boottest/v4.4.6) replace
                  I few points:
                  • It looks like lmtest performs a classical score test after estimates with robust/clustered standard errors, where scoretest "robustifies" its results (which is what boottest is really for). I believe that results from fracreg are robust by default because its errors are inevitably heteroskedastic. So the two commands give different results there. It seems like it would be good for lmtest/lgrgtest to provide a warning in such cases.
                  • Typically in a score test, most entries of the gradient vector should be exactly 0, because optimization with respect to those parameters is unconstrained. In practice, there are usually not quite zero. Thus it matters a little whether you include them in the computation, or drop them as if they were 0. I think lmtest retains them. scoretest does not, and that won't change because it would complicate the code too much. I don't have a strong view on which is better. I think it explains a discrepancy I found for dsge.
                  • A few Stata commands are inconsistent in subtle ways that complicate scoretest's attempt to automate the process of running the estimate with the user's hypothesis imposed. For example, after xttobit lnwage_1 age ..., the constraint "[lnwage_1]age=0" fails, when it should not. I now make boottest and scoretest error if asked to impose the null on xttobit and xtintreg. A different issue affects slogit, so scoretest fails there too.
                  Below are the results from my test suite, and the code for the test suite:

                  Code:
                  -----------------------------------------------
                             | scoretest scoretest lmtest  lmtest
                             |        df      chi2     df    chi2
                  -----------+-----------------------------------
                  nlogit     |         1     7.202              
                  dsge       |         1     0.035      1   0.037
                  eprobit    |         2    66.111      2  66.111
                  frontier   |         1     7.885      1   7.885
                  mlexp      |         1   117.426      1 117.426
                  mprobit    |         2     8.300              
                  slogit     |                          2 127.951
                  truncreg   |         1     9.000      1   9.000
                  arch       |         1     2.766      1   2.766
                  arfima     |         1     0.003      1   0.003
                  arima      |         1     0.627      1   0.627
                  dfactor    |         1    25.422              
                  mgarch     |         2    10.268      2  10.268
                  ucm        |         1     1.679              
                  xtcloglog  |         1     1.227      1   1.227
                  xtlogit    |         1     1.055      1   1.055
                  xtprobit   |         1     0.951      1   0.951
                  xtfrontier |         1   485.899      1 485.899
                  xtintreg   |                          1 239.865
                  xtpoisson  |         1     2.394      1   2.394
                  xtnbreg    |         1     2.113      1   2.113
                  xttobit    |                          1  32.367
                  fracreg    |         1   156.321      1 162.646
                  ologit     |         1    14.813      1  14.813
                  oprobit    |         1    16.327      1  16.327
                  etpoisson  |         2    46.295      2  46.295
                  -----------------------------------------------
                  Code:
                  collect clear
                  
                  cap program drop tests
                  program define tests
                  noi di 1, "`e(cmdline)'"
                    cap noi collect r(chi2) r(df), tags(testcmd[scoretest] estcmd[`e(cmd)']): scoretest `*'
                    constraint 1 `*'
                    local cmdline `e(cmdline)'
                    _parse comma lhs rhs: cmdline
                    `lhs'`=cond(`"`rhs'"'=="",",","")'`rhs' constr(1)
                    cap noi collect r(chi2) r(df), tags(testcmd[lmtest] estcmd[`e(cmd)']): lmtest, forcevce
                  end
                  
                  webuse restaurant, clear
                  nlogitgen type = restaurant(fast: Freebirds | MamasPizza, family: CafeEccell | LosNortenos | WingsNmore, fancy: Christophers | MadCows)
                  nlogit chosen cost distance rating || type: income kids, base(family) || restaurant:, noconst case(family_id)
                  tests cost
                  
                  webuse rates2, clear
                  generate p = 400*(ln(gdpdef) - ln(L.gdpdef))
                  dsge (p = {beta}*F.p + {kappa}*x) (x = F.x -(r - F.p - g), unobserved) (r = (1/{beta})*p + u) (F.u = {rhou}*u, state) (F.g = {rhoz}*g, state)
                  tests [/structural]beta = .5
                  
                  webuse heartsm, clear
                  eprobit attack age bmi i.exercise, select(full = age bmi i.checkup)
                  tests age
                  
                  webuse pig, clear
                  meglm weight week || id:
                  tests week
                  
                  use https://www.stata-press.com/data/r18/gsem_womenwk, clear
                  generate selected = 0 if wage < .
                  generate notselected = 0 if wage >= .
                  gsem (wage <- educ age L) (selected <- married children educ age L@1, family(gaussian, udepvar(notselected))), var(L@1 e.wage@a e.selected@a)
                  tests [wage]educ=1
                  
                  webuse greene9, clear
                  frontier lnv lnk lnl
                  tests lnk
                  
                  sysuse auto, clear
                  mlexp (ln(normalden(mpg, {b0} + {b1}*gear_ratio, {sigma})))
                  tests /b1=0
                  
                  webuse sysdsn1 , clear
                  mprobit insure age male nonwhite i.site
                  tests 2.site
                  
                  webuse auto2yr, clear
                  slogit repair foreign mpg price gratio
                  tests mpg
                  
                  webuse laborsub, clear
                  truncreg whrs kl6 k618 wa we, ll(0)
                  tests kl6
                  
                  webuse wpi1, clear
                  arch D.ln_wpi, arch(1/3)
                  tests L.arch
                  
                  webuse mloa, clear
                  arfima S12.log, ar(1) ma(2)
                  tests [ARFIMA]d=.4
                  
                  webuse wpi1, clear
                  arima wpi, arima(1,1,1)
                  tests [ARMA]L.ar=.8
                  
                  webuse dfex, clear
                  dfactor (D.(ipman income hours unemp) = , noconstant) (f = , ar(1/2))
                  tests L.f
                  
                  webuse stocks, clear
                  mgarch dvech (toyota honda = L.toyota L.honda), arch(1)
                  tests L.toyota
                  
                  webuse unrate, clear
                  ucm unrate, cycle(1)
                  tests [cycle1]damping=.99
                  
                  webuse union, clear
                  xtcloglog union age grade south##c.year
                  tests age
                  
                  xtlogit union age grade i.not_smsa south##c.year
                  tests age
                  
                  xtprobit union age grade i.not_smsa south##c.year
                  tests age
                  
                  webuse xtfrontier1, clear
                  xtfrontier lnwidgets lnmachines lnworkers, ti
                  tests lnmachines
                  
                  webuse nlswork5, clear
                  xtintreg ln_wage1 ln_wage2 union age grade south##c.year occ_code
                  tests union
                  
                  webuse airacc, clear
                  xtpoisson i_cnt inprog, exposure(pmiles) irr
                  tests inprog
                  
                  xtnbreg i_cnt inprog, exposure(pmiles) irr
                  tests inprog
                  
                  webuse nlswork3, clear
                  xttobit ln_wage union age grade not_smsa south##c.year, ul(1.9)
                  tests age
                  
                  webuse 401k, clear
                  fracreg probit prate mrate c.ltotemp##c.ltotemp c.age##c.age i.sole
                  tests mrate
                  
                  webuse fullauto, clear
                  ologit rep77 foreign length mpg
                  tests foreign
                  
                  oprobit rep77 foreign length mpg
                  tests foreign
                  
                  webuse trip1, clear
                  etpoisson trips cbd ptn worker weekend, treat(owncar = cbd ptn worker realinc)
                  tests cbd
                  
                  collect style cell result[chi2], nformat(%6.3f)
                  collect layout (estcmd) (testcmd#result[df chi2])
                  Last edited by David Roodman; 27 May 2023, 20:09.

                  Comment


                  • #10
                    The new version is on SSC now.

                    Also, that "noi di 1, "`e(cmdline)'" line is unnecessary. I don't know how it snuck in there.

                    Comment

                    Working...
                    X