def test_FeatureUnion_pipeline(): # pipeline with segmentation plus multiple feature extraction steps = [ ("segment", RandomIntervalSegmenter(n_intervals=3)), ( "transform", FeatureUnion([ ( "mean", RowTransformer( FunctionTransformer(func=np.mean, validate=False)), ), ( "std", RowTransformer( FunctionTransformer(func=np.std, validate=False)), ), ]), ), ("clf", DecisionTreeClassifier()), ] clf = Pipeline(steps) clf.fit(X_train, y_train) y_pred = clf.predict(X_test) assert y_pred.shape[0] == y_test.shape[0] np.testing.assert_array_equal(np.unique(y_pred), np.unique(y_test))
def test_different_pipelines(): random_state = 1233 X_train, y_train = make_classification_problem() steps = [ ('segment', RandomIntervalSegmenter(n_intervals='sqrt', random_state=random_state)), ('transform', FeatureUnion([ ('mean', RowTransformer(FunctionTransformer(func=np.mean, validate=False))), ('std', RowTransformer(FunctionTransformer(func=np.std, validate=False))), ('slope', RowTransformer( FunctionTransformer(func=time_series_slope, validate=False))), ])), ] pipe = Pipeline(steps) a = pipe.fit_transform(X_train) tran = RandomIntervalFeatureExtractor( n_intervals='sqrt', features=[np.mean, np.std, time_series_slope], random_state=random_state) b = tran.fit_transform(X_train) np.testing.assert_array_equal(a, b) np.testing.assert_array_equal(pipe.steps[0][1].intervals_, tran.intervals_)
def test_row_transformer_function_transformer_series_to_primitives(): X, y = load_gunpoint(return_X_y=True) ft = FunctionTransformer(func=np.mean, validate=False) t = RowTransformer(ft) Xt = t.fit_transform(X, y) assert Xt.shape == X.shape assert isinstance(Xt.iloc[0, 0], float) # check series-to-primitive transforms
def rise_benchmarking(): for i in range(len(benchmark_datasets)): dataset = benchmark_datasets[i] print(str(i) + " problem = " + dataset) rise = fb.RandomIntervalSpectralForest(n_estimators=100) exp.run_experiment(overwrite=True, problem_path=data_dir, results_path=results_dir, cls_name="PythonRISE", classifier=rise, dataset=dataset, train_file=False) steps = [('segment', RandomIntervalSegmenter(n_intervals=1, min_length=5)), ('transform', FeatureUnion([('acf', RowTransformer( FunctionTransformer(func=acf_coefs, validate=False))), ('ps', RowTransformer( FunctionTransformer(func=powerspectrum, validate=False)))])), ('tabularise', Tabularizer()), ('clf', DecisionTreeClassifier())] base_estimator = Pipeline(steps) rise = TimeSeriesForestClassifier(estimator=base_estimator, n_estimators=100) exp.run_experiment(overwrite=True, problem_path=data_dir, results_path=results_dir, cls_name="PythonRISEComposite", classifier=rise, dataset=dataset, train_file=False)
def test_row_transformer_transform_inverse_transform(): X, y = load_gunpoint(return_X_y=True) t = RowTransformer(StandardScaler()) Xt = t.fit_transform(X) Xit = t.inverse_transform(Xt) assert Xit.shape == X.shape assert isinstance(Xit.iloc[0, 0], ( pd.Series, np.ndarray)) # check series-to-series transforms np.testing.assert_array_almost_equal(tabularize(X).values, tabularize(Xit).values, decimal=5)
def set_classifier(cls, resampleId): """ Basic way of determining the classifier to build. To differentiate settings just and another elif. So, for example, if you wanted tuned TSF, you just pass TuneTSF and set up the tuning mechanism in the elif. This may well get superceded, it is just how e have always done it :param cls: String indicating which classifier you want :return: A classifier. """ if cls.lower() == 'pf': return pf.ProximityForest(random_state=resampleId) elif cls.lower() == 'pt': return pf.ProximityTree(random_state=resampleId) elif cls.lower() == 'ps': return pf.ProximityStump(random_state=resampleId) elif cls.lower() == 'rise': return fb.RandomIntervalSpectralForest(random_state=resampleId) elif cls.lower() == 'tsf': return ib.TimeSeriesForest(random_state=resampleId) elif cls.lower() == 'boss': return db.BOSSEnsemble(random_state=resampleId) elif cls.lower() == 'cboss': return db.BOSSEnsemble(random_state=resampleId, randomised_ensemble=True, max_ensemble_size=50) elif cls.lower() == 'tde': return tde.TemporalDictionaryEnsemble(random_state=resampleId) elif cls.lower() == 'st': return st.ShapeletTransformClassifier(time_contract_in_mins=1500) elif cls.lower() == 'dtwcv': return nn.KNeighborsTimeSeriesClassifier(metric="dtwcv") elif cls.lower() == 'ee' or cls.lower() == 'elasticensemble': return dist.ElasticEnsemble() elif cls.lower() == 'tsfcomposite': #It defaults to TSF return ensemble.TimeSeriesForestClassifier() elif cls.lower() == 'risecomposite': steps = [('segment', RandomIntervalSegmenter(n_intervals=1, min_length=5)), ('transform', FeatureUnion([('acf', RowTransformer( FunctionTransformer(func=acf_coefs, validate=False))), ('ps', RowTransformer( FunctionTransformer(func=powerspectrum, validate=False)))])), ('tabularise', Tabularizer()), ('clf', DecisionTreeClassifier())] base_estimator = Pipeline(steps) return ensemble.TimeSeriesForestClassifier(estimator=base_estimator, n_estimators=100) else: raise Exception('UNKNOWN CLASSIFIER')
def test_FeatureUnion(): X, y = load_gunpoint(return_X_y=True) transformer1 = RowTransformer( FunctionTransformer(func=np.mean, validate=False)) transformer2 = RowTransformer( FunctionTransformer(func=np.std, validate=False)) feature_union = FeatureUnion([("mean", transformer1), ("std", transformer2)]) Xt = feature_union.fit_transform(X, y) assert Xt.shape == (X.shape[0], X.shape[1] * len(feature_union.transformer_list))
def test_FeatureUnion(): X, y = load_gunpoint(return_X_y=True) ft = FunctionTransformer(func=np.mean, validate=False) t = RowTransformer(ft) fu = FeatureUnion([ ('mean', t), ('std', RowTransformer(FunctionTransformer(func=np.std, validate=False))) ]) Xt = fu.fit_transform(X, y) assert Xt.shape == (X.shape[0], X.shape[1] * len(fu.transformer_list))
def test_row_transformer_sklearn_transfomer(): mu = 10 X = generate_df_from_array(np.random.normal(loc=mu, scale=5, size=(100,)), n_rows=10, n_cols=1) t = StandardScaler(with_mean=True, with_std=True) r = RowTransformer(t) Xt = r.fit_transform(X) assert Xt.shape == X.shape assert isinstance(Xt.iloc[0, 0], ( pd.Series, np.ndarray)) # check series-to-series transform np.testing.assert_almost_equal(Xt.iloc[0, 0].mean(), 0) # check standardisation np.testing.assert_almost_equal(Xt.iloc[0, 0].std(), 1, decimal=2)
def test_row_transformer_function_transformer_series_to_series(): X, y = load_gunpoint(return_X_y=True) # series-to-series transform function def powerspectrum(x): fft = np.fft.fft(x) ps = fft.real * fft.real + fft.imag * fft.imag return ps[:ps.shape[0] // 2] ft = FunctionTransformer(func=powerspectrum, validate=False) t = RowTransformer(ft) Xt = t.fit_transform(X, y) assert Xt.shape == X.shape assert isinstance(Xt.iloc[0, 0], ( pd.Series, np.ndarray)) # check series-to-series transforms
def test_feature_importances_single_feature_interval_and_estimator(): random_state = 1234 # Compute using default method features = [np.mean] steps = [('transform', RandomIntervalFeatureExtractor(n_intervals=1, features=features, random_state=random_state)), ('clf', DecisionTreeClassifier())] base_estimator = Pipeline(steps) clf1 = TimeSeriesForestClassifier(estimator=base_estimator, random_state=random_state, n_estimators=1) clf1.fit(X_train, y_train) # Extract the interval and the estimator, and compute using pipelines intervals = clf1.estimators_[0].steps[0][1].intervals_ steps = [('segment', IntervalSegmenter(intervals)), ('transform', FeatureUnion([('mean', RowTransformer( FunctionTransformer(func=np.mean, validate=False)))])), ('clf', clone(clf1.estimators_[0].steps[-1][1]))] clf2 = Pipeline(steps) clf2.fit(X_train, y_train) # Check for feature importances obtained from the estimators fi_expected = clf1.estimators_[0].steps[-1][1].feature_importances_ fi_actual = clf2.steps[-1][1].feature_importances_ np.testing.assert_array_equal(fi_actual, fi_expected)
def test_different_implementations(): random_state = 1233 X_train, y_train = make_classification_problem() # Compare with chained transformations. tran1 = RandomIntervalSegmenter(n_intervals='sqrt', random_state=random_state) tran2 = RowTransformer(FunctionTransformer(func=np.mean, validate=False)) A = tran2.fit_transform(tran1.fit_transform(X_train)) tran = RandomIntervalFeatureExtractor(n_intervals='sqrt', features=[np.mean], random_state=random_state) B = tran.fit_transform(X_train) np.testing.assert_array_equal(A, B)
def test_RowTransformer_pipeline(): X_train, y_train = load_basic_motions(split="train", return_X_y=True) X_test, y_test = load_basic_motions(split="test", return_X_y=True) # using pure sklearn def row_mean(X): if isinstance(X, pd.Series): X = pd.DataFrame(X) Xt = pd.concat([pd.Series(col.apply(np.mean)) for _, col in X.items()], axis=1) return Xt def row_first(X): if isinstance(X, pd.Series): X = pd.DataFrame(X) Xt = pd.concat( [ pd.Series(from_nested_to_2d_array(col).iloc[:, 0]) for _, col in X.items() ], axis=1, ) return Xt # specify column as a list, otherwise pandas Series are selected and # passed on to the transformers transformer = ColumnTransformer( [ ("mean", FunctionTransformer(func=row_mean, validate=False), ["dim_0"]), ("first", FunctionTransformer(func=row_first, validate=False), ["dim_1"]), ] ) estimator = RandomForestClassifier(n_estimators=2, random_state=1) steps = [("extract", transformer), ("classify", estimator)] model = Pipeline(steps=steps) model.fit(X_train, y_train) expected = model.predict(X_test) # using sktime with sklearn pipeline transformer = ColumnTransformer( [ ( "mean", RowTransformer(FunctionTransformer(func=np.mean, validate=False)), ["dim_0"], ), ("first", FunctionTransformer(func=row_first, validate=False), ["dim_1"]), ] ) estimator = RandomForestClassifier(n_estimators=2, random_state=1) steps = [("extract", transformer), ("classify", estimator)] model = Pipeline(steps=steps) model.fit(X_train, y_train) actual = model.predict(X_test) np.testing.assert_array_equal(expected, actual)
def test_equivalent_model_specifications(n_intervals, n_estimators): random_state = 1234 X_train, y_train = load_gunpoint(split="train", return_X_y=True) X_test, y_test = load_gunpoint(split="test", return_X_y=True) # Due to tie-breaking/floating point rounding in the final decision tree # classifier, the results depend on the # exact column order of the input data # Compare pipeline predictions outside of ensemble. steps = [ ('segment', RandomIntervalSegmenter(n_intervals=n_intervals, random_state=random_state)), ('transform', FeatureUnion([ ('mean', RowTransformer(FunctionTransformer(func=np.mean, validate=False))), ('std', RowTransformer(FunctionTransformer(func=np.std, validate=False))), ('slope', RowTransformer( FunctionTransformer(func=time_series_slope, validate=False))) ])), ('clf', DecisionTreeClassifier(random_state=random_state)) ] clf1 = Pipeline(steps) clf1.fit(X_train, y_train) a = clf1.predict(X_test) steps = [('transform', RandomIntervalFeatureExtractor( n_intervals=n_intervals, features=[np.mean, np.std, time_series_slope], random_state=random_state)), ('clf', DecisionTreeClassifier(random_state=random_state))] clf2 = Pipeline(steps) clf2.fit(X_train, y_train) b = clf2.predict(X_test) np.array_equal(a, b)
def tsf_benchmarking(): for i in range(len(benchmark_datasets)): dataset = benchmark_datasets[i] print(str(i) + " problem = " + dataset) tsf = ib.TimeSeriesForest(n_estimators=100) exp.run_experiment(overwrite=False, problem_path=data_dir, results_path=results_dir, cls_name="PythonTSF", classifier=tsf, dataset=dataset, train_file=False) steps = [ ('segment', RandomIntervalSegmenter(n_intervals='sqrt')), ('transform', FeatureUnion([('mean', RowTransformer( FunctionTransformer(func=np.mean, validate=False))), ('std', RowTransformer( FunctionTransformer(func=np.std, validate=False))), ('slope', RowTransformer( FunctionTransformer(func=time_series_slope, validate=False)))])), ('clf', DecisionTreeClassifier()) ] base_estimator = Pipeline(steps) tsf = TimeSeriesForestClassifier(estimator=base_estimator, n_estimators=100) exp.run_experiment(overwrite=False, problem_path=data_dir, results_path=results_dir, cls_name="PythonTSFComposite", classifier=tsf, dataset=dataset, train_file=False)
def set_classifier(cls, resampleId): """ Basic way of determining the classifier to build. To differentiate settings just and another elif. So, for example, if you wanted tuned TSF, you just pass TuneTSF and set up the tuning mechanism in the elif. This may well get superceded, it is just how e have always done it :param cls: String indicating which classifier you want :return: A classifier. """ if cls.lower() == 'pf': return pf.ProximityForest(random_state=resampleId) elif cls.lower() == 'pt': return pf.ProximityTree(random_state=resampleId) elif cls.lower() == 'ps': return pf.ProximityStump(random_state=resampleId) elif cls.lower() == 'rise': return fb.RandomIntervalSpectralForest(random_state=resampleId) elif cls.lower() == 'tsf': return ib.TimeSeriesForest(random_state=resampleId) elif cls.lower() == 'boss': return db.BOSSEnsemble() elif cls.lower() == 'st': return st.ShapeletTransformClassifier(time_contract_in_mins=1500) elif cls.lower() == 'dtw': return nn.KNeighborsTimeSeriesClassifier(metric="dtw") elif cls.lower() == 'ee' or cls.lower() == 'elasticensemble': return dist.ElasticEnsemble() elif cls.lower() == 'shapedtw_raw': return ShapeDTW(subsequence_length=30, shape_descriptor_function="raw", metric_params=None) elif cls.lower() == 'shapedtw_dwt': return ShapeDTW(subsequence_length=30, shape_descriptor_function="dwt", metric_params={"num_levels_dwt": 3}) elif cls.lower() == 'shapedtw_paa': return ShapeDTW(subsequence_length=30, shape_descriptor_function="paa", metric_params={"num_intervals_paa": 5}) elif cls.lower() == 'shapedtw_slope': return ShapeDTW(subsequence_length=30, shape_descriptor_function="slope", metric_params={"num_intervals_slope": 5}) elif cls.lower() == 'shapedtw_hog1d': return ShapeDTW(subsequence_length=30, shape_descriptor_function="hog1d", metric_params={ "num_bins_hog1d": 8, "num_intervals_hog1d": 2, "scaling_factor_hog1d": 0.1 }) elif cls.lower() == 'tsfcomposite': #It defaults to TSF return ensemble.TimeSeriesForestClassifier() elif cls.lower() == 'risecomposite': steps = [('segment', RandomIntervalSegmenter(n_intervals=1, min_length=5)), ('transform', FeatureUnion([('acf', RowTransformer( FunctionTransformer(func=acf_coefs, validate=False))), ('ps', RowTransformer( FunctionTransformer(func=powerspectrum, validate=False)))])), ('tabularise', Tabularizer()), ('clf', DecisionTreeClassifier())] base_estimator = Pipeline(steps) return ensemble.TimeSeriesForestClassifier(estimator=base_estimator, n_estimators=100) else: raise Exception('UNKNOWN CLASSIFIER')
def test_feature_importances_multi_intervals_estimators( n_intervals, n_estimators): random_state = 1234 n_features = 3 # Compute feature importances using the default method features = [np.mean, np.std, time_series_slope] steps = [('transform', RandomIntervalFeatureExtractor(n_intervals=n_intervals, features=features, random_state=random_state)), ('clf', DecisionTreeClassifier())] base_estimator = Pipeline(steps) clf1 = TimeSeriesForestClassifier(estimator=base_estimator, random_state=random_state, n_estimators=n_estimators) clf1.fit(X_train, y_train) fi_expected = np.zeros([n_estimators, n_intervals * n_features]) fi_actual = np.zeros([n_estimators, n_intervals * n_features]) # Obtain intervals and decision trees from fitted classifier for i in range(n_estimators): intervals = clf1.estimators_[i].steps[0][1].intervals_ steps = [ ('segment', IntervalSegmenter(intervals)), ('transform', FeatureUnion([('mean', RowTransformer( FunctionTransformer(func=np.mean, validate=False))), ('std', RowTransformer( FunctionTransformer(func=np.std, validate=False))), ('slope', RowTransformer( FunctionTransformer(func=time_series_slope, validate=False)))])), ('clf', clone(clf1.estimators_[i].steps[-1][1])) ] clf2 = Pipeline(steps) clf2.fit(X_train, y_train) # Compute and check for individual feature importances fi_expected[i, :] = clf1.estimators_[i].steps[-1][1].\ feature_importances_ fi_actual[i, :] = clf2.steps[-1][1].feature_importances_ np.testing.assert_array_equal(fi_actual[i, :], fi_expected[i, :]) # Compute normalised feature values of the time series using the # default property fis_expacted = clf1.feature_importances_ # Compute normalised feature values of the time series from the pipeline # implementation n_timepoints = len(clf1.estimators_[0].steps[0][1]._time_index) fis_actual = np.zeros((n_timepoints, n_features)) for i in range(n_estimators): intervals = clf1.estimators_[i].steps[0][1].intervals_ for j in range(n_features): for k in range(n_intervals): start, end = intervals[k] fis_actual[start:end, j] += fi_actual[i, (j * n_intervals) + k] fis_actual = fis_actual / n_estimators / n_intervals np.testing.assert_array_equal(fis_actual, fis_expacted)
def main(): #1. Loading and splitting the dataset X_train, y_train = load_italy_power_demand(split='train', return_X_y=True) X_test, y_test = load_italy_power_demand(split='test', return_X_y=True) print('Shape of X, y train and test dataset', X_train.shape, y_train.shape, X_test.shape, y_test.shape, '\n') print('X_train:', X_train.head(), '\n') print('\nX_train info', X_train.info(), '\n') labels, counts = np.unique(y_train, return_counts=True) print( '\nThere are', labels, 'labels in this dataset, one corresponds to winter and the other to summer. The counter of each one is', counts, '\n') #2. Creating a Model, Fit and Predict Sklearn Classifier #Sktime Tabularizing the data X_train_tab = tabularize(X_train) X_test_tab = tabularize(X_test) print('\n X_train tabularized\n', X_train_tab.head(), '\n') #2.1 SKlearn RandomForest Classifier classifier = RandomForestClassifier(n_estimators=100) classifier.fit(X_train_tab, y_train) y_pred = classifier.predict(X_test_tab) print('Accuracy sklearn RandomForestClassifier', round(accuracy_score(y_test, y_pred), 4), '\n') #2.2 Same SKlearn as above but using make_pipeline w/ Sktime Tabularizer classifier = make_pipeline(Tabularizer(), RandomForestClassifier(n_estimators=100), verbose=True) classifier.fit(X_train, y_train) print( 'Accuracy sklearn RandomForestClassifier using sklearn make_pipeline in which the first step is to sktime Tabularize()', round(classifier.score(X_test, y_test), 4), '\n') #3 Sklearn using make_pipeline w/ Sktime TSFreshFeatureExtractor classifier = make_pipeline(TSFreshFeatureExtractor(show_warnings=False), RandomForestClassifier(n_estimators=100)) classifier.fit(X_train, y_train) print( 'Accuracy sklearn RandomForestClassifier using sklearn make_pipeline in which the first step is to sktime TSFreshFeatureExtractor that automatically extracts and filters several key statistical features from the nested X_train time series', round(classifier.score(X_test, y_test), 4), '\n') #4. Using Time series algorithms and classifiers from sklearn/sktime steps = [ ('segment', RandomIntervalSegmenter(n_intervals='sqrt')), #Sktime ( 'transform', FeatureUnion([ #Sklearn ('mean', RowTransformer( FunctionTransformer(func=np.mean, validate=False))), #sktime ('std', RowTransformer( FunctionTransformer(func=np.std, validate=False))), #sktime ('slope', RowTransformer( FunctionTransformer(func=time_series_slope, validate=False))) #sktime ])), ('clf', DecisionTreeClassifier()) #From Sklearn ] time_series_tree = Pipeline(steps, verbose=True) #sklearn time_series_tree.fit(X_train, y_train) print( 'Accuracy sklearn DecisionTreeClassifier using sklearn Pipeline() as well as segmentation and transformation techniques from sktime and sklearn', round(time_series_tree.score(X_test, y_test), 4)) #5. Using Time series Sktime tsf = TimeSeriesForestClassifier(n_estimators=100, verbose=True) tsf.fit(X_train, y_train) print('Accuracy sktime TimeSeriesForestClassifier', round(tsf.score(X_test, y_test), 4))
EXCLUDED_ESTIMATORS = [ 'ElasticEnsemble', 'KNeighborsTimeSeriesClassifier', 'ProximityForest', 'ProximityStump', 'ProximityTree', ] EXCLUDED_TESTS = { "ShapeletTransformClassifier": ["check_fit_idempotent"], "ContractedShapeletTransform": ["check_fit_idempotent"], } TRANSFORMER = StandardScaler() TRANSFORMERS = [ ("t1", RowTransformer(TRANSFORMER)), ("t2", RowTransformer(TRANSFORMER)), ] REGRESSOR = LinearRegression() TIME_SERIES_CLASSIFIER = TimeSeriesForest(random_state=1) TIME_SERIES_CLASSIFIERS = [("tsf1", TIME_SERIES_CLASSIFIER), ("tsf2", TIME_SERIES_CLASSIFIER)] FORECASTER = ExponentialSmoothing() FORECASTERS = [("ses1", FORECASTER), ("ses2", FORECASTER)] STEPS = [("t", Detrender(ThetaForecaster())), ("f", NaiveForecaster())] ESTIMATOR_TEST_PARAMS = { DirectRegressionForecaster: { "regressor": REGRESSOR }, RecursiveRegressionForecaster: { "regressor": REGRESSOR
EXCLUDED_ESTIMATORS = [ "ElasticEnsemble", "KNeighborsTimeSeriesClassifier", "ProximityForest", "ProximityStump", "ProximityTree", ] EXCLUDED_TESTS = { "ShapeletTransformClassifier": ["check_fit_idempotent"], "ContractedShapeletTransform": ["check_fit_idempotent"], } TRANSFORMER = StandardScaler() TRANSFORMERS = [ ("transformer1", RowTransformer(TRANSFORMER)), ("transformer2", RowTransformer(TRANSFORMER)), ] REGRESSOR = LinearRegression() TIME_SERIES_CLASSIFIER = TimeSeriesForest(n_estimators=5, random_state=1) TIME_SERIES_CLASSIFIERS = [ ("tsf1", TIME_SERIES_CLASSIFIER), ("tsf2", TIME_SERIES_CLASSIFIER), ] FORECASTER = ExponentialSmoothing() FORECASTERS = [("ses1", FORECASTER), ("ses2", FORECASTER)] STEPS = [ ("transformer", Detrender(ThetaForecaster())), ("forecaster", NaiveForecaster()), ] ESTIMATOR_TEST_PARAMS = {