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",".",")"]
docstr: fit model with penalized reweighted least squares
          
docstr_tok: ["fit","model","with","penalized","reweighted","least","squares"]
code: def _fit_pirls(
      self,
      alpha,
      start_params=None,
      maxiter=100,
      tol=1e-8,
      scale=None,
      cov_type="nonrobust",
      cov_kwds=None,
      use_t=None,
      weights=None,
  ):
      """fit model with penalized reweighted least squares"""
      # TODO: this currently modifies several attributes
      # self.scale, self.scaletype, self.mu, self.weights
      # self.data_weights,
      # and possibly self._offset_exposure
      # several of those might not be necessary, e.g. mu and weights
  
      # alpha = alpha * len(y) * self.scale / 100
      # TODO: we need to rescale alpha
      endog = self.endog
      wlsexog = self.exog  # smoother.basis
      spl_s = self.penal.penalty_matrix(alpha=alpha)
  
      nobs, n_columns = wlsexog.shape
  
      # TODO what are these values?
      if weights is None:
          self.data_weights = np.array([1.0] * nobs)
      else:
          self.data_weights = weights
  
      if not hasattr(self, "_offset_exposure"):
          self._offset_exposure = 0
  
      self.scaletype = scale
      # TODO: check default scale types
      # self.scaletype = 'dev'
      # during iteration
      self.scale = 1
  
      if start_params is None:
          mu = self.family.starting_mu(endog)
          lin_pred = self.family.predict(mu)
      else:
          lin_pred = (
              np.dot(wlsexog, start_params) + self._offset_exposure
          )
          mu = self.family.fitted(lin_pred)
      dev = self.family.deviance(endog, mu)
  
      history = dict(
          params=[None, start_params], deviance=[np.inf, dev]
      )
      converged = False
      criterion = history["deviance"]
      # This special case is used to get the likelihood for a specific
      # params vector.
      if maxiter == 0:
          mu = self.family.fitted(lin_pred)
          self.scale = self.estimate_scale(mu)
          wls_results = lm.RegressionResults(self, start_params, None)
          iteration = 0
  
      for iteration in range(maxiter):
          # TODO: is this equivalent to point 1 of page 136:
          # w = 1 / (V(mu) * g'(mu))  ?
          self.weights = self.data_weights * self.family.weights(mu)
  
          # TODO: is this equivalent to point 1 of page 136:
          # z = g(mu)(y - mu) + X beta  ?
          wlsendog = (
              lin_pred
              + self.family.link.deriv(mu) * (endog - mu)
              - self._offset_exposure
          )
  
          # this defines the augmented matrix point 2a on page 136
          wls_results = penalized_wls(
              wlsendog, wlsexog, spl_s, self.weights
          )
          lin_pred = np.dot(wlsexog, wls_results.params).ravel()
          lin_pred += self._offset_exposure
          mu = self.family.fitted(lin_pred)
  
          # We do not need to update scale in GLM/LEF models
          # We might need it in dispersion models.
          # self.scale = self.estimate_scale(mu)
          history = self._update_history(wls_results, mu, history)
  
          if endog.squeeze().ndim == 1 and np.allclose(mu - endog, 0):
              msg = "Perfect separation detected, results not available"
              raise PerfectSeparationError(msg)
  
          # TODO need atol, rtol
          # args of _check_convergence: (criterion, iteration, atol, rtol)
          converged = _check_convergence(criterion, iteration, tol, 0)
          if converged:
              break
      self.mu = mu
      self.scale = self.estimate_scale(mu)
      glm_results = GLMGamResults(
          self,
          wls_results.params,
          wls_results.normalized_cov_params,
          self.scale,
          cov_type=cov_type,
          cov_kwds=cov_kwds,
          use_t=use_t,
      )
  
      glm_results.method = "PIRLS"
      history["iteration"] = iteration + 1
      glm_results.fit_history = history
      glm_results.converged = converged
  
      return GLMGamResultsWrapper(glm_results)
  
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 4 for calling the GLMGam obj's underlying member method code with example usage: obj._fit_pirls(alpha, start_params, maxiter, tol, scale, cov_type, cov_kwds, use_t, weights) and returns: GLMGamResultsWrapper