Commit 304d6f3f authored by Antoine Guillaume's avatar Antoine Guillaume

Adding subwindow approach support

parent e3496cd6
This diff is collapsed.
...@@ -34,6 +34,12 @@ Configuration parameters are located at the beginning of CV_script, you MUST cha ...@@ -34,6 +34,12 @@ Configuration parameters are located at the beginning of CV_script, you MUST cha
To change or check the algorithms parameters, they all are redefined in custom wrapper classes to avoid errors, if a parameter is not specified in the constructor, it is left as default. To change or check the algorithms parameters, they all are redefined in custom wrapper classes to avoid errors, if a parameter is not specified in the constructor, it is left as default.
The representations methods are defined inside utils.representations and the classifications methods inside utils.classifications. The representations methods are defined inside utils.representations and the classifications methods inside utils.classifications.
To change the parameter of TS-CHIEF, you can change the values of the following arguments in the ts-chief script:
```bash
-trees="300" -s="ee:4,boss:50,rise:50"
```
If you want to give more predictive power to this algorithm, increasing the number of trees and the number of random split generated by each method (boss, rise, ...) is the way to go. We used those value to avoid memory errors, the shorter the input time series, the higher those values can be without causing trouble.
## Usage ## Usage
Extract the files of the dataset archive located in ~/datasets in the dataset folder Extract the files of the dataset archive located in ~/datasets in the dataset folder
...@@ -74,8 +80,6 @@ by ...@@ -74,8 +80,6 @@ by
from sktime.utils.data_container import tabularize, from_3d_numpy_to_nested from sktime.utils.data_container import tabularize, from_3d_numpy_to_nested
``` ```
* We also modified InceptionTime to use binary_crossentropy (change loss name and use sigmod layer with 1 neuron as an output) and weighted accuracy for early stopping. This is not mandatory but is more suited to our problem.
## Contributing ## Contributing
If any bug should occur, please open a issue so we can work on a fix ! If any bug should occur, please open a issue so we can work on a fix !
......
#!/bin/bash #!/bin/bash
n_cv=9 n_cv=9
n_r=4 n_r=4
size=1000 size=1513
for id_r in `seq 1 $n_r` for id_r in `seq 1 $n_r`
do do
for id_cv in `seq 0 $n_cv` for id_cv in `seq 0 $n_cv`
do do
jdk/jdk-15/bin/java -jar tschief.jar -train="datasets/TSCHIEF/data_Train_"$size"_"$id_cv"_R"$id_r".csv" -test="datasets/TSCHIEF/data_Test_"$size"_"$id_cv"_R"$id_r".csv" -out="results/TSCHIEF/" -repeats="1" -trees="500" -s="ee:10,boss:150,rise:150" -export="1" -verbosity="1" -shuffle="True" -target_column="last" jdk/jdk-15/bin/java -Xms6G -Xmx12G -jar tschief.jar -train="datasets/TSCHIEF/data_Train_"$size"_"$id_cv"_R"$id_r".csv" -test="datasets/TSCHIEF/data_Test_"$size"_"$id_cv"_R"$id_r".csv" -out="results/TSCHIEF/" -repeats="1" -trees="300" -s="ee:4,boss:50,rise:50" -export="1" -verbosity="1" -shuffle="True" -target_column="last"
done done
done done
...@@ -9,7 +9,7 @@ from sklearn.svm import SVC ...@@ -9,7 +9,7 @@ from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import RidgeClassifier from sklearn.linear_model import RidgeClassifier
from sktime.classification.interval_based import TimeSeriesForest from sktime.classification.interval_based import TimeSeriesForest
from sktime.utils.data_container import concat_nested_arrays as cna from sktime.utils.data_container import _concat_nested_arrays as cna
from sktime.classification.frequency_based import RandomIntervalSpectralForest from sktime.classification.frequency_based import RandomIntervalSpectralForest
from sklearn.base import BaseEstimator, ClassifierMixin from sklearn.base import BaseEstimator, ClassifierMixin
...@@ -58,14 +58,13 @@ class ResNetV2(BaseEstimator, ClassifierMixin): ...@@ -58,14 +58,13 @@ class ResNetV2(BaseEstimator, ClassifierMixin):
classes=1, classes=1,
classifier_activation="sigmoid", classifier_activation="sigmoid",
) )
model.compile(optimizer=self.optimizer, loss=self.loss, weighted_metrics=['accuracy']) model.compile(optimizer=self.optimizer, loss=self.loss, metrics=['accuracy'])
self.model = model self.model = model
def fit(self, X, y, epochs=1000, batch_size=32, return_hist=False, el_patience=70, verbose=0, val_size=0.1): def fit(self, X, y, epochs=1500, batch_size=32, return_hist=False, el_patience=100, verbose=0, val_size=0.1):
self.init_model((X.shape[1], X.shape[2], X.shape[3])) self.init_model((X.shape[1], X.shape[2], X.shape[3]))
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=val_size) X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=val_size)
el = EarlyStopping(monitor='val_accuracy', patience=el_patience, restore_best_weights=True, mode='max') el = EarlyStopping(monitor='val_loss', patience=el_patience, restore_best_weights=True, mode='min')
cw = compute_class_weight('balanced', np.unique(y_train), y_train)
self.model.fit( self.model.fit(
X_train, y_train, X_train, y_train,
...@@ -74,8 +73,7 @@ class ResNetV2(BaseEstimator, ClassifierMixin): ...@@ -74,8 +73,7 @@ class ResNetV2(BaseEstimator, ClassifierMixin):
batch_size=batch_size, batch_size=batch_size,
verbose=verbose, verbose=verbose,
callbacks=[el], callbacks=[el],
shuffle=True, shuffle=True
class_weight={0:cw[0],1:cw[1]}
) )
return self return self
...@@ -85,7 +83,7 @@ class ResNetV2(BaseEstimator, ClassifierMixin): ...@@ -85,7 +83,7 @@ class ResNetV2(BaseEstimator, ClassifierMixin):
def predict_proba(self,X): def predict_proba(self,X):
return self.model.predict(X) return self.model.predict(X)
#Depending on your sktime_dl version, this might throw import errors, see Readme for a fix.
from sktime_dl.deeplearning.inceptiontime._classifier import InceptionTimeClassifier from sktime_dl.deeplearning.inceptiontime._classifier import InceptionTimeClassifier
...@@ -100,8 +98,8 @@ class InceptionTime(BaseEstimator, ClassifierMixin): ...@@ -100,8 +98,8 @@ class InceptionTime(BaseEstimator, ClassifierMixin):
el_patience=100, verbose=False, val_size=0.1): el_patience=100, verbose=False, val_size=0.1):
self.model = InceptionTimeClassifier(verbose=verbose, depth=self.depth, self.model = InceptionTimeClassifier(verbose=verbose, depth=self.depth,
nb_filters=self.nb_filters, bottleneck_size=self.bottleneck_size, nb_filters=self.nb_filters, bottleneck_size=self.bottleneck_size,
callbacks=[EarlyStopping(monitor='val_accuracy', patience=el_patience, callbacks=[EarlyStopping(monitor='val_loss', patience=el_patience,
restore_best_weights=True, mode='max')]) restore_best_weights=True, mode='min')])
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=val_size) X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=val_size)
self.model.fit(X_train, y_train, validation_X=X_val,validation_y=y_val) self.model.fit(X_train, y_train, validation_X=X_val,validation_y=y_val)
...@@ -141,7 +139,8 @@ class RISE(BaseEstimator, ClassifierMixin, SktimeEstimator): ...@@ -141,7 +139,8 @@ class RISE(BaseEstimator, ClassifierMixin, SktimeEstimator):
def fit(self,X,y): def fit(self,X,y):
X, y = self._sktime_format(X,y) X, y = self._sktime_format(X,y)
self.estimator = RandomIntervalSpectralForest(n_estimators=self.n_estimators, min_interval=self.min_length) self.estimator = RandomIntervalSpectralForest(n_estimators=self.n_estimators,
min_interval=self.min_length)
self.estimator.fit(X,y) self.estimator.fit(X,y)
return self return self
...@@ -155,11 +154,10 @@ class RISE(BaseEstimator, ClassifierMixin, SktimeEstimator): ...@@ -155,11 +154,10 @@ class RISE(BaseEstimator, ClassifierMixin, SktimeEstimator):
class Random_Forest(BaseEstimator, ClassifierMixin): class Random_Forest(BaseEstimator, ClassifierMixin):
def __init__(self, n_estimators=300, max_depth=None, max_features=0.75, max_samples=0.75, def __init__(self, n_estimators=300, max_depth=None, max_samples=0.75,
ccp_alpha=0.0225, class_weight="balanced_subsample"): ccp_alpha=0.0225, class_weight="balanced_subsample"):
self.n_estimators=n_estimators self.n_estimators=n_estimators
self.max_depth=max_depth self.max_depth=max_depth
self.max_features=max_features
self.max_samples=max_samples self.max_samples=max_samples
self.ccp_alpha=ccp_alpha self.ccp_alpha=ccp_alpha
self.class_weight=class_weight self.class_weight=class_weight
...@@ -167,9 +165,11 @@ class Random_Forest(BaseEstimator, ClassifierMixin): ...@@ -167,9 +165,11 @@ class Random_Forest(BaseEstimator, ClassifierMixin):
def fit(self, X, y): def fit(self, X, y):
X = np.asarray([x.astype(np.float32) for x in X]) X = np.asarray([x.astype(np.float32) for x in X])
self.estimator = RandomForestClassifier(n_estimators=self.n_estimators, max_depth=self.max_depth, self.estimator = RandomForestClassifier(n_estimators=self.n_estimators,
max_features=self.max_features, max_samples=self.max_samples, max_depth=self.max_depth,
ccp_alpha=self.ccp_alpha,class_weight=self.class_weight) max_samples=self.max_samples,
ccp_alpha=self.ccp_alpha,
class_weight=self.class_weight)
self.estimator.fit(X,y) self.estimator.fit(X,y)
return self return self
...@@ -183,14 +183,15 @@ class Random_Forest(BaseEstimator, ClassifierMixin): ...@@ -183,14 +183,15 @@ class Random_Forest(BaseEstimator, ClassifierMixin):
return self.estimator.predict_proba(X) return self.estimator.predict_proba(X)
class KNN_classif(BaseEstimator, ClassifierMixin): class KNN_classif(BaseEstimator, ClassifierMixin):
def __init__(self, n_neighbors=9, weights='distance',p=2): def __init__(self, n_neighbors=7, weights='distance',p=2):
self.n_neighbors = n_neighbors self.n_neighbors = n_neighbors
self.weights = weights self.weights = weights
self.p = p self.p = p
self.estimator = None self.estimator = None
def fit(self,X,y): def fit(self,X,y):
self.estimator = KNeighborsClassifier(n_neighbors=self.n_neighbors, weights=self.weights, p=self.p) self.estimator = KNeighborsClassifier(n_neighbors=self.n_neighbors,
weights=self.weights, p=self.p)
self.estimator.fit(X,y) self.estimator.fit(X,y)
return self return self
...@@ -201,7 +202,7 @@ class KNN_classif(BaseEstimator, ClassifierMixin): ...@@ -201,7 +202,7 @@ class KNN_classif(BaseEstimator, ClassifierMixin):
return self.estimator.predict_proba(X) return self.estimator.predict_proba(X)
class TimeSeries_Forest(BaseEstimator, ClassifierMixin, SktimeEstimator): class TimeSeries_Forest(BaseEstimator, ClassifierMixin, SktimeEstimator):
def __init__(self, n_estimators=300, min_interval=3): def __init__(self, n_estimators=300, min_interval=5):
self.n_estimators = n_estimators self.n_estimators = n_estimators
self.min_interval = min_interval self.min_interval = min_interval
self.estimator = None self.estimator = None
...@@ -228,7 +229,7 @@ class SVM_classif(BaseEstimator, ClassifierMixin): ...@@ -228,7 +229,7 @@ class SVM_classif(BaseEstimator, ClassifierMixin):
cache_size=500, class_weight='balanced'): cache_size=500, class_weight='balanced'):
self.C = C self.C = C
self.kernel = kernel self.kernel = kernel
self.degree = degree self.degree = degree #Not used with RBF
self.gamma = gamma self.gamma = gamma
self.cache_size = cache_size self.cache_size = cache_size
self.class_weight = class_weight self.class_weight = class_weight
...@@ -275,7 +276,7 @@ class Ridge_classif(BaseEstimator, ClassifierMixin): ...@@ -275,7 +276,7 @@ class Ridge_classif(BaseEstimator, ClassifierMixin):
return self.estimator.predict_proba(X) return self.estimator.predict_proba(X)
class KNN_TS_classif(BaseEstimator, ClassifierMixin, PytsEstimator): class KNN_TS_classif(BaseEstimator, ClassifierMixin, PytsEstimator):
def __init__(self, n_neighbors=9, weights='distance', p=2): def __init__(self, n_neighbors=7, weights='distance', p=2):
self.n_neighbors = n_neighbors self.n_neighbors = n_neighbors
self.weights = weights self.weights = weights
self.p = p self.p = p
...@@ -296,11 +297,10 @@ class KNN_TS_classif(BaseEstimator, ClassifierMixin, PytsEstimator): ...@@ -296,11 +297,10 @@ class KNN_TS_classif(BaseEstimator, ClassifierMixin, PytsEstimator):
X = self._format_X(X) X = self._format_X(X)
return self.estimator.predict_proba(X) return self.estimator.predict_proba(X)
class BOSSVS_classif(BaseEstimator, ClassifierMixin, PytsEstimator): class BOSSVS_classif(BaseEstimator, ClassifierMixin, PytsEstimator):
def __init__(self, word_size=9, n_bins=7, window_size=0.2, window_step=1, def __init__(self, word_size=5, n_bins=5, window_size=0.15, window_step=0.01,
anova=True, drop_sum=False, norm_mean=False, norm_std=False, anova=True, drop_sum=False, norm_mean=False, norm_std=False,
strategy='uniform', alphabet=None): strategy='quantile', alphabet=None,smooth_idf=True):
self.word_size = word_size self.word_size = word_size
self.n_bins = n_bins self.n_bins = n_bins
self.window_size = window_size self.window_size = window_size
...@@ -311,6 +311,7 @@ class BOSSVS_classif(BaseEstimator, ClassifierMixin, PytsEstimator): ...@@ -311,6 +311,7 @@ class BOSSVS_classif(BaseEstimator, ClassifierMixin, PytsEstimator):
self.norm_std = norm_std self.norm_std = norm_std
self.strategy = strategy self.strategy = strategy
self.alphabet = alphabet self.alphabet = alphabet
self.smooth_idf = smooth_idf
self.estimator = None self.estimator = None
def fit(self,X,y): def fit(self,X,y):
...@@ -319,7 +320,8 @@ class BOSSVS_classif(BaseEstimator, ClassifierMixin, PytsEstimator): ...@@ -319,7 +320,8 @@ class BOSSVS_classif(BaseEstimator, ClassifierMixin, PytsEstimator):
window_size=self.window_size, window_step=self.window_step, window_size=self.window_size, window_step=self.window_step,
anova=self.anova, drop_sum=self.drop_sum, anova=self.anova, drop_sum=self.drop_sum,
norm_mean=self.norm_mean, norm_std=self.norm_std, norm_mean=self.norm_mean, norm_std=self.norm_std,
strategy=self.strategy, alphabet=self.alphabet) strategy=self.strategy, alphabet=self.alphabet,
smooth_idf=self.smooth_idf)
self.estimator.fit(X,y) self.estimator.fit(X,y)
return self return self
......
...@@ -109,7 +109,7 @@ class PiecewiseApproximation_transform(BaseEstimator, TransformerMixin): ...@@ -109,7 +109,7 @@ class PiecewiseApproximation_transform(BaseEstimator, TransformerMixin):
return self return self
class SymbolicAggregate_transform(BaseEstimator, TransformerMixin): class SymbolicAggregate_transform(BaseEstimator, TransformerMixin):
def __init__(self, n_bins=7, strategy='uniform', alphabet='ordinal'): def __init__(self, n_bins=5, strategy='uniform', alphabet='ordinal'):
self.n_bins = n_bins self.n_bins = n_bins
self.strategy = strategy self.strategy = strategy
self.alphabet = alphabet self.alphabet = alphabet
...@@ -128,8 +128,8 @@ class SymbolicAggregate_transform(BaseEstimator, TransformerMixin): ...@@ -128,8 +128,8 @@ class SymbolicAggregate_transform(BaseEstimator, TransformerMixin):
return self return self
class SymbolicFourrier_transform(BaseEstimator, TransformerMixin): class SymbolicFourrier_transform(BaseEstimator, TransformerMixin):
def __init__(self, n_coefs=20, n_bins=7, strategy='uniform', drop_sum=False, def __init__(self, n_coefs=10, n_bins=5, strategy='uniform', drop_sum=True,
anova=True, norm_mean=True, norm_std=False, alphabet='ordinal'): anova=True, norm_mean=False, norm_std=False, alphabet='ordinal'):
self.n_coefs = n_coefs self.n_coefs = n_coefs
self.n_bins = n_bins self.n_bins = n_bins
self.strategy = strategy self.strategy = strategy
...@@ -156,7 +156,7 @@ class SymbolicFourrier_transform(BaseEstimator, TransformerMixin): ...@@ -156,7 +156,7 @@ class SymbolicFourrier_transform(BaseEstimator, TransformerMixin):
class MatrixProfile_transform(): class MatrixProfile_transform():
def __init__(self, window_size=0.075): def __init__(self, window_size=0.15):
self.window_size = window_size self.window_size = window_size
def transform(self, X, y=None): def transform(self, X, y=None):
...@@ -170,7 +170,7 @@ class MatrixProfile_transform(): ...@@ -170,7 +170,7 @@ class MatrixProfile_transform():
return self return self
class ROCKET_transform(BaseEstimator, TransformerMixin): class ROCKET_transform(BaseEstimator, TransformerMixin):
def __init__(self, n_kernels=15000, kernel_sizes=(5,7,9), flatten=False): def __init__(self, n_kernels=20000, kernel_sizes=(5,7,9,11), flatten=False):
self.flatten = flatten self.flatten = flatten
self.n_kernels = n_kernels self.n_kernels = n_kernels
self.kernel_sizes = kernel_sizes self.kernel_sizes = kernel_sizes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment