def test_y_proba_on_gunpoint(): X, y = load_gunpoint(return_X_y=True) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.1, random_state=42 ) estimator = TimeSeriesForestClassifier(random_state=42, n_estimators=20) estimator.fit(X_train, y_train) actual = estimator.predict_proba(X_test) np.testing.assert_array_equal(actual, expected)
def test_tsf_on_unit_test_data(): """Test of TimeSeriesForestClassifier on unit test data.""" # load unit test data X_train, y_train = load_unit_test(split="train") X_test, y_test = load_unit_test(split="test") indices = np.random.RandomState(0).choice(len(y_train), 10, replace=False) # train TSF tsf = TimeSeriesForestClassifier(n_estimators=10, random_state=0) tsf.fit(X_train, y_train) # assert probabilities are the same probas = tsf.predict_proba(X_test.iloc[indices]) testing.assert_array_equal(probas, tsf_unit_test_probas)
def test_teaser_near_classification_points(): """Test of TEASER with incremental time stamps outside defined class points.""" X_train, y_train, X_test, y_test, indices = load_unit_data() # train probability threshold teaser = TEASER( random_state=0, classification_points=[6, 10, 14, 18, 24], estimator=TimeSeriesForestClassifier(n_estimators=10, random_state=0), ) teaser.fit(X_train, y_train) # use test_points that are not within list above test_points = [7, 11, 19, 20] X_test = from_nested_to_3d_numpy(X_test) states = None for i in test_points: X = X_test[indices, :, :i] if i == 20: with pytest.raises(ValueError): probas, decisions, states = teaser.predict_proba( X, state_info=states) else: probas, decisions, states = teaser.predict_proba(X, state_info=states)
def test_teaser_with_different_decision_maker(): """Test of TEASER with different One-Class-Classifier.""" X_train, y_train, X_test, y_test, indices = load_unit_data() # train probability threshold teaser = TEASER( random_state=0, classification_points=[6, 10, 16, 24], estimator=TimeSeriesForestClassifier(n_estimators=10, random_state=0), one_class_classifier=IsolationForest(n_estimators=5), one_class_param_grid={"bootstrap": [True, False]}, ) teaser.fit(X_train, y_train) final_probas = np.zeros((10, 2)) final_decisions = np.zeros(10) X_test = from_nested_to_3d_numpy(X_test) states = None for i in teaser.classification_points: X = X_test[indices, :, :i] probas, decisions, states = teaser.predict_proba(X, state_info=states) for n in range(10): if decisions[n] and final_decisions[n] == 0: final_probas[n] = probas[n] final_decisions[n] = i testing.assert_array_equal(final_probas, teaser_if_unit_test_probas)
def test_run_classification_experiment(tmp_path): """Test running and saving results for classifiers. Currently it just checks the files have been created, then deletes them. """ dataset = "UnitTest" train_X, train_Y = load_unit_test("TRAIN") test_X, test_Y = load_unit_test("TEST") run_classification_experiment( train_X, train_Y, test_X, test_Y, TimeSeriesForestClassifier(n_estimators=10), str(tmp_path), cls_name="TSF", dataset="UnitTest", resample_id=0, train_file=True, ) test_path = tmp_path.joinpath( f"TSF/Predictions/{dataset}/testResample0.csv") train_path = tmp_path.joinpath( f"TSF/Predictions/{dataset}/trainResample0.csv") assert test_path.is_file() assert train_path.is_file() # remove files test_path.unlink() train_path.unlink()
def test_prob_threshold_on_unit_test_data(): """Test of ProbabilityThresholdEarlyClassifier on unit test data.""" # load unit test data X_train, y_train = load_unit_test(split="train", return_X_y=True) X_test, y_test = load_unit_test(split="test", return_X_y=True) indices = np.random.RandomState(0).choice(len(y_train), 10, replace=False) # train probability threshold pt = ProbabilityThresholdEarlyClassifier( random_state=0, classification_points=[6, 16, 24], probability_threshold=1, estimator=TimeSeriesForestClassifier(n_estimators=10, random_state=0), ) pt.fit(X_train, y_train) final_probas = np.zeros((10, 2)) final_decisions = np.zeros(10) X_test = from_nested_to_3d_numpy(X_test) states = None for i in pt.classification_points: X = X_test[indices, :, :i] probas = pt.predict_proba(X) decisions, states = pt.decide_prediction_safety(X, probas, states) for n in range(10): if decisions[n] and final_decisions[n] == 0: final_probas[n] = probas[n] final_decisions[n] = i testing.assert_array_equal(final_probas, pt_unit_test_probas)
def test_run_classification_experiment(): """Test running and saving results for classifiers. Currently it just checks the files have been created, then deletes them. """ dataset = "UnitTest" train_X, train_Y = load_unit_test("TRAIN", return_X_y=True) test_X, test_Y = load_unit_test("TEST", return_X_y=True) run_classification_experiment( train_X, train_Y, test_X, test_Y, TimeSeriesForestClassifier(n_estimators=10), "../Temp/", cls_name="TSF", dataset="UnitTest", resample_id=0, train_file=True, ) test_path = f"../Temp/TSF/Predictions/{dataset}/testResample0.csv" train_path = f"../Temp/TSF/Predictions/{dataset}/trainResample0.csv" assert os.path.isfile(test_path) assert os.path.isfile(train_path) os.remove(test_path) os.remove(train_path)
def test_teaser_on_unit_test_data(): """Test of TEASER on unit test data.""" X_train, y_train, X_test, y_test, indices = load_unit_data() # train probability threshold teaser = TEASER( random_state=0, classification_points=[6, 10, 16, 24], estimator=TimeSeriesForestClassifier(n_estimators=10, random_state=0), ) teaser.fit(X_train, y_train) final_probas = np.zeros((10, 2)) final_decisions = np.zeros(10) X_test = from_nested_to_3d_numpy(X_test) states = None for i in teaser.classification_points: X = X_test[indices, :, :i] probas, decisions, states = teaser.predict_proba(X, state_info=states) for n in range(10): if decisions[n] and final_decisions[n] == 0: final_probas[n] = probas[n] final_decisions[n] = i testing.assert_array_equal(final_probas, teaser_unit_test_probas)
def set_classifier(cls, resampleId=None): """ Basic way of creating the classifier to build using the default settings. This set up is to help with batch jobs for multiple problems to facilitate easy reproducability. You can set up bespoke classifier in many other ways. :param cls: String indicating which classifier you want :param resampleId: classifier random seed :return: A classifier. """ name = cls.lower() # Distance based if name == "pf" or name == "proximityforest": return ProximityForest(random_state=resampleId) elif name == "pt" or name == "proximitytree": return ProximityTree(random_state=resampleId) elif name == "ps" or name == "proximityStump": return ProximityStump(random_state=resampleId) elif name == "dtwcv" or name == "kneighborstimeseriesclassifier": return KNeighborsTimeSeriesClassifier(distance="dtwcv") elif name == "dtw" or name == "1nn-dtw": return KNeighborsTimeSeriesClassifier(distance="dtw") elif name == "msm" or name == "1nn-msm": return KNeighborsTimeSeriesClassifier(distance="msm") elif name == "ee" or name == "elasticensemble": return ElasticEnsemble() elif name == "shapedtw": return ShapeDTW() # Dictionary based elif name == "boss" or name == "bossensemble": return BOSSEnsemble(random_state=resampleId) elif name == "cboss" or name == "contractableboss": return ContractableBOSS(random_state=resampleId) elif name == "tde" or name == "temporaldictionaryensemble": return TemporalDictionaryEnsemble(random_state=resampleId) elif name == "weasel": return WEASEL(random_state=resampleId) elif name == "muse": return MUSE(random_state=resampleId) # Interval based elif name == "rise" or name == "randomintervalspectralforest": return RandomIntervalSpectralForest(random_state=resampleId) elif name == "tsf" or name == "timeseriesforestclassifier": return TimeSeriesForestClassifier(random_state=resampleId) elif name == "cif" or name == "canonicalintervalforest": return CanonicalIntervalForest(random_state=resampleId) elif name == "drcif": return DrCIF(random_state=resampleId) # Shapelet based elif name == "stc" or name == "shapelettransformclassifier": return ShapeletTransformClassifier( random_state=resampleId, time_contract_in_mins=1 ) elif name == "mrseql" or name == "mrseqlclassifier": return MrSEQLClassifier(seql_mode="fs", symrep=["sax", "sfa"]) elif name == "rocket": return ROCKETClassifier(random_state=resampleId) elif name == "arsenal": return Arsenal(random_state=resampleId) # Hybrid elif name == "catch22": return Catch22ForestClassifier(random_state=resampleId) elif name == "hivecotev1": return HIVECOTEV1(random_state=resampleId) else: raise Exception("UNKNOWN CLASSIFIER")
def StartTrain(self): train_files = glob.glob(self.lineEdit.text() + "\\*.csv") test_files = glob.glob(self.lineEdit_2.text() + "\\*.csv") train_li = [] for filename in train_files: df = pd.read_csv(filename, index_col=None, header=None,usecols=[2]) train_li.append(df) X_df = pd.concat(train_li, axis=1, ignore_index=True) X_df = X_df.T test_li = [] for filename in test_files: df = pd.read_csv(filename, index_col=None, header=None,usecols=[2]) test_li.append(df) X_df_ng = pd.concat(test_li, axis=1, ignore_index=True) X_df_ng = X_df_ng.T X_df = X_df.append(X_df_ng) X_df_tab = from_2d_array_to_nested(X_df) Y_df_ok = np.zeros(len(test_li), dtype="int32") Y_df_ng = np.ones(len(train_li), dtype="int32") Y_df = np.concatenate([Y_df_ok, Y_df_ng], 0) X_train, X_test, y_train, y_test = train_test_split(X_df_tab, Y_df, test_size= (100 - self.horizontalSlider.value()) / 100) self.tableWidget.setRowCount(0) selectedModel = self.comboBox.currentText() if(selectedModel == "RandomForestClassifier"): classifier = make_pipeline(Tabularizer(), RandomForestClassifier()) classifier.fit(X_train, y_train) self.lineEdit_5.setText(str(classifier.score(X_train, y_train))) self.lineEdit_6.setText(str(classifier.score(X_test, y_test))) for i in range(len(X_test)): row = self.tableWidget.rowCount() self.tableWidget.setRowCount(row) classifier_preds = classifier.predict(X_test.iloc[i].to_frame()) self.addTableRow(self.tableWidget, [str(i),str(y_test[i]), str(classifier_preds)]) elif(selectedModel == "RocketClassifier"): rocket = RocketClassifier() rocket.fit(X_train, y_train) self.lineEdit_5.setText(str(rocket.score(X_train, y_train))) self.lineEdit_6.setText(str(rocket.score(X_test, y_test))) for i in range(len(X_test)): row = self.tableWidget.rowCount() self.tableWidget.setRowCount(row) rocket_preds = rocket.predict(X_test.iloc[i].to_frame()) self.addTableRow(self.tableWidget, [str(i),str(y_test[i]), str(rocket_preds)]) elif(selectedModel == "TimeSeriesForestClassifier"): tsf = TimeSeriesForestClassifier(n_estimators=50, random_state=47) tsf.fit(X_train, y_train) self.lineEdit_5.setText(str(tsf.score(X_train, y_train))) self.lineEdit_6.setText(str(tsf.score(X_test, y_test))) for i in range(len(X_test)): row = self.tableWidget.rowCount() self.tableWidget.setRowCount(row) tsf_preds = tsf.predict(X_test.iloc[i].to_frame()) self.addTableRow(self.tableWidget, [str(i),str(y_test[i]), str(tsf_preds)]) elif(selectedModel == "RandomIntervalSpectralEnsemble"): rise = RandomIntervalSpectralEnsemble(n_estimators=50, random_state=47) rise.fit(X_train, y_train) self.lineEdit_5.setText(str(rise.score(X_train, y_train))) self.lineEdit_6.setText(str(rise.score(X_test, y_test))) for i in range(len(X_test)): row = self.tableWidget.rowCount() self.tableWidget.setRowCount(row) rise_preds = rise.predict(X_test.iloc[i].to_frame()) self.addTableRow(self.tableWidget, [str(i),str(y_test[i]), str(rise_preds)]) elif(selectedModel == "SupervisedTimeSeriesForest"): stsf = SupervisedTimeSeriesForest(n_estimators=50, random_state=47) stsf.fit(X_train, y_train) self.lineEdit_5.setText(str(stsf.score(X_train, y_train))) self.lineEdit_6.setText(str(stsf.score(X_test, y_test))) for i in range(len(X_test)): row = self.tableWidget.rowCount() self.tableWidget.setRowCount(row) stsf_preds = rise.predict(X_test.iloc[i].to_frame()) self.addTableRow(self.tableWidget, [str(i),str(y_test[i]), str(stsf_preds)]) else: print("None")
class HIVECOTEV1(BaseClassifier): """Hierarchical Vote Collective of Transformation-based Ensembles (HIVE-COTE) V1. An ensemble of the STC, TSF, RISE and cBOSS classifiers from different feature representations using the CAWPE structure as described in [1]. Parameters ---------- verbose : int, level of output printed to the console (for information only) (default = 0) n_jobs : int, optional (default=1) The number of jobs to run in parallel for both `fit` and `predict`. ``-1`` means using all processors. random_state : int or None, seed for random, integer, optional (default to no seed) Attributes ---------- n_classes : extracted from the data Notes ----- ..[1] Anthony Bagnall, Michael Flynn, James Large, Jason Lines and Matthew Middlehurst. "On the usage and performance of the Hierarchical Vote Collective of Transformation-based Ensembles version 1.0 (hive-cote v1. 0)" International Workshop on Advanced Analytics and Learning on Temporal Data 2020 Java version https://github.com/uea-machine-learning/tsml/blob/master/src/main/java/ tsml/classifiers/hybrids/HIVE_COTE.java """ # Capability tags capabilities = { "multivariate": False, "unequal_length": False, "missing_values": False, "train_estimate": False, "contractable": False, } def __init__( self, stc_params=None, tsf_params=None, rise_params=None, cboss_params=None, verbose=0, n_jobs=1, random_state=None, ): if stc_params is None: stc_params = {"n_estimators": 500} if tsf_params is None: tsf_params = {"n_estimators": 500} if rise_params is None: rise_params = {"n_estimators": 500} if cboss_params is None: cboss_params = {} self.stc_params = stc_params self.tsf_params = tsf_params self.rise_params = rise_params self.cboss_params = cboss_params self.verbose = verbose self.n_jobs = n_jobs self.random_state = random_state self.stc = None self.tsf = None self.rise = None self.cboss = None self.stc_weight = 0 self.tsf_weight = 0 self.rise_weight = 0 self.cboss_weight = 0 self.n_classes = 0 self.classes_ = [] super(HIVECOTEV1, self).__init__() def fit(self, X, y): """Fit a HIVE-COTEv1.0 classifier. Parameters ---------- X : nested pandas DataFrame of shape [n_instances, 1] Nested dataframe with univariate time-series in cells. y : array-like, shape = [n_instances] The class labels. Returns ------- self : object """ X, y = check_X_y(X, y, enforce_univariate=True) self.n_classes = np.unique(y).shape[0] self.classes_ = class_distribution(np.asarray(y).reshape(-1, 1))[0][0] cv_size = 10 _, counts = np.unique(y, return_counts=True) min_class = np.min(counts) if min_class < cv_size: cv_size = min_class self.stc = ShapeletTransformClassifier( **self.stc_params, random_state=self.random_state, ) self.stc.fit(X, y) if self.verbose > 0: print("STC ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa train_preds = cross_val_predict( ShapeletTransformClassifier( **self.stc_params, random_state=self.random_state, ), X=X, y=y, cv=cv_size, n_jobs=self.n_jobs, ) self.stc_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "STC train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("STC weight = " + str(self.stc_weight)) # noqa self.tsf = TimeSeriesForestClassifier( **self.tsf_params, random_state=self.random_state, n_jobs=self.n_jobs, ) self.tsf.fit(X, y) if self.verbose > 0: print("TSF ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa train_preds = cross_val_predict( TimeSeriesForestClassifier(**self.tsf_params, random_state=self.random_state), X=X, y=y, cv=cv_size, n_jobs=self.n_jobs, ) self.tsf_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "TSF train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("TSF weight = " + str(self.tsf_weight)) # noqa self.rise = RandomIntervalSpectralForest( **self.rise_params, random_state=self.random_state, n_jobs=self.n_jobs, ) self.rise.fit(X, y) if self.verbose > 0: print("RISE ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa train_preds = cross_val_predict( RandomIntervalSpectralForest( **self.rise_params, random_state=self.random_state, ), X=X, y=y, cv=cv_size, n_jobs=self.n_jobs, ) self.rise_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "RISE train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("RISE weight = " + str(self.rise_weight)) # noqa self.cboss = ContractableBOSS(**self.cboss_params, random_state=self.random_state, n_jobs=self.n_jobs) self.cboss.fit(X, y) train_probs = self.cboss._get_train_probs(X) train_preds = self.cboss.classes_[np.argmax(train_probs, axis=1)] self.cboss_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "cBOSS (estimate included) ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("cBOSS weight = " + str(self.cboss_weight)) # noqa self._is_fitted = True return self def predict(self, X): """Make predictions for all cases in X. Parameters ---------- X : The testing input samples of shape [n_instances,1]. Returns ------- output : numpy array of shape = [n_instances] """ rng = check_random_state(self.random_state) return np.array([ self.classes_[int(rng.choice(np.flatnonzero(prob == prob.max())))] for prob in self.predict_proba(X) ]) def predict_proba(self, X): """Make class probability estimates on each case in X. Parameters ---------- X - pandas dataframe of testing data of shape [n_instances,1]. Returns ------- output : numpy array of shape = [n_instances, num_classes] of probabilities """ self.check_is_fitted() X = check_X(X, enforce_univariate=True) dists = np.zeros((X.shape[0], self.n_classes)) dists = np.add( dists, self.stc.predict_proba(X) * (np.ones(self.n_classes) * self.stc_weight), ) dists = np.add( dists, self.tsf.predict_proba(X) * (np.ones(self.n_classes) * self.tsf_weight), ) dists = np.add( dists, self.rise.predict_proba(X) * (np.ones(self.n_classes) * self.rise_weight), ) dists = np.add( dists, self.cboss.predict_proba(X) * (np.ones(self.n_classes) * self.cboss_weight), ) return dists / dists.sum(axis=1, keepdims=True)
def fit(self, X, y): """Fit a HIVE-COTEv1.0 classifier. Parameters ---------- X : nested pandas DataFrame of shape [n_instances, 1] Nested dataframe with univariate time-series in cells. y : array-like, shape = [n_instances] The class labels. Returns ------- self : object """ X, y = check_X_y(X, y, enforce_univariate=True) self.n_classes = np.unique(y).shape[0] self.classes_ = class_distribution(np.asarray(y).reshape(-1, 1))[0][0] cv_size = 10 _, counts = np.unique(y, return_counts=True) min_class = np.min(counts) if min_class < cv_size: cv_size = min_class self.stc = ShapeletTransformClassifier( **self.stc_params, random_state=self.random_state, ) self.stc.fit(X, y) if self.verbose > 0: print("STC ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa train_preds = cross_val_predict( ShapeletTransformClassifier( **self.stc_params, random_state=self.random_state, ), X=X, y=y, cv=cv_size, n_jobs=self.n_jobs, ) self.stc_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "STC train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("STC weight = " + str(self.stc_weight)) # noqa self.tsf = TimeSeriesForestClassifier( **self.tsf_params, random_state=self.random_state, n_jobs=self.n_jobs, ) self.tsf.fit(X, y) if self.verbose > 0: print("TSF ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa train_preds = cross_val_predict( TimeSeriesForestClassifier(**self.tsf_params, random_state=self.random_state), X=X, y=y, cv=cv_size, n_jobs=self.n_jobs, ) self.tsf_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "TSF train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("TSF weight = " + str(self.tsf_weight)) # noqa self.rise = RandomIntervalSpectralForest( **self.rise_params, random_state=self.random_state, n_jobs=self.n_jobs, ) self.rise.fit(X, y) if self.verbose > 0: print("RISE ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa train_preds = cross_val_predict( RandomIntervalSpectralForest( **self.rise_params, random_state=self.random_state, ), X=X, y=y, cv=cv_size, n_jobs=self.n_jobs, ) self.rise_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "RISE train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("RISE weight = " + str(self.rise_weight)) # noqa self.cboss = ContractableBOSS(**self.cboss_params, random_state=self.random_state, n_jobs=self.n_jobs) self.cboss.fit(X, y) train_probs = self.cboss._get_train_probs(X) train_preds = self.cboss.classes_[np.argmax(train_probs, axis=1)] self.cboss_weight = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "cBOSS (estimate included) ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("cBOSS weight = " + str(self.cboss_weight)) # noqa self._is_fitted = True return self
def set_classifier(cls, resample_id=None, train_file=False): """Construct a classifier. Basic way of creating the classifier to build using the default settings. This set up is to help with batch jobs for multiple problems to facilitate easy reproducibility for use with load_and_run_classification_experiment. You can pass a classifier object instead to run_classification_experiment. Parameters ---------- cls : str String indicating which classifier you want. resample_id : int or None, default=None Classifier random seed. train_file : bool, default=False Whether a train file is being produced. Return ------ classifier : A BaseClassifier. The classifier matching the input classifier name. """ name = cls.lower() # Dictionary based if name == "boss" or name == "bossensemble": return BOSSEnsemble(random_state=resample_id) elif name == "cboss" or name == "contractableboss": return ContractableBOSS(random_state=resample_id) elif name == "tde" or name == "temporaldictionaryensemble": return TemporalDictionaryEnsemble( random_state=resample_id, save_train_predictions=train_file ) elif name == "weasel": return WEASEL(random_state=resample_id) elif name == "muse": return MUSE(random_state=resample_id) # Distance based elif name == "pf" or name == "proximityforest": return ProximityForest(random_state=resample_id) elif name == "pt" or name == "proximitytree": return ProximityTree(random_state=resample_id) elif name == "ps" or name == "proximityStump": return ProximityStump(random_state=resample_id) elif name == "dtwcv" or name == "kneighborstimeseriesclassifier": return KNeighborsTimeSeriesClassifier(distance="dtwcv") elif name == "dtw" or name == "1nn-dtw": return KNeighborsTimeSeriesClassifier(distance="dtw") elif name == "msm" or name == "1nn-msm": return KNeighborsTimeSeriesClassifier(distance="msm") elif name == "ee" or name == "elasticensemble": return ElasticEnsemble(random_state=resample_id) elif name == "shapedtw": return ShapeDTW() # Feature based elif name == "catch22": return Catch22Classifier( random_state=resample_id, estimator=RandomForestClassifier(n_estimators=500) ) elif name == "matrixprofile": return MatrixProfileClassifier(random_state=resample_id) elif name == "signature": return SignatureClassifier( random_state=resample_id, estimator=RandomForestClassifier(n_estimators=500), ) elif name == "tsfresh": return TSFreshClassifier( random_state=resample_id, estimator=RandomForestClassifier(n_estimators=500) ) elif name == "tsfresh-r": return TSFreshClassifier( random_state=resample_id, estimator=RandomForestClassifier(n_estimators=500), relevant_feature_extractor=True, ) # Hybrid elif name == "hc1" or name == "hivecotev1": return HIVECOTEV1(random_state=resample_id) elif name == "hc2" or name == "hivecotev2": return HIVECOTEV2(random_state=resample_id) # Interval based elif name == "rise" or name == "randomintervalspectralforest": return RandomIntervalSpectralEnsemble( random_state=resample_id, n_estimators=500 ) elif name == "tsf" or name == "timeseriesforestclassifier": return TimeSeriesForestClassifier(random_state=resample_id, n_estimators=500) elif name == "cif" or name == "canonicalintervalforest": return CanonicalIntervalForest(random_state=resample_id, n_estimators=500) elif name == "stsf" or name == "supervisedtimeseriesforest": return SupervisedTimeSeriesForest(random_state=resample_id, n_estimators=500) elif name == "drcif": return DrCIF( random_state=resample_id, n_estimators=500, save_transformed_data=train_file ) # Kernel based elif name == "rocket": return ROCKETClassifier(random_state=resample_id) elif name == "arsenal": return Arsenal(random_state=resample_id, save_transformed_data=train_file) # Shapelet based elif name == "stc" or name == "shapelettransformclassifier": return ShapeletTransformClassifier( random_state=resample_id, save_transformed_data=train_file ) elif name == "mrseql" or name == "mrseqlclassifier": return MrSEQLClassifier(seql_mode="fs", symrep=["sax", "sfa"]) else: raise Exception("UNKNOWN CLASSIFIER")
import numpy as np import sktime sktime.datatypes.check_is_mtype(obj, mtype) #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ # time series forest classifier from sktime.classification.interval_based import TimeSeriesForestClassifier TimeSeriesForestClassifier(n_estimators=200, min_interval=3, n_jobs=1, random_state=None|0) # cannot handle multivariate series .fit(X, y, **kwargs) .predict(X, **kwargs) .predict_proba(X, **kwargs) # example: time_series = [1,2,3,4,5,6,7,8,9] x_train = [ [1,2,3], [2,3,4], [3,4,5], [4,5,6] ] y_train = [ 1, 1, 0, 0, ] model = TimeSeriesForestClassifier(n_estimators=5, min_interval=2) model.fit(np.array(x_train), np.array(y_train)) y_pred = model.predict(np.array(x_train)) print(y_pred) # [1,1,0,0] # examine input output structure: from sktime.datasets import load_unit_test X_train, y_train = load_unit_test(split='train', return_X_y=True) X_test, y_test = load_unit_test(split='test', return_X_y=True) x = [ [list(j) for j in i] for i in X_train.to_numpy()] y = list(y_train)
_print_array( "RandomIntervalSpectralEnsemble - UnitTest", _reproduce_classification_unit_test( RandomIntervalSpectralEnsemble(n_estimators=10, random_state=0) ), ) _print_array( "SupervisedTimeSeriesForest - UnitTest", _reproduce_classification_unit_test( SupervisedTimeSeriesForest(n_estimators=10, random_state=0) ), ) _print_array( "TimeSeriesForestClassifier - UnitTest", _reproduce_classification_unit_test( TimeSeriesForestClassifier(n_estimators=10, random_state=0) ), ) _print_array( "Arsenal - UnitTest", _reproduce_classification_unit_test( Arsenal(num_kernels=200, n_estimators=5, random_state=0) ), ) _print_array( "Arsenal - BasicMotions", _reproduce_classification_basic_motions( Arsenal(num_kernels=200, n_estimators=5, random_state=0) ), ) _print_array(
class HIVECOTEV1(BaseClassifier): """Hierarchical Vote Collective of Transformation-based Ensembles (HIVE-COTE) V1. An ensemble of the STC, TSF, RISE and cBOSS classifiers from different feature representations using the CAWPE structure as described in [1]_. Parameters ---------- stc_params : dict or None, default=None Parameters for the ShapeletTransformClassifier module. If None, uses the default parameters with a 2 hour transform contract. tsf_params : dict or None, default=None Parameters for the TimeSeriesForestClassifier module. If None, uses the default parameters with n_estimators set to 500. rise_params : dict or None, default=None Parameters for the RandomIntervalSpectralForest module. If None, uses the default parameters with n_estimators set to 500. cboss_params : dict or None, default=None Parameters for the ContractableBOSS module. If None, uses the default parameters. verbose : int, default=0 Level of output printed to the console (for information only). n_jobs : int, default=1 The number of jobs to run in parallel for both `fit` and `predict`. ``-1`` means using all processors. random_state : int or None, default=None Seed for random number generation. Attributes ---------- n_classes_ : int The number of classes. classes_ : list The unique class labels. stc_weight_ : float The weight for STC probabilities. tsf_weight_ : float The weight for TSF probabilities. rise_weight_ : float The weight for RISE probabilities. cboss_weight_ : float The weight for cBOSS probabilities. See Also -------- HIVECOTEV2, ShapeletTransformClassifier, TimeSeriesForestClassifier, RandomIntervalSpectralForest, ContractableBOSS Notes ----- For the Java version, see `https://github.com/uea-machine-learning/tsml/blob/master/src/main/java/ tsml/classifiers/hybrids/HIVE_COTE.java`_. References ---------- .. [1] Anthony Bagnall, Michael Flynn, James Large, Jason Lines and Matthew Middlehurst. "On the usage and performance of the Hierarchical Vote Collective of Transformation-based Ensembles version 1.0 (hive-cote v1.0)" International Workshop on Advanced Analytics and Learning on Temporal Data 2020 Examples -------- >>> from sktime.classification.hybrid import HIVECOTEV1 >>> from sktime.contrib.vector_classifiers._rotation_forest import RotationForest >>> from sktime.datasets import load_unit_test >>> X_train, y_train = load_unit_test(split="train", return_X_y=True) >>> X_test, y_test = load_unit_test(split="test", return_X_y=True) >>> clf = HIVECOTEV1( ... stc_params={ ... "estimator": RotationForest(n_estimators=3), ... "n_shapelet_samples": 500, ... "max_shapelets": 20, ... "batch_size": 100, ... }, ... tsf_params={"n_estimators": 10}, ... rise_params={"n_estimators": 10}, ... cboss_params={"n_parameter_samples": 25, "max_ensemble_size": 5}, ... ) >>> clf.fit(X_train, y_train) HIVECOTEV1(...) >>> y_pred = clf.predict(X_test) """ _tags = { "capability:multithreading": True, } def __init__( self, stc_params=None, tsf_params=None, rise_params=None, cboss_params=None, verbose=0, n_jobs=1, random_state=None, ): self.stc_params = stc_params self.tsf_params = tsf_params self.rise_params = rise_params self.cboss_params = cboss_params self.verbose = verbose self.n_jobs = n_jobs self.random_state = random_state self.stc_weight_ = 0 self.tsf_weight_ = 0 self.rise_weight_ = 0 self.cboss_weight_ = 0 self._stc_params = stc_params self._tsf_params = tsf_params self._rise_params = rise_params self._cboss_params = cboss_params self._stc = None self._tsf = None self._rise = None self._cboss = None super(HIVECOTEV1, self).__init__() def _fit(self, X, y): """Fit HIVE-COTE 1.0 to training data. Parameters ---------- X : 3D np.array of shape = [n_instances, n_dimensions, series_length] The training data. y : array-like, shape = [n_instances] The class labels. Returns ------- self : Reference to self. Notes ----- Changes state by creating a fitted model that updates attributes ending in "_" and sets is_fitted flag to True. """ # Default values from HC1 paper if self.stc_params is None: self._stc_params = {"transform_limit_in_minutes": 120} if self.tsf_params is None: self._tsf_params = {"n_estimators": 500} if self.rise_params is None: self._rise_params = {"n_estimators": 500} if self.cboss_params is None: self._cboss_params = {} # Cross-validation size for TSF and RISE cv_size = 10 _, counts = np.unique(y, return_counts=True) min_class = np.min(counts) if min_class < cv_size: cv_size = min_class # Build STC self._stc = ShapeletTransformClassifier( **self._stc_params, save_transformed_data=True, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._stc.fit(X, y) if self.verbose > 0: print("STC ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa # Find STC weight using train set estimate train_probs = self._stc._get_train_probs(X, y) train_preds = self._stc.classes_[np.argmax(train_probs, axis=1)] self.stc_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "STC train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("STC weight = " + str(self.stc_weight_)) # noqa # Build TSF self._tsf = TimeSeriesForestClassifier( **self._tsf_params, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._tsf.fit(X, y) if self.verbose > 0: print("TSF ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa # Find TSF weight using train set estimate found through CV train_preds = cross_val_predict( TimeSeriesForestClassifier(**self._tsf_params, random_state=self.random_state), X=X, y=y, cv=cv_size, n_jobs=self._threads_to_use, ) self.tsf_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "TSF train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("TSF weight = " + str(self.tsf_weight_)) # noqa # Build RISE self._rise = RandomIntervalSpectralEnsemble( **self._rise_params, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._rise.fit(X, y) if self.verbose > 0: print("RISE ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa # Find RISE weight using train set estimate found through CV train_preds = cross_val_predict( RandomIntervalSpectralEnsemble( **self._rise_params, random_state=self.random_state, ), X=X, y=y, cv=cv_size, n_jobs=self._threads_to_use, ) self.rise_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "RISE train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("RISE weight = " + str(self.rise_weight_)) # noqa # Build cBOSS self._cboss = ContractableBOSS( **self._cboss_params, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._cboss.fit(X, y) # Find cBOSS weight using train set estimate train_probs = self._cboss._get_train_probs(X, y) train_preds = self._cboss.classes_[np.argmax(train_probs, axis=1)] self.cboss_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "cBOSS (estimate included)", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("cBOSS weight = " + str(self.cboss_weight_)) # noqa return self def _predict(self, X): """Predicts labels for sequences in X. Parameters ---------- X : 3D np.array of shape = [n_instances, n_dimensions, series_length] The data to make predictions for. Returns ------- y : array-like, shape = [n_instances] Predicted class labels. """ rng = check_random_state(self.random_state) return np.array([ self.classes_[int(rng.choice(np.flatnonzero(prob == prob.max())))] for prob in self.predict_proba(X) ]) def _predict_proba(self, X): """Predicts labels probabilities for sequences in X. Parameters ---------- X : 3D np.array of shape = [n_instances, n_dimensions, series_length] The data to make predict probabilities for. Returns ------- y : array-like, shape = [n_instances, n_classes_] Predicted probabilities using the ordering in classes_. """ dists = np.zeros((X.shape[0], self.n_classes_)) # Call predict proba on each classifier, multiply the probabilities by the # classifiers weight then add them to the current HC1 probabilities dists = np.add( dists, self._stc.predict_proba(X) * (np.ones(self.n_classes_) * self.stc_weight_), ) dists = np.add( dists, self._tsf.predict_proba(X) * (np.ones(self.n_classes_) * self.tsf_weight_), ) dists = np.add( dists, self._rise.predict_proba(X) * (np.ones(self.n_classes_) * self.rise_weight_), ) dists = np.add( dists, self._cboss.predict_proba(X) * (np.ones(self.n_classes_) * self.cboss_weight_), ) # Make each instances probability array sum to 1 and return return dists / dists.sum(axis=1, keepdims=True)
def _fit(self, X, y): """Fit HIVE-COTE 1.0 to training data. Parameters ---------- X : 3D np.array of shape = [n_instances, n_dimensions, series_length] The training data. y : array-like, shape = [n_instances] The class labels. Returns ------- self : Reference to self. Notes ----- Changes state by creating a fitted model that updates attributes ending in "_" and sets is_fitted flag to True. """ # Default values from HC1 paper if self.stc_params is None: self._stc_params = {"transform_limit_in_minutes": 120} if self.tsf_params is None: self._tsf_params = {"n_estimators": 500} if self.rise_params is None: self._rise_params = {"n_estimators": 500} if self.cboss_params is None: self._cboss_params = {} # Cross-validation size for TSF and RISE cv_size = 10 _, counts = np.unique(y, return_counts=True) min_class = np.min(counts) if min_class < cv_size: cv_size = min_class # Build STC self._stc = ShapeletTransformClassifier( **self._stc_params, save_transformed_data=True, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._stc.fit(X, y) if self.verbose > 0: print("STC ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa # Find STC weight using train set estimate train_probs = self._stc._get_train_probs(X, y) train_preds = self._stc.classes_[np.argmax(train_probs, axis=1)] self.stc_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "STC train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("STC weight = " + str(self.stc_weight_)) # noqa # Build TSF self._tsf = TimeSeriesForestClassifier( **self._tsf_params, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._tsf.fit(X, y) if self.verbose > 0: print("TSF ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa # Find TSF weight using train set estimate found through CV train_preds = cross_val_predict( TimeSeriesForestClassifier(**self._tsf_params, random_state=self.random_state), X=X, y=y, cv=cv_size, n_jobs=self._threads_to_use, ) self.tsf_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "TSF train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("TSF weight = " + str(self.tsf_weight_)) # noqa # Build RISE self._rise = RandomIntervalSpectralEnsemble( **self._rise_params, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._rise.fit(X, y) if self.verbose > 0: print("RISE ", datetime.now().strftime("%H:%M:%S %d/%m/%Y")) # noqa # Find RISE weight using train set estimate found through CV train_preds = cross_val_predict( RandomIntervalSpectralEnsemble( **self._rise_params, random_state=self.random_state, ), X=X, y=y, cv=cv_size, n_jobs=self._threads_to_use, ) self.rise_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "RISE train estimate ", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("RISE weight = " + str(self.rise_weight_)) # noqa # Build cBOSS self._cboss = ContractableBOSS( **self._cboss_params, random_state=self.random_state, n_jobs=self._threads_to_use, ) self._cboss.fit(X, y) # Find cBOSS weight using train set estimate train_probs = self._cboss._get_train_probs(X, y) train_preds = self._cboss.classes_[np.argmax(train_probs, axis=1)] self.cboss_weight_ = accuracy_score(y, train_preds)**4 if self.verbose > 0: print( # noqa "cBOSS (estimate included)", datetime.now().strftime("%H:%M:%S %d/%m/%Y"), ) print("cBOSS weight = " + str(self.cboss_weight_)) # noqa return self