
    M/PhQ                         d Z ddlZddlmZ ddlmZ ddlm	Z	  G d d          Z
 G d d          Z G d	 d
e          ZdS )ax  
Mixed effects models

Author: Jonathan Taylor
Author: Josef Perktold
License: BSD-3


Notes
-----

It's pretty slow if the model is misspecified, in my first example convergence
in loglike is not reached within 2000 iterations. Added stop criteria based
on convergence of parameters instead.

With correctly specified model, convergence is fast, in 6 iterations in
example.

    N)LikelihoodModelResults)cache_readonlyc                   `    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 ZddZddZddZdS )Unita  
    Individual experimental unit for
    EM implementation of (repeated measures)
    mixed effects model.

    'Maximum Likelihood Computations with Repeated Measures:
    Application of the EM Algorithm'

    Nan Laird; Nicholas Lange; Daniel Stram

    Journal of the American Statistical Association,
    Vol. 82, No. 397. (Mar., 1987), pp. 97-105.


    Parameters
    ----------
    endog : ndarray, (nobs,)
        response, endogenous variable
    exog_fe : ndarray, (nobs, k_vars_fe)
        explanatory variables as regressors or fixed effects,
        should include exog_re to correct mean of random
        coefficients, see Notes
    exog_re : ndarray, (nobs, k_vars_re)
        explanatory variables or random effects or coefficients

    Notes
    -----
    If the exog_re variables are not included in exog_fe, then the
    mean of the random constants or coefficients are not centered.
    The covariance matrix of the random parameter estimates are not
    centered in this case. (That's how it looks to me. JP)
    c                 T    || _         || _        || _        |j        d         | _        d S )Nr   )YXZshapen)selfendogexog_feexog_res       _/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/statsmodels/sandbox/panel/mixed.py__init__zUnit.__init__=   s(    Q    c                     t          j        | j                  |dz  z  t          j        | j        t          j        || j        j                            z   | _        dS )zcovariance of observations (nobs_i, nobs_i)  (JP check)
        Display (3.3) from Laird, Lange, Stram (see help(Unit))
           N)npidentityr   dotr
   TS)r   Dsigmas      r   
_compute_SzUnit._compute_SD   sJ     +df%%q0&468!4!4556r   c                 B    t          j        | j                  | _        dS )zinverse covariance of observations (nobs_i, nobs_i)  (JP check)
        Display (3.2) from Laird, Lange, Stram (see help(Unit))
        N)Linvr   Wr   s    r   
_compute_WzUnit._compute_WK   s     tvr   c                     t          j        | j        | j                  }| j        t          j        t          j        ||          |j                  z
  | _        dS )zprojection matrix (nobs_i, nobs_i) (M in regression ?)  (JP check, guessing)
        Display (3.10) from Laird, Lange, Stram (see help(Unit))

        W - W X Sinv X' W'
        N)r   r   r!   r	   r   P)r   Sinvts      r   	compute_PzUnit.compute_PQ   sC     F4646"""&4!#666r   c                 T    | j         t          j        | j        |          z
  | _        dS )zoresidual after removing fixed effects

        Display (3.5) from Laird, Lange, Stram (see help(Unit))
        N)r   r   r   r	   r)r   alphas     r   
_compute_rzUnit._compute_rZ   s$    
 "&///r   c           	          t          j        |t          j        t          j        | j        j        | j                  | j                            | _        dS )zcoefficients for random effects/coefficients
        Display (3.4) from Laird, Lange, Stram (see help(Unit))

        D Z' W r
        N)r   r   r
   r   r!   r*   b)r   r   s     r   
_compute_bzUnit._compute_ba   s;     26"&46":":DFCCDDr   c                     |                      ||           |                                  |                     |           |                     |           dS )z
        Compute unit specific parameters in
        Laird, Lange, Stram (see help(Unit)).

        Displays (3.2)-(3.5).
        N)r   r#   r,   r/   )r   ar   r   s       r   fitzUnit.fiti   sR     	5!!!r   c                 p    t          j        t          j        | j        | j                  | j                  S )zU
        Utility function to compute X^tWY (transposed ?) for Unit instance.
        )r   r   r!   r   r	   r"   s    r   compute_xtwyzUnit.compute_xtwyv   s(     vbfTVTV,,df555r   c                 z    t          j        t          j        | j        j        | j                  | j                  S )zF
        Utility function to compute X^tWX for Unit instance.
        )r   r   r	   r   r!   r"   s    r   compute_xtwxzUnit.compute_xtwx|   s*     vbfTVXtv..777r   Nc                     ||                      |           t          j        | j        |          }|t          j        t          j        |j        | j                  |          z
  S )aa  
        Approximate covariance of estimates of random effects. Just after
        Display (3.10) in Laird, Lange, Stram (see help(Unit)).

        D - D' Z' P Z D

        Notes
        -----
        In example where the mean of the random coefficient is not zero, this
        is not a covariance but a non-centered moment. (proof by example)
        )r(   r   r   r
   r   r%   )r   r   r&   r'   s       r   
cov_randomzUnit.cov_random   sV     NN4   F46126"&df--q1111r   Fc                    |rht          j        t          j        | j                            | j        t          j        | j        | j                  z                                  z
  dz  S |t          d          | j	        t          j        | j
        |          z
  }t          j        t          j        | j                            |t          j        | j        |          z                                  z
  dz  S )a  
        Individual contributions to the log-likelihood, tries to return REML
        contribution by default though this requires estimated
        fixed effect a to be passed as an argument.

        no constant with pi included

        a is not used if ML=true  (should be a=None in signature)
        If ML is false, then the residuals are calculated for the given fixed
        effects parameters a.
        g       @Nz;need fixed effect a for REML contribution to log-likelihood)r   logr   detr!   r*   r   sum
ValueErrorr   r	   )r   r1   MLr*   s       r   logLz	Unit.logL   s      	PF15==))TVbfTVTV6L6L-L,Q,Q,S,SSWYYYy !^___***AF15==))Q1B1B-B,G,G,I,IIROOr   c                 4    d|                      |          z  S z@deviance defined as 2 times the negative loglikelihood

        r>   r?   r   r>   s     r   deviancezUnit.deviance   s     TYY"Y%%%%r   NF)__name__
__module____qualname____doc__r   r   r#   r(   r,   r/   r2   r4   r6   r8   r?   rF    r   r   r   r      s         D     7 7 7  7 7 70 0 0E E E  6 6 68 8 82 2 2 2"P P P P*& & & & & &r   r   c                       e Zd ZdZd Zd ZddZddZd Zd Z	e
d	             Ze
d
             Zd Ze
d             ZddZddZd ZddZddZdS )OneWayMixeda  
    Model for
    EM implementation of (repeated measures)
    mixed effects model.

    'Maximum Likelihood Computations with Repeated Measures:
    Application of the EM Algorithm'

    Nan Laird; Nicholas Lange; Daniel Stram

    Journal of the American Statistical Association,
    Vol. 82, No. 397. (Mar., 1987), pp. 97-105.


    Parameters
    ----------
    units : list of units
       the data for the individual units should be attached to the units
    response, fixed and random : formula expression, called as argument to Formula


    *available results and alias*

    (subject to renaming, and coversion to cached attributes)

    params() -> self.a : coefficient for fixed effects or exog
    cov_params() -> self.Sinv : covariance estimate of fixed effects/exog
    bse() : standard deviation of params

    cov_random -> self.D : estimate of random effects covariance
    params_random_units -> [self.units[...].b] : random coefficient for each unit


    *attributes*

    (others)

    self.m : number of units
    self.p : k_vars_fixed
    self.q : k_vars_random
    self.N : nobs (total)


    Notes
    -----
    Fit returns a result instance, but not all results that use the inherited
    methods have been checked.

    Parameters need to change: drop formula and we require a naming convention for
    the units (currently Y,X,Z). - endog, exog_fe, endog_re ?

    logL does not include constant, e.g. sqrt(pi)
    llf is for MLE not for REML


    convergence criteria for iteration
    Currently convergence in the iterative solver is reached if either the loglikelihood
    *or* the fixed effects parameter do not change above tolerance.

    In some examples, the fixed effects parameters converged to 1e-5 within 150 iterations
    while the log likelihood did not converge within 2000 iterations. This might be
    the case if the fixed effects parameters are well estimated, but there are still
    changes in the random effects. If params_rtol and params_atol are set at a higher
    level, then the random effects might not be estimated to a very high precision.

    The above was with a misspecified model, without a constant. With a
    correctly specified model convergence is fast, within a few iterations
    (6 in example).
    c                 X   || _         t          | j                   | _        | j        | _        t	          d | j         D                       | _        | j        | _        | j         d         j        }|j        d         | _	        | j	        | _
        t          j        | j	        t          j                  | _        | j         d         j        }|j        d         | _        | j        | _        t          j        | j        fdz  t          j                  | _        d| _        t          j        | _        d S )Nc              3   :   K   | ]}|j         j        d          V  dS )r   N)r	   r   .0units     r   	<genexpr>z'OneWayMixed.__init__.<locals>.<genexpr>   s*      <<TV\!_<<<<<<r   r      r   g      ?)unitslenmn_unitsr<   Nnobsr	   r   p	k_exog_fer   zerosfloat64r1   r
   q	k_exog_rer   r   infdev)r   rW   ds      r   r   zOneWayMixed.__init__   s    
TZv<<<<<<<F	 JqMO$&"*-- JqMO46)A+rz22
6r   c                 N   | j         D ](}|                    | j        | j        | j                   )t          d | j         D                       }t          d | j         D                       }t          j        |          | _        t          j
        | j        |          | _        dS )zjfixed effects parameters

        Display (3.1) of
        Laird, Lange, Stram (see help(Mixed)).
        c                 6    g | ]}|                                 S rM   )r6   rR   s     r   
<listcomp>z*OneWayMixed._compute_a.<locals>.<listcomp>  $    <<<""$$<<<r   c                 6    g | ]}|                                 S rM   )r4   rR   s     r   rh   z*OneWayMixed._compute_a.<locals>.<listcomp>  ri   r   N)rW   r2   r1   r   r   r<   r   pinvr&   r   r   )r   rT   r   r   s       r   
_compute_azOneWayMixed._compute_a  s     J 	1 	1DHHTVTVTZ0000<<<<<==<<<<<==F1II		1%%r   Fc                    d}| j         D ]}|r|j        }n!|                    | j                   |j        }|j        t          j        |j        |j	                  z
  }|t          j
        |d                                          z  }|| j        dz  t          j        t          j        |j                  | j        dz  |z  z
            z  z  }t          j        || j        z            | _        dS )a,  
        Estimate sigma. If ML is True, return the ML estimate of sigma,
        else return the REML estimate.

        If ML, this is (3.6) in Laird, Lange, Stram (see help(Mixed)),
        otherwise it corresponds to (3.8).

        sigma is the standard deviation of the noise (residual)
                r   N)rW   r!   r(   r&   r%   r*   r   r   r
   r.   powerr<   r   tracer   r   sqrtr[   )r   r>   sigmasqrT   r!   r'   s         r   _compute_sigmazOneWayMixed._compute_sigma  s     J 		B 		BD Fty)))F///Arx1~~))+++Gtz1}rxDF0C0C/3z1}q/@1A (B (B B BGGWWtv-..


r   c           	         d}| j         D ]}|r|j        }n!|                    | j                   |j        }|t
          j                            |j        |j                  z  }t          j	        |j
        | j                  }|| j        t          j	        t          j	        |j        |          |          z
  z  }|| j        z  | _        dS )a	  
        Estimate random effects covariance D.
        If ML is True, return the ML estimate of sigma,
        else return the REML estimate.

        If ML, this is (3.7) in Laird, Lange, Stram (see help(Mixed)),
        otherwise it corresponds to (3.9).
        rn   N)rW   r!   r(   r&   r%   r   multiplyouterr.   r   r
   r   r   rY   )r   r>   r   rT   r!   r'   s         r   
_compute_DzOneWayMixed._compute_D5  s     J 	4 	4D Fty)))F""4646222Atvtv&&A"&Q3333AATVr   c                     | j         S )z
        Approximate covariance of estimates of fixed effects.

        Just after Display (3.10) in Laird, Lange, Stram (see help(Mixed)).
        )r&   r"   s    r   	cov_fixedzOneWayMixed.cov_fixedK  s     yr   c                     | j         S )z
        Estimate random effects covariance D.

        If ML is True, return the ML estimate of sigma, else return the REML estimate.

        see _compute_D, alias for self.D
        )r   r"   s    r   r8   zOneWayMixed.cov_randomU  s     vr   c                     | j         S )z|
        estimated coefficients for exogeneous variables or fixed effects

        see _compute_a, alias for self.a
        )r1   r"   s    r   paramszOneWayMixed.params_  s     vr   c                 H    t          j        d | j        D                       S )z+random coefficients for each unit

        c                     g | ]	}|j         
S rM   )r.   rR   s     r   rh   z3OneWayMixed.params_random_units.<locals>.<listcomp>m  s    777D777r   )r   arrayrW   r"   s    r   params_random_unitszOneWayMixed.params_random_unitsh  s%    
 x77DJ777888r   c                 *    |                                  S )z
        estimated covariance for coefficients for exogeneous variables or fixed effects

        see cov_fixed, and Sinv in _compute_a
        )ry   r"   s    r   
cov_paramszOneWayMixed.cov_paramso  s     ~~r   c                 r    t          j        t          j        |                                                     S )z]
        standard errors of estimated coefficients for exogeneous variables (fixed)

        )r   rq   diagr   r"   s    r   bsezOneWayMixed.bsex  s(     wrwt0011222r   c                 4    d|                      |          z  S rA   rD   rE   s     r   rF   zOneWayMixed.deviance  s     DIII$$$$r   c                     d}| j         D ]!}||                    | j        |          z  }"|s1|t          j        t          j        | j                            dz  z  }|S )z9
        Return log-likelihood, REML by default.
        rn   )r1   r>   r   )rW   r?   r1   r   r:   r   r;   r&   )r   r>   r?   rT   s       r   r?   zOneWayMixed.logL  sj    
 J 	/ 	/DDII2I...DD 	1BF15++,,q00Dr   c                 n   t          d | j        D                       }t          d | j        D                       }t          j        ||d          d         | _        d}d}d}| j        D ]}|j        t          j        |j        | j                  z
  |_	        | j
        dk    r-t          j        |j        |j	        d          d         |_        nS|j                            |j        j        d         df          }t          j        ||j	        d          d         |_        |t          j        |j        d                                           | j        t          j        |j        j        |j                  z                                   z
  |j        t          j        |j        j        |j	                  z                                   z
  z  }|t          j                            |j        |j                  z  }|t          j        t          j        |j        j        |j                            z  }| j        | j        dz
  | j
        z  z
  | j        z
  | _        || j        | j        dz
  | j
        z  z
  | j        z
  z  }t          j        |          | _        |||z  z
  | j        z  | _        d S )Nc                 V    g | ]&}t          j        |j        j        |j                  'S rM   )r   r   r	   r   rR   s     r   rh   z*OneWayMixed.initialize.<locals>.<listcomp>  *    AAAd$&))AAAr   c                 V    g | ]&}t          j        |j        j        |j                  'S rM   )r   r   r	   r   r   rR   s     r   rh   z*OneWayMixed.initialize.<locals>.<listcomp>  r   r   )rcondr   rV   r   )r<   rW   r   lstsqr1   r   r   r   r	   r*   ra   r
   r.   reshaper   ro   r   ru   rv   rk   r[   rY   r]   df_residrq   r   r   )r   r   r   r   r'   rr   rT   r
   s           r   
initializezOneWayMixed.initialize  sG   AAdjAAABBAAdjAAABBAR(((+J 	2 	2DVbfTVTV444DFvzzr:::1=FNNDFLOQ#788DF"555a8++//11"&46":"::??AAB"&46":"::??AAB CG ""4646222Atvx00111AA 46A:"77$&@DFdfqjDF22TV;<WW%%
gk/TV+r   h㈵>-C6?c                    |                      |          | j        c| _        }| j        d                             | j                   | j        d                             | j                                                   | j        d                             | j                                                   t          j        | j        |z
  | j        z            |k     r	d| _	        dS t          j
        t          j        | j        | j        z
            || j        z  |z   k               r	d| _	        dS | j                                        | _        dS )z4convergence check for iterative estimation

        rC   llfr|   r   FT)rF   rd   historyappendr1   copyr   r   fabsterminationallabs_a_old)r   r>   rtolparams_rtolparams_atololds         r   contzOneWayMixed.cont  s   
 ,,dh# 	U""48,,,X%%dfkkmm444S  ///7DHsNdh.//$66$D5 6"&$+-..+2F2TUVV 	'D5v{{}}tr   d   ư>c                    t           j        | j        z  | _        g g g d| _        t          |          D ]]}|                                  |                     |           |                     |           | 	                    ||||          s n^d| _
        t          d           || _        t          |           }d|_        |                                 |_        |S )N)r   r|   r   rC   )r>   r   r   r   maxiterz-Warning: maximum number of iterations reachedrV   )r   rc   r1   r   r   rangerl   rs   rw   r   r   print
iterationsOneWayMixedResultsscaler   normalized_cov_params)r   r   r>   r   r   r   iresultss           r   r2   zOneWayMixed.fit  s     ftvo 2266w 		C 		CAOO2&&&OOrO"""99;9D  F F   )DABBB$T**(,(9(9%r   NrH   )Fr   r   r   )r   Fr   r   r   )rI   rJ   rK   rL   r   rl   rs   rw   ry   r8   propertyr|   r   r   r   rF   r?   r   r   r2   rM   r   r   rO   rO      sD       D DL  0& & & / / / /.   ,       X 9 9 X9      3 3 X3% % % %   , , ,8   4     r   rO   c                   p    e Zd ZdZd Zed             Zed             Zd Z	ddZ
d ZddZddZddZd	S )r   z*Results class for OneWayMixed models

    c                 ,    || _         |j        | _        d S rG   )modelr|   )r   r   s     r   r   zOneWayMixedResults.__init__  s    
lr   c                 8    | j                             d          S )NTrC   )r   r?   r"   s    r   r   zOneWayMixedResults.llf  s    z$'''r   c                     | j         j        S rG   )r   r   r"   s    r   r   z&OneWayMixedResults.params_random_units  s    z--r   c                 4    | j                                         S rG   )r   r8   r"   s    r   r8   zOneWayMixedResults.cov_random  s    z$$&&&r   lastexogc                 "   |dk    r| j         | j        j         d          }nmt          |t                    r:t          |          | j        j        k    st          d          | j         |         }nt          j        | j        j                  }|S )Nr   z&length of idx different from k_exog_re)	r|   r   rb   
isinstancelistrX   r=   r   r_   )r   idxmeanrs      r   mean_randomzOneWayMixedResults.mean_random  s    *K!5 5 6 67EET"" 	3s88tz333 !IJJJC(HTZ122Er   c                 r    t          j        t          j        |                                                     S rG   )r   rq   r   r8   r"   s    r   
std_randomzOneWayMixedResults.std_random  s&    wrwt0011222r   NTc           
         ddl m} ddlm} |                                }| j        j        }|dk    r't          t          j	        |dz                      d}}n|d}}|dd| j        j
        d	z  z  z   }|r|                                 }	ndg|z  }	|                                 }
t          |          D ]}|                    |||          }|                    |	|         | j        dd|f         z   |d
          \  }}}t          j        |d         |d         d          }|                    d|z             |                    ||                    ||	|         |
|                   d           |S )a  create plot of marginal distribution of random effects

        Parameters
        ----------
        bins : int or bin edges
            option for bins in matplotlibs hist method. Current default is not
            very sophisticated. All distributions use the same setting for
            bins.
        use_loc : bool
            If True, then the distribution with mean given by the fixed
            effect is used.

        Returns
        -------
        Figure
            figure with subplots

        Notes
        -----
        What can make this fancier?

        Bin edges will not make sense if loc or scale differ across random
        effect distributions.

        r   N)norm   g      ?r   rV      gUUUUUU?T)binsnormedr      z&Random Effect %d Marginal Distribution)locr   r*   )matplotlib.pyplotpyplotscipy.statsr   figurer   rb   intr   ceilrZ   r   r   r   add_subplothistr   linspace	set_titleplotpdf)r   r   use_locpltnormalfigkrowscolsr   r   iiaxfreqbins__pointss                    r   plot_random_univariatez)OneWayMixedResults.plot_random_univariate  s   6 	('''''......jjllJ q55RWQW--..$DDA$D< q4:-666D 	""$$CC#a%C!!(( 	 	BtR00BWWSWt/G"/M%M)-d % < <ND%[q59c::F
 LLABFGGGGGFJJv3r7%)JDD    
r   c                 &   ddl m} |-|                                }|                    ddd          }|}| j        dd|f         }| j        dd|f         }	|                    ||	dd           |d||fz  }|                    |           |}|S )a  create scatter plot of two random effects

        Parameters
        ----------
        idx1, idx2 : int
            indices of the two random effects to display, corresponding to
            columns of exog_re
        title : None or string
            If None, then a default title is added
        ax : None or matplotlib axis instance
            If None, then a figure with one axis is created and returned.
            If ax is not None, then the scatter plot is created on it, and
            this axis instance is returned.

        Returns
        -------
        ax_or_fig : axis or figure instance
            see ax parameter

        Notes
        -----
        Still needs ellipse from estimated parameters

        r   NrV   og      ?)r+   zRandom Effects %d and %d)r   r   r   r   r   r   r   )
r   idx1idx2titler   r   r   	ax_or_figre1re2s
             r   plot_scatter_pairsz%OneWayMixedResults.plot_scatter_pairsO  s    2 	(''''':**,,C1Q''BI&qqqv.&qqqv.
S#T***=.$=E
U	r   c                 t    ddl m} | j        j        dk     rt	          d           || j        ddi          S )Nr   )scatter_ellipser   z!less than two variables availablecolorr*   )ell_kwds)statsmodels.graphics.plot_gridsr   r   rb   r=   r   )r   r   r   s      r   plot_scatter_all_pairsz)OneWayMixedResults.plot_scatter_all_pairsx  sX    CCCCCC:!##@AAAt7)07 7 7 	7r   )r   )NT)NNrG   )rI   rJ   rK   rL   r   r   r   r   r   r8   r   r   r   r   r   rM   r   r   r   r     s         # # # ( ( ^( . . X.' ' '   3 3 3> > > >@' ' ' 'R7 7 7 7 7 7r   r   )rL   numpyr   numpy.linalglinalgr   statsmodels.base.modelr   statsmodels.tools.decoratorsr   r   rO   r   rM   r   r   <module>r      s    &           9 9 9 9 9 9 7 7 7 7 7 7R& R& R& R& R& R& R& R&ju u u u u u u up	X7 X7 X7 X7 X7/ X7 X7 X7 X7 X7r   