Commit f19ebde9 authored by evanfeinberg's avatar evanfeinberg
Browse files

added ability to use any sklearn model

parent 15958094
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ class DataFeaturizer(object):
    self.verbose = verbose
    self.log_every_n = log_every_n

  def featurize(self, input_file, feature_dir, shard_size=128):
  def featurize(self, input_file, feature_dir, samples_dir, shard_size=128):
    """Featurize provided file and write to specified location."""
    input_type = _get_input_type(input_file)

@@ -139,11 +139,6 @@ class DataFeaturizer(object):
      log("Sharding and standardizing into shard-%s / %s shards" % (str(j+1), len(interval_points)-1), self.verbose)
      raw_df_shard = raw_df.iloc[range(interval_points[j], interval_points[j+1])]
      
      print("featurize()")
      print("raw_df_shard.keys()")
      print(raw_df_shard.keys())
      print("self.id_field")
      print(self.id_field)
      df = self._standardize_df(raw_df_shard) 
      log("Aggregating User-Specified Features", self.verbose)
      self._add_user_specified_features(df)
@@ -161,7 +156,13 @@ class DataFeaturizer(object):
      shard_out = os.path.join(feature_dir, "features_shard%d.joblib" % j)
      save_to_disk(df, shard_out)
      shard_files.append(shard_out)
    return shard_files

    featurizers = self.compound_featurizers + self.complex_featurizers
    samples = FeaturizedSamples(samples_dir=samples_dir, featurizers=featurizers, 
                                dataset_files=shard_files,
                                reload_data=False)

    return samples

  def _process_raw_sample(self, input_type, row, fields):
    """Extract information from row data."""
@@ -318,8 +319,6 @@ class FeaturizedSamples(object):
    compound_rows = []
    for dataset_file in self.dataset_files:
      df = load_from_disk(dataset_file)
      print("_get_compounds.df.keys()")
      print(df.keys())
      compound_ids = list(df["mol_id"])
      smiles = list(df["smiles"])
      if "split" in df.keys():
@@ -352,7 +351,7 @@ class FeaturizedSamples(object):
      for ind, row in df.iterrows():
        if row["mol_id"] in compound_ids:
          visible_inds.append(ind)
      yield df.iloc[visible_inds]
      yield df.loc[visible_inds]

  def train_test_split(self, splittype, train_dir, test_dir, seed=None,
                       frac_train=.8):
+21 −16
Original line number Diff line number Diff line
@@ -19,10 +19,11 @@ class Model(object):
  Abstract base class for different ML models.
  """
  # List of registered models
  registered_model_types = {}
  def __init__(self, model_type, task_types, model_params,
  registered_model_classes = {}
  non_sklearn_models = ["SingleTaskDNN", "MultiTaskDNN", "DockingDNN"]
  def __init__(self, task_types, model_params, model_instance=None,
               initialize_raw_model=True, verbose=True):
    self.model_type = model_type
    self.model_class = model_instance.__class__
    self.task_types = task_types
    self.model_params = model_params
    self.raw_model = None
@@ -69,24 +70,25 @@ class Model(object):
    return os.path.join(out_dir, "model_params.joblib")

  @staticmethod
  def model_builder(model_type, task_types, model_params,
  def model_builder(model_instance, task_types, model_params,
                    initialize_raw_model=True):
    """
    Factory method that initializes model of requested type.
    """
    if model_type in Model.registered_model_types:
      model = Model.registered_model_types[model_type](
          model_type, task_types, model_params, initialize_raw_model)
    if model_instance.__class__ in non_sklearn_models:
      model = model_instance(task_types, model_params, initialize_raw_model)
    else:
      raise ValueError("model_type %s is not supported" % model_type)
      model = Model.registered_model_classes["SklearnModel"](model_instance, 
                                                       task_types, model_params,
                                                       initialize_raw_model)
    return model

  @staticmethod
  def register_model_type(model_type, model_class):
  def register_model_type(model_class):
    """
    Registers model types in static variable for factory/dispatchers to use.
    """
    Model.registered_model_types[model_type] = model_class
    Model.registered_model_classes[model_class.__class__] = model_class

  @staticmethod
  def get_task_type(model_name):
@@ -100,24 +102,27 @@ class Model(object):
      return "regression"

  @staticmethod
  def load(model_type, model_dir):
  def load(model_dir):
    """Dispatcher function for loading."""
    params = load_from_disk(Model.get_params_filename(model_dir))
    if model_type in Model.registered_model_types:
      model = Model.registered_model_types[model_type](
          model_type=params["model_type"],
    model_class = params["model_class"]
    if model_class in Model.registered_model_classes:
      model = Model.registered_model_classes[model_class](
          task_types=params["task_types"],
          model_params=params["model_params"])
      model.load(model_dir)
    else:
      raise ValueError("model_type %s is not supported" % model_type)
      model = Model.registered_model_classes["SklearnModel"](model_instance=model_class,
                           task_types=params["task_types"],
                           model_params=params["model_params"])
      model.load(model_dir)
    return model

  def save(self, out_dir):
    """Dispatcher function for saving."""
    params = {"model_params" : self.model_params,
              "task_types" : self.task_types,
              "model_type": self.model_type}
              "model_class": self.__class__}
    save_to_disk(params, Model.get_params_filename(out_dir))

  def fit(self, dataset):
+12 −10
Original line number Diff line number Diff line
@@ -53,10 +53,10 @@ class MultiTaskDNN(KerasModel):
  """
  Model for multitask MLP in keras.
  """
  def __init__(self, model_type, task_types, model_params,
  def __init__(self, task_types, model_params,
               initialize_raw_model=True):
    super(MultiTaskDNN, self).__init__(model_type, task_types, model_params,
                                       initialize_raw_model)
    super(MultiTaskDNN, self).__init__(task_types, model_params,
                                       initialize_raw_model=initialize_raw_model)
    if initialize_raw_model:
      sorted_tasks = sorted(task_types.keys())
      (n_inputs,) = model_params["data_shape"]
@@ -146,24 +146,26 @@ class MultiTaskDNN(KerasModel):
        # output the most likely class.
        y_pred_task = np.squeeze(np.argmax(y_pred_dict[taskname], axis=1))
      else:
        print("taskname")
        print(taskname)
        print("y_pred_dict.keys()")
        print(y_pred_dict.keys())
        y_pred_task = np.squeeze(y_pred_dict[taskname])
      y_pred[:, ind] = y_pred_task
    y_pred = np.squeeze(y_pred)
    return y_pred

Model.register_model_type("multitask_deep_regressor", MultiTaskDNN)
Model.register_model_type("multitask_deep_classifier", MultiTaskDNN)
Model.register_model_type(MultiTaskDNN)

class SingleTaskDNN(MultiTaskDNN):
  """
  Abstract base class for different ML models.
  """
  def __init__(self, model_type, task_types, model_params, initialize_raw_model=True):
    super(SingleTaskDNN, self).__init__(model_type, task_types, model_params,
                                        initialize_raw_model)
  def __init__(self, task_types, model_params, initialize_raw_model=True):
    super(SingleTaskDNN, self).__init__(task_types, model_params,
                                        initialize_raw_model=initialize_raw_model)

Model.register_model_type("singletask_deep_regressor", SingleTaskDNN)
Model.register_model_type("singletask_deep_classifier", SingleTaskDNN)
Model.register_model_type(SingleTaskDNN)

def to_one_hot(y):
  """Transforms label vector into one-hot encoding.
+3 −3
Original line number Diff line number Diff line
@@ -36,8 +36,8 @@ class DockingDNN(KerasModel):
  """
  Wrapper class for fitting 3D convolutional networks for deep docking.
  """
  def __init__(self, model_type, task_types, model_params, initialize_raw_model=True):
    super(DockingDNN, self).__init__(model_type, task_types, model_params, initialize_raw_model)
  def __init__(self, task_types, model_params, initialize_raw_model=True):
    super(DockingDNN, self).__init__(DockingDNN, task_types, model_params, initialize_raw_model)
    if initialize_raw_model:
      (axis_length, _, _, n_channels) = model_params["data_shape"]
      self.input_shape = (n_channels,
@@ -98,4 +98,4 @@ class DockingDNN(KerasModel):
    y_pred = np.squeeze(y_pred)
    return y_pred

Model.register_model_type("convolutional_3D_regressor", DockingDNN)
Model.register_model_type(DockingDNN)
+9 −24
Original line number Diff line number Diff line
@@ -18,34 +18,14 @@ class SklearnModel(Model):
  """
  Abstract base class for different ML models.
  """
  def __init__(self, model_type, task_types, model_params,
  def __init__(self, task_types, model_params, 
               model_instance=RandomForestRegressor(),
               initialize_raw_model=True):
    super(SklearnModel, self).__init__(
        model_type, task_types, model_params, initialize_raw_model)
        task_types, model_params, initialize_raw_model)
    self.task_types = task_types
    self.model_params = model_params
    if initialize_raw_model:
      if self.model_type == "rf_regressor":
        raw_model = RandomForestRegressor(
            n_estimators=500, n_jobs=-1, warm_start=True, max_features="sqrt")
      elif self.model_type == "rf_classifier":
        raw_model = RandomForestClassifier(
            n_estimators=500, n_jobs=-1, warm_start=True, max_features="sqrt")
      elif self.model_type == "logistic":
        raw_model = LogisticRegression(class_weight="auto")
      elif self.model_type == "linear":
        raw_model = LinearRegression(normalize=True)
      elif self.model_type == "ridge":
        raw_model = RidgeCV(alphas=[0.01, 0.1, 1.0, 10.0], normalize=True)
      elif self.model_type == "lasso":
        raw_model = LassoCV(max_iter=2000, n_jobs=-1)
      elif self.model_type == "lasso_lars":
        raw_model = LassoLarsCV(max_iter=2000, n_jobs=-1)
      elif self.model_type == "elastic_net":
        raw_model = ElasticNetCV(max_iter=2000, n_jobs=-1)
      else:
        raise ValueError("Invalid model type provided.")
    self.raw_model = raw_model
    self.raw_model = model_instance

  # TODO(rbharath): This does not work with very large datasets! sklearn does
  # support partial_fit, but only for some models. Might make sense to make
@@ -77,6 +57,10 @@ class SklearnModel(Model):
    """Loads sklearn model from joblib file on disk."""
    self.raw_model = load_from_disk(Model.get_model_filename(model_dir))

Model.register_model_type(SklearnModel)

#TODO(enf/rbharath): deprecate the following if __init__.py functions as planned.
'''
Model.register_model_type("logistic", SklearnModel)
Model.register_model_type("rf_classifier", SklearnModel)
Model.register_model_type("rf_regressor", SklearnModel)
@@ -85,3 +69,4 @@ Model.register_model_type("ridge", SklearnModel)
Model.register_model_type("lasso", SklearnModel)
Model.register_model_type("lasso_lars", SklearnModel)
Model.register_model_type("elastic_net", SklearnModel)
'''
 No newline at end of file
Loading