class_docstr: Proposes new trials using a linear model.
  
  The model suggests an architecture no deeper than those in the trials.
  Sometimes (by a coin flip) adds one layer of depth to the suggestion.
class_docstr_tok: ["Proposes","new","trials","using","a","linear","model",".","The","model","suggests","an","architecture","no","deeper","than","those","in","the","trials",".","Sometimes","(","by","a","coin","flip",")","adds","one","layer","of","depth","to","the","suggestion","."]
docstr: Fits a linear model for loss = f(architecture) and finds its argmin.
  
  Main computational subroutine for trial data already in feature vector form.
  
  Args:
    architectures: (n_trials, depth) integer matrix of architectures.
    losses: (n_trials) positive validation error.
  
  Returns:
    predicted_loss: Scalar loss predicted for the chosen architecture.
    ints_best: (depth) integer vector representing
        the architecture that minimizes loss according to the model.
docstr_tok: ["Fits","a","linear","model","for","loss","=","f","(","architecture",")","and","finds","its","argmin",".","Main","computational","subroutine","for","trial","data","already","in","feature","vector","form",".","Args",":","architectures",":","(","n_trials",",","depth",")","integer","matrix","of","architectures",".","losses",":","(","n_trials",")","positive","validation","error",".","Returns",":","predicted_loss",":","Scalar","loss","predicted","for","the","chosen","architecture",".","ints_best",":","(","depth",")","integer","vector","representing","the","architecture","that","minimizes","loss","according","to","the","model","."]
code: def _predict_best_architecture(self, architectures, losses):
      """Fits a linear model for loss = f(architecture) and finds its argmin.
  
      Main computational subroutine for trial data already in feature vector form.
  
      Args:
        architectures: (n_trials, depth) integer matrix of architectures.
        losses: (n_trials) positive validation error.
  
      Returns:
        predicted_loss: Scalar loss predicted for the chosen architecture.
        ints_best: (depth) integer vector representing
            the architecture that minimizes loss according to the model.
      """
      if (
          self._phoenix_spec.linear_model.remove_outliers
          and len(losses) >= 10
      ):
          median, decile = np.percentile(
              losses, [50, 90], interpolation="higher"
          )
          keep = losses < min(decile, 10 * median)
          architectures = architectures[keep]
          losses = losses[keep]
  
      n_trials, depth = architectures.shape
      n_blocks = len(self._block_indices)
  
      # Reshaping because we have many values (layers) of one categorical feature
      # rather than many different categorical features.
      encoder = sklearn.preprocessing.OneHotEncoder(
          categories=[list(self._block_indices)]
      )
      flat = architectures.reshape(-1, 1)
      x_onehot_flat = encoder.fit_transform(flat)
      x = x_onehot_flat.reshape((n_trials, depth * n_blocks))
      assert np.all(np.sum(x, axis=1) == depth)
  
      # Use ridge regession in case problem is underdetermined, which is likely.
      model = sklearn.linear_model.Ridge(
          alpha=self._phoenix_spec.linear_model.ridge_penalty
      )
      model = model.fit(x, losses)
      weights = model.coef_
      weights_bylayer = weights.reshape((depth, n_blocks))
  
      # Pick the block with minimum weight per layer. Break ties randomly.
      weights_min_bylayer = np.amin(weights_bylayer, axis=1)
      indicator_best = 1.0 * (
          weights_bylayer == weights_min_bylayer[:, None]
      )
      onehot_best = _one_nonzero_per_row(indicator_best)
  
      predicted_loss = model.predict(onehot_best.reshape((1, -1)))[0]
      ints_best = encoder.inverse_transform(onehot_best).flatten()
      assert ints_best.shape == (depth,)
      return predicted_loss, ints_best
  
file_path: model_search/model_search/search/linear_model.py
imports: from model_search import block_builder
  from model_search.architecture import architecture_utils
  from model_search.proto import phoenix_spec_pb2
  from model_search.search import common
  from model_search.search import search_algorithm
  import numpy
  import sklearn
  import sklearn.linear_model
label_desc: Use image node_id 2 for calling the LinearModel obj's underlying member method code with example usage: obj._predict_best_architecture(architectures, losses) and returns: predicted_loss,  ints_best