U
    Kvf+                     @   sR  d Z ddlmZ ddlZddlmZmZ ddlm	Z	 ddl
Z
ddlmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ G dd dZG dd dZG dd deZG dd dZG dd deeZG dd deeZG dd deZG dd deZe
jjdde dG dd deZ!G d d! d!eZ"e
jjd"de#dG d#d$ d$eZ$dS )%a|	  Tests for gam.AdditiveModel and GAM with Polynomials compared to OLS and GLM


Created on Sat Nov 05 14:16:07 2011

Author: Josef Perktold
License: BSD


Notes
-----

TODO: TestGAMGamma: has test failure (GLM looks good),
        adding log-link did not help
        resolved: gamma does not fail anymore after tightening the
                  convergence criterium (rtol=1e-6)
TODO: TestGAMNegativeBinomial: rvs generation does not work,
        nbinom needs 2 parameters
TODO: TestGAMGaussianLogLink: test failure,
        but maybe precision issue, not completely off

        but something is wrong, either the testcase or with the link
        >>> tt3.__class__
        <class '__main__.TestGAMGaussianLogLink'>
        >>> tt3.res2.mu_pred.mean()
        3.5616368292650766
        >>> tt3.res1.mu_pred.mean()
        3.6144278964707679
        >>> tt3.mu_true.mean()
        34.821904835958122
        >>>
        >>> tt3.y_true.mean()
        2.685225067611543
        >>> tt3.res1.y_pred.mean()
        0.52991541684645616
        >>> tt3.res2.y_pred.mean()
        0.44626406889363229



one possible change
~~~~~~~~~~~~~~~~~~~
add average, integral based tests, instead of or additional to sup
    * for example mean squared error for mu and eta (predict, fittedvalues)
      or mean absolute error, what's the scale for this? required precision?
    * this will also work for real non-parametric tests

example: Gamma looks good in average bias and average RMSE (RMISE)

>>> tt3 = _estGAMGamma()
>>> np.mean((tt3.res2.mu_pred - tt3.mu_true))/tt3.mu_true.mean()
-0.0051829977497423706
>>> np.mean((tt3.res2.y_pred - tt3.y_true))/tt3.y_true.mean()
0.00015255264651864049
>>> np.mean((tt3.res1.y_pred - tt3.y_true))/tt3.y_true.mean()
0.00015255538823786711
>>> np.mean((tt3.res1.mu_pred - tt3.mu_true))/tt3.mu_true.mean()
-0.0051937668989744494
>>> np.sqrt(np.mean((tt3.res1.mu_pred - tt3.mu_true)**2))/tt3.mu_true.mean()
0.022946118520401692
>>> np.sqrt(np.mean((tt3.res2.mu_pred - tt3.mu_true)**2))/tt3.mu_true.mean()
0.022953913332599746
>>> maxabs = lambda x: np.max(np.abs(x))
>>> maxabs((tt3.res1.mu_pred - tt3.mu_true))/tt3.mu_true.mean()
0.079540546242707733
>>> maxabs((tt3.res2.mu_pred - tt3.mu_true))/tt3.mu_true.mean()
0.079578857986784574
>>> maxabs((tt3.res2.y_pred - tt3.y_true))/tt3.y_true.mean()
0.016282852522951426
>>> maxabs((tt3.res1.y_pred - tt3.y_true))/tt3.y_true.mean()
0.016288391235613865



    )lrangeN)assert_almost_equalassert_equal)stats)AdditiveModel)Model)familylinks)GLM)OLSc                   @   s   e Zd ZdS )DummyN)__name__
__module____qualname__ r   r   F/tmp/pip-unpacked-wheel-2v6byqio/statsmodels/sandbox/tests/test_gam.pyr   [   s   r   c                   @   sP   e Zd Zdd Zejjdedddd Zdd	 Z	ejjd
de
ddd ZdS )CheckAMc                 C   s8   t | jj| jjdd t | jj| jjd d dd d S N   decimal
   )r   res1y_predres2y_predshortselfr   r   r   test_predict`   s      zCheckAM.test_predictz&Unknown, results do not match expectedT)reasonraisesstrictc                 C   s8   t | jj| jjdd t | jj| jjd d dd d S r   )r   r   r   r   Zfittedvaluesr   r   r   r   r   test_fittedf   s      zCheckAM.test_fittedc                 C   sH   t | jjdd  | jjdd  dd t | jjd | jjd dd d S )N   r   r   )r   r   paramsr   r   r   r   r   test_paramso   s     
 zCheckAM.test_paramszres_ps attribute does not existr   r!   r    c                 C   s@   t | j | jj t | j | jj t | j | jj d S N)r   Zres_psZdf_modelr   Zdf_fitZdf_residr   r   r   r   test_dfx   s    zCheckAM.test_dfN)r   r   r   r   pytestmarkxfailAssertionErrorr"   r%   AttributeErrorr(   r   r   r   r   r   ^   s    
	 r   c                   @   s   e Zd Zdd Zdd ZdS )CheckGAMc                 C   s   t | jj| jjdd d S )Nr   r   )r   r   mu_predr   r   r   r   r   test_mu   s     zCheckGAM.test_muc                 C   s"   t | jj| jjd d dd d S )Nr   r   r   )r   r   r   r   r   r   r   r   r   test_prediction   s     zCheckGAM.test_predictionN)r   r   r   r0   r1   r   r   r   r   r.      s   r.   c                   @   s   e Zd Zedd ZdS )BaseAMc                 C   s   d}d}d\}}t |||}t d| }t ||  d d| f}|d d d d d f t |d d d d d f  |d}t|d d }	|	|d = |d d |	f }
|d}|| _	|||
  | _
| _| _d S )N      )g      r3   r   r#   g      ?)npZlinspacesinZcolumn_stackmaxZarangeZreshaper   sumnobsy_truexexog)clsorderr:   ZlbZubx1Zx2r<   r=   idxZexog_reducedr;   r   r   r   setup_class   s    :

zBaseAM.setup_classN)r   r   r   classmethodrB   r   r   r   r   r2      s   r2   c                       s,   e Zd Ze fddZ fddZ  ZS )TestAdditiveModelc                    s   t t|   | j}| j| j| j  }}}tj	d d}||tj
|  }t|}|| |j}t|| }	t  | _}
|	 | _}|||
_|	j|	j||_||d d |
_dd |jD }|jtdd |jD  }t|g| |
_d S )N) g?r   c                 S   s$   g | ]}|j d d D ]}|qqS r#   Nr$   .0ssir   r   r   
<listcomp>   s       z1TestAdditiveModel.setup_class.<locals>.<listcomp>c                 S   s   g | ]}|j d  qS r#   rG   rI   rJ   r   r   r   rL      s     )superrD   rB   r:   r;   r<   r=   r6   randomseedZrandnr   fitresultsr   r   r   r   predictr   modelr$   r   	smoothersalphar9   array)r>   r:   r;   r<   r=   Zsigma_noiseymres_gamZres_olsr   r   slopesconst	__class__r   r   rB      s$    

zTestAdditiveModel.setup_classc                    s   t t|   d S r'   )rO   rD   r"   r   r^   r   r   r"      s    zTestAdditiveModel.test_fitted)r   r   r   rC   rB   r"   __classcell__r   r   r^   r   rD      s   rD   c                   @   s   e Zd Zedd ZdS )BaseGAMc                 C   sx  | j }| j| j| j  }}}t| ds,d}n| j}| j}|j| | _	}t
jd z| j|||d}W n" tk
r   | j||d}Y nX t|||d}	|	j|dd |	j}
|
| _|	| _t|||d }t  | _}| | _}|jj|j|d	d
|_|
||_|
|d d |_|jj|j|dd
|_|
j|_dd |	jD }|
j t!dd |	jD  }t
"|g| |_d S )Nscaler#   rE   )rb   size)rc   )r   d   )maxiterZlinear)whichr   Zmeanc                 S   s$   g | ]}|j d d D ]}|qqS rF   rG   rH   r   r   r   rL      s       z BaseGAM.init.<locals>.<listcomp>c                 S   s   g | ]}|j d  qS rM   rG   rN   r   r   r   rL      s     )#r:   r;   r<   r=   hasattrrb   r   linkZinversemu_truer6   rP   rQ   rvs	TypeErrorGAMrR   rS   r[   Zmod_gamr
   r   r   r   rU   rT   r$   r   r   r/   murV   rW   r9   rX   )r>   r:   r;   r<   r=   rb   fri   Zy_obsrZ   r[   Zres_glmr   r   r\   r]   r   r   r   init   s8    

zBaseGAM.initN)r   r   r   rC   ro   r   r   r   r   ra      s   ra   c                       s    e Zd Ze fddZ  ZS )TestGAMPoissonc                    s.   t t|   t | _tjj| _|   d S r'   )	rO   rp   rB   r   ZPoissonr   Zpoissonrj   ro   r>   r^   r   r   rB     s    

zTestGAMPoisson.setup_classr   r   r   rC   rB   r`   r   r   r^   r   rp      s   rp   c                       s    e Zd Ze fddZ  ZS )TestGAMBinomialc                    s.   t t|   t | _tjj| _|   d S r'   )	rO   rs   rB   r   ZBinomialr   Z	bernoullirj   ro   rq   r^   r   r   rB     s    

zTestGAMBinomial.setup_classrr   r   r   r^   r   rs   
  s   rs   z'Unknown, results do not match expected.Tr&   c                       s    e Zd Ze fddZ  ZS )TestGAMGaussianLogLinkc                    s:   t t|   tt | _tjj	| _	d| _
|   d S )N   )rO   rt   rB   r   ZGaussianr	   Logr   Znormrj   rb   ro   rq   r^   r   r   rB   !  s
    
z"TestGAMGaussianLogLink.setup_classrr   r   r   r^   r   rt     s   rt   c                       s    e Zd Ze fddZ  ZS )TestGAMGammac                    s4   t t|   tt | _tjj	| _	| 
  d S r'   )rO   rw   rB   r   Gammar	   rv   r   gammarj   ro   rq   r^   r   r   rB   .  s    
zTestGAMGamma.setup_classrr   r   r   r^   r   rw   ,  s   rw   6Passing wrong number of args/kwargs to _parse_args_rvsc                       s\   e Zd Ze fddZejjdded fddZ	ejjdded fdd	Z
  ZS )
TestGAMNegativeBinomialc                    s.   t t|   t | _tjj| _|   d S r'   )	rO   r{   rB   r   ZNegativeBinomialr   Znbinomrj   ro   rq   r^   r   r   rB   >  s    

z#TestGAMNegativeBinomial.setup_classrz   Tr&   c                    s   t t|   d S r'   )rO   r{   r"   r   r^   r   r   r"   G  s    z#TestGAMNegativeBinomial.test_fittedc                    s   t t|   d S r'   )rO   r{   r(   r   r^   r   r   r(   O  s    zTestGAMNegativeBinomial.test_df)r   r   r   rC   rB   r)   r*   r+   rk   r"   r(   r`   r   r   r^   r   r{   8  s     r{   )%__doc__Zstatsmodels.compat.pythonr   Znumpyr6   Znumpy.testingr   r   Zscipyr   r)   Zstatsmodels.sandbox.gamr   r   rl   Zstatsmodels.genmod.familiesr   r	   Z+statsmodels.genmod.generalized_linear_modelr
   Z#statsmodels.regression.linear_modelr   r   r   r.   r2   rD   ra   rp   rs   r*   r+   r,   rt   rw   rk   r{   r   r   r   r   <module>   s:   K#(2  