*! version 2.1.0 12feb2012 *! author: Partha Deb * version 2.0.1 15may2009 * version 2.0.0 27aug2008 * version 1.2.1 29jul2008 * version 1.2.0 18jun2008 * version 1.0.0 06mar2007 program fmm, properties(ml_score svyb svyj svyr swml) version 9.2 if replay() { if ("`e(cmd)'" != "fmm") error 301 Replay `0' } else Estimate `0' end program Estimate, eclass // parse the command syntax varlist [if] [in] /// [fweight pweight iweight] /// , COMPonents(string) MIXtureof(string) /// [PROBability(string) /// Robust CLuster(varname) noCONStant /// OFFset(varname numeric) /// EXPosure(varname numeric) /// SHift(real 0.05) SEarch(string) FRom(string) /// DF(real 5) *] mlopts mlopts, `options' gettoken lhs rhs : varlist if "`search'"=="" local search "off" if "`cluster'" != "" { local clopt cluster(`cluster') } if "`weight'" != "" { tempvar wvar quietly gen double `wvar' `exp' local wgt "[`weight'=`wvar']" } if "`offset'" != "" { local offopt "offset(`offset')" } if "`exposure'" != "" { local expopt "exposure(`exposure')" } // mark the estimation sample marksample touse markout `touse' `wvar' `offset' `exposure' markout `touse' `probability' markout `touse' `cluster', strok global fmm_components = `components' global fmm_tdf = `df' // check syntax for number of components if "`components'"<"2" | "`components'">"9" { di in red "number of components, components(#), is a required option" di in red "# must be an integer greater than 1 and less than 10" exit 198 } // check syntax for the distribution mixtureof if "`mixtureof'"!="" /// & "`mixtureof'"!="gamma" /// & "`mixtureof'"!="lognormal" /// & "`mixtureof'"!="negbin1" /// & "`mixtureof'"!="negbin2" /// & "`mixtureof'"!="normal" /// & "`mixtureof'"!="poisson" /// & "`mixtureof'"!="studentt" /// { di in red "invalid syntax: component distribution, mixtureof(), incorrectly specified" exit 198 } // test collinearity for component RHS variables _rmcoll `rhs' `wgt' if `touse', `constant' local rhs `r(varlist)' _rmcoll `probability' `wgt' if `touse', `constant' local probability `r(varlist)' // create density names and equations for ml model local fx `"`fx' (component1: `lhs' = `rhs', `constant' `offopt' `expopt')"' forvalues i=2/`components' { local fx `"`fx' (component`i': = `rhs', `constant' `offopt' `expopt')"' } if "`mixtureof'"=="gamma" { local densityname "Gamma" forvalues i=1/`components' { local scale `"`scale' /lnalpha`i'"' } } if "`mixtureof'"=="lognormal" { local densityname "Lognormal" forvalues i=1/`components' { local scale `"`scale' /lnsigma`i'"' } } if "`mixtureof'"=="negbin1" { local densityname "Negative Binomial-1" forvalues i=1/`components' { local scale `"`scale' /lndelta`i'"' } } if "`mixtureof'"=="negbin2" { local densityname "Negative Binomial-2" forvalues i=1/`components' { local scale `"`scale' /lnalpha`i'"' } } if "`mixtureof'"=="normal" { local densityname "Normal" forvalues i=1/`components' { local scale `"`scale' /lnsigma`i'"' } } if "`mixtureof'"=="poisson" { local densityname "Poisson" } if "`mixtureof'"=="studentt" { local densityname "Student-t" forvalues i=1/`components' { local scale `"`scale' /lnsigma`i'"' } } // SET UP MODELS WITH CONSTANT PROBABILITY SPECIFICATION if "`probability'"=="" { forvalues i=1/`=`components'-1' { local ilp`i' "/imlogitpi`i'" local ilp `" `ilp' `ilp`i'' "' } local Model `"`fx' `ilp' `scale' "' // GENERATE STARTING VALUES if "`from'"=="" { if "`components'"=="2" { tempname lln bn cbn sn bnincr s if "`mixtureof'"=="gamma" { // fit a glm gamma model qui glm `lhs' `rhs' `wgt' if `touse' `in', family(gamma) link(log) /// `constant' `offopt' `expopt' matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = 0 matrix `s' = `bn', `sn' // fit a gamma regression model `quietly' display as txt _n "Fitting Gamma regression model:" ml model d2 gammareg_lf (`lhs'=`rhs', `constant' `offopt' `expopt' ) /// /lndelta `wgt' if `touse' `in' /// , `robust' `clopt' `mlopts' collinear missing init(`s', copy) /// maximize search(off) matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = `bn'[1,`cbn'] matrix `bn' = `bn'[1,1..(`cbn'-1)] matrix `bnincr'=`bn' matrix `bnincr'[1,`cbn'-1] = `bnincr'[1,`cbn'-1]+`shift' } if "`mixtureof'"=="lognormal" { // fit an ols regression model tempvar loglhs qui gen `loglhs' = ln(`lhs') qui reg `loglhs' `rhs' `wgt' if `touse' `in', `constant' matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = ln(e(rmse)) matrix `s' = `bn', `sn' // fit a loglinear regression model `quietly' display as txt _n "Fitting Logormal regression model:" ml model d2 lognormalreg_lf (`lhs'=`rhs', `constant' `offopt' `expopt') /// /lnsigma `wgt' if `touse' `in' /// , `robust' `clopt' `mlopts' collinear missing init(`s', copy) /// maximize search(off) matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = `bn'[1,`cbn'] matrix `bn' = `bn'[1,1..(`cbn'-1)] matrix `bnincr'=`bn' matrix `bnincr'[1,`cbn'-1] = `bnincr'[1,`cbn'-1]*(1+`shift') } if "`mixtureof'"=="negbin1" { // fit a nbreg model `quietly' display as txt _n "Fitting Negative Binomial-1 model:" nbreg `lhs' `rhs' `wgt' if `touse' `in' , `robust' `clopt' /// dispersion(constant) nodisplay `constant' `offopt' `expopt' matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = `bn'[1,`cbn'] matrix `bn' = `bn'[1,1..(`cbn'-1)] matrix `bnincr'=`bn' matrix `bnincr'[1,`cbn'-1] = `bnincr'[1,`cbn'-1]+`shift' } if "`mixtureof'"=="negbin2" { // fit a nbreg model `quietly' display as txt _n "Fitting Negative Binomial-2 model:" nbreg `lhs' `rhs' `wgt' if `touse' `in' , `robust' `clopt' /// dispersion(mean) nodisplay `constant' `offopt' `expopt' matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = `bn'[1,`cbn'] matrix `bn' = `bn'[1,1..(`cbn'-1)] matrix `bnincr'=`bn' matrix `bnincr'[1,`cbn'-1] = `bnincr'[1,`cbn'-1]+`shift' } if "`mixtureof'"=="normal" { // fit an ols regression model qui reg `lhs' `rhs' `wgt' if `touse' `in', `constant' matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = ln(e(rmse)) matrix `s' = `bn', `sn' // fit a linear regression model `quietly' display as txt _n "Fitting Normal regression model:" ml model d2 normalreg_lf (`lhs'=`rhs', `constant' `offopt' `expopt') /// /lnsigma `wgt' if `touse' `in' /// , `robust' `clopt' `mlopts' collinear missing init(`s', copy) /// maximize search(off) matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = `bn'[1,`cbn'] matrix `bn' = `bn'[1,1..(`cbn'-1)] matrix `bnincr'=`bn' matrix `bnincr'[1,`cbn'-1] = `bnincr'[1,`cbn'-1]*(1+`shift') } if "`mixtureof'"=="poisson" { // fit a Poisson model `quietly' display as txt _n "Fitting Poisson model:" poisson `lhs' `rhs' `wgt' if `touse' `in' , `robust' `clopt' /// nodisplay `constant' `offopt' `expopt' matrix `bn' = e(b) scalar `cbn'=colsof(`bn') matrix `bnincr'=`bn' matrix `bnincr'[1,`cbn'] = `bnincr'[1,`cbn']+`shift' matrix `s' = `bn', `bnincr', 1 local contin init(`s', copy) search(`search') } if "`mixtureof'"=="studentt" { // fit an ols regression model qui reg `lhs' `rhs' `wgt' if `touse' `in', `constant' matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = ln(e(rmse)) matrix `s' = `bn', `sn' // fit a Student-t regression model `quietly' display as txt _n "Fitting Student-t regression model:" ml model d2 studenttreg_lf (`lhs'=`rhs', `constant' `offopt' `expopt') /// /lnsigma `wgt' if `touse' `in' /// , `robust' `clopt' `mlopts' collinear missing init(`s', copy) /// maximize search(off) matrix `bn' = e(b) scalar `cbn' = colsof(`bn') matrix `sn' = `bn'[1,`cbn'] matrix `bn' = `bn'[1,1..(`cbn'-1)] matrix `bnincr'=`bn' matrix `bnincr'[1,`cbn'-1] = `bnincr'[1,`cbn'-1]*(1+`shift') } if "`mixtureof'"=="poisson" { matrix `s' = `bn', `bnincr', 1 } else { matrix `s' = `bn', `bnincr', 1, `sn', `sn' } local contin init(`s', copy) search(`search') } if "`components'">"2" { if "`e(cmd)'"!="fmm" | "`e(components)'"!="`=`components'-1'" /// | "`e(mixtureof)'"!="`mixtureof'" | "`e(probability)'"!="" { di in red "provide starting values or estimate `=`components'-1' component `mixtureof' model" di in red "with constant component probabilities" exit 198 } if "`mixtureof'"=="poisson" { forvalues i=1/`components' { local tnames `" `tnames' b`i' "' } forvalues i=1/`=`components'-1' { local tnames `" `tnames' ipi`i' pi`i' "' } tempname b cb cb1cl C incr den s sumpi `tnames' pi`components' matrix `b' = e(b) scalar `cb' = colsof(`b') scalar `cb1cl' = (1/(`components'-1))*(`cb'-`components'+2) forvalues i=1/`=`components'-1' { matrix `b`i''=`b'[1,((`i'-1)*`cb1cl'+1)..(`i'*`cb1cl')] } forvalues i=1/`=`components'-2' { scalar `ipi`i'' = `b'[1,`cb'-(`components'-2)+`i'] } scalar `den' = 1 forvalues i=1/`=`components'-2' { scalar `den' = `den' + exp(`ipi`i'') } scalar `sumpi' = 0 forvalues i=1/`=`components'-2' { scalar `pi`i'' = exp(`ipi`i'')/`den' scalar `sumpi' = `sumpi' + `pi`i'' } scalar `pi`=`components'-1'' = 1-`sumpi' matrix `b`components'' = `b1' local C 1 matrix `incr'=J(1,`cb1cl',0) matrix `incr'[1,`cb1cl'] = `shift' forvalues i=2/`=`components'-1' { if `pi`i'' > `pi`=`i'-1''{ local C `=`i'' matrix `b`components'' = `b`i'' } } scalar `pi`C'' = (1-`shift')*`pi`C'' scalar `pi`components'' = `shift'*`pi`C'' forvalues i=1/`=`components'-1' { scalar `ipi`i'' = ln(`pi`i''/`pi`components'') } forvalues i=1/`=`components'-1' { local bnames `" `bnames' `b`i'', "' local ipinames `" `ipinames', `ipi`i'' "' } matrix `s' = `bnames' `b`components''+`incr' `ipinames' local contin init(`s', copy) search(`search') } if "`mixtureof'"!="poisson" { forvalues i=1/`components' { local tnames `" `tnames' b`i' scale`i' "' } forvalues i=1/`=`components'-1' { local tnames `" `tnames' ipi`i' pi`i' "' } tempname b cb cb1cl C bcincr den s sumpi `tnames' pi`components' matrix `b' = e(b) scalar `cb' = colsof(`b') scalar `cb1cl' = (1/(`components'-1))*(`cb'-2*`components'+3) forvalues i=1/`=`components'-1' { matrix `b`i'' = `b'[1,((`i'-1)*`cb1cl'+1)..(`i'*`cb1cl')] scalar `scale`i'' = `b'[1,`cb'-`components'+1+`i'] } forvalues i=1/`=`components'-2' { scalar `ipi`i'' = `b'[1,`cb'-2*`components'+3+`i'] } scalar `den' = 1 forvalues i=1/`=`components'-2' { scalar `den' = `den' + exp(`ipi`i'') } scalar `sumpi' = 0 forvalues i=1/`=`components'-2' { scalar `pi`i'' = exp(`ipi`i'')/`den' scalar `sumpi' = `sumpi' + `pi`i'' } scalar `pi`=`components'-1'' = 1-`sumpi' matrix `b`components'' = `b1' matrix `scale`components'' = `scale1' local C 1 forvalues i=2/`=`components'-1' { if `pi`i'' > `pi`=`i'-1''{ local C `=`i'' matrix `b`components'' = `b`i'' scalar `scale`components'' = `scale`i'' } } matrix `bcincr'=`b`components'' matrix `bcincr'[1,`cb1cl'] = `bcincr'[1,`cb1cl']*(1+`shift') scalar `pi`C'' = (1-`shift')*`pi`C'' scalar `pi`components'' = `shift'*`pi`C'' forvalues i=1/`=`components'-1' { scalar `ipi`i'' = ln(`pi`i''/`pi`components'') } forvalues i=1/`=`components'-1' { local bnames `" `bnames' `b`i'', "' local ipinames `" `ipinames', `ipi`i'' "' } forvalues i=1/`components' { local scalenames `" `scalenames', `scale`i'' "' } matrix `s' = `bnames' `bcincr' `ipinames' `scalenames' local contin init(`s', copy) search(`search') } } } // if starting values are provided if `"`from'"'!="" { local contin init(`from',copy) search(`search') } // fit the full model local title "`components' component `densityname' regression" `quietly' display as txt _n "Fitting `components' component `densityname' model:" /* ml model d2debug fmm_`mixtureof'_lf `Model' `wgt' if `touse' `in' /// , `contin' maximize */ ml model d2 fmm_`mixtureof'_lf `Model' `wgt' if `touse' `in' /// , title(`title') `robust' `clopt' `mlopts' `contin' /// collinear missing waldtest(`components') maximize ereturn local cmd fmm ereturn local components "`components'" ereturn local mixtureof "`mixtureof'" ereturn local predict "fmm_`mixtureof'_p" if "`mixtureof'"=="poisson" { ereturn scalar k_aux = `components'-1 } else { ereturn scalar k_aux = 2*`components'-1 } Replay } // SET UP MODELS WITH REGRESSORS IN THE PROBABILITY SPECIFICATION if "`probability'"!="" { forvalues i=1/`=`components'-1' { local ilp `" `ilp' (imlogitpi`i': = `probability')"' } local Model `"`fx' `ilp' `scale' "' if "`from'"=="" { if "`e(cmd)'"!="fmm" | "`e(components)'"!="`=`components''" /// | "`e(mixtureof)'"!="`mixtureof'" | "`e(probability)'"!="" { di in red "provide starting values or estimate `components' component `densityname' model" di in red "with constant component probabilities" exit 198 } // get starting values from prior LC model tempname s mat `s'= e(b) local contin init(`s') search(`search') } if `"`from'"'!="" { local contin init(`from',copy) search(`search') } // fit the full model local title `title' `quietly' display as txt _n "Fitting `components' component `densityname' model:" ml model d2 fmm_`mixtureof'_lf `Model' `wgt' if `touse' `in' /// , title(`title') `robust' `clopt' `mlopts' `contin' /// collinear missing waldtest(`components') maximize ereturn local cmd fmm ereturn local components "`components'" ereturn local mixtureof "`mixtureof'" ereturn local probability "`probability'" ereturn local predict "fmm_`mixtureof'_p" if "`mixtureof'"=="poisson" { ereturn scalar k_aux = 0 } else { ereturn scalar k_aux = `components' } Replay } end program Replay, eclass ml display local components `e(components)' local mixtureof `e(mixtureof)' local probability `e(probability)' if "`mixtureof'"=="gamma" { local scale `"alpha"' } if "`mixtureof'"=="lognormal" { local scale `"sigma"' } if "`mixtureof'"=="negbin1" { local scale "delta" } if "`mixtureof'"=="negbin2" { local scale "alpha" } if "`mixtureof'"=="normal" { local scale `"sigma"' } if "`mixtureof'"=="studentt" { local scale `"sigma"' } if "`probability'"=="" { if `components'==2 { if "`mixtureof'"!="poisson" { _diparm ln`scale'1, exp label(`scale'1) ereturn scalar `scale'1_est = r(est) ereturn scalar `scale'1_se = r(se) _diparm ln`scale'2, exp label(`scale'2) ereturn scalar `scale'2_est = r(est) ereturn scalar `scale'2_se = r(se) } _diparm imlogitpi1, invlogit label(pi1) ereturn scalar pi1_est = r(est) ereturn scalar pi1_se = r(se) local prob2 diparm(imlogitpi1, func(1-exp(@)/(1+exp(@))) /// der(-exp(@)/((1+exp(@))^2)) label(pi2)) _diparm imlogitpi1, func(1-exp(@)/(1+exp(@))) /// der(-exp(@)/((1+exp(@))^2)) label(pi2) ereturn scalar pi2_est = r(est) ereturn scalar pi2_se = r(se) } if `components'>=3 { if "`mixtureof'"!="poisson" { forvalues j=1/`components' { _diparm ln`scale'`j', exp label(`scale'`j') ereturn scalar `scale'`j'_est = r(est) ereturn scalar `scale'`j'_se = r(se) } } local den "1" forvalues i=1/`=`components'-1' { local den `"`den'+exp(@`i')"' local invml `"`invml' imlogitpi`i'"' } forvalues i=1/`=`components'-1' { local prob`i' `"_diparm `invml', func(exp(@`i')/(`den')) der("' forvalues j=1/`=`components'-1' { if `i'==`j' { local prod `"`den'-exp(@`i')"' local der`i'`j' `"+0+exp(@`i')*(`prod')/((`den')^2)"' } else { local der`i'`j' `"-exp(@`i')*exp(@`j')/((`den')^2)"' } local prob`i' `"`prob`i'' `der`i'`j''"' } local prob`i' `" `prob`i'' ) label(pi`i') ci(logit) "' `prob`i'' ereturn scalar pi`i'_est = r(est) ereturn scalar pi`i'_se = r(se) } forvalues j=1/`=`components'-1' { forvalues i=1/`=`components'-1' { local sumder`j' `"`sumder`j''`der`i'`j''"' } local derivs `"`derivs'`sumder`j'' "' } _diparm `invml', func(1-(`den'-1)/(`den')) /// der(`derivs') label(pi`components') ereturn scalar pi`components'_est = r(est) ereturn scalar pi`components'_se = r(se) } _diparm __bot__ } if "`probability'"!="" { if "`mixtureof'"!="poisson" { forvalues j=1/`components' { _diparm ln`scale'`j', exp label(`scale'`j') ereturn scalar `scale'`j'_est = r(est) ereturn scalar `scale'`j'_se = r(se) } _diparm __bot__ } } end