class_docstr: Generalized Additive Models (GAM)
  
  This inherits from `GLM`.
  
  Warning: Not all inherited methods might take correctly account of the
  penalization. Not all options including offset and exposure have been
  verified yet.
  
  Parameters
  ----------
  endog : array_like
      The response variable.
  exog : array_like or None
      This explanatory variables are treated as linear. The model in this
      case is a partial linear model.
  smoother : instance of additive smoother class
      Examples of smoother instances include Bsplines or CyclicCubicSplines.
  alpha : float or list of floats
      Penalization weights for smooth terms. The length of the list needs
      to be the same as the number of smooth terms in the ``smoother``.
  family : instance of GLM family
      See GLM.
  offset : None or array_like
      See GLM.
  exposure : None or array_like
      See GLM.
  missing : 'none'
      Missing value handling is not supported in this class.
  **kwargs
      Extra keywords are used in call to the super classes.
  
  Notes
  -----
  Status: experimental. This has full unit test coverage for the core
  results with Gaussian and Poisson (without offset and exposure). Other
  options and additional results might not be correctly supported yet.
  (Binomial with counts, i.e. with n_trials, is most likely wrong in pirls.
  User specified var or freq weights are most likely also not correct for
  all results.)
class_docstr_tok: ["Generalized","Additive","Models","(","GAM",")","This","inherits","from","`","GLM","`",".","Warning",":","Not","all","inherited","methods","might","take","correctly","account","of","the","penalization",".","Not","all","options","including","offset","and","exposure","have","been","verified","yet",".","Parameters","--","--","--","--","--","endog",":","array_like","The","response","variable",".","exog",":","array_like","or","None","This","explanatory","variables","are","treated","as","linear",".","The","model","in","this","case","is","a","partial","linear","model",".","smoother",":","instance","of","additive","smoother","class","Examples","of","smoother","instances","include","Bsplines","or","CyclicCubicSplines",".","alpha",":","float","or","list","of","floats","Penalization","weights","for","smooth","terms",".","The","length","of","the","list","needs","to","be","the","same","as","the","number","of","smooth","terms","in","the","``","smoother","``",".","family",":","instance","of","GLM","family","See","GLM",".","offset",":","None","or","array_like","See","GLM",".","exposure",":","None","or","array_like","See","GLM",".","missing",":","'none'","Missing","value","handling","is","not","supported","in","this","class",".","*","*","kwargs","Extra","keywords","are","used","in","call","to","the","super","classes",".","Notes","--","--","-","Status",":","experimental",".","This","has","full","unit","test","coverage","for","the","core","results","with","Gaussian","and","Poisson","(","without","offset","and","exposure",")",".","Other","options","and","additional","results","might","not","be","correctly","supported","yet",".","(","Binomial","with","counts",",","i.e",".","with","n_trials",",","is","most","likely","wrong","in","pirls",".","User","specified","var","or","freq","weights","are","most","likely","also","not","correct","for","all","results",".",")"]
code: def __init__(
      self,
      endog,
      exog=None,
      smoother=None,
      alpha=0,
      family=None,
      offset=None,
      exposure=None,
      missing="none",
      **kwargs,
  ):
      # TODO: check usage of hasconst
      hasconst = kwargs.get("hasconst", None)
      xnames_linear = None
      if hasattr(exog, "design_info"):
          self.design_info_linear = exog.design_info
          xnames_linear = self.design_info_linear.column_names
  
      is_pandas = _is_using_pandas(exog, None)
  
      # TODO: handle data is experimental, see #5469
      # This is a bit wasteful because we need to `handle_data twice`
      self.data_linear = self._handle_data(
          endog, exog, missing, hasconst
      )
      if xnames_linear is None:
          xnames_linear = self.data_linear.xnames
      if exog is not None:
          exog_linear = self.data_linear.exog
          k_exog_linear = exog_linear.shape[1]
      else:
          exog_linear = None
          k_exog_linear = 0
      self.k_exog_linear = k_exog_linear
      # We need exog_linear for k-fold cross validation
      # TODO: alternative is to take columns from combined exog
      self.exog_linear = exog_linear
  
      self.smoother = smoother
      self.k_smooths = smoother.k_variables
      self.alpha = self._check_alpha(alpha)
      penal = MultivariateGamPenalty(
          smoother, alpha=self.alpha, start_idx=k_exog_linear
      )
      kwargs.pop("penal", None)
      if exog_linear is not None:
          exog = np.column_stack((exog_linear, smoother.basis))
      else:
          exog = smoother.basis
  
      # TODO: check: xnames_linear will be None instead of empty list
      #       if no exog_linear
      # can smoother be empty ? I guess not allowed.
      if xnames_linear is None:
          xnames_linear = []
      xnames = xnames_linear + self.smoother.col_names
  
      if is_pandas and exog_linear is not None:
          # we a dataframe so we can get a PandasData instance for wrapping
          exog = pd.DataFrame(
              exog, index=self.data_linear.row_labels, columns=xnames
          )
  
      super().__init__(
          endog,
          exog=exog,
          family=family,
          offset=offset,
          exposure=exposure,
          penal=penal,
          missing=missing,
          **kwargs,
      )
  
      if not is_pandas:
          # set exog nanmes if not given by pandas DataFrame
          self.exog_names[:] = xnames
  
      # TODO: the generic data handling might attach the design_info from the
      #       linear part, but this is incorrect for the full model and
      #       causes problems in wald_test_terms
  
      if hasattr(self.data, "design_info"):
          del self.data.design_info
      # formula also might be attached which causes problems in predict
      if hasattr(self, "formula"):
          self.formula_linear = self.formula
          self.formula = None
          del self.formula
  
imports: from collections.abc import Iterable
  import copy
  import numpy
  from scipy import optimize
  import pandas
  import statsmodels.base.wrapper
  from statsmodels.discrete.discrete_model import Logit
  from statsmodels.genmod.generalized_linear_model import GLM, GLMResults, GLMResultsWrapper, _check_convergence
  import statsmodels.regression.linear_model
  from statsmodels.tools.sm_exceptions import PerfectSeparationError, ValueWarning
  from statsmodels.tools.decorators import cache_readonly
  from statsmodels.tools.data import _is_using_pandas
  from statsmodels.tools.linalg import matrix_sqrt
  from statsmodels.base._penalized import PenalizedMixin
  from statsmodels.gam.gam_penalties import MultivariateGamPenalty
  from statsmodels.gam.gam_cross_validation.gam_cross_validation import MultivariateGAMCVPath
  from statsmodels.gam.gam_cross_validation.cross_validators import KFold
label_desc: Use image node_id 1 to create a new GLMGam object from inherited base classes: PenalizedMixin, GLM with example: obj = GLMGam(endog, exog, smoother, alpha, family, offset, exposure, missing)