code: def _logistic_grad_hess(w, X, y, alpha, sample_weight=None):
      """Computes the gradient and the Hessian, in the case of a logistic loss.
  
      Parameters
      ----------
      w : ndarray, shape (n_features,) or (n_features + 1,)
          Coefficient vector.
  
      X : {array-like, sparse matrix}, shape (n_samples, n_features)
          Training data.
  
      y : ndarray, shape (n_samples,)
          Array of labels.
  
      alpha : float
          Regularization parameter. alpha is equal to 1 / C.
  
      sample_weight : array-like, shape (n_samples,) optional
          Array of weights that are assigned to individual samples.
          If not provided, then each sample is given unit weight.
  
      Returns
      -------
      grad : ndarray, shape (n_features,) or (n_features + 1,)
          Logistic gradient.
  
      Hs : callable
          Function that takes the gradient as a parameter and returns the
          matrix product of the Hessian and gradient.
      """
      n_samples, n_features = X.shape
      grad = np.empty_like(w)
      fit_intercept = grad.shape[0] > n_features
  
      w, c, yz = _intercept_dot(w, X, y)
  
      if sample_weight is None:
          sample_weight = np.ones(y.shape[0])
  
      z = expit(yz)
      z0 = sample_weight * (z - 1) * y
  
      grad[:n_features] = safe_sparse_dot(X.T, z0) + alpha * w
  
      # Case where we fit the intercept.
      if fit_intercept:
          grad[-1] = z0.sum()
  
      # The mat-vec product of the Hessian
      d = sample_weight * z * (1 - z)
      if sparse.issparse(X):
          dX = safe_sparse_dot(
              sparse.dia_matrix((d, 0), shape=(n_samples, n_samples)), X
          )
      else:
          # Precompute as much as possible
          dX = d[:, np.newaxis] * X
  
      if fit_intercept:
          # Calculate the double derivative with respect to intercept
          # In the case of sparse matrices this returns a matrix object.
          dd_intercept = np.squeeze(np.array(dX.sum(axis=0)))
  
      def Hs(s):
          ret = np.empty_like(s)
          ret[:n_features] = X.T.dot(dX.dot(s[:n_features]))
          ret[:n_features] += alpha * s[:n_features]
  
          # For the fit intercept case.
          if fit_intercept:
              ret[:n_features] += s[-1] * dd_intercept
              ret[-1] = dd_intercept.dot(s[:n_features])
              ret[-1] += d.sum() * s[-1]
          return ret
  
      return grad, Hs
  
imports: import numbers
  import warnings
  import numpy
  from scipy import optimize, sparse
  from .base import LinearClassifierMixin, SparseCoefMixin, BaseEstimator
  from .sag import sag_solver
  from ..feature_selection.from_model import _LearntSelectorMixin
  from ..preprocessing import LabelEncoder, LabelBinarizer
  from ..svm.base import _fit_liblinear
  from ..utils import check_array, check_consistent_length, compute_class_weight
  from ..utils import check_random_state
  from ..utils.extmath import logsumexp, log_logistic, safe_sparse_dot, softmax, squared_norm
  from ..utils.extmath import row_norms
  from ..utils.optimize import newton_cg
  from ..utils.validation import check_X_y
  from ..exceptions import NotFittedError
  from ..utils.fixes import expit
  from ..utils.multiclass import check_classification_targets
  from ..externals.joblib import Parallel, delayed
  from ..model_selection import check_cv
  from ..externals import six
  from ..metrics import SCORERS
label_desc: Use image node_id 4 for calling a global function with example usage: _logistic_grad_hess(w, X, y, alpha, sample_weight) and returns: grad,  Hs, ret