ことの発端
RDKitDescriptorsを用いてtraining回したらtestデータの結果が余りにもバリデーションと乖離してる……一体何故……?
こんなissueを見つけた
Transforming datasets before or after Split? #1556
Transformer
Deepchemの前処理では, Transformer というパイプラインを一般に用います.
LogTransformer, ClippingTransformer, NormalizationTransformer, BalancingTransformer, MinMaxTransformer, などの既存のTransformerに加え、Transformerクラスを継承することで様々な前処理ができます (DeepChemで欠損値を含む列を除去するTransformerを書いてみる).
Transformerはdeepchem特有のデータセット型dc.data.Dataset
に対して適用されます.
Dataset
の中身はnp.array型のX, y, w, ids, などです.
一回の前処理で適用できるデータは一つで, どのデータに対してTransformerを適用するのかを引数で指定します.
class Transformer(object):
def __init__(self,
transform_X: bool = False,
transform_y: bool = False,
transform_w: bool = False,
transform_ids: bool = False,
dataset: Optional[Dataset] = None):
"""Initializes transformation based on dataset statistics.
Parameters
----------
transform_X: bool, optional (default False)
Whether to transform X
transform_y: bool, optional (default False)
Whether to transform y
transform_w: bool, optional (default False)
Whether to transform w
transform_ids: bool, optional (default False)
Whether to transform ids
dataset: dc.data.Dataset object, optional (default None)
Dataset to be transformed
"""
if self.__class__.__name__ == "Transformer":
raise ValueError(
"Transformer is an abstract superclass and cannot be directly instantiated. You probably want to instantiate a concrete subclass instead."
)
self.transform_X = transform_X
self.transform_y = transform_y
self.transform_w = transform_w
self.transform_ids = transform_ids
# Some transformation must happen
assert transform_X or transform_y or transform_w or transform_ids
使用上の注意
NormalizationTransformerは平均を0, 標準偏差を1に変換するTransformerです.
transform_y = True
を指定している参考コードが多く, そのままコピペするとおそらく意図しない結果が得られます.
transform_X = True
を設定する必要があります.
なぜならたいていの場合, 私たちは目的変数を標準化したいのではなく, 説明変数を標準化したいからです.
考えてみれば当たり前ですが, 結構重要なことだと思ったので, 記事にしました.
結論
コピペするときは理解してから使おう