Commit 59e5dc2a authored by Franklin Lee's avatar Franklin Lee
Browse files

CDF Transformer (WIP)

parent 47f17ca4
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -107,3 +107,18 @@ class TestDatasetAPI(TestAPI):
        verbosity="low")
    return loader.featurize(input_file, self.data_dir)

  def load_gaussian_cdf_data(self):
    """Load example with numerical features sampled from Gaussian normal distribution."""
    if os.path.exists(self.data_dir):
      shutil.rmtree(self.data_dir)
    features = ["feat0"]
    featurizer = UserDefinedFeaturizer(features)
    tasks = ["task0"]
    input_file = os.path.join(
        self.current_dir, "../../models/tests/gaussian_cdf_example.csv")
    loader = DataLoader(
        tasks=tasks,
        featurizer=featurizer,
        id_field="id",
        verbosity="low")
    return loader.featurize(input_file, self.data_dir)
+1002 −0

File added.

Preview size limit exceeded, changes collapsed.

+56 −2
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@ from functools import partial
from deepchem.utils.save import save_to_disk
from deepchem.utils.save import load_from_disk
from deepchem.utils import pad_array
import shutil
from deepchem.datasets import Dataset

def undo_transforms(y, transformers):
  """Undoes all transformations applied."""
@@ -120,8 +122,7 @@ class NormalizationTransformer(Transformer):
    row = df.iloc[i]

    if self.transform_X:
      X = load_from_disk(
          os.path.join(data_dir, row['X-transformed']))
      X = load_from_disk(os.path.join(data_dir, row['X-transformed']))
      X = np.nan_to_num((X - self.X_means) / self.X_stds)
      save_to_disk(X, os.path.join(data_dir, row['X-transformed']))

@@ -456,3 +457,56 @@ class CoulombBinarizationTransformer(Transformer):

  def untranform(self, z):
    print("Cannot undo CoulombBinarizationTransformer.")

class CDFTransformer(Transformer):
  """Histograms the data and assigns values based on sorted list."""
  """Acts like a Cumulative Distribution Function (CDF)."""
  def __init__(self, transform_X=False,
               transform_y=False,
               bins=2,
               dataset=None):
    self.dataset = dataset
    self.transform_X = transform_X
    self.transform_y = transform_y
    self.bins = bins

  def transform(self, dataset):
    """Performs CDF transform on data."""
    X, y, w, ids = dataset.to_numpy()
    w_t = w
    ids_t = ids
    if self.transform_X:
      X_t = self.get_cdf_values(X)
      y_t = y
    if self.transform_y:
      y_t = self.get_cdf_values(y)
      X_t = X
    # TODO (rbharath): Find a more elegant solution to saving the data?
    # shutil.rmtree(dataset.data_dir)
    # os.makedirs(dataset.data_dir)
    # Dataset.from_numpy(dataset.data_dir, X_t, y_t, w_t, ids_t)
    
    return X_t, y_t, w_t, ids_t

  def get_cdf_values(self, array): 
    cols = len(array[0,:])
    rows = len(array[:,0])
    array_t = np.zeros((rows,cols))
    parts = rows/self.bins
    hist_values = np.zeros((rows,1))
    sorted_hist_values = np.zeros((rows,1))
    for row in xrange(rows):
      if np.remainder(self.bins,2)==1:
        hist_values[row,0] = np.floor(np.divide(row,parts))*1/(self.bins-1)
      else:
        hist_values[row,0] = np.floor(np.divide(row,parts))*1/self.bins
    order = np.argsort(array, axis=0)
    for col in xrange(cols):
      sorted_hist_values[:,0] = hist_values[order[:,col],0]
      array_t[:,col] = sorted_hist_values[:,0]

    return array_t

  def untransform(self, z):
    print("Cannot undo CDF Transformer.")
    # Need this for transform_y
+25 −0
Original line number Diff line number Diff line
@@ -12,10 +12,12 @@ __license__ = "GPL"
import unittest
import numpy as np
import pandas as pd
import numpy.random as random
import os
from deepchem.transformers import LogTransformer
from deepchem.transformers import NormalizationTransformer
from deepchem.transformers import BalancingTransformer
from deepchem.transformers import CDFTransformer
from deepchem.datasets.tests import TestDatasetAPI

class TestTransformerAPI(TestDatasetAPI):
@@ -182,6 +184,29 @@ class TestTransformerAPI(TestDatasetAPI):
    ## Check that untransform does the right thing.
    #np.testing.assert_allclose(normalization_transformer.untransform(X_t), X)

  def test_cdf_transformer(self):
    """Test CDF transformer on Gaussian normal dataset."""
    target = np.array(np.transpose(np.linspace(0.,1.,1001)))
    target = np.array([target])
    gaussian_dataset = self.load_gaussian_cdf_data()
    cdf_transformer = CDFTransformer(
        transform_X=True, bins=1001, dataset=gaussian_dataset)
    # cdf_transformer.transform(gaussian_dataset)
    # X_t, y_t, w_t, ids_t = gaussian_dataset.to_numpy()
    X_t, y_t, w_t, ids_t = cdf_transformer.transform(gaussian_dataset)
    X, y, w, ids = gaussian_dataset.to_numpy()

    # Check ids are unchanged.
    for id_elt, id_t_elt in zip(ids, ids_t):
      assert id_elt == id_t_elt
    # Check y is unchanged since this is an X transformer
    np.testing.assert_allclose(y, y_t)
    # Check w is unchanged since this is an X transformer
    np.testing.assert_allclose(w, w_t)
    # Check X is now holding the proper values when sorted.
    sorted = np.sort(X_t)
    np.testing.assert_allclose(sorted, target)

  def test_singletask_balancing_transformer(self):
    """Test balancing transformer on single-task dataset."""