Repository: sintel-dev/Draco (language: python)

Issue:
Remove `dfs` based pipelines
Remove `dfs` based pipelines from the `Draco` repository.
Draco will be restricted to space state models and support deep learning based pipelines such as LSTM.




Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 08effaa..365c442 100644
--- a/README.md
+++ b/README.md
@@ -220,18 +220,17 @@ The returned `pipeline` variable will be `list` containing the names of all the
 available in the Draco system:
 
 ```
-['dfs_xgb',
- 'dfs_xgb_with_unstack',
- 'dfs_xgb_with_normalization',
- 'dfs_xgb_with_unstack_normalization',
- 'dfs_xgb_prob_with_unstack_normalization']
+['lstm',
+ 'lstm_with_unstack',
+ 'double_lstm',
+ 'double_lstm_with_unstack']
 ```
 
 For the rest of this tutorial, we will select and use the pipeline
-`dfs_xgb_with_unstack_normalization` as our template.
+`lstm_with_unstack` as our template.
 
 ```python3
-pipeline_name = 'dfs_xgb_with_unstack_normalization'
+pipeline_name = 'lstm_with_unstack'
 ```
 
 ## 3. Fitting the Pipeline
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb.json b/draco/pipelines/dfs_xgb/dfs_xgb.json
deleted file mode 100644
index 4cb3cbf..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.entity_dataframe"
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "dataframe": "readings"
-        }
-    }
-}
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_double_normalization.json b/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_double_normalization.json
deleted file mode 100644
index 4231115..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_double_normalization.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier:probabilities",
-        "numpy.take"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.double_entity_normalization",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "featuretools.EntitySet.entity_from_dataframe#1": {
-                    "dataframe": "readings"
-                }
-            }
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        },
-        "numpy.take#1": {
-            "indices": 1,
-            "axis": 1
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "X": "readings"
-        }
-    }
-}
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack.json b/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack.json
deleted file mode 100644
index 03ef141..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier:probabilities",
-        "numpy.take"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
-        },
-        "mlblocks.MLPipeline#2": {
-            "pipeline": "preprocessing.entity_dataframe"
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        },
-        "numpy.take#1": {
-            "indices": 1,
-            "axis": 1
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "X": "readings"
-        },
-        "mlblocks.MLPipeline#2": {
-            "dataframe": "readings",
-            "turbines": "turbines"
-        }
-    }
-}
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack_normalization.json b/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack_normalization.json
deleted file mode 100644
index ca0c4fa..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack_normalization.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier:probabilities",
-        "numpy.take"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
-        },
-        "mlblocks.MLPipeline#2": {
-            "pipeline": "preprocessing.entity_normalization"
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        },
-        "numpy.take#1": {
-            "indices": 1,
-            "axis": 1
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "X": "readings"
-        },
-        "mlblocks.MLPipeline#2": {
-            "dataframe": "readings"
-        }
-    }
-}
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb_with_double_normalization.json b/draco/pipelines/dfs_xgb/dfs_xgb_with_double_normalization.json
deleted file mode 100644
index 82ae325..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb_with_double_normalization.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.double_entity_normalization",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "featuretools.EntitySet.entity_from_dataframe#1": {
-                    "dataframe": "readings"
-                }
-            }
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "X": "readings"
-        }
-    }
-}
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb_with_normalization.json b/draco/pipelines/dfs_xgb/dfs_xgb_with_normalization.json
deleted file mode 100644
index d9d7911..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb_with_normalization.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.entity_normalization"
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "dataframe": "readings"
-        }
-    }
-}
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack.json b/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack.json
deleted file mode 100644
index dd01f23..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
-        },
-        "mlblocks.MLPipeline#2": {
-            "pipeline": "preprocessing.entity_dataframe"
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "X": "readings"
-        },
-        "mlblocks.MLPipeline#2": {
-            "dataframe": "readings",
-            "turbines": "turbines"
-        }
-    }
-}
diff --git a/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack_normalization.json b/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack_normalization.json
deleted file mode 100644
index 87e6999..0000000
--- a/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack_normalization.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-    "primitives": [
-        "mlblocks.MLPipeline",
-        "mlblocks.MLPipeline",
-        "featuretools.dfs",
-        "mlprimitives.custom.feature_extraction.CategoricalEncoder",
-        "xgboost.XGBClassifier"
-    ],
-    "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "preprocessing.unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
-        },
-        "mlblocks.MLPipeline#2": {
-            "pipeline": "preprocessing.entity_normalization"
-        },
-        "featuretools.dfs#1": {
-            "target_entity": "turbines",
-            "index": "turbine_id",
-            "time_index": "cutoff_time",
-            "encode": false,
-            "max_depth": -1,
-            "copy": true,
-            "verbose": false,
-            "n_jobs": 1,
-            "training_window": "1d"
-        }
-    },
-    "input_names": {
-        "mlblocks.MLPipeline#1": {
-            "X": "readings"
-        },
-        "mlblocks.MLPipeline#2": {
-            "dataframe": "readings"
-        }
-    }
-}
diff --git a/draco/pipelines/double_lstm/double_lstm_prob_with_unstack.json b/draco/pipelines/double_lstm/double_lstm_prob_with_unstack.json
index 289a794..ea48a87 100644
--- a/draco/pipelines/double_lstm/double_lstm_prob_with_unstack.json
+++ b/draco/pipelines/double_lstm/double_lstm_prob_with_unstack.json
@@ -1,6 +1,7 @@
 {
     "primitives": [
-        "mlblocks.MLPipeline",
+        "pandas.DataFrame.resample",
+        "pandas.DataFrame.unstack",
         "pandas.DataFrame.pop",
         "pandas.DataFrame.pop",
         "sklearn.impute.SimpleImputer",
@@ -13,16 +14,19 @@
         "numpy.take"
     ],
     "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
+        "pandas.DataFrame.resample#1": {
+            "rule": "3600s",
+            "on": "timestamp",
+            "groupby": [
+                "turbine_id",
+                "signal_id"
+            ],
+            "aggregation": "mean",
+            "reset_index": false
+        },
+        "pandas.DataFrame.unstack#1": {
+            "level": "signal_id",
+            "reset_index": true
         },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
@@ -63,7 +67,10 @@
         }
     },
     "input_names": {
-        "mlblocks.MLPipeline#1": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
             "X": "readings"
         },
         "pandas.DataFrame.pop#1": {
@@ -94,6 +101,12 @@
         }
     },
     "output_names": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
+            "X": "readings"
+        },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
         },
diff --git a/draco/pipelines/double_lstm/double_lstm_with_unstack.json b/draco/pipelines/double_lstm/double_lstm_with_unstack.json
index 1d08259..dede502 100644
--- a/draco/pipelines/double_lstm/double_lstm_with_unstack.json
+++ b/draco/pipelines/double_lstm/double_lstm_with_unstack.json
@@ -1,6 +1,7 @@
 {
     "primitives": [
-        "mlblocks.MLPipeline",
+        "pandas.DataFrame.resample",
+        "pandas.DataFrame.unstack",
         "pandas.DataFrame.pop",
         "pandas.DataFrame.pop",
         "sklearn.impute.SimpleImputer",
@@ -12,16 +13,19 @@
         "keras.Sequential.DoubleLSTMTimeSeriesClassifier"
     ],
     "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
+        "pandas.DataFrame.resample#1": {
+            "rule": "3600s",
+            "on": "timestamp",
+            "groupby": [
+                "turbine_id",
+                "signal_id"
+            ],
+            "aggregation": "mean",
+            "reset_index": false
+        },
+        "pandas.DataFrame.unstack#1": {
+            "level": "signal_id",
+            "reset_index": true
         },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
@@ -56,7 +60,10 @@
         }
     },
     "input_names": {
-        "mlblocks.MLPipeline#1": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
             "X": "readings"
         },
         "pandas.DataFrame.pop#1": {
@@ -87,6 +94,12 @@
         }
     },
     "output_names": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
+            "X": "readings"
+        },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
         },
diff --git a/draco/pipelines/lstm/lstm_prob_with_unstack.json b/draco/pipelines/lstm/lstm_prob_with_unstack.json
index 1ad69bc..9272257 100644
--- a/draco/pipelines/lstm/lstm_prob_with_unstack.json
+++ b/draco/pipelines/lstm/lstm_prob_with_unstack.json
@@ -1,6 +1,7 @@
 {
     "primitives": [
-        "mlblocks.MLPipeline",
+        "pandas.DataFrame.resample",
+        "pandas.DataFrame.unstack",
         "pandas.DataFrame.pop",
         "pandas.DataFrame.pop",
         "sklearn.impute.SimpleImputer",
@@ -13,16 +14,19 @@
         "numpy.take"
     ],
     "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
+        "pandas.DataFrame.resample#1": {
+            "rule": "3600s",
+            "on": "timestamp",
+            "groupby": [
+                "turbine_id",
+                "signal_id"
+            ],
+            "aggregation": "mean",
+            "reset_index": false
+        },
+        "pandas.DataFrame.unstack#1": {
+            "level": "signal_id",
+            "reset_index": true
         },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
@@ -63,7 +67,10 @@
         }
     },
     "input_names": {
-        "mlblocks.MLPipeline#1": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
             "X": "readings"
         },
         "pandas.DataFrame.pop#1": {
@@ -94,6 +101,12 @@
         }
     },
     "output_names": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
+            "X": "readings"
+        },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
         },
diff --git a/draco/pipelines/lstm/lstm_with_unstack.json b/draco/pipelines/lstm/lstm_with_unstack.json
index 18c486a..ab9dd99 100644
--- a/draco/pipelines/lstm/lstm_with_unstack.json
+++ b/draco/pipelines/lstm/lstm_with_unstack.json
@@ -1,6 +1,7 @@
 {
     "primitives": [
-        "mlblocks.MLPipeline",
+        "pandas.DataFrame.resample",
+        "pandas.DataFrame.unstack",
         "pandas.DataFrame.pop",
         "pandas.DataFrame.pop",
         "sklearn.impute.SimpleImputer",
@@ -12,16 +13,19 @@
         "keras.Sequential.LSTMTimeSeriesClassifier"
     ],
     "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
+        "pandas.DataFrame.resample#1": {
+            "rule": "3600s",
+            "on": "timestamp",
+            "groupby": [
+                "turbine_id",
+                "signal_id"
+            ],
+            "aggregation": "mean",
+            "reset_index": false
+        },
+        "pandas.DataFrame.unstack#1": {
+            "level": "signal_id",
+            "reset_index": true
         },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
@@ -56,7 +60,10 @@
         }
     },
     "input_names": {
-        "mlblocks.MLPipeline#1": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
             "X": "readings"
         },
         "pandas.DataFrame.pop#1": {
@@ -87,6 +94,12 @@
         }
     },
     "output_names": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
+            "X": "readings"
+        },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
         },
diff --git a/draco/pipelines/lstm_regressor/lstm_regressor_with_unstack.json b/draco/pipelines/lstm_regressor/lstm_regressor_with_unstack.json
index d546827..9e183b9 100644
--- a/draco/pipelines/lstm_regressor/lstm_regressor_with_unstack.json
+++ b/draco/pipelines/lstm_regressor/lstm_regressor_with_unstack.json
@@ -1,6 +1,7 @@
 {
     "primitives": [
-        "mlblocks.MLPipeline",
+        "pandas.DataFrame.resample",
+        "pandas.DataFrame.unstack",
         "pandas.DataFrame.pop",
         "pandas.DataFrame.pop",
         "sklearn.impute.SimpleImputer",
@@ -12,16 +13,19 @@
         "keras.Sequential.LSTMTimeSeriesRegressor"
     ],
     "init_params": {
-        "mlblocks.MLPipeline#1": {
-            "pipeline": "unstack",
-            "input_names": {
-                "pandas.DataFrame.resample#1": {
-                    "X": "df"
-                },
-                "pandas.DataFrame.unstack#1": {
-                    "X": "readings"
-                }
-            }
+        "pandas.DataFrame.resample#1": {
+            "rule": "600s",
+            "on": "timestamp",
+            "groupby": [
+                "turbine_id",
+                "signal_id"
+            ],
+            "aggregation": "mean",
+            "reset_index": false
+        },
+        "pandas.DataFrame.unstack#1": {
+            "level": "signal_id",
+            "reset_index": true
         },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
@@ -52,11 +56,14 @@
         },
         "keras.Sequential.LSTMTimeSeriesRegressor#1": {
             "epochs": 35,
-            "verbose": false
+            "verbose": true
         }
     },
     "input_names": {
-        "mlblocks.MLPipeline#1": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
             "X": "readings"
         },
         "pandas.DataFrame.pop#1": {
@@ -87,6 +94,12 @@
         }
     },
     "output_names": {
+        "pandas.DataFrame.resample#1": {
+            "X": "readings"
+        },
+        "pandas.DataFrame.unstack#1": {
+            "X": "readings"
+        },
         "pandas.DataFrame.pop#1": {
             "item": "turbine_id"
         },
diff --git a/draco/pipelines/preprocessing/double_entity_normalization.json b/draco/pipelines/preprocessing/double_entity_normalization.json
deleted file mode 100644
index 1438bbe..0000000
--- a/draco/pipelines/preprocessing/double_entity_normalization.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-    "primitives": [
-        "pandas.DataFrame.resample",
-        "featuretools.EntitySet.entity_from_dataframe",
-        "featuretools.EntitySet.normalize_entity",
-        "featuretools.EntitySet.normalize_entity"
-    ],
-    "init_params": {
-        "pandas.DataFrame.resample#1": {
-            "rule": "600s",
-            "on": "timestamp",
-            "groupby": [
-                "turbine_id",
-                "signal_id"
-            ],
-            "aggregation": "mean",
-            "reset_index": true
-        },
-        "featuretools.EntitySet.entity_from_dataframe#1": {
-            "entity_id": "readings",
-            "index": "reading_id",
-            "make_index": true,
-            "time_index": "timestamp"
-        },
-        "featuretools.EntitySet.normalize_entity#1": {
-            "base_entity_id": "readings",
-            "new_entity_id": "turbines",
-            "index": "turbine_id",
-            "make_time_index": false
-        },
-        "featuretools.EntitySet.normalize_entity#2": {
-            "base_entity_id": "readings",
-            "new_entity_id": "signals",
-            "index": "signal_id",
-            "make_time_index": false
-        }
-    },
-    "input_names": {
-        "pandas.DataFrame.resample#1": {
-            "X": "readings"
-        },
-        "featuretools.EntitySet.entity_from_dataframe#1": {
-            "dataframe": "readings"
-        }
-    },
-    "output_names": {
-        "pandas.DataFrame.resample#1": {
-            "X": "readings"
-        }
-    }
-}
diff --git a/draco/pipelines/preprocessing/entity_dataframe.json b/draco/pipelines/preprocessing/entity_dataframe.json
deleted file mode 100644
index 0bd238a..0000000
--- a/draco/pipelines/preprocessing/entity_dataframe.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-    "primitives": [
-        "featuretools.EntitySet.entity_from_dataframe",
-        "featuretools.EntitySet.entity_from_dataframe",
-        "featuretools.EntitySet.add_relationship"
-    ],
-    "init_params": {
-        "featuretools.EntitySet.entity_from_dataframe#1": {
-            "entity_id": "readings",
-            "index": "reading_id",
-            "make_index": true,
-            "time_index": "timestamp"
-        },
-        "featuretools.EntitySet.entity_from_dataframe#2": {
-            "entity_id": "turbines",
-            "index": "turbine_id",
-            "make_index": false
-        },
-        "featuretools.EntitySet.add_relationship#1": {
-            "parent": "turbines",
-            "parent_column": "turbine_id",
-            "child": "readings",
-            "child_column": "turbine_id"
-        }
-    }
-}
diff --git a/draco/pipelines/preprocessing/entity_normalization.json b/draco/pipelines/preprocessing/entity_normalization.json
deleted file mode 100644
index 9f3f3ab..0000000
--- a/draco/pipelines/preprocessing/entity_normalization.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "primitives": [
-        "featuretools.EntitySet.entity_from_dataframe",
-        "featuretools.EntitySet.normalize_entity"
-    ],
-    "init_params": {
-        "featuretools.EntitySet.entity_from_dataframe#1": {
-            "entity_id": "readings",
-            "index": "reading_id",
-            "make_index": true,
-            "time_index": "timestamp"
-        },
-        "featuretools.EntitySet.normalize_entity#1": {
-            "base_entity_id": "readings",
-            "new_entity_id": "turbines",
-            "index": "turbine_id",
-            "make_time_index": false
-        }
-    }
-}
diff --git a/draco/pipelines/preprocessing/unstack.json b/draco/pipelines/preprocessing/unstack.json
deleted file mode 100644
index 1acd833..0000000
--- a/draco/pipelines/preprocessing/unstack.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-    "primitives": [
-        "pandas.DataFrame.resample",
-        "pandas.DataFrame.unstack"
-    ],
-    "init_params": {
-        "pandas.DataFrame.resample#1": {
-            "rule": "600s",
-            "on": "timestamp",
-            "groupby": [
-                "turbine_id",
-                "signal_id"
-            ],
-            "aggregation": "mean",
-            "reset_index": false
-        },
-        "pandas.DataFrame.unstack#1": {
-            "level": "signal_id",
-            "reset_index": true
-        }
-    },
-    "input_names": {
-        "pandas.DataFrame.unstack#1": {
-            "X": "readings"
-        }
-    },
-    "output_names": {
-        "pandas.DataFrame.resample#1": {
-            "X": "readings"
-        },
-        "pandas.DataFrame.unstack#1": {
-            "X": "readings"
-        }
-    },
-    "outputs": {
-        "default": [
-            {
-                "name": "readings",
-                "variable": "pandas.DataFrame.unstack#1.readings"
-            }
-        ]
-    }
-}
diff --git a/setup.py b/setup.py
index 0118bd0..1dfcc4b 100644
--- a/setup.py
+++ b/setup.py
@@ -20,10 +20,10 @@
     'mlprimitives>=0.3.2,<0.4',
     'mlblocks>=0.4.0,<0.5',
     'pymongo>=3.7.2,<4',
-    'scikit-learn>=0.21',
+    'scikit-learn>=0.21,<1.2',
     'tqdm<4.50.0,>=4.36.1',
     'scipy>=1.0.1,<2',
-    'numpy>=1.16.0,<1.21.0',
+    'numpy>=1.16.0,<1.19',
     'pandas>=1,<2',
     'tensorflow>=2,<2.3',
     'partd>=1.1.0,<2',
@@ -33,7 +33,8 @@
     'xlsxwriter>=1.3.6<1.4',
     # fix conflicts
     'protobuf<4',
-    'importlib-metadata<2,>=0.12',
+    'importlib-metadata<5',
+    #'importlib-metadata<2,>=0.12',
 ]
 
 setup_requires = [
diff --git a/tutorials/01_Draco_Machine_Learning.ipynb b/tutorials/01_Draco_Machine_Learning.ipynb
index 6b1089e..8138127 100644
--- a/tutorials/01_Draco_Machine_Learning.ipynb
+++ b/tutorials/01_Draco_Machine_Learning.ipynb
@@ -414,14 +414,9 @@
     {
      "data": {
       "text/plain": [
-       "['dfs_xgb_prob_with_unstack',\n",
-       " 'dfs_xgb_with_normalization',\n",
-       " 'dfs_xgb',\n",
-       " 'dfs_xgb_with_unstack',\n",
-       " 'dfs_xgb_prob_with_unstack_normalization',\n",
-       " 'dfs_xgb_with_unstack_normalization',\n",
-       " 'dfs_xgb_prob_with_double_normalization',\n",
-       " 'dfs_xgb_with_double_normalization',\n",
+       "['dummy',\n",
+       " 'lstm_regressor_with_unstack',\n",
+       " 'lstm_regressor',\n",
        " 'double_lstm_prob_with_unstack',\n",
        " 'double_lstm_prob',\n",
        " 'double_lstm',\n",
@@ -458,14 +453,16 @@
     {
      "data": {
       "text/plain": [
-       "['dfs_xgb_prob_with_unstack',\n",
-       " 'dfs_xgb_with_normalization',\n",
-       " 'dfs_xgb',\n",
-       " 'dfs_xgb_with_unstack',\n",
-       " 'dfs_xgb_prob_with_unstack_normalization',\n",
-       " 'dfs_xgb_with_unstack_normalization',\n",
-       " 'dfs_xgb_prob_with_double_normalization',\n",
-       " 'dfs_xgb_with_double_normalization']"
+       "['lstm_regressor_with_unstack',\n",
+       " 'lstm_regressor',\n",
+       " 'double_lstm_prob_with_unstack',\n",
+       " 'double_lstm_prob',\n",
+       " 'double_lstm',\n",
+       " 'double_lstm_with_unstack',\n",
+       " 'lstm_prob_with_unstack',\n",
+       " 'lstm_with_unstack',\n",
+       " 'lstm_prob',\n",
+       " 'lstm']"
       ]
      },
      "execution_count": 11,
@@ -474,7 +471,7 @@
     }
    ],
    "source": [
-    "get_pipelines('dfs')"
+    "get_pipelines('lstm')"
    ]
   },
   {
@@ -493,14 +490,16 @@
     {
      "data": {
       "text/plain": [
-       "{'dfs_xgb_prob_with_unstack': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack.json',\n",
-       " 'dfs_xgb_with_normalization': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb_with_normalization.json',\n",
-       " 'dfs_xgb': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb.json',\n",
-       " 'dfs_xgb_with_unstack': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack.json',\n",
-       " 'dfs_xgb_prob_with_unstack_normalization': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_unstack_normalization.json',\n",
-       " 'dfs_xgb_with_unstack_normalization': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb_with_unstack_normalization.json',\n",
-       " 'dfs_xgb_prob_with_double_normalization': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb_prob_with_double_normalization.json',\n",
-       " 'dfs_xgb_with_double_normalization': '/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/draco/pipelines/dfs_xgb/dfs_xgb_with_double_normalization.json'}"
+       "{'lstm_regressor_with_unstack': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/lstm_regressor/lstm_regressor_with_unstack.json',\n",
+       " 'lstm_regressor': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/lstm_regressor/lstm_regressor.json',\n",
+       " 'double_lstm_prob_with_unstack': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/double_lstm/double_lstm_prob_with_unstack.json',\n",
+       " 'double_lstm_prob': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/double_lstm/double_lstm_prob.json',\n",
+       " 'double_lstm': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/double_lstm/double_lstm.json',\n",
+       " 'double_lstm_with_unstack': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/double_lstm/double_lstm_with_unstack.json',\n",
+       " 'lstm_prob_with_unstack': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/lstm/lstm_prob_with_unstack.json',\n",
+       " 'lstm_with_unstack': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/lstm/lstm_with_unstack.json',\n",
+       " 'lstm_prob': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/lstm/lstm_prob.json',\n",
+       " 'lstm': '/Users/sarah/anaconda3/envs/draco/lib/python3.8/site-packages/draco/pipelines/lstm/lstm.json'}"
       ]
      },
      "execution_count": 12,
@@ -509,7 +508,7 @@
     }
    ],
    "source": [
-    "get_pipelines('dfs', path=True)"
+    "get_pipelines('lstm', path=True)"
    ]
   },
   {
@@ -539,8 +538,8 @@
    "outputs": [],
    "source": [
     "templates = [\n",
-    "    'dfs_xgb_with_unstack_normalization', \n",
-    "    'dfs_xgb_with_double_normalization'\n",
+    "    'lstm_with_unstack', \n",
+    "    'double_lstm_with_unstack'\n",
     "]"
    ]
   },
@@ -613,56 +612,43 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "INFO:btb.session:Obtaining default configuration for dfs_xgb_with_unstack_normalization\n",
-      "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: dfs_xgb_with_unstack_normalization \n",
-      "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 0\n",
-      "      ('xgboost.XGBClassifier#1', 'n_estimators'): 100\n",
-      "      ('xgboost.XGBClassifier#1', 'max_depth'): 3\n",
-      "      ('xgboost.XGBClassifier#1', 'learning_rate'): 0.1\n",
-      "      ('xgboost.XGBClassifier#1', 'gamma'): 0.0\n",
-      "      ('xgboost.XGBClassifier#1', 'min_child_weight'): 1\n",
-      "INFO:btb.session:New optimal found: dfs_xgb_with_unstack_normalization - 0.6117760013143775\n",
-      "INFO:btb.session:Obtaining default configuration for dfs_xgb_with_double_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_unstack_normalization\n",
+      "INFO:btb.session:Obtaining default configuration for lstm_with_unstack\n",
+      "2023-04-07 14:17:30.569247: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA\n",
+      "2023-04-07 14:17:30.594310: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fa3c50cbbb0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:\n",
+      "2023-04-07 14:17:30.594323: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: dfs_xgb_with_unstack_normalization \n",
+      "  Template: lstm_with_unstack \n",
       "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 90\n",
-      "      ('xgboost.XGBClassifier#1', 'n_estimators'): 342\n",
-      "      ('xgboost.XGBClassifier#1', 'max_depth'): 6\n",
-      "      ('xgboost.XGBClassifier#1', 'learning_rate'): 0.9043352048331922\n",
-      "      ('xgboost.XGBClassifier#1', 'gamma'): 0.5258350872963311\n",
-      "      ('xgboost.XGBClassifier#1', 'min_child_weight'): 9\n",
-      "INFO:btb.session:New optimal found: dfs_xgb_with_unstack_normalization - 0.6205571445297473\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_double_normalization\n",
+      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): mean\n",
+      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80\n",
+      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3\n",
+      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dense_1_units'): 80\n",
+      "INFO:btb.session:New optimal found: lstm_with_unstack - 0.6292647327130085\n",
+      "INFO:btb.session:Obtaining default configuration for double_lstm_with_unstack\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: dfs_xgb_with_double_normalization \n",
+      "  Template: double_lstm_with_unstack \n",
       "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 80\n",
-      "      ('xgboost.XGBClassifier#1', 'n_estimators'): 66\n",
-      "      ('xgboost.XGBClassifier#1', 'max_depth'): 10\n",
-      "      ('xgboost.XGBClassifier#1', 'learning_rate'): 0.6434375682152088\n",
-      "      ('xgboost.XGBClassifier#1', 'gamma'): 0.14135407511034503\n",
-      "      ('xgboost.XGBClassifier#1', 'min_child_weight'): 10\n",
-      "INFO:btb.session:New optimal found: dfs_xgb_with_double_normalization - 0.629513025867624\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_double_normalization\n"
+      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): mean\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 80\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_2_rate'): 0.3\n",
+      "INFO:btb.session:New optimal found: double_lstm_with_unstack - 0.6434978589136803\n",
+      "INFO:btb.session:Generating new proposal configuration for double_lstm_with_unstack\n"
      ]
     },
     {
      "data": {
       "text/plain": [
-       "{'id': '452a22a136f67c575aee3341c9dc2395',\n",
-       " 'name': 'dfs_xgb_with_double_normalization',\n",
-       " 'config': {('mlprimitives.custom.feature_extraction.CategoricalEncoder#1',\n",
-       "   'max_labels'): 80,\n",
-       "  ('xgboost.XGBClassifier#1', 'n_estimators'): 66,\n",
-       "  ('xgboost.XGBClassifier#1', 'max_depth'): 10,\n",
-       "  ('xgboost.XGBClassifier#1', 'learning_rate'): 0.6434375682152088,\n",
-       "  ('xgboost.XGBClassifier#1', 'gamma'): 0.14135407511034503,\n",
-       "  ('xgboost.XGBClassifier#1', 'min_child_weight'): 10},\n",
-       " 'score': 0.629513025867624}"
+       "{'id': '2904e940a6e56612e275f93afc00c6e6',\n",
+       " 'name': 'double_lstm_with_unstack',\n",
+       " 'config': {('sklearn.impute.SimpleImputer#1', 'strategy'): 'mean',\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 80,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1',\n",
+       "   'dropout_2_rate'): 0.3},\n",
+       " 'score': 0.6434978589136803}"
       ]
      },
      "execution_count": 16,
@@ -671,7 +657,7 @@
     }
    ],
    "source": [
-    "session.run(5)"
+    "session.run(3)"
    ]
   },
   {
@@ -690,16 +676,15 @@
     {
      "data": {
       "text/plain": [
-       "{'id': '452a22a136f67c575aee3341c9dc2395',\n",
-       " 'name': 'dfs_xgb_with_double_normalization',\n",
-       " 'config': {('mlprimitives.custom.feature_extraction.CategoricalEncoder#1',\n",
-       "   'max_labels'): 80,\n",
-       "  ('xgboost.XGBClassifier#1', 'n_estimators'): 66,\n",
-       "  ('xgboost.XGBClassifier#1', 'max_depth'): 10,\n",
-       "  ('xgboost.XGBClassifier#1', 'learning_rate'): 0.6434375682152088,\n",
-       "  ('xgboost.XGBClassifier#1', 'gamma'): 0.14135407511034503,\n",
-       "  ('xgboost.XGBClassifier#1', 'min_child_weight'): 10},\n",
-       " 'score': 0.629513025867624}"
+       "{'id': '2904e940a6e56612e275f93afc00c6e6',\n",
+       " 'name': 'double_lstm_with_unstack',\n",
+       " 'config': {('sklearn.impute.SimpleImputer#1', 'strategy'): 'mean',\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 80,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1',\n",
+       "   'dropout_2_rate'): 0.3},\n",
+       " 'score': 0.6434978589136803}"
       ]
      },
      "execution_count": 17,
@@ -726,13 +711,11 @@
     {
      "data": {
       "text/plain": [
-       "{('mlprimitives.custom.feature_extraction.CategoricalEncoder#1',\n",
-       "  'max_labels'): 80,\n",
-       " ('xgboost.XGBClassifier#1', 'n_estimators'): 66,\n",
-       " ('xgboost.XGBClassifier#1', 'max_depth'): 10,\n",
-       " ('xgboost.XGBClassifier#1', 'learning_rate'): 0.6434375682152088,\n",
-       " ('xgboost.XGBClassifier#1', 'gamma'): 0.14135407511034503,\n",
-       " ('xgboost.XGBClassifier#1', 'min_child_weight'): 10}"
+       "{('sklearn.impute.SimpleImputer#1', 'strategy'): 'mean',\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80,\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3,\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 80,\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_2_rate'): 0.3}"
       ]
      },
      "execution_count": 18,
@@ -759,7 +742,7 @@
     {
      "data": {
       "text/plain": [
-       "'dfs_xgb_with_double_normalization'"
+       "'double_lstm_with_unstack'"
       ]
      },
      "execution_count": 19,
@@ -787,7 +770,7 @@
     {
      "data": {
       "text/plain": [
-       "0.629513025867624"
+       "0.6434978589136803"
       ]
      },
      "execution_count": 20,
@@ -817,41 +800,40 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_unstack_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_unstack_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_double_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_double_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_unstack_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_unstack_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_double_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_unstack_normalization\n",
+      "INFO:btb.session:Generating new proposal configuration for lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for double_lstm_with_unstack\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: dfs_xgb_with_unstack_normalization \n",
+      "  Template: double_lstm_with_unstack \n",
       "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 48\n",
-      "      ('xgboost.XGBClassifier#1', 'n_estimators'): 130\n",
-      "      ('xgboost.XGBClassifier#1', 'max_depth'): 8\n",
-      "      ('xgboost.XGBClassifier#1', 'learning_rate'): 0.7437898568465957\n",
-      "      ('xgboost.XGBClassifier#1', 'gamma'): 0.9963350624783064\n",
-      "      ('xgboost.XGBClassifier#1', 'min_child_weight'): 10\n",
-      "INFO:btb.session:New optimal found: dfs_xgb_with_unstack_normalization - 0.651642052400304\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_double_normalization\n",
-      "INFO:btb.session:Generating new proposal configuration for dfs_xgb_with_unstack_normalization\n"
+      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): constant\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 224\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.31140813814002105\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 268\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_2_rate'): 0.607924752631197\n",
+      "INFO:btb.session:New optimal found: double_lstm_with_unstack - 0.654373123123123\n",
+      "INFO:btb.session:Generating new proposal configuration for lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for double_lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for double_lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for double_lstm_with_unstack\n",
+      "INFO:btb.session:Generating new proposal configuration for lstm_with_unstack\n"
      ]
     },
     {
      "data": {
       "text/plain": [
-       "{'id': '22ec731234212508b7b4413ccce34294',\n",
-       " 'name': 'dfs_xgb_with_unstack_normalization',\n",
-       " 'config': {('mlprimitives.custom.feature_extraction.CategoricalEncoder#1',\n",
-       "   'max_labels'): 48,\n",
-       "  ('xgboost.XGBClassifier#1', 'n_estimators'): 130,\n",
-       "  ('xgboost.XGBClassifier#1', 'max_depth'): 8,\n",
-       "  ('xgboost.XGBClassifier#1', 'learning_rate'): 0.7437898568465957,\n",
-       "  ('xgboost.XGBClassifier#1', 'gamma'): 0.9963350624783064,\n",
-       "  ('xgboost.XGBClassifier#1', 'min_child_weight'): 10},\n",
-       " 'score': 0.651642052400304}"
+       "{'id': 'a34709538eddbb67637d57d48237d69d',\n",
+       " 'name': 'double_lstm_with_unstack',\n",
+       " 'config': {('sklearn.impute.SimpleImputer#1', 'strategy'): 'constant',\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 224,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1',\n",
+       "   'dropout_1_rate'): 0.31140813814002105,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 268,\n",
+       "  ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1',\n",
+       "   'dropout_2_rate'): 0.607924752631197},\n",
+       " 'score': 0.654373123123123}"
       ]
      },
      "execution_count": 21,
@@ -871,7 +853,7 @@
     {
      "data": {
       "text/plain": [
-       "0.651642052400304"
+       "0.654373123123123"
       ]
      },
      "execution_count": 22,
@@ -891,13 +873,13 @@
     {
      "data": {
       "text/plain": [
-       "{('mlprimitives.custom.feature_extraction.CategoricalEncoder#1',\n",
-       "  'max_labels'): 48,\n",
-       " ('xgboost.XGBClassifier#1', 'n_estimators'): 130,\n",
-       " ('xgboost.XGBClassifier#1', 'max_depth'): 8,\n",
-       " ('xgboost.XGBClassifier#1', 'learning_rate'): 0.7437898568465957,\n",
-       " ('xgboost.XGBClassifier#1', 'gamma'): 0.9963350624783064,\n",
-       " ('xgboost.XGBClassifier#1', 'min_child_weight'): 10}"
+       "{('sklearn.impute.SimpleImputer#1', 'strategy'): 'constant',\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 224,\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1',\n",
+       "  'dropout_1_rate'): 0.31140813814002105,\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 268,\n",
+       " ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1',\n",
+       "  'dropout_2_rate'): 0.607924752631197}"
       ]
      },
      "execution_count": 23,
@@ -964,7 +946,7 @@
     {
      "data": {
       "text/plain": [
-       "0.608695652173913"
+       "0.6521739130434783"
       ]
      },
      "execution_count": 26,
@@ -1067,7 +1049,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.11"
+   "version": "3.8.16"
   }
  },
  "nbformat": 4,
diff --git a/tutorials/03_Benchmarking.ipynb b/tutorials/03_Benchmarking.ipynb
index 12c5e47..f22224a 100644
--- a/tutorials/03_Benchmarking.ipynb
+++ b/tutorials/03_Benchmarking.ipynb
@@ -77,7 +77,7 @@
    "source": [
     "templates = [\n",
     "    'lstm_prob_with_unstack',\n",
-    "    'dfs_xgb_prob_with_double_normalization'\n",
+    "    'double_lstm_prob_with_unstack'\n",
     "]\n",
     "window_size_rule = [('1d', '1h'), ('2d', '2h')]\n",
     "init_params = {\n",
@@ -85,6 +85,11 @@
     "        'keras.Sequential.LSTMTimeSeriesClassifier#1': {\n",
     "            'epochs': 1,\n",
     "        }\n",
+    "    },\n",
+    "    'double_lstm_prob_with_unstack': {\n",
+    "        'keras.Sequential.DoubleLSTMTimeSeriesClassifier#1': {\n",
+    "            'epochs': 1,\n",
+    "        }\n",
     "    }\n",
     "}\n"
    ]
@@ -100,90 +105,58 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "INFO:draco.benchmark:Evaluating template probability.unstack_lstm_timeseries_classifier on problem None (1d, 1h)\n",
+      "INFO:draco.benchmark:Evaluating template lstm_prob_with_unstack on problem None (1d, 1h)\n",
+      "2023-04-07 14:33:33.017625: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA\n",
+      "2023-04-07 14:33:33.043631: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fc3e937a8e0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:\n",
+      "2023-04-07 14:33:33.043643: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.unstack_lstm_timeseries_classifier \n",
+      "  Template: lstm_prob_with_unstack \n",
       "    Hyperparameters: \n",
       "      ('sklearn.impute.SimpleImputer#1', 'strategy'): mean\n",
       "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80\n",
       "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3\n",
       "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dense_1_units'): 80\n",
+      "INFO:draco.benchmark:Evaluating template lstm_prob_with_unstack on problem None (2d, 2h)\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.unstack_lstm_timeseries_classifier \n",
-      "    Hyperparameters: \n",
-      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): constant\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'lstm_1_units'): 287\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.565737233372491\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dense_1_units'): 145\n",
-      "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.unstack_lstm_timeseries_classifier \n",
-      "    Hyperparameters: \n",
-      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): constant\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'lstm_1_units'): 269\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.5973752345055594\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dense_1_units'): 412\n",
-      "INFO:draco.benchmark:Evaluating template probability.unstack_lstm_timeseries_classifier on problem None (2d, 2h)\n",
-      "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.unstack_lstm_timeseries_classifier \n",
+      "  Template: lstm_prob_with_unstack \n",
       "    Hyperparameters: \n",
       "      ('sklearn.impute.SimpleImputer#1', 'strategy'): mean\n",
       "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80\n",
       "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3\n",
       "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dense_1_units'): 80\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.unstack_lstm_timeseries_classifier \n",
+      "  Template: lstm_prob_with_unstack \n",
       "    Hyperparameters: \n",
-      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): mean\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'lstm_1_units'): 114\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.016427744327526084\n",
-      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dense_1_units'): 224\n",
-      "INFO:draco.benchmark:Evaluating template probability.normalize_dfs_xgb_classifier on problem None (1d, 1h)\n",
-      "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.normalize_dfs_xgb_classifier \n",
-      "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 0\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'n_estimators'): 100\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'max_depth'): 3\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'learning_rate'): 0.1\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'gamma'): 0.0\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'min_child_weight'): 1\n",
-      "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.normalize_dfs_xgb_classifier \n",
-      "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 11\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'n_estimators'): 231\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'max_depth'): 9\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'learning_rate'): 0.554989010368875\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'gamma'): 0.909957492053926\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'min_child_weight'): 7\n",
+      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): median\n",
+      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'lstm_1_units'): 137\n",
+      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.612475373625103\n",
+      "      ('keras.Sequential.LSTMTimeSeriesClassifier#1', 'dense_1_units'): 191\n",
+      "INFO:draco.benchmark:Evaluating template double_lstm_prob_with_unstack on problem None (1d, 1h)\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.normalize_dfs_xgb_classifier \n",
+      "  Template: double_lstm_prob_with_unstack \n",
       "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 61\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'n_estimators'): 122\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'max_depth'): 5\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'learning_rate'): 0.6840927016151666\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'gamma'): 0.5480298094360865\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'min_child_weight'): 6\n",
-      "INFO:draco.benchmark:Evaluating template probability.normalize_dfs_xgb_classifier on problem None (2d, 2h)\n",
+      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): mean\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 80\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_2_rate'): 0.3\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.normalize_dfs_xgb_classifier \n",
+      "  Template: double_lstm_prob_with_unstack \n",
       "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 0\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'n_estimators'): 100\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'max_depth'): 3\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'learning_rate'): 0.1\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'gamma'): 0.0\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'min_child_weight'): 1\n",
+      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): constant\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 245\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.4308586778212253\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 221\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_2_rate'): 0.5926391753395145\n",
+      "INFO:draco.benchmark:Evaluating template double_lstm_prob_with_unstack on problem None (2d, 2h)\n",
       "INFO:draco.pipeline:New configuration found:\n",
-      "  Template: probability.normalize_dfs_xgb_classifier \n",
+      "  Template: double_lstm_prob_with_unstack \n",
       "    Hyperparameters: \n",
-      "      ('mlprimitives.custom.feature_extraction.CategoricalEncoder#1', 'max_labels'): 99\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'n_estimators'): 616\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'max_depth'): 8\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'learning_rate'): 0.0700166745838724\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'gamma'): 0.40990340522001234\n",
-      "      ('xgboost.XGBClassifier:probabilities#1', 'min_child_weight'): 10\n"
+      "      ('sklearn.impute.SimpleImputer#1', 'strategy'): mean\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_1_units'): 80\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_1_rate'): 0.3\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'lstm_2_units'): 80\n",
+      "      ('keras.Sequential.DoubleLSTMTimeSeriesClassifier#1', 'dropout_2_rate'): 0.3\n"
      ]
     }
    ],
@@ -252,20 +225,20 @@
        "      <td>None</td>\n",
        "      <td>1d</td>\n",
        "      <td>1h</td>\n",
-       "      <td>probability.unstack_lstm_timeseries_classifier</td>\n",
-       "      <td>0.350122</td>\n",
-       "      <td>0.538316</td>\n",
-       "      <td>0.618558</td>\n",
-       "      <td>0.463675</td>\n",
+       "      <td>lstm_prob_with_unstack</td>\n",
+       "      <td>0.494505</td>\n",
+       "      <td>0.589905</td>\n",
+       "      <td>0.589905</td>\n",
+       "      <td>0.322650</td>\n",
        "      <td>roc_auc_score</td>\n",
        "      <td>{'threshold': 0.5}</td>\n",
-       "      <td>0 days 00:00:04.250012</td>\n",
-       "      <td>0 days 00:00:14.374875</td>\n",
-       "      <td>0 days 00:00:15.360015</td>\n",
-       "      <td>0 days 00:01:10.806375</td>\n",
+       "      <td>0 days 00:00:03.873157</td>\n",
+       "      <td>0 days 00:00:14.369536</td>\n",
+       "      <td>0 days 00:00:08.178422</td>\n",
+       "      <td>0 days 00:00:47.144655</td>\n",
        "      <td>OK</td>\n",
-       "      <td>0.640449</td>\n",
-       "      <td>0.058824</td>\n",
+       "      <td>0.280899</td>\n",
+       "      <td>0.255814</td>\n",
        "      <td>1.0</td>\n",
        "      <td>0.0</td>\n",
        "    </tr>\n",
@@ -274,20 +247,20 @@
        "      <td>None</td>\n",
        "      <td>2d</td>\n",
        "      <td>2h</td>\n",
-       "      <td>probability.unstack_lstm_timeseries_classifier</td>\n",
-       "      <td>0.686203</td>\n",
-       "      <td>0.491949</td>\n",
-       "      <td>0.556803</td>\n",
-       "      <td>0.510989</td>\n",
+       "      <td>lstm_prob_with_unstack</td>\n",
+       "      <td>0.446581</td>\n",
+       "      <td>0.543056</td>\n",
+       "      <td>0.561570</td>\n",
+       "      <td>0.707875</td>\n",
        "      <td>roc_auc_score</td>\n",
        "      <td>{'threshold': 0.5}</td>\n",
-       "      <td>0 days 00:00:04.410682</td>\n",
-       "      <td>0 days 00:00:14.411205</td>\n",
-       "      <td>0 days 00:00:10.633619</td>\n",
-       "      <td>0 days 00:00:55.011304</td>\n",
+       "      <td>0 days 00:00:03.460467</td>\n",
+       "      <td>0 days 00:00:12.121905</td>\n",
+       "      <td>0 days 00:00:08.275919</td>\n",
+       "      <td>0 days 00:00:44.449291</td>\n",
        "      <td>OK</td>\n",
-       "      <td>0.595506</td>\n",
-       "      <td>0.307692</td>\n",
+       "      <td>0.730337</td>\n",
+       "      <td>0.586207</td>\n",
        "      <td>1.0</td>\n",
        "      <td>0.0</td>\n",
        "    </tr>\n",
@@ -296,20 +269,20 @@
        "      <td>None</td>\n",
        "      <td>1d</td>\n",
        "      <td>1h</td>\n",
-       "      <td>probability.normalize_dfs_xgb_classifier</td>\n",
-       "      <td>0.697802</td>\n",
-       "      <td>0.669508</td>\n",
-       "      <td>0.701792</td>\n",
-       "      <td>0.766789</td>\n",
+       "      <td>double_lstm_prob_with_unstack</td>\n",
+       "      <td>0.813187</td>\n",
+       "      <td>0.307993</td>\n",
+       "      <td>0.592696</td>\n",
+       "      <td>0.417582</td>\n",
        "      <td>roc_auc_score</td>\n",
        "      <td>{'threshold': 0.5}</td>\n",
-       "      <td>0 days 00:01:11.416859</td>\n",
-       "      <td>0 days 00:02:55.012078</td>\n",
-       "      <td>0 days 00:00:00.806430</td>\n",
-       "      <td>0 days 00:05:20.653100</td>\n",
+       "      <td>0 days 00:00:05.460985</td>\n",
+       "      <td>0 days 00:00:18.103660</td>\n",
+       "      <td>0 days 00:00:14.011877</td>\n",
+       "      <td>0 days 00:01:11.192546</td>\n",
        "      <td>OK</td>\n",
-       "      <td>0.797753</td>\n",
-       "      <td>0.666667</td>\n",
+       "      <td>0.303371</td>\n",
+       "      <td>0.367347</td>\n",
        "      <td>1.0</td>\n",
        "      <td>0.0</td>\n",
        "    </tr>\n",
@@ -318,20 +291,20 @@
        "      <td>None</td>\n",
        "      <td>2d</td>\n",
        "      <td>2h</td>\n",
-       "      <td>probability.normalize_dfs_xgb_classifier</td>\n",
-       "      <td>0.720391</td>\n",
-       "      <td>0.718617</td>\n",
-       "      <td>0.740664</td>\n",
-       "      <td>0.782662</td>\n",
+       "      <td>double_lstm_prob_with_unstack</td>\n",
+       "      <td>0.245726</td>\n",
+       "      <td>0.663919</td>\n",
+       "      <td>0.663919</td>\n",
+       "      <td>0.293346</td>\n",
        "      <td>roc_auc_score</td>\n",
        "      <td>{'threshold': 0.5}</td>\n",
-       "      <td>0 days 00:01:03.612676</td>\n",
-       "      <td>0 days 00:02:26.925796</td>\n",
-       "      <td>0 days 00:00:00.755424</td>\n",
-       "      <td>0 days 00:04:37.570182</td>\n",
+       "      <td>0 days 00:00:05.568835</td>\n",
+       "      <td>0 days 00:00:17.948361</td>\n",
+       "      <td>0 days 00:00:14.003816</td>\n",
+       "      <td>0 days 00:01:11.051792</td>\n",
        "      <td>OK</td>\n",
-       "      <td>0.820225</td>\n",
-       "      <td>0.692308</td>\n",
+       "      <td>0.303371</td>\n",
+       "      <td>0.184211</td>\n",
        "      <td>1.0</td>\n",
        "      <td>0.0</td>\n",
        "    </tr>\n",
@@ -340,41 +313,41 @@
        "</div>"
       ],
       "text/plain": [
-       "  problem_name window_size resample_rule  \\\n",
-       "0         None          1d            1h   \n",
-       "1         None          2d            2h   \n",
-       "2         None          1d            1h   \n",
-       "3         None          2d            2h   \n",
+       "  problem_name window_size resample_rule                       template  \\\n",
+       "0         None          1d            1h         lstm_prob_with_unstack   \n",
+       "1         None          2d            2h         lstm_prob_with_unstack   \n",
+       "2         None          1d            1h  double_lstm_prob_with_unstack   \n",
+       "3         None          2d            2h  double_lstm_prob_with_unstack   \n",
        "\n",
-       "                                         template  default_test  default_cv  \\\n",
-       "0  probability.unstack_lstm_timeseries_classifier      0.350122    0.538316   \n",
-       "1  probability.unstack_lstm_timeseries_classifier      0.686203    0.491949   \n",
-       "2        probability.normalize_dfs_xgb_classifier      0.697802    0.669508   \n",
-       "3        probability.normalize_dfs_xgb_classifier      0.720391    0.718617   \n",
+       "   default_test  default_cv  tuned_cv  tuned_test  tuning_metric  \\\n",
+       "0      0.494505    0.589905  0.589905    0.322650  roc_auc_score   \n",
+       "1      0.446581    0.543056  0.561570    0.707875  roc_auc_score   \n",
+       "2      0.813187    0.307993  0.592696    0.417582  roc_auc_score   \n",
+       "3      0.245726    0.663919  0.663919    0.293346  roc_auc_score   \n",
        "\n",
-       "   tuned_cv  tuned_test  tuning_metric tuning_metric_kwargs  \\\n",
-       "0  0.618558    0.463675  roc_auc_score   {'threshold': 0.5}   \n",
-       "1  0.556803    0.510989  roc_auc_score   {'threshold': 0.5}   \n",
-       "2  0.701792    0.766789  roc_auc_score   {'threshold': 0.5}   \n",
-       "3  0.740664    0.782662  roc_auc_score   {'threshold': 0.5}   \n",
+       "  tuning_metric_kwargs       fit_predict_time        default_cv_time  \\\n",
+       "0   {'threshold': 0.5} 0 days 00:00:03.873157 0 days 00:00:14.369536   \n",
+       "1   {'threshold': 0.5} 0 days 00:00:03.460467 0 days 00:00:12.121905   \n",
+       "2   {'threshold': 0.5} 0 days 00:00:05.460985 0 days 00:00:18.103660   \n",
+       "3   {'threshold': 0.5} 0 days 00:00:05.568835 0 days 00:00:17.948361   \n",
        "\n",
-       "        fit_predict_time        default_cv_time        average_cv_time  \\\n",
-       "0 0 days 00:00:04.250012 0 days 00:00:14.374875 0 days 00:00:15.360015   \n",
-       "1 0 days 00:00:04.410682 0 days 00:00:14.411205 0 days 00:00:10.633619   \n",
-       "2 0 days 00:01:11.416859 0 days 00:02:55.012078 0 days 00:00:00.806430   \n",
-       "3 0 days 00:01:03.612676 0 days 00:02:26.925796 0 days 00:00:00.755424   \n",
+       "         average_cv_time             total_time status  \\\n",
+       "0 0 days 00:00:08.178422 0 days 00:00:47.144655     OK   \n",
+       "1 0 days 00:00:08.275919 0 days 00:00:44.449291     OK   \n",
+       "2 0 days 00:00:14.011877 0 days 00:01:11.192546     OK   \n",
+       "3 0 days 00:00:14.003816 0 days 00:01:11.051792     OK   \n",
        "\n",
-       "              total_time status  accuracy_threshold/0.5  f1_threshold/0.5  \\\n",
-       "0 0 days 00:01:10.806375     OK                0.640449          0.058824   \n",
-       "1 0 days 00:00:55.011304     OK                0.595506          0.307692   \n",
-       "2 0 days 00:05:20.653100     OK                0.797753          0.666667   \n",
-       "3 0 days 00:04:37.570182     OK                0.820225          0.692308   \n",
+       "   accuracy_threshold/0.5  f1_threshold/0.5  fpr_threshold/0.5  \\\n",
+       "0                0.280899          0.255814                1.0   \n",
+       "1                0.730337          0.586207                1.0   \n",
+       "2                0.303371          0.367347                1.0   \n",
+       "3                0.303371          0.184211                1.0   \n",
        "\n",
-       "   fpr_threshold/0.5  tpr_threshold/0.5  \n",
-       "0                1.0                0.0  \n",
-       "1                1.0                0.0  \n",
-       "2                1.0                0.0  \n",
-       "3                1.0                0.0  "
+       "   tpr_threshold/0.5  \n",
+       "0                0.0  \n",
+       "1                0.0  \n",
+       "2                0.0  \n",
+       "3                0.0  "
       ]
      },
      "execution_count": 4,
@@ -403,7 +376,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.11"
+   "version": "3.8.16"
   }
  },
  "nbformat": 4,
diff --git a/tutorials/04_Draco_Regression_Pipeline.ipynb b/tutorials/04_Draco_Regression_Pipeline.ipynb
index 709c839..4d241ca 100644
--- a/tutorials/04_Draco_Regression_Pipeline.ipynb
+++ b/tutorials/04_Draco_Regression_Pipeline.ipynb
@@ -515,14 +515,7 @@
     {
      "data": {
       "text/plain": [
-       "['dfs_xgb_prob_with_unstack',\n",
-       " 'dfs_xgb_with_normalization',\n",
-       " 'dfs_xgb',\n",
-       " 'dfs_xgb_with_unstack',\n",
-       " 'dfs_xgb_prob_with_unstack_normalization',\n",
-       " 'dfs_xgb_with_unstack_normalization',\n",
-       " 'dfs_xgb_prob_with_double_normalization',\n",
-       " 'dfs_xgb_with_double_normalization',\n",
+       "['dummy',\n",
        " 'lstm_regressor_with_unstack',\n",
        " 'lstm_regressor',\n",
        " 'double_lstm_prob_with_unstack',\n",
@@ -615,7 +608,13 @@
    "source": [
     "from draco.pipeline import DracoPipeline\n",
     "\n",
-    "pipeline = DracoPipeline(pipeline_name)"
+    "init_params = {\n",
+    "    \"keras.Sequential.LSTMTimeSeriesRegressor#1\": {\n",
+    "        \"epochs\": 10\n",
+    "    }\n",
+    "}\n",
+    "\n",
+    "pipeline = DracoPipeline(pipeline_name, init_params=init_params)"
    ]
   },
   {
@@ -634,10 +633,35 @@
      "name": "stderr",
      "output_type": "stream",
      "text": [
-      "2022-02-01 15:05:13.365367: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations:  AVX2 FMA\n",
-      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
-      "2022-02-01 15:05:13.379993: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7fe6a0ec50a0 initialized for platform Host (this does not guarantee that XLA will be used). Devices:\n",
-      "2022-02-01 15:05:13.380010: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version\n"
+      "2023-04-07 16:46:35.571262: I tensorflow/core/platform/cpu_feature_guard.cc:143] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA\n",
+      "2023-04-07 16:46:35.594871: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7ff23c392800 initialized for platform Host (this does not guarantee that XLA will be used). Devices:\n",
+      "2023-04-07 16:46:35.594885: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Epoch 1/10\n",
+      "227/227 [==============================] - 6s 28ms/step - loss: 9064.8613 - mse: 9064.8613 - val_loss: 11566.7559 - val_mse: 11566.7559\n",
+      "Epoch 2/10\n",
+      "227/227 [==============================] - 6s 27ms/step - loss: 6775.8911 - mse: 6775.8911 - val_loss: 9392.9561 - val_mse: 9392.9561\n",
+      "Epoch 3/10\n",
+      "227/227 [==============================] - 6s 27ms/step - loss: 5391.6719 - mse: 5391.6719 - val_loss: 7923.1221 - val_mse: 7923.1221\n",
+      "Epoch 4/10\n",
+      "227/227 [==============================] - 6s 28ms/step - loss: 4524.3457 - mse: 4524.3457 - val_loss: 6955.8647 - val_mse: 6955.8647\n",
+      "Epoch 5/10\n",
+      "227/227 [==============================] - 7s 33ms/step - loss: 4040.5396 - mse: 4040.5396 - val_loss: 6356.0605 - val_mse: 6356.0605\n",
+      "Epoch 6/10\n",
+      "227/227 [==============================] - 6s 28ms/step - loss: 3802.5298 - mse: 3802.5298 - val_loss: 5998.2061 - val_mse: 5998.2061\n",
+      "Epoch 7/10\n",
+      "227/227 [==============================] - 7s 30ms/step - loss: 3683.9429 - mse: 3683.9429 - val_loss: 5790.9092 - val_mse: 5790.9092\n",
+      "Epoch 8/10\n",
+      "227/227 [==============================] - 7s 33ms/step - loss: 3636.9177 - mse: 3636.9177 - val_loss: 5674.6558 - val_mse: 5674.6558\n",
+      "Epoch 9/10\n",
+      "227/227 [==============================] - 7s 30ms/step - loss: 3609.4973 - mse: 3609.4973 - val_loss: 5619.3926 - val_mse: 5619.3926\n",
+      "Epoch 10/10\n",
+      "227/227 [==============================] - 7s 29ms/step - loss: 3617.7119 - mse: 3617.7119 - val_loss: 5587.2671 - val_mse: 5587.2671\n"
      ]
     }
    ],
@@ -658,7 +682,15 @@
    "cell_type": "code",
    "execution_count": 17,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2/2 [==============================] - 0s 3ms/step\n"
+     ]
+    }
+   ],
    "source": [
     "predictions = pipeline.predict(test_target_times, readings)"
    ]
@@ -678,7 +710,7 @@
     {
      "data": {
       "text/plain": [
-       "0.6362969806460871"
+       "-0.1533211964451806"
       ]
      },
      "execution_count": 18,
@@ -748,14 +780,21 @@
    "execution_count": 21,
    "metadata": {},
    "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2/2 [==============================] - 0s 5ms/step\n"
+     ]
+    },
     {
      "data": {
       "text/plain": [
-       "array([[129.89064 ],\n",
-       "       [139.89001 ],\n",
-       "       [ 39.425865],\n",
-       "       [110.67838 ],\n",
-       "       [ 98.52903 ]], dtype=float32)"
+       "array([[91.7917  ],\n",
+       "       [91.791695],\n",
+       "       [91.79166 ],\n",
+       "       [91.79167 ],\n",
+       "       [91.79167 ]], dtype=float32)"
       ]
      },
      "execution_count": 21,
@@ -785,7 +824,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.11"
+   "version": "3.8.16"
   }
  },
  "nbformat": 4,
diff --git a/tutorials/pipelines/dfs_xgb_with_double_normalization.ipynb b/tutorials/pipelines/dfs_xgb_with_double_normalization.ipynb
deleted file mode 100644
index 6fd5f1e..0000000
--- a/tutorials/pipelines/dfs_xgb_with_double_normalization.ipynb
+++ /dev/null
@@ -1,1363 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# dfs_xgb_with_double_normalization"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from draco.demo import load_demo\n",
-    "\n",
-    "target_times, readings = load_demo()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "pipeline_name = 'dfs_xgb_with_double_normalization'"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/dask/dataframe/utils.py:14: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n",
-      "  import pandas.util.testing as tm\n"
-     ]
-    }
-   ],
-   "source": [
-    "from draco.pipeline import DracoPipeline\n",
-    "\n",
-    "pipeline = DracoPipeline(pipeline_name)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['mlblocks.MLPipeline',\n",
-       " 'featuretools.dfs',\n",
-       " 'mlprimitives.custom.feature_extraction.CategoricalEncoder',\n",
-       " 'xgboost.XGBClassifier']"
-      ]
-     },
-     "execution_count": 4,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "pipeline.template['primitives']"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Step by Step execution"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Input Data"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>signal_id</th>\n",
-       "      <th>timestamp</th>\n",
-       "      <th>value</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>323.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S02</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>320.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S03</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>284.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S04</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>348.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S05</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>273.0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id signal_id  timestamp  value\n",
-       "0       T001       S01 2013-01-10  323.0\n",
-       "1       T001       S02 2013-01-10  320.0\n",
-       "2       T001       S03 2013-01-10  284.0\n",
-       "3       T001       S04 2013-01-10  348.0\n",
-       "4       T001       S05 2013-01-10  273.0"
-      ]
-     },
-     "execution_count": 5,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "readings.head()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>cutoff_time</th>\n",
-       "      <th>target</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-12</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-13</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-14</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-15</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-16</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id cutoff_time  target\n",
-       "0       T001  2013-01-12       0\n",
-       "1       T001  2013-01-13       0\n",
-       "2       T001  2013-01-14       0\n",
-       "3       T001  2013-01-15       1\n",
-       "4       T001  2013-01-16       0"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "target_times.head()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Data Preparation (part of Draco Pipeline)\n",
-    "\n",
-    "* Input: target_times, readings, turbines\n",
-    "* Output: X, y, readings, turbines\n",
-    "* Effect: target_times has been split into X and y"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## mlblocks.MLPipeline\n",
-    "\n",
-    "### pandas.DataFrame.resample\n",
-    "\n",
-    "* Input: readings\n",
-    "* Output: readings (resampled)\n",
-    "* Effect: readings have been resampled to the indicated resample rule and turbine_id,\n",
-    "  signal_id and timestamp have been set as a multi-index\n",
-    "\n",
-    "###  featuretools.EntitySet.entity_from_dataframe\n",
-    "\n",
-    "* Input: readings (resampled)\n",
-    "* Output: entityset\n",
-    "* Effect: Entityset has been generated from readings\n",
-    "\n",
-    "### featuretools.EntitySet.normalize_entity\n",
-    "\n",
-    "* Input: entityset\n",
-    "* Output: entityset with relationship (readings.turbine_id with turbines.turbine_id)\n",
-    "* Effect: establish relation between readings and turbines\n",
-    "\n",
-    "### featuretools.EntitySet.normalize_entity\n",
-    "\n",
-    "* Input: entityset\n",
-    "* Output: entityset with relationship (readings.signal_id with signals.signal_id)\n",
-    "* Effect: establish relationship between readings and signals"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 0\n",
-    "context = pipeline.fit(target_times, readings, output_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'X', 'y', 'entityset'])"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "Entityset: entityset\n",
-       "  Entities:\n",
-       "    readings [Rows: 1329146, Columns: 5]\n",
-       "    turbines [Rows: 1, Columns: 1]\n",
-       "    signals [Rows: 26, Columns: 1]\n",
-       "  Relationships:\n",
-       "    readings.turbine_id -> turbines.turbine_id\n",
-       "    readings.signal_id -> signals.signal_id"
-      ]
-     },
-     "execution_count": 9,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['entityset']"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## featuretools.dfs\n",
-    "\n",
-    "* Input: entityset (unstacked, no turbine_id, no timestamp)\n",
-    "* Output: X (has additional features)\n",
-    "* Effect: build features for relational dataset using DFS"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 1\n",
-    "context = pipeline.fit(**context, output_=step, start_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'entityset', 'X', 'y'])"
-      ]
-     },
-     "execution_count": 11,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>SUM(readings.value)</th>\n",
-       "      <th>STD(readings.value)</th>\n",
-       "      <th>MAX(readings.value)</th>\n",
-       "      <th>SKEW(readings.value)</th>\n",
-       "      <th>MIN(readings.value)</th>\n",
-       "      <th>MEAN(readings.value)</th>\n",
-       "      <th>COUNT(readings)</th>\n",
-       "      <th>NUM_UNIQUE(readings.signal_id)</th>\n",
-       "      <th>MODE(readings.signal_id)</th>\n",
-       "      <th>NUM_UNIQUE(readings.DAY(timestamp))</th>\n",
-       "      <th>...</th>\n",
-       "      <th>MEAN(readings.signals.NUM_UNIQUE(readings.WEEKDAY(timestamp)))</th>\n",
-       "      <th>MEAN(readings.signals.NUM_UNIQUE(readings.YEAR(timestamp)))</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.DAY(timestamp)))</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.YEAR(timestamp)))</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.WEEKDAY(timestamp)))</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.MONTH(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.DAY(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.YEAR(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.WEEKDAY(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.MONTH(timestamp)))</th>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.433649e+09</td>\n",
-       "      <td>1.456860e+06</td>\n",
-       "      <td>3448719.0</td>\n",
-       "      <td>1.019214</td>\n",
-       "      <td>0.0</td>\n",
-       "      <td>917107.079193</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2</td>\n",
-       "      <td>...</td>\n",
-       "      <td>2.0</td>\n",
-       "      <td>1.0</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>11</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>4</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.441489e+09</td>\n",
-       "      <td>1.459865e+06</td>\n",
-       "      <td>3453777.0</td>\n",
-       "      <td>1.018761</td>\n",
-       "      <td>0.0</td>\n",
-       "      <td>919201.162179</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2</td>\n",
-       "      <td>...</td>\n",
-       "      <td>2.0</td>\n",
-       "      <td>1.0</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>12</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>5</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.455470e+09</td>\n",
-       "      <td>1.465277e+06</td>\n",
-       "      <td>3463880.0</td>\n",
-       "      <td>1.018192</td>\n",
-       "      <td>2.7</td>\n",
-       "      <td>922935.352244</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2</td>\n",
-       "      <td>...</td>\n",
-       "      <td>2.0</td>\n",
-       "      <td>1.0</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>13</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>6</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.475361e+09</td>\n",
-       "      <td>1.473337e+06</td>\n",
-       "      <td>3474703.0</td>\n",
-       "      <td>1.017666</td>\n",
-       "      <td>-1.0</td>\n",
-       "      <td>928248.092869</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2</td>\n",
-       "      <td>...</td>\n",
-       "      <td>2.0</td>\n",
-       "      <td>1.0</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>14</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>0</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>2.888083e+09</td>\n",
-       "      <td>1.477958e+06</td>\n",
-       "      <td>3485019.0</td>\n",
-       "      <td>1.032002</td>\n",
-       "      <td>0.0</td>\n",
-       "      <td>924186.531200</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2</td>\n",
-       "      <td>...</td>\n",
-       "      <td>2.0</td>\n",
-       "      <td>1.0</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>15</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "<p>5 rows × 99 columns</p>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "            SUM(readings.value)  STD(readings.value)  MAX(readings.value)  \\\n",
-       "turbine_id                                                                  \n",
-       "T001               3.433649e+09         1.456860e+06            3448719.0   \n",
-       "T001               3.441489e+09         1.459865e+06            3453777.0   \n",
-       "T001               3.455470e+09         1.465277e+06            3463880.0   \n",
-       "T001               3.475361e+09         1.473337e+06            3474703.0   \n",
-       "T001               2.888083e+09         1.477958e+06            3485019.0   \n",
-       "\n",
-       "            SKEW(readings.value)  MIN(readings.value)  MEAN(readings.value)  \\\n",
-       "turbine_id                                                                    \n",
-       "T001                    1.019214                  0.0         917107.079193   \n",
-       "T001                    1.018761                  0.0         919201.162179   \n",
-       "T001                    1.018192                  2.7         922935.352244   \n",
-       "T001                    1.017666                 -1.0         928248.092869   \n",
-       "T001                    1.032002                  0.0         924186.531200   \n",
-       "\n",
-       "            COUNT(readings)  NUM_UNIQUE(readings.signal_id)  \\\n",
-       "turbine_id                                                    \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "\n",
-       "           MODE(readings.signal_id)  NUM_UNIQUE(readings.DAY(timestamp))  ...  \\\n",
-       "turbine_id                                                                ...   \n",
-       "T001                            S01                                    2  ...   \n",
-       "T001                            S01                                    2  ...   \n",
-       "T001                            S01                                    2  ...   \n",
-       "T001                            S01                                    2  ...   \n",
-       "T001                            S01                                    2  ...   \n",
-       "\n",
-       "            MEAN(readings.signals.NUM_UNIQUE(readings.WEEKDAY(timestamp)))  \\\n",
-       "turbine_id                                                                   \n",
-       "T001                                                      2.0                \n",
-       "T001                                                      2.0                \n",
-       "T001                                                      2.0                \n",
-       "T001                                                      2.0                \n",
-       "T001                                                      2.0                \n",
-       "\n",
-       "            MEAN(readings.signals.NUM_UNIQUE(readings.YEAR(timestamp)))  \\\n",
-       "turbine_id                                                                \n",
-       "T001                                                      1.0             \n",
-       "T001                                                      1.0             \n",
-       "T001                                                      1.0             \n",
-       "T001                                                      1.0             \n",
-       "T001                                                      1.0             \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.DAY(timestamp)))  \\\n",
-       "turbine_id                                                               \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.YEAR(timestamp)))  \\\n",
-       "turbine_id                                                                \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.WEEKDAY(timestamp)))  \\\n",
-       "turbine_id                                                                   \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.MONTH(timestamp)))  \\\n",
-       "turbine_id                                                                 \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.DAY(timestamp)))  \\\n",
-       "turbine_id                                                         \n",
-       "T001                                                       11      \n",
-       "T001                                                       12      \n",
-       "T001                                                       13      \n",
-       "T001                                                       14      \n",
-       "T001                                                       15      \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.YEAR(timestamp)))  \\\n",
-       "turbine_id                                                          \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.WEEKDAY(timestamp)))  \\\n",
-       "turbine_id                                                             \n",
-       "T001                                                        4          \n",
-       "T001                                                        5          \n",
-       "T001                                                        6          \n",
-       "T001                                                        0          \n",
-       "T001                                                        1          \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.MONTH(timestamp)))  \n",
-       "turbine_id                                                          \n",
-       "T001                                                        1       \n",
-       "T001                                                        1       \n",
-       "T001                                                        1       \n",
-       "T001                                                        1       \n",
-       "T001                                                        1       \n",
-       "\n",
-       "[5 rows x 99 columns]"
-      ]
-     },
-     "execution_count": 12,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['X'].head()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "99"
-      ]
-     },
-     "execution_count": 13,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# features generated (the turbine_id is set as index).\n",
-    "len(context['X'].columns)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>signal_id</th>\n",
-       "      <th>timestamp</th>\n",
-       "      <th>value</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>323.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S02</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>320.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S03</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>284.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S04</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>348.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S05</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>273.0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id signal_id  timestamp  value\n",
-       "0       T001       S01 2013-01-10  323.0\n",
-       "1       T001       S02 2013-01-10  320.0\n",
-       "2       T001       S03 2013-01-10  284.0\n",
-       "3       T001       S04 2013-01-10  348.0\n",
-       "4       T001       S05 2013-01-10  273.0"
-      ]
-     },
-     "execution_count": 14,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['readings'].head()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## mlprimitives.custom.feature_extraction.CategoricalEncoder\n",
-    "\n",
-    "* Input: X\n",
-    "* Output: X (label encoded)\n",
-    "* Effect: encodes categorical features using OneHotLabelEncoder"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 2\n",
-    "context = pipeline.fit(**context, output_=step, start_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'entityset', 'X', 'y'])"
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>SUM(readings.value)</th>\n",
-       "      <th>STD(readings.value)</th>\n",
-       "      <th>MAX(readings.value)</th>\n",
-       "      <th>SKEW(readings.value)</th>\n",
-       "      <th>MIN(readings.value)</th>\n",
-       "      <th>MEAN(readings.value)</th>\n",
-       "      <th>COUNT(readings)</th>\n",
-       "      <th>NUM_UNIQUE(readings.signal_id)</th>\n",
-       "      <th>NUM_UNIQUE(readings.DAY(timestamp))</th>\n",
-       "      <th>NUM_UNIQUE(readings.MONTH(timestamp))</th>\n",
-       "      <th>...</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.DAY(timestamp)))</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.YEAR(timestamp)))</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.WEEKDAY(timestamp)))</th>\n",
-       "      <th>NUM_UNIQUE(readings.signals.MODE(readings.MONTH(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.DAY(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.YEAR(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.WEEKDAY(timestamp)))</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.MONTH(timestamp)))</th>\n",
-       "      <th>MODE(readings.signal_id)=S01</th>\n",
-       "      <th>MODE(readings.signals.MODE(readings.turbine_id))=T001</th>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.433649e+09</td>\n",
-       "      <td>1.456860e+06</td>\n",
-       "      <td>3448719.0</td>\n",
-       "      <td>1.019214</td>\n",
-       "      <td>0.0</td>\n",
-       "      <td>917107.079193</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>2</td>\n",
-       "      <td>1</td>\n",
-       "      <td>...</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>11</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>4</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.441489e+09</td>\n",
-       "      <td>1.459865e+06</td>\n",
-       "      <td>3453777.0</td>\n",
-       "      <td>1.018761</td>\n",
-       "      <td>0.0</td>\n",
-       "      <td>919201.162179</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>2</td>\n",
-       "      <td>1</td>\n",
-       "      <td>...</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>12</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>5</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.455470e+09</td>\n",
-       "      <td>1.465277e+06</td>\n",
-       "      <td>3463880.0</td>\n",
-       "      <td>1.018192</td>\n",
-       "      <td>2.7</td>\n",
-       "      <td>922935.352244</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>2</td>\n",
-       "      <td>1</td>\n",
-       "      <td>...</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>13</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>6</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>3.475361e+09</td>\n",
-       "      <td>1.473337e+06</td>\n",
-       "      <td>3474703.0</td>\n",
-       "      <td>1.017666</td>\n",
-       "      <td>-1.0</td>\n",
-       "      <td>928248.092869</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>2</td>\n",
-       "      <td>1</td>\n",
-       "      <td>...</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>14</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>0</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>2.888083e+09</td>\n",
-       "      <td>1.477958e+06</td>\n",
-       "      <td>3485019.0</td>\n",
-       "      <td>1.032002</td>\n",
-       "      <td>0.0</td>\n",
-       "      <td>924186.531200</td>\n",
-       "      <td>3744</td>\n",
-       "      <td>26</td>\n",
-       "      <td>2</td>\n",
-       "      <td>1</td>\n",
-       "      <td>...</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>15</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "<p>5 rows × 99 columns</p>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "            SUM(readings.value)  STD(readings.value)  MAX(readings.value)  \\\n",
-       "turbine_id                                                                  \n",
-       "T001               3.433649e+09         1.456860e+06            3448719.0   \n",
-       "T001               3.441489e+09         1.459865e+06            3453777.0   \n",
-       "T001               3.455470e+09         1.465277e+06            3463880.0   \n",
-       "T001               3.475361e+09         1.473337e+06            3474703.0   \n",
-       "T001               2.888083e+09         1.477958e+06            3485019.0   \n",
-       "\n",
-       "            SKEW(readings.value)  MIN(readings.value)  MEAN(readings.value)  \\\n",
-       "turbine_id                                                                    \n",
-       "T001                    1.019214                  0.0         917107.079193   \n",
-       "T001                    1.018761                  0.0         919201.162179   \n",
-       "T001                    1.018192                  2.7         922935.352244   \n",
-       "T001                    1.017666                 -1.0         928248.092869   \n",
-       "T001                    1.032002                  0.0         924186.531200   \n",
-       "\n",
-       "            COUNT(readings)  NUM_UNIQUE(readings.signal_id)  \\\n",
-       "turbine_id                                                    \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "T001                   3744                              26   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.DAY(timestamp))  \\\n",
-       "turbine_id                                        \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.MONTH(timestamp))  ...  \\\n",
-       "turbine_id                                         ...   \n",
-       "T001                                            1  ...   \n",
-       "T001                                            1  ...   \n",
-       "T001                                            1  ...   \n",
-       "T001                                            1  ...   \n",
-       "T001                                            1  ...   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.DAY(timestamp)))  \\\n",
-       "turbine_id                                                               \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "T001                                                        1            \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.YEAR(timestamp)))  \\\n",
-       "turbine_id                                                                \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "T001                                                        1             \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.WEEKDAY(timestamp)))  \\\n",
-       "turbine_id                                                                   \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "T001                                                        1                \n",
-       "\n",
-       "            NUM_UNIQUE(readings.signals.MODE(readings.MONTH(timestamp)))  \\\n",
-       "turbine_id                                                                 \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "T001                                                        1              \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.DAY(timestamp)))  \\\n",
-       "turbine_id                                                         \n",
-       "T001                                                       11      \n",
-       "T001                                                       12      \n",
-       "T001                                                       13      \n",
-       "T001                                                       14      \n",
-       "T001                                                       15      \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.YEAR(timestamp)))  \\\n",
-       "turbine_id                                                          \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "T001                                                     2013       \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.WEEKDAY(timestamp)))  \\\n",
-       "turbine_id                                                             \n",
-       "T001                                                        4          \n",
-       "T001                                                        5          \n",
-       "T001                                                        6          \n",
-       "T001                                                        0          \n",
-       "T001                                                        1          \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.MONTH(timestamp)))  \\\n",
-       "turbine_id                                                           \n",
-       "T001                                                        1        \n",
-       "T001                                                        1        \n",
-       "T001                                                        1        \n",
-       "T001                                                        1        \n",
-       "T001                                                        1        \n",
-       "\n",
-       "            MODE(readings.signal_id)=S01  \\\n",
-       "turbine_id                                 \n",
-       "T001                                   1   \n",
-       "T001                                   1   \n",
-       "T001                                   1   \n",
-       "T001                                   1   \n",
-       "T001                                   1   \n",
-       "\n",
-       "            MODE(readings.signals.MODE(readings.turbine_id))=T001  \n",
-       "turbine_id                                                         \n",
-       "T001                                                        1      \n",
-       "T001                                                        1      \n",
-       "T001                                                        1      \n",
-       "T001                                                        1      \n",
-       "T001                                                        1      \n",
-       "\n",
-       "[5 rows x 99 columns]"
-      ]
-     },
-     "execution_count": 17,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['X'].head()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>signal_id</th>\n",
-       "      <th>timestamp</th>\n",
-       "      <th>value</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>323.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S02</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>320.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S03</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>284.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S04</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>348.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S05</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>273.0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id signal_id  timestamp  value\n",
-       "0       T001       S01 2013-01-10  323.0\n",
-       "1       T001       S02 2013-01-10  320.0\n",
-       "2       T001       S03 2013-01-10  284.0\n",
-       "3       T001       S04 2013-01-10  348.0\n",
-       "4       T001       S05 2013-01-10  273.0"
-      ]
-     },
-     "execution_count": 18,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['readings'].head()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## xgboost.XGBClassifier\n",
-    "\n",
-    "* Input: X (label encoded and featurized)\n",
-    "* Output: None\n",
-    "* Effect: trained model"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 3\n",
-    "context = pipeline.fit(**context, output_=step, start_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 20,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'entityset', 'X', 'y'])"
-      ]
-     },
-     "execution_count": 20,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.7.11"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/tutorials/pipelines/dfs_xgb_with_unstack_normalization.ipynb b/tutorials/pipelines/dfs_xgb_with_unstack_normalization.ipynb
deleted file mode 100644
index 5731706..0000000
--- a/tutorials/pipelines/dfs_xgb_with_unstack_normalization.ipynb
+++ /dev/null
@@ -1,1611 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# dfs_xgb_with_unstack_normalization"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from draco.demo import load_demo\n",
-    "\n",
-    "target_times, readings = load_demo()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "pipeline_name = 'dfs_xgb_with_unstack_normalization'"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "/Users/sarah/opt/anaconda3/envs/draco/lib/python3.7/site-packages/dask/dataframe/utils.py:14: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n",
-      "  import pandas.util.testing as tm\n"
-     ]
-    }
-   ],
-   "source": [
-    "from draco.pipeline import DracoPipeline\n",
-    "\n",
-    "pipeline = DracoPipeline(pipeline_name)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['mlblocks.MLPipeline',\n",
-       " 'mlblocks.MLPipeline',\n",
-       " 'featuretools.dfs',\n",
-       " 'mlprimitives.custom.feature_extraction.CategoricalEncoder',\n",
-       " 'xgboost.XGBClassifier']"
-      ]
-     },
-     "execution_count": 4,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "pipeline.template['primitives']"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Step by Step execution"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Input Data"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>signal_id</th>\n",
-       "      <th>timestamp</th>\n",
-       "      <th>value</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S01</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>323.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S02</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>320.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S03</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>284.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S04</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>348.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>S05</td>\n",
-       "      <td>2013-01-10</td>\n",
-       "      <td>273.0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id signal_id  timestamp  value\n",
-       "0       T001       S01 2013-01-10  323.0\n",
-       "1       T001       S02 2013-01-10  320.0\n",
-       "2       T001       S03 2013-01-10  284.0\n",
-       "3       T001       S04 2013-01-10  348.0\n",
-       "4       T001       S05 2013-01-10  273.0"
-      ]
-     },
-     "execution_count": 5,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "readings.head()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>cutoff_time</th>\n",
-       "      <th>target</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-12</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-13</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-14</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-15</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-16</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id cutoff_time  target\n",
-       "0       T001  2013-01-12       0\n",
-       "1       T001  2013-01-13       0\n",
-       "2       T001  2013-01-14       0\n",
-       "3       T001  2013-01-15       1\n",
-       "4       T001  2013-01-16       0"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "target_times.head()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Data Preparation (part of Draco Pipeline)\n",
-    "\n",
-    "* Input: target_times, readings, turbines\n",
-    "* Output: X, y, readings, turbines\n",
-    "* Effect: target_times has been split into X and y"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## mlblocks.MLPipeline 1\n",
-    "\n",
-    "### pandas.DataFrame.resample\n",
-    "\n",
-    "* Input: readings\n",
-    "* Output: readings (resampled)\n",
-    "* Effect: readings have been resampled to the indicated resample rule and turbine_id,\n",
-    "  signal_id and timestamp have been set as a multi-index\n",
-    "  \n",
-    "### pandas.DataFrame.unstack\n",
-    "\n",
-    "* Input: readings (resampled)\n",
-    "* Output: readings (unstacked)\n",
-    "* Effect: readings have been unstacked"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 0\n",
-    "context = pipeline.fit(target_times, readings, output_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'X', 'y'])"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>timestamp</th>\n",
-       "      <th>value_S01</th>\n",
-       "      <th>value_S02</th>\n",
-       "      <th>value_S03</th>\n",
-       "      <th>value_S04</th>\n",
-       "      <th>value_S05</th>\n",
-       "      <th>value_S06</th>\n",
-       "      <th>value_S07</th>\n",
-       "      <th>value_S08</th>\n",
-       "      <th>...</th>\n",
-       "      <th>value_S17</th>\n",
-       "      <th>value_S18</th>\n",
-       "      <th>value_S19</th>\n",
-       "      <th>value_S20</th>\n",
-       "      <th>value_S21</th>\n",
-       "      <th>value_S22</th>\n",
-       "      <th>value_S23</th>\n",
-       "      <th>value_S24</th>\n",
-       "      <th>value_S25</th>\n",
-       "      <th>value_S26</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:00:00</td>\n",
-       "      <td>323.0</td>\n",
-       "      <td>320.0</td>\n",
-       "      <td>284.0</td>\n",
-       "      <td>348.0</td>\n",
-       "      <td>273.0</td>\n",
-       "      <td>342.0</td>\n",
-       "      <td>280.0</td>\n",
-       "      <td>3197842.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>11.7</td>\n",
-       "      <td>3131020.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>47.0</td>\n",
-       "      <td>58.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>58.0</td>\n",
-       "      <td>47.0</td>\n",
-       "      <td>356.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:10:00</td>\n",
-       "      <td>346.0</td>\n",
-       "      <td>384.0</td>\n",
-       "      <td>367.0</td>\n",
-       "      <td>411.0</td>\n",
-       "      <td>331.0</td>\n",
-       "      <td>360.0</td>\n",
-       "      <td>249.0</td>\n",
-       "      <td>3197900.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>10.2</td>\n",
-       "      <td>3131420.0</td>\n",
-       "      <td>58.0</td>\n",
-       "      <td>63.0</td>\n",
-       "      <td>62.0</td>\n",
-       "      <td>67.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>61.0</td>\n",
-       "      <td>42.0</td>\n",
-       "      <td>400.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:20:00</td>\n",
-       "      <td>407.0</td>\n",
-       "      <td>363.0</td>\n",
-       "      <td>407.0</td>\n",
-       "      <td>393.0</td>\n",
-       "      <td>275.0</td>\n",
-       "      <td>335.0</td>\n",
-       "      <td>270.0</td>\n",
-       "      <td>3197968.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>9.5</td>\n",
-       "      <td>3131822.0</td>\n",
-       "      <td>68.0</td>\n",
-       "      <td>61.0</td>\n",
-       "      <td>67.0</td>\n",
-       "      <td>66.0</td>\n",
-       "      <td>46.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>402.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:30:00</td>\n",
-       "      <td>257.0</td>\n",
-       "      <td>307.0</td>\n",
-       "      <td>315.0</td>\n",
-       "      <td>361.0</td>\n",
-       "      <td>317.0</td>\n",
-       "      <td>354.0</td>\n",
-       "      <td>271.0</td>\n",
-       "      <td>3198011.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>10.5</td>\n",
-       "      <td>3132179.0</td>\n",
-       "      <td>43.0</td>\n",
-       "      <td>51.0</td>\n",
-       "      <td>53.0</td>\n",
-       "      <td>62.0</td>\n",
-       "      <td>53.0</td>\n",
-       "      <td>60.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>357.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:40:00</td>\n",
-       "      <td>267.0</td>\n",
-       "      <td>309.0</td>\n",
-       "      <td>314.0</td>\n",
-       "      <td>355.0</td>\n",
-       "      <td>262.0</td>\n",
-       "      <td>246.0</td>\n",
-       "      <td>212.0</td>\n",
-       "      <td>3198056.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>9.6</td>\n",
-       "      <td>3132501.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>51.0</td>\n",
-       "      <td>54.0</td>\n",
-       "      <td>59.0</td>\n",
-       "      <td>43.0</td>\n",
-       "      <td>41.0</td>\n",
-       "      <td>36.0</td>\n",
-       "      <td>322.0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "<p>5 rows × 28 columns</p>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id           timestamp  value_S01  value_S02  value_S03  value_S04  \\\n",
-       "0       T001 2013-01-10 00:00:00      323.0      320.0      284.0      348.0   \n",
-       "1       T001 2013-01-10 00:10:00      346.0      384.0      367.0      411.0   \n",
-       "2       T001 2013-01-10 00:20:00      407.0      363.0      407.0      393.0   \n",
-       "3       T001 2013-01-10 00:30:00      257.0      307.0      315.0      361.0   \n",
-       "4       T001 2013-01-10 00:40:00      267.0      309.0      314.0      355.0   \n",
-       "\n",
-       "   value_S05  value_S06  value_S07  value_S08  ...  value_S17  value_S18  \\\n",
-       "0      273.0      342.0      280.0  3197842.0  ...       11.7  3131020.0   \n",
-       "1      331.0      360.0      249.0  3197900.0  ...       10.2  3131420.0   \n",
-       "2      275.0      335.0      270.0  3197968.0  ...        9.5  3131822.0   \n",
-       "3      317.0      354.0      271.0  3198011.0  ...       10.5  3132179.0   \n",
-       "4      262.0      246.0      212.0  3198056.0  ...        9.6  3132501.0   \n",
-       "\n",
-       "   value_S19  value_S20  value_S21  value_S22  value_S23  value_S24  \\\n",
-       "0       55.0       55.0       47.0       58.0       45.0       58.0   \n",
-       "1       58.0       63.0       62.0       67.0       55.0       61.0   \n",
-       "2       68.0       61.0       67.0       66.0       46.0       55.0   \n",
-       "3       43.0       51.0       53.0       62.0       53.0       60.0   \n",
-       "4       45.0       51.0       54.0       59.0       43.0       41.0   \n",
-       "\n",
-       "   value_S25  value_S26  \n",
-       "0       47.0      356.0  \n",
-       "1       42.0      400.0  \n",
-       "2       45.0      402.0  \n",
-       "3       45.0      357.0  \n",
-       "4       36.0      322.0  \n",
-       "\n",
-       "[5 rows x 28 columns]"
-      ]
-     },
-     "execution_count": 9,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['readings'].head()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## mlblocks.MLPipeline 2\n",
-    "\n",
-    "###  featuretools.EntitySet.entity_from_dataframe\n",
-    "\n",
-    "* Input: readings (resampled)\n",
-    "* Output: entityset\n",
-    "* Effect: Entityset has been generated from readings\n",
-    "\n",
-    "### featuretools.EntitySet.normalize_entity\n",
-    "\n",
-    "* Input: entityset\n",
-    "* Output: entityset with relationship (readings.turbine_id with turbines.turbine_id)\n",
-    "* Effect: establish relation between readings and turbines"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 1\n",
-    "context = pipeline.fit(**context, output_=step, start_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'X', 'y', 'entityset'])"
-      ]
-     },
-     "execution_count": 11,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "Entityset: entityset\n",
-       "  Entities:\n",
-       "    readings [Rows: 51121, Columns: 29]\n",
-       "    turbines [Rows: 1, Columns: 1]\n",
-       "  Relationships:\n",
-       "    readings.turbine_id -> turbines.turbine_id"
-      ]
-     },
-     "execution_count": 12,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['entityset']"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## featuretools.dfs\n",
-    "\n",
-    "* Input: entityset (unstacked, no turbine_id, no timestamp)\n",
-    "* Output: X (has additional features)\n",
-    "* Effect: build features for relational dataset using DFS"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 2\n",
-    "context = pipeline.fit(**context, output_=step, start_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'entityset', 'X', 'y'])"
-      ]
-     },
-     "execution_count": 14,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys() "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>SUM(readings.value_S14)</th>\n",
-       "      <th>SUM(readings.value_S11)</th>\n",
-       "      <th>SUM(readings.value_S25)</th>\n",
-       "      <th>SUM(readings.value_S23)</th>\n",
-       "      <th>SUM(readings.value_S17)</th>\n",
-       "      <th>SUM(readings.value_S19)</th>\n",
-       "      <th>SUM(readings.value_S04)</th>\n",
-       "      <th>SUM(readings.value_S05)</th>\n",
-       "      <th>SUM(readings.value_S21)</th>\n",
-       "      <th>SUM(readings.value_S16)</th>\n",
-       "      <th>...</th>\n",
-       "      <th>MEAN(readings.value_S20)</th>\n",
-       "      <th>COUNT(readings)</th>\n",
-       "      <th>NUM_UNIQUE(readings.YEAR(timestamp))</th>\n",
-       "      <th>NUM_UNIQUE(readings.MONTH(timestamp))</th>\n",
-       "      <th>NUM_UNIQUE(readings.DAY(timestamp))</th>\n",
-       "      <th>NUM_UNIQUE(readings.WEEKDAY(timestamp))</th>\n",
-       "      <th>MODE(readings.YEAR(timestamp))</th>\n",
-       "      <th>MODE(readings.MONTH(timestamp))</th>\n",
-       "      <th>MODE(readings.DAY(timestamp))</th>\n",
-       "      <th>MODE(readings.WEEKDAY(timestamp))</th>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>465421817.0</td>\n",
-       "      <td>496362516.0</td>\n",
-       "      <td>2743.0</td>\n",
-       "      <td>2780.0</td>\n",
-       "      <td>994.6</td>\n",
-       "      <td>3174.0</td>\n",
-       "      <td>19412.0</td>\n",
-       "      <td>17083.0</td>\n",
-       "      <td>3061.0</td>\n",
-       "      <td>550.4</td>\n",
-       "      <td>...</td>\n",
-       "      <td>22.326389</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>11</td>\n",
-       "      <td>4</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>465897578.0</td>\n",
-       "      <td>496952628.0</td>\n",
-       "      <td>4237.0</td>\n",
-       "      <td>4640.0</td>\n",
-       "      <td>1166.7</td>\n",
-       "      <td>5112.0</td>\n",
-       "      <td>38289.0</td>\n",
-       "      <td>34344.0</td>\n",
-       "      <td>4919.0</td>\n",
-       "      <td>713.7</td>\n",
-       "      <td>...</td>\n",
-       "      <td>35.166667</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>12</td>\n",
-       "      <td>5</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>466806830.0</td>\n",
-       "      <td>498019072.0</td>\n",
-       "      <td>9008.0</td>\n",
-       "      <td>9179.0</td>\n",
-       "      <td>1581.7</td>\n",
-       "      <td>9134.0</td>\n",
-       "      <td>86707.0</td>\n",
-       "      <td>78749.0</td>\n",
-       "      <td>9863.0</td>\n",
-       "      <td>916.3</td>\n",
-       "      <td>...</td>\n",
-       "      <td>53.381944</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>13</td>\n",
-       "      <td>6</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>468250434.0</td>\n",
-       "      <td>499530451.0</td>\n",
-       "      <td>10073.0</td>\n",
-       "      <td>10310.0</td>\n",
-       "      <td>1690.9</td>\n",
-       "      <td>10674.0</td>\n",
-       "      <td>87907.0</td>\n",
-       "      <td>83264.0</td>\n",
-       "      <td>10638.0</td>\n",
-       "      <td>970.6</td>\n",
-       "      <td>...</td>\n",
-       "      <td>61.423611</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>14</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>371675934.0</td>\n",
-       "      <td>400196323.0</td>\n",
-       "      <td>7381.0</td>\n",
-       "      <td>8228.0</td>\n",
-       "      <td>1666.0</td>\n",
-       "      <td>8831.0</td>\n",
-       "      <td>68811.0</td>\n",
-       "      <td>64088.0</td>\n",
-       "      <td>8629.0</td>\n",
-       "      <td>948.8</td>\n",
-       "      <td>...</td>\n",
-       "      <td>87.575221</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>15</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "<p>5 rows × 165 columns</p>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "            SUM(readings.value_S14)  SUM(readings.value_S11)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                    465421817.0              496362516.0   \n",
-       "T001                    465897578.0              496952628.0   \n",
-       "T001                    466806830.0              498019072.0   \n",
-       "T001                    468250434.0              499530451.0   \n",
-       "T001                    371675934.0              400196323.0   \n",
-       "\n",
-       "            SUM(readings.value_S25)  SUM(readings.value_S23)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                         2743.0                   2780.0   \n",
-       "T001                         4237.0                   4640.0   \n",
-       "T001                         9008.0                   9179.0   \n",
-       "T001                        10073.0                  10310.0   \n",
-       "T001                         7381.0                   8228.0   \n",
-       "\n",
-       "            SUM(readings.value_S17)  SUM(readings.value_S19)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                          994.6                   3174.0   \n",
-       "T001                         1166.7                   5112.0   \n",
-       "T001                         1581.7                   9134.0   \n",
-       "T001                         1690.9                  10674.0   \n",
-       "T001                         1666.0                   8831.0   \n",
-       "\n",
-       "            SUM(readings.value_S04)  SUM(readings.value_S05)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                        19412.0                  17083.0   \n",
-       "T001                        38289.0                  34344.0   \n",
-       "T001                        86707.0                  78749.0   \n",
-       "T001                        87907.0                  83264.0   \n",
-       "T001                        68811.0                  64088.0   \n",
-       "\n",
-       "            SUM(readings.value_S21)  SUM(readings.value_S16)  ...  \\\n",
-       "turbine_id                                                    ...   \n",
-       "T001                         3061.0                    550.4  ...   \n",
-       "T001                         4919.0                    713.7  ...   \n",
-       "T001                         9863.0                    916.3  ...   \n",
-       "T001                        10638.0                    970.6  ...   \n",
-       "T001                         8629.0                    948.8  ...   \n",
-       "\n",
-       "            MEAN(readings.value_S20)  COUNT(readings)  \\\n",
-       "turbine_id                                              \n",
-       "T001                       22.326389              144   \n",
-       "T001                       35.166667              144   \n",
-       "T001                       53.381944              144   \n",
-       "T001                       61.423611              144   \n",
-       "T001                       87.575221              144   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.YEAR(timestamp))  \\\n",
-       "turbine_id                                         \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.MONTH(timestamp))  \\\n",
-       "turbine_id                                          \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.DAY(timestamp))  \\\n",
-       "turbine_id                                        \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.WEEKDAY(timestamp))  \\\n",
-       "turbine_id                                            \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "\n",
-       "            MODE(readings.YEAR(timestamp))  MODE(readings.MONTH(timestamp))  \\\n",
-       "turbine_id                                                                    \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "\n",
-       "            MODE(readings.DAY(timestamp))  MODE(readings.WEEKDAY(timestamp))  \n",
-       "turbine_id                                                                    \n",
-       "T001                                   11                                  4  \n",
-       "T001                                   12                                  5  \n",
-       "T001                                   13                                  6  \n",
-       "T001                                   14                                  0  \n",
-       "T001                                   15                                  1  \n",
-       "\n",
-       "[5 rows x 165 columns]"
-      ]
-     },
-     "execution_count": 15,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['X'].head()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "165"
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# features generated (the turbine_id is set as index).\n",
-    "len(context['X'].columns)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## mlprimitives.custom.feature_extraction.CategoricalEncoder\n",
-    "\n",
-    "* Input: X\n",
-    "* Output: X (label encoded)\n",
-    "* Effect: encodes categorical features using OneHotLabelEncoder"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 3\n",
-    "context = pipeline.fit(**context, output_=step, start_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'entityset', 'X', 'y'])"
-      ]
-     },
-     "execution_count": 18,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>SUM(readings.value_S14)</th>\n",
-       "      <th>SUM(readings.value_S11)</th>\n",
-       "      <th>SUM(readings.value_S25)</th>\n",
-       "      <th>SUM(readings.value_S23)</th>\n",
-       "      <th>SUM(readings.value_S17)</th>\n",
-       "      <th>SUM(readings.value_S19)</th>\n",
-       "      <th>SUM(readings.value_S04)</th>\n",
-       "      <th>SUM(readings.value_S05)</th>\n",
-       "      <th>SUM(readings.value_S21)</th>\n",
-       "      <th>SUM(readings.value_S16)</th>\n",
-       "      <th>...</th>\n",
-       "      <th>MEAN(readings.value_S20)</th>\n",
-       "      <th>COUNT(readings)</th>\n",
-       "      <th>NUM_UNIQUE(readings.YEAR(timestamp))</th>\n",
-       "      <th>NUM_UNIQUE(readings.MONTH(timestamp))</th>\n",
-       "      <th>NUM_UNIQUE(readings.DAY(timestamp))</th>\n",
-       "      <th>NUM_UNIQUE(readings.WEEKDAY(timestamp))</th>\n",
-       "      <th>MODE(readings.YEAR(timestamp))</th>\n",
-       "      <th>MODE(readings.MONTH(timestamp))</th>\n",
-       "      <th>MODE(readings.DAY(timestamp))</th>\n",
-       "      <th>MODE(readings.WEEKDAY(timestamp))</th>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "      <th></th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>465421817.0</td>\n",
-       "      <td>496362516.0</td>\n",
-       "      <td>2743.0</td>\n",
-       "      <td>2780.0</td>\n",
-       "      <td>994.6</td>\n",
-       "      <td>3174.0</td>\n",
-       "      <td>19412.0</td>\n",
-       "      <td>17083.0</td>\n",
-       "      <td>3061.0</td>\n",
-       "      <td>550.4</td>\n",
-       "      <td>...</td>\n",
-       "      <td>22.326389</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>11</td>\n",
-       "      <td>4</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>465897578.0</td>\n",
-       "      <td>496952628.0</td>\n",
-       "      <td>4237.0</td>\n",
-       "      <td>4640.0</td>\n",
-       "      <td>1166.7</td>\n",
-       "      <td>5112.0</td>\n",
-       "      <td>38289.0</td>\n",
-       "      <td>34344.0</td>\n",
-       "      <td>4919.0</td>\n",
-       "      <td>713.7</td>\n",
-       "      <td>...</td>\n",
-       "      <td>35.166667</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>12</td>\n",
-       "      <td>5</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>466806830.0</td>\n",
-       "      <td>498019072.0</td>\n",
-       "      <td>9008.0</td>\n",
-       "      <td>9179.0</td>\n",
-       "      <td>1581.7</td>\n",
-       "      <td>9134.0</td>\n",
-       "      <td>86707.0</td>\n",
-       "      <td>78749.0</td>\n",
-       "      <td>9863.0</td>\n",
-       "      <td>916.3</td>\n",
-       "      <td>...</td>\n",
-       "      <td>53.381944</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>13</td>\n",
-       "      <td>6</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>468250434.0</td>\n",
-       "      <td>499530451.0</td>\n",
-       "      <td>10073.0</td>\n",
-       "      <td>10310.0</td>\n",
-       "      <td>1690.9</td>\n",
-       "      <td>10674.0</td>\n",
-       "      <td>87907.0</td>\n",
-       "      <td>83264.0</td>\n",
-       "      <td>10638.0</td>\n",
-       "      <td>970.6</td>\n",
-       "      <td>...</td>\n",
-       "      <td>61.423611</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>14</td>\n",
-       "      <td>0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>T001</th>\n",
-       "      <td>371675934.0</td>\n",
-       "      <td>400196323.0</td>\n",
-       "      <td>7381.0</td>\n",
-       "      <td>8228.0</td>\n",
-       "      <td>1666.0</td>\n",
-       "      <td>8831.0</td>\n",
-       "      <td>68811.0</td>\n",
-       "      <td>64088.0</td>\n",
-       "      <td>8629.0</td>\n",
-       "      <td>948.8</td>\n",
-       "      <td>...</td>\n",
-       "      <td>87.575221</td>\n",
-       "      <td>144</td>\n",
-       "      <td>1</td>\n",
-       "      <td>1</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2</td>\n",
-       "      <td>2013</td>\n",
-       "      <td>1</td>\n",
-       "      <td>15</td>\n",
-       "      <td>1</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "<p>5 rows × 165 columns</p>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "            SUM(readings.value_S14)  SUM(readings.value_S11)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                    465421817.0              496362516.0   \n",
-       "T001                    465897578.0              496952628.0   \n",
-       "T001                    466806830.0              498019072.0   \n",
-       "T001                    468250434.0              499530451.0   \n",
-       "T001                    371675934.0              400196323.0   \n",
-       "\n",
-       "            SUM(readings.value_S25)  SUM(readings.value_S23)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                         2743.0                   2780.0   \n",
-       "T001                         4237.0                   4640.0   \n",
-       "T001                         9008.0                   9179.0   \n",
-       "T001                        10073.0                  10310.0   \n",
-       "T001                         7381.0                   8228.0   \n",
-       "\n",
-       "            SUM(readings.value_S17)  SUM(readings.value_S19)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                          994.6                   3174.0   \n",
-       "T001                         1166.7                   5112.0   \n",
-       "T001                         1581.7                   9134.0   \n",
-       "T001                         1690.9                  10674.0   \n",
-       "T001                         1666.0                   8831.0   \n",
-       "\n",
-       "            SUM(readings.value_S04)  SUM(readings.value_S05)  \\\n",
-       "turbine_id                                                     \n",
-       "T001                        19412.0                  17083.0   \n",
-       "T001                        38289.0                  34344.0   \n",
-       "T001                        86707.0                  78749.0   \n",
-       "T001                        87907.0                  83264.0   \n",
-       "T001                        68811.0                  64088.0   \n",
-       "\n",
-       "            SUM(readings.value_S21)  SUM(readings.value_S16)  ...  \\\n",
-       "turbine_id                                                    ...   \n",
-       "T001                         3061.0                    550.4  ...   \n",
-       "T001                         4919.0                    713.7  ...   \n",
-       "T001                         9863.0                    916.3  ...   \n",
-       "T001                        10638.0                    970.6  ...   \n",
-       "T001                         8629.0                    948.8  ...   \n",
-       "\n",
-       "            MEAN(readings.value_S20)  COUNT(readings)  \\\n",
-       "turbine_id                                              \n",
-       "T001                       22.326389              144   \n",
-       "T001                       35.166667              144   \n",
-       "T001                       53.381944              144   \n",
-       "T001                       61.423611              144   \n",
-       "T001                       87.575221              144   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.YEAR(timestamp))  \\\n",
-       "turbine_id                                         \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "T001                                           1   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.MONTH(timestamp))  \\\n",
-       "turbine_id                                          \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "T001                                            1   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.DAY(timestamp))  \\\n",
-       "turbine_id                                        \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "T001                                          2   \n",
-       "\n",
-       "            NUM_UNIQUE(readings.WEEKDAY(timestamp))  \\\n",
-       "turbine_id                                            \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "T001                                              2   \n",
-       "\n",
-       "            MODE(readings.YEAR(timestamp))  MODE(readings.MONTH(timestamp))  \\\n",
-       "turbine_id                                                                    \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "T001                                  2013                                1   \n",
-       "\n",
-       "            MODE(readings.DAY(timestamp))  MODE(readings.WEEKDAY(timestamp))  \n",
-       "turbine_id                                                                    \n",
-       "T001                                   11                                  4  \n",
-       "T001                                   12                                  5  \n",
-       "T001                                   13                                  6  \n",
-       "T001                                   14                                  0  \n",
-       "T001                                   15                                  1  \n",
-       "\n",
-       "[5 rows x 165 columns]"
-      ]
-     },
-     "execution_count": 19,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['X'].head()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 20,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<div>\n",
-       "<style scoped>\n",
-       "    .dataframe tbody tr th:only-of-type {\n",
-       "        vertical-align: middle;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe tbody tr th {\n",
-       "        vertical-align: top;\n",
-       "    }\n",
-       "\n",
-       "    .dataframe thead th {\n",
-       "        text-align: right;\n",
-       "    }\n",
-       "</style>\n",
-       "<table border=\"1\" class=\"dataframe\">\n",
-       "  <thead>\n",
-       "    <tr style=\"text-align: right;\">\n",
-       "      <th></th>\n",
-       "      <th>turbine_id</th>\n",
-       "      <th>timestamp</th>\n",
-       "      <th>value_S01</th>\n",
-       "      <th>value_S02</th>\n",
-       "      <th>value_S03</th>\n",
-       "      <th>value_S04</th>\n",
-       "      <th>value_S05</th>\n",
-       "      <th>value_S06</th>\n",
-       "      <th>value_S07</th>\n",
-       "      <th>value_S08</th>\n",
-       "      <th>...</th>\n",
-       "      <th>value_S17</th>\n",
-       "      <th>value_S18</th>\n",
-       "      <th>value_S19</th>\n",
-       "      <th>value_S20</th>\n",
-       "      <th>value_S21</th>\n",
-       "      <th>value_S22</th>\n",
-       "      <th>value_S23</th>\n",
-       "      <th>value_S24</th>\n",
-       "      <th>value_S25</th>\n",
-       "      <th>value_S26</th>\n",
-       "    </tr>\n",
-       "  </thead>\n",
-       "  <tbody>\n",
-       "    <tr>\n",
-       "      <th>0</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:00:00</td>\n",
-       "      <td>323.0</td>\n",
-       "      <td>320.0</td>\n",
-       "      <td>284.0</td>\n",
-       "      <td>348.0</td>\n",
-       "      <td>273.0</td>\n",
-       "      <td>342.0</td>\n",
-       "      <td>280.0</td>\n",
-       "      <td>3197842.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>11.7</td>\n",
-       "      <td>3131020.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>47.0</td>\n",
-       "      <td>58.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>58.0</td>\n",
-       "      <td>47.0</td>\n",
-       "      <td>356.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>1</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:10:00</td>\n",
-       "      <td>346.0</td>\n",
-       "      <td>384.0</td>\n",
-       "      <td>367.0</td>\n",
-       "      <td>411.0</td>\n",
-       "      <td>331.0</td>\n",
-       "      <td>360.0</td>\n",
-       "      <td>249.0</td>\n",
-       "      <td>3197900.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>10.2</td>\n",
-       "      <td>3131420.0</td>\n",
-       "      <td>58.0</td>\n",
-       "      <td>63.0</td>\n",
-       "      <td>62.0</td>\n",
-       "      <td>67.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>61.0</td>\n",
-       "      <td>42.0</td>\n",
-       "      <td>400.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>2</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:20:00</td>\n",
-       "      <td>407.0</td>\n",
-       "      <td>363.0</td>\n",
-       "      <td>407.0</td>\n",
-       "      <td>393.0</td>\n",
-       "      <td>275.0</td>\n",
-       "      <td>335.0</td>\n",
-       "      <td>270.0</td>\n",
-       "      <td>3197968.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>9.5</td>\n",
-       "      <td>3131822.0</td>\n",
-       "      <td>68.0</td>\n",
-       "      <td>61.0</td>\n",
-       "      <td>67.0</td>\n",
-       "      <td>66.0</td>\n",
-       "      <td>46.0</td>\n",
-       "      <td>55.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>402.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>3</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:30:00</td>\n",
-       "      <td>257.0</td>\n",
-       "      <td>307.0</td>\n",
-       "      <td>315.0</td>\n",
-       "      <td>361.0</td>\n",
-       "      <td>317.0</td>\n",
-       "      <td>354.0</td>\n",
-       "      <td>271.0</td>\n",
-       "      <td>3198011.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>10.5</td>\n",
-       "      <td>3132179.0</td>\n",
-       "      <td>43.0</td>\n",
-       "      <td>51.0</td>\n",
-       "      <td>53.0</td>\n",
-       "      <td>62.0</td>\n",
-       "      <td>53.0</td>\n",
-       "      <td>60.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>357.0</td>\n",
-       "    </tr>\n",
-       "    <tr>\n",
-       "      <th>4</th>\n",
-       "      <td>T001</td>\n",
-       "      <td>2013-01-10 00:40:00</td>\n",
-       "      <td>267.0</td>\n",
-       "      <td>309.0</td>\n",
-       "      <td>314.0</td>\n",
-       "      <td>355.0</td>\n",
-       "      <td>262.0</td>\n",
-       "      <td>246.0</td>\n",
-       "      <td>212.0</td>\n",
-       "      <td>3198056.0</td>\n",
-       "      <td>...</td>\n",
-       "      <td>9.6</td>\n",
-       "      <td>3132501.0</td>\n",
-       "      <td>45.0</td>\n",
-       "      <td>51.0</td>\n",
-       "      <td>54.0</td>\n",
-       "      <td>59.0</td>\n",
-       "      <td>43.0</td>\n",
-       "      <td>41.0</td>\n",
-       "      <td>36.0</td>\n",
-       "      <td>322.0</td>\n",
-       "    </tr>\n",
-       "  </tbody>\n",
-       "</table>\n",
-       "<p>5 rows × 28 columns</p>\n",
-       "</div>"
-      ],
-      "text/plain": [
-       "  turbine_id           timestamp  value_S01  value_S02  value_S03  value_S04  \\\n",
-       "0       T001 2013-01-10 00:00:00      323.0      320.0      284.0      348.0   \n",
-       "1       T001 2013-01-10 00:10:00      346.0      384.0      367.0      411.0   \n",
-       "2       T001 2013-01-10 00:20:00      407.0      363.0      407.0      393.0   \n",
-       "3       T001 2013-01-10 00:30:00      257.0      307.0      315.0      361.0   \n",
-       "4       T001 2013-01-10 00:40:00      267.0      309.0      314.0      355.0   \n",
-       "\n",
-       "   value_S05  value_S06  value_S07  value_S08  ...  value_S17  value_S18  \\\n",
-       "0      273.0      342.0      280.0  3197842.0  ...       11.7  3131020.0   \n",
-       "1      331.0      360.0      249.0  3197900.0  ...       10.2  3131420.0   \n",
-       "2      275.0      335.0      270.0  3197968.0  ...        9.5  3131822.0   \n",
-       "3      317.0      354.0      271.0  3198011.0  ...       10.5  3132179.0   \n",
-       "4      262.0      246.0      212.0  3198056.0  ...        9.6  3132501.0   \n",
-       "\n",
-       "   value_S19  value_S20  value_S21  value_S22  value_S23  value_S24  \\\n",
-       "0       55.0       55.0       47.0       58.0       45.0       58.0   \n",
-       "1       58.0       63.0       62.0       67.0       55.0       61.0   \n",
-       "2       68.0       61.0       67.0       66.0       46.0       55.0   \n",
-       "3       43.0       51.0       53.0       62.0       53.0       60.0   \n",
-       "4       45.0       51.0       54.0       59.0       43.0       41.0   \n",
-       "\n",
-       "   value_S25  value_S26  \n",
-       "0       47.0      356.0  \n",
-       "1       42.0      400.0  \n",
-       "2       45.0      402.0  \n",
-       "3       45.0      357.0  \n",
-       "4       36.0      322.0  \n",
-       "\n",
-       "[5 rows x 28 columns]"
-      ]
-     },
-     "execution_count": 20,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context['readings'].head()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## xgboost.XGBClassifier\n",
-    "\n",
-    "* Input: X (label encoded and featurized)\n",
-    "* Output: None\n",
-    "* Effect: trained model"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "step = 4\n",
-    "context = pipeline.fit(**context, output_=step, start_=step)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 22,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "dict_keys(['readings', 'turbines', 'entityset', 'X', 'y'])"
-      ]
-     },
-     "execution_count": 22,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "context.keys()"
-   ]
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.7.11"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}


Test patch:
diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py
index d88425b..60736b0 100644
--- a/tests/test_benchmark.py
+++ b/tests/test_benchmark.py
@@ -8,7 +8,7 @@
 def test_predict():
     # setup
     templates = [
-        'dfs_xgb_prob_with_unstack_normalization'
+        'lstm_with_unstack'
     ]
 
     window_size_rule = [