def summary(self):
        """produce a summary of the model statistics

        Parameters
        ----------
        None

        Returns
        -------
        None
        """
        if not self._is_fitted:
            raise AttributeError('GAM has not been fitted. Call fit first.')

        # high-level model summary
        width_details = 47
        width_results = 58

        model_fmt = [
            (self.__class__.__name__, 'model_details', width_details),
            ('', 'model_results', width_results)
            ]

        model_details = []

        objective = 'UBRE' if self.distribution._known_scale else 'GCV'

        model_details.append({'model_details': space_row('Distribution:', self.distribution.__class__.__name__, total_width=width_details),
                              'model_results': space_row('Effective DoF:', str(np.round(self.statistics_['edof'], 4)), total_width=width_results)})
        model_details.append({'model_details': space_row('Link Function:', self.link.__class__.__name__, total_width=width_details),
                              'model_results': space_row('Log Likelihood:', str(np.round(self.statistics_['loglikelihood'], 4)), total_width=width_results)})
        model_details.append({'model_details': space_row('Number of Samples:', str(self.statistics_['n_samples']), total_width=width_details),
                              'model_results': space_row('AIC: ', str(np.round(self.statistics_['AIC'], 4)), total_width=width_results)})
        model_details.append({'model_results': space_row('AICc: ', str(np.round(self.statistics_['AICc'], 4)), total_width=width_results)})
        model_details.append({'model_results': space_row(objective + ':', str(np.round(self.statistics_[objective], 4)), total_width=width_results)})
        model_details.append({'model_results': space_row('Scale:', str(np.round(self.statistics_['scale'], 4)), total_width=width_results)})
        model_details.append({'model_results': space_row('Pseudo R-Squared:', str(np.round(self.statistics_['pseudo_r2']['explained_deviance'], 4)), total_width=width_results)})

        # term summary
        data = []

        for i, term in enumerate(self.terms):

            # TODO bug: if the number of samples is less than the number of coefficients
            # we cant get the edof per term
            if len(self.statistics_['edof_per_coef']) == len(self.coef_):
                idx = self.terms.get_coef_indices(i)
                edof = np.round(self.statistics_['edof_per_coef'][idx].sum(), 1)
            else:
                edof = ''

            term_data = {
                        'feature_func': repr(term),
                        'lam': '' if term.isintercept else np.round(flatten(term.lam), 4),
                        'rank': '{}'.format(term.n_coefs),
                        'edof': '{}'.format(edof),
                        'p_value': '%.2e'%(self.statistics_['p_values'][i]),
                        'sig_code': sig_code(self.statistics_['p_values'][i])
                        }

            data.append(term_data)

        fmt = [
            ('Feature Function', 'feature_func', 33),
            ('Lambda', 'lam', 20),
            ('Rank', 'rank', 12),
            ('EDoF', 'edof', 12),
            ('P > x', 'p_value', 12),
            ('Sig. Code', 'sig_code', 12)
            ]

        print( TablePrinter(model_fmt, ul='=', sep=' ')(model_details) )
        print("="*106)
        print( TablePrinter(fmt, ul='=')(data) )
        print("="*106)
        print("Significance codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1")
        print()
        print("WARNING: Fitting splines and a linear function to a feature introduces a model identifiability problem\n" \
              "         which can cause p-values to appear significant when they are not.")
        print()
        print("WARNING: p-values calculated in this manner behave correctly for un-penalized models or models with\n" \
              "         known smoothing parameters, but when smoothing parameters have been estimated, the p-values\n" \
              "         are typically lower than they should be, meaning that the tests reject the null too readily.")

        # P-VALUE BUG
        warnings.warn("KNOWN BUG: p-values computed in this summary are likely "\
                      "much smaller than they should be. \n \n"\
                      "Please do not make inferences based on these values! \n\n"\
                      "Collaborate on a solution, and stay up to date at: \n"\
                      "github.com/dswah/pyGAM/issues/163 \n", stacklevel=2)
def summary ( self ) : if not self . _is_fitted : raise AttributeError ( 'GAM has not been fitted. Call fit first.' ) width_details = 47 width_results = 58 model_fmt = [ ( self . __class__ . __name__ , 'model_details' , width_details ) , ( '' , 'model_results' , width_results ) ] model_details = [ ] objective = 'UBRE' if self . distribution . _known_scale else 'GCV' model_details . append ( { 'model_details' : space_row ( 'Distribution:' , self . distribution . __class__ . __name__ , total_width = width_details ) , 'model_results' : space_row ( 'Effective DoF:' , str ( np . round ( self . statistics_ [ 'edof' ] , 4 ) ) , total_width = width_results ) } ) model_details . append ( { 'model_details' : space_row ( 'Link Function:' , self . link . __class__ . __name__ , total_width = width_details ) , 'model_results' : space_row ( 'Log Likelihood:' , str ( np . round ( self . statistics_ [ 'loglikelihood' ] , 4 ) ) , total_width = width_results ) } ) model_details . append ( { 'model_details' : space_row ( 'Number of Samples:' , str ( self . statistics_ [ 'n_samples' ] ) , total_width = width_details ) , 'model_results' : space_row ( 'AIC: ' , str ( np . round ( self . statistics_ [ 'AIC' ] , 4 ) ) , total_width = width_results ) } ) model_details . append ( { 'model_results' : space_row ( 'AICc: ' , str ( np . round ( self . statistics_ [ 'AICc' ] , 4 ) ) , total_width = width_results ) } ) model_details . append ( { 'model_results' : space_row ( objective + ':' , str ( np . round ( self . statistics_ [ objective ] , 4 ) ) , total_width = width_results ) } ) model_details . append ( { 'model_results' : space_row ( 'Scale:' , str ( np . round ( self . statistics_ [ 'scale' ] , 4 ) ) , total_width = width_results ) } ) model_details . append ( { 'model_results' : space_row ( 'Pseudo R-Squared:' , str ( np . round ( self . statistics_ [ 'pseudo_r2' ] [ 'explained_deviance' ] , 4 ) ) , total_width = width_results ) } ) data = [ ] for i , term in enumerate ( self . terms ) : if len ( self . statistics_ [ 'edof_per_coef' ] ) == len ( self . coef_ ) : idx = self . terms . get_coef_indices ( i ) edof = np . round ( self . statistics_ [ 'edof_per_coef' ] [ idx ] . sum ( ) , 1 ) else : edof = '' term_data = { 'feature_func' : repr ( term ) , 'lam' : '' if term . isintercept else np . round ( flatten ( term . lam ) , 4 ) , 'rank' : '{}' . format ( term . n_coefs ) , 'edof' : '{}' . format ( edof ) , 'p_value' : '%.2e' % ( self . statistics_ [ 'p_values' ] [ i ] ) , 'sig_code' : sig_code ( self . statistics_ [ 'p_values' ] [ i ] ) } data . append ( term_data ) fmt = [ ( 'Feature Function' , 'feature_func' , 33 ) , ( 'Lambda' , 'lam' , 20 ) , ( 'Rank' , 'rank' , 12 ) , ( 'EDoF' , 'edof' , 12 ) , ( 'P > x' , 'p_value' , 12 ) , ( 'Sig. Code' , 'sig_code' , 12 ) ] print ( TablePrinter ( model_fmt , ul = '=' , sep = ' ' ) ( model_details ) ) print ( "=" * 106 ) print ( TablePrinter ( fmt , ul = '=' ) ( data ) ) print ( "=" * 106 ) print ( "Significance codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1" ) print ( ) print ( "WARNING: Fitting splines and a linear function to a feature introduces a model identifiability problem\n" "         which can cause p-values to appear significant when they are not." ) print ( ) print ( "WARNING: p-values calculated in this manner behave correctly for un-penalized models or models with\n" "         known smoothing parameters, but when smoothing parameters have been estimated, the p-values\n" "         are typically lower than they should be, meaning that the tests reject the null too readily." ) warnings . warn ( "KNOWN BUG: p-values computed in this summary are likely " "much smaller than they should be. \n \n" "Please do not make inferences based on these values! \n\n" "Collaborate on a solution, and stay up to date at: \n" "github.com/dswah/pyGAM/issues/163 \n" , stacklevel = 2 )
produce a summary of the model statistics

        Parameters
        ----------
        None

        Returns
        -------
        None