diff --git a/CHANGELOG.md b/CHANGELOG.md index ace06b6e..e292e9a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## [0.10.2](https://github.com/eonu/sequentia/releases/tag/v0.10.2) + +#### Major changes + +- Add support for dependent feature warping (addresses [#124](https://github.com/eonu/sequentia/pull/124)). ([#135](https://github.com/eonu/sequentia/pull/135)) +- Add multi-processed predictions for `HMMClassifier` (addresses [#121](https://github.com/eonu/sequentia/pull/121)). ([#136](https://github.com/eonu/sequentia/pull/136)) +- Re-order `predict()` and `evaluate()` arguments. ([#138](https://github.com/eonu/sequentia/pull/138)) + +#### Minor changes + +- Add `original_labels` documentation to `KNNClassifier`. ([#133](https://github.com/eonu/sequentia/pull/133)) +- Simplify `GMMHMM` documentation. ([#134](https://github.com/eonu/sequentia/pull/134)) +- Fix posterior comment in `classifier.svg`. ([#137](https://github.com/eonu/sequentia/pull/137)) + ## [0.10.1](https://github.com/eonu/sequentia/releases/tag/v0.10.1) #### Minor changes diff --git a/README.md b/README.md index 935fcb0b..2b096231 100644 --- a/README.md +++ b/README.md @@ -58,12 +58,13 @@ The following algorithms provided within Sequentia support the use of multivaria ### Classification algorithms -- [x] Hidden Markov Models (via [`hmmlearn`](https://github.com/hmmlearn/hmmlearn))
Learning with the Baum-Welch algorithm [[1]](#references) +- [x] Hidden Markov Models (via [`hmmlearn`](https://github.com/hmmlearn/hmmlearn))
Learning with the Baum-Welch algorithm [[1]](#references) - [x] Gaussian Mixture Model emissions - [x] Linear, left-right and ergodic topologies + - [x] Multi-processed predictions - [x] Dynamic Time Warping k-Nearest Neighbors (via [`dtaidistance`](https://github.com/wannesm/dtaidistance)) - [x] Sakoe–Chiba band global warping constraint - - [x] Feature-independent warping (DTWI) + - [x] Dependent and independent feature warping (DTWD & DTWI) - [x] Custom distance-weighted predictions - [x] Multi-processed predictions diff --git a/docs/_static/classifier.svg b/docs/_static/classifier.svg index 6538744b..a802b033 100644 --- a/docs/_static/classifier.svg +++ b/docs/_static/classifier.svg @@ -1,3 +1,3 @@ -
Class

Class 1...
Class

Class 2...
Class

Class C...
Train a HMM for each class
(Baum-Welch algorithm)
Train a HMM for each class...
Calculate un-normalized posterior (likelihood prior)
for a new observation sequence
(Forward algorithm)
Calculate un-normalized posterior...
\lamb...
Find the HMM that maximizes the posterior probability of given
Find the HMM that maximizes the post...
\math...
c^{(n...
c^{(n...
c^{(n...
Split training data by class
Split training data by class
\mathb...
\mathb...
\mathb...
c'
Assign to the class represented by the model with the highest posterior
Assign O' to the class c' represente...
Viewer does not support full SVG 1.1
\ No newline at end of file +
Class

Class 1...
Class

Class 2...
Class

Class C...
Train a HMM for each class
(Baum-Welch algorithm)
Train a HMM for each class...
Calculate un-normalized posterior (likelihood prior)
for a new observation sequence
(Forward algorithm)
Calculate un-normalized posterior...
\lamb...
Find the HMM that maximizes the posterior probability of given
Find the HMM that maximizes the post...
\math...
c^{(n...
c^{(n...
c^{(n...
Split training data by class
Split training data by class
\mathb...
\mathb...
\mathb...
c'
Assign to the class represented by the model with the highest posterior
Assign O' to the class c' represente...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/sections/classifiers/gmmhmm.rst b/docs/sections/classifiers/gmmhmm.rst index bb8ac95a..2a65f74f 100644 --- a/docs/sections/classifiers/gmmhmm.rst +++ b/docs/sections/classifiers/gmmhmm.rst @@ -70,17 +70,16 @@ Note that even in the case that multiple Gaussian densities are not needed, the can be adjusted so that irrelevant Gaussians are omitted and only a single Gaussian remains. However, the default setting of the :class:`~GMMHMM` class is a single Gaussian. -Then a GMM-HMM is completely determined by the learnable parameters -:math:`\lambda=(\boldsymbol{\pi}, A, B)` where :math:`B=(C,\Pi,\Psi)` and +Then a GMM-HMM is completely determined by +:math:`\lambda=(\boldsymbol{\pi}, A, B)`, where :math:`B` is a collection of +:math:`M` emission distributions (one for each state :math:`m=1,\ldots,M`), which are each +parameterized by a collection of -- :math:`C=\big(c_1^{(m)}, \ldots, c_K^{(m)}\big)_{m=1}^M` is - a collection of the mixture weights, -- :math:`\Pi=\big(\boldsymbol\mu_1^{(m)}, \ldots, \boldsymbol\mu_K^{(m)}\big)_{m=1}^M` is - a collection of the mean vectors, -- :math:`\Psi=\big(\Sigma_1^{(m)}, \ldots, \Sigma_K^{(m)}\big)_{m=1}^M` is - a collection of the covariance matrices, +- mixture weights :math:`c_1^{(m)}, \ldots, c_K^{(m)}`, +- mean vectors :math:`\boldsymbol\mu_1^{(m)}, \ldots, \boldsymbol\mu_K^{(m)}`, +- covariance matrices :math:`\Sigma_1^{(m)}, \ldots, \Sigma_K^{(m)}`, -for every mixture component of each state of the HMM. +for each of the :math:`1,\ldots,K` mixture components of each state. Usually if :math:`K` is large enough, a mixture of :math:`K` Gaussian densities can effectively model any probability density function. With large enough :math:`K`, we can also restrict the @@ -89,8 +88,8 @@ and at the same time decrease the number of parameters that need to be updated d The covariance matrix type can be specified by a string parameter ``covariance_type`` in the :class:`~GMMHMM` constructor that takes values `'spherical'`, `'diag'`, `'full'` or `'tied'`. -The various types are explained well in this `StackExchange answer `_, -and summarized in the below image (also courtesy of the same StackExchange answerer). +The various types are explained well `here `_, +and summarized in the below image (also courtesy of the author of the response in the previous link). .. image:: /_static/covariance_types.png :alt: Covariance Types diff --git a/lib/sequentia/__init__.py b/lib/sequentia/__init__.py index e7c389e7..8a295646 100644 --- a/lib/sequentia/__init__.py +++ b/lib/sequentia/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.10.1' +__version__ = '0.10.2' from .classifiers import * from .preprocessing import * \ No newline at end of file diff --git a/lib/sequentia/classifiers/hmm/hmm_classifier.py b/lib/sequentia/classifiers/hmm/hmm_classifier.py index 8f2ef552..96d1a6c8 100644 --- a/lib/sequentia/classifiers/hmm/hmm_classifier.py +++ b/lib/sequentia/classifiers/hmm/hmm_classifier.py @@ -1,4 +1,6 @@ -import numpy as np, pickle +import tqdm, tqdm.auto, numpy as np, pickle +from joblib import Parallel, delayed +from multiprocessing import cpu_count from .gmmhmm import GMMHMM from sklearn.metrics import confusion_matrix from sklearn.preprocessing import LabelEncoder @@ -43,7 +45,7 @@ def fit(self, models): self._encoder = LabelEncoder() self._encoder.fit([model.label for model in models]) - def predict(self, X, prior='frequency', return_scores=False, original_labels=True): + def predict(self, X, prior='frequency', return_scores=False, original_labels=True, verbose=True, n_jobs=1): """Predicts the label for an observation sequence (or multiple sequences) according to maximum likelihood or posterior scores. Parameters @@ -66,6 +68,18 @@ def predict(self, X, prior='frequency', return_scores=False, original_labels=Tru original_labels: bool Whether to inverse-transform the labels to their original encoding. + verbose: bool + Whether to display a progress bar or not. + + .. note:: + If both ``verbose=True`` and ``n_jobs > 1``, then the progress bars for each process + are always displayed in the console, regardless of where you are running this function from + (e.g. a Jupyter notebook). + + n_jobs: int > 0 or -1 + | The number of jobs to run in parallel. + | Setting this to -1 will use all available CPU cores. + Returns ------- prediction(s): str/numeric or :class:`numpy:numpy.ndarray` (str/numeric) @@ -92,6 +106,9 @@ def predict(self, X, prior='frequency', return_scores=False, original_labels=Tru else: self._val.one_of(prior, ['frequency', 'uniform'], desc='prior') self._val.boolean(return_scores, desc='return_scores') + self._val.boolean(original_labels, desc='original_labels') + self._val.boolean(verbose, desc='verbose') + self._val.restricted_integer(n_jobs, lambda x: x == -1 or x > 0, 'number of jobs', '-1 or greater than zero') # Create look-up for prior probabilities if prior == 'frequency': @@ -105,10 +122,15 @@ def predict(self, X, prior='frequency', return_scores=False, original_labels=Tru # Convert single observation sequence to a singleton list X = [X] if isinstance(X, np.ndarray) else X + # Lambda for calculating the log un-normalized posteriors as a sum of the log forward probabilities (likelihoods) and log priors + posteriors = lambda x: np.array([model.forward(x) + np.log(prior[model.label]) for model in self._models]) + # Calculate log un-normalized posteriors as a sum of the log forward probabilities (likelihoods) and log priors # Perform the MAP classification rule and return labels to original encoding if necessary - posteriors = lambda x: np.array([model.forward(x) + np.log(prior[model.label]) for model in self._models]) - scores = np.array([posteriors(x) for x in X]) + n_jobs = min(cpu_count() if n_jobs == -1 else n_jobs, len(X)) + X_chunks = [list(chunk) for chunk in np.array_split(np.array(X, dtype=object), n_jobs)] + scores = Parallel(n_jobs=n_jobs)(delayed(self._chunk_predict)(i+1, posteriors, chunk, verbose) for i, chunk in enumerate(X_chunks)) + scores = np.concatenate(scores) best_idxs = np.atleast_1d(scores.argmax(axis=1)) labels = self._encoder.inverse_transform(best_idxs) if original_labels else best_idxs @@ -117,7 +139,7 @@ def predict(self, X, prior='frequency', return_scores=False, original_labels=Tru else: return (labels, scores) if return_scores else labels - def evaluate(self, X, y, prior='frequency'): + def evaluate(self, X, y, prior='frequency', verbose=True, n_jobs=1): """Evaluates the performance of the classifier on a batch of observation sequences and their labels. Parameters @@ -137,6 +159,18 @@ def evaluate(self, X, y, prior='frequency'): Alternatively, class prior probabilities can be specified in an iterable of floats, e.g. `[0.1, 0.3, 0.6]`. + verbose: bool + Whether to display a progress bar or not. + + .. note:: + If both ``verbose=True`` and ``n_jobs > 1``, then the progress bars for each process + are always displayed in the console, regardless of where you are running this function from + (e.g. a Jupyter notebook). + + n_jobs: int > 0 or -1 + | The number of jobs to run in parallel. + | Setting this to -1 will use all available CPU cores. + Returns ------- accuracy: float @@ -146,7 +180,7 @@ def evaluate(self, X, y, prior='frequency'): The confusion matrix representing the discrepancy between predicted and actual labels. """ X, y = self._val.observation_sequences_and_labels(X, y) - predictions = self.predict(X, prior=prior, return_scores=False, original_labels=False) + predictions = self.predict(X, prior=prior, return_scores=False, original_labels=False, verbose=verbose, n_jobs=n_jobs) cm = confusion_matrix(self._encoder.transform(y), predictions, labels=self._encoder.transform(self._encoder.classes_)) return np.sum(np.diag(cm)) / np.sum(cm), cm @@ -183,6 +217,13 @@ def load(cls, path): with open(path, 'rb') as file: return pickle.load(file) + def _chunk_predict(self, process, posteriors, chunk, verbose): # Requires fit + """Makes predictions (scores) for a chunk of the observation sequences, for a given subprocess.""" + return np.array([posteriors(x) for x in tqdm.auto.tqdm( + chunk, desc='Classifying examples (process {})'.format(process), + disable=not(verbose), position=process-1 + )]) + @property def models(self): try: diff --git a/lib/sequentia/classifiers/knn/knn_classifier.py b/lib/sequentia/classifiers/knn/knn_classifier.py index cf8c5049..882eace1 100644 --- a/lib/sequentia/classifiers/knn/knn_classifier.py +++ b/lib/sequentia/classifiers/knn/knn_classifier.py @@ -1,7 +1,7 @@ import warnings, tqdm, tqdm.auto, numpy as np, types, pickle, marshal from joblib import Parallel, delayed from multiprocessing import cpu_count -from dtaidistance import dtw +from dtaidistance import dtw, dtw_ndim from sklearn.metrics import confusion_matrix from sklearn.preprocessing import LabelEncoder from ...internals import _Validator @@ -20,7 +20,7 @@ class KNNClassifier: k: int > 0 Number of neighbors. - classes: array-liike of str/numeric + classes: array-like of str/numeric The complete set of possible classes/labels. weighting: 'uniform' or callable @@ -60,6 +60,9 @@ class KNNClassifier: pip install -vvv --upgrade --no-cache-dir --force-reinstall dtaidistance + independent: bool + Whether or not to allow features to be warped independently from each other. See `here `_ for a good overview of both approaches. + random_state: numpy.random.RandomState, int, optional A random state object or seed for reproducible randomness. @@ -84,7 +87,7 @@ class KNNClassifier: The complete set of possible classes/labels. """ - def __init__(self, k, classes, weighting='uniform', window=1., use_c=False, random_state=None): + def __init__(self, k, classes, weighting='uniform', window=1., use_c=False, independent=False, random_state=None): self._val = _Validator() self._k = self._val.restricted_integer( k, lambda x: x > 0, desc='number of neighbors', expected='greater than zero') @@ -116,6 +119,9 @@ def __init__(self, k, classes, weighting='uniform', window=1., use_c=False, rand warnings.warn('DTAIDistance C library not available – using Python implementation', ImportWarning) self._use_c = False + self._independent = self._val.boolean(independent, 'independent') + self._dtw = self._dtwi if independent else self._dtwd + def fit(self, X, y): """Fits the classifier by adding labeled training observation sequences. @@ -131,7 +137,7 @@ def fit(self, X, y): self._X, self._y = X, self._encoder.transform(y) self._n_features = X[0].shape[1] - def predict(self, X, verbose=True, original_labels=True, n_jobs=1): + def predict(self, X, original_labels=True, verbose=True, n_jobs=1): """Predicts the label for an observation sequence (or multiple sequences). Parameters @@ -139,6 +145,9 @@ def predict(self, X, verbose=True, original_labels=True, n_jobs=1): X: numpy.ndarray (float) or list of numpy.ndarray (float) An individual observation sequence or a list of multiple observation sequences. + original_labels: bool + Whether to inverse-transform the labels to their original encoding. + verbose: bool Whether to display a progress bar or not. @@ -165,6 +174,7 @@ def predict(self, X, verbose=True, original_labels=True, n_jobs=1): raise RuntimeError('The classifier needs to be fitted before predictions are made') X = self._val.observation_sequences(X, allow_single=True) + self._val.boolean(original_labels, desc='original_labels') self._val.boolean(verbose, desc='verbose') self._val.restricted_integer(n_jobs, lambda x: x == -1 or x > 0, 'number of jobs', '-1 or greater than zero') @@ -172,9 +182,9 @@ def predict(self, X, verbose=True, original_labels=True, n_jobs=1): distances = np.array([self._dtw(X, x) for x in tqdm.auto.tqdm(self._X, desc='Calculating distances', disable=not(verbose))]) return self._output(self._find_nearest(distances), original_labels) else: - n_jobs = cpu_count() if n_jobs == -1 else n_jobs + n_jobs = min(cpu_count() if n_jobs == -1 else n_jobs, len(X)) X_chunks = [list(chunk) for chunk in np.array_split(np.array(X, dtype=object), n_jobs)] - labels = Parallel(n_jobs=min(n_jobs, len(X)))(delayed(self._chunk_predict)(i+1, chunk, verbose) for i, chunk in enumerate(X_chunks)) + labels = Parallel(n_jobs=n_jobs)(delayed(self._chunk_predict)(i+1, chunk, verbose) for i, chunk in enumerate(X_chunks)) return self._output(np.concatenate(labels), original_labels) # Flatten the resulting array def evaluate(self, X, y, verbose=True, n_jobs=1): @@ -205,7 +215,7 @@ def evaluate(self, X, y, verbose=True, n_jobs=1): """ X, y = self._val.observation_sequences_and_labels(X, y) self._val.boolean(verbose, desc='verbose') - predictions = self.predict(X, verbose=verbose, original_labels=False, n_jobs=n_jobs) + predictions = self.predict(X, original_labels=False, verbose=verbose, n_jobs=n_jobs) cm = confusion_matrix(self._encoder.transform(y), predictions, labels=self._encoder.transform(self._encoder.classes_)) return np.sum(np.diag(cm)) / np.sum(cm), cm @@ -235,6 +245,7 @@ def save(self, path): 'weighting': marshal.dumps((self._weighting.__code__, self._weighting.__name__)), 'window': self._window, 'use_c': self._use_c, + 'independent': self._independent, 'random_state': self._random_state, 'X': self._X, 'y': self._y, @@ -259,7 +270,7 @@ def load(cls, path): data = pickle.load(file) # Check deserialized object dictionary and keys - keys = set(('k', 'classes', 'weighting', 'window', 'use_c', 'random_state', 'X', 'y', 'n_features')) + keys = set(('k', 'classes', 'weighting', 'window', 'use_c', 'independent', 'random_state', 'X', 'y', 'n_features')) if not isinstance(data, dict): raise TypeError('Expected deserialized object to be a dictionary - make sure the object was serialized with the save() function') else: @@ -277,6 +288,7 @@ def load(cls, path): weighting=weighting, window=data['window'], use_c=data['use_c'], + independent=data['independent'], random_state=data['random_state'] ) @@ -290,11 +302,16 @@ def _dtw_1d(self, a, b, window): # Requires fit """Computes the DTW distance between two univariate sequences.""" return dtw.distance(a, b, use_c=self._use_c, window=window) - def _dtw(self, A, B): # Requires fit - """Computes the multivariate DTW distance as the sum of the pairwise per-feature DTW distances.""" + def _dtwi(self, A, B): # Requires fit + """Computes the multivariate DTW distance as the sum of the pairwise per-feature DTW distances, allowing each feature to be warped independently.""" window = max(1, int(self._window * max(len(A), len(B)))) return np.sum([self._dtw_1d(A[:, i], B[:, i], window=window) for i in range(self._n_features)]) + def _dtwd(self, A, B): # Requires fit + """Computes the multivariate DTW distance so that the warping of the features depends on each other, by modifying the local distance measure.""" + window = max(1, int(self._window * max(len(A), len(B)))) + return dtw_ndim.distance(A, B, use_c=self._use_c, window=window) + def _argmax(self, a): """Same as numpy.argmax but returns all occurrences of the maximum, and is O(n) instead of O(2n). From: https://stackoverflow.com/a/58652335 @@ -391,6 +408,7 @@ def __repr__(self): ('k', repr(self._k)), ('window', repr(self._window)), ('use_c', repr(self._use_c)), + ('independent', repr(self._independent)), ('classes', repr(list(self._encoder.classes_))) ] try: diff --git a/lib/test/lib/classifiers/knn/test_knn_classifier.py b/lib/test/lib/classifiers/knn/test_knn_classifier.py index 43057888..a1a9c987 100644 --- a/lib/test/lib/classifiers/knn/test_knn_classifier.py +++ b/lib/test/lib/classifiers/knn/test_knn_classifier.py @@ -20,7 +20,8 @@ 'k=1': KNNClassifier(k=1, classes=classes, random_state=rng), 'k=2': KNNClassifier(k=2, classes=classes, random_state=rng), 'k=3': KNNClassifier(k=3, classes=classes, random_state=rng), - 'weighted': KNNClassifier(k=3, classes=classes, weighting=(lambda x: np.exp(-x)), random_state=rng) + 'weighted': KNNClassifier(k=3, classes=classes, weighting=(lambda x: np.exp(-x)), random_state=rng), + 'independent': KNNClassifier(k=1, classes=classes, independent=True, random_state=rng) } for _, clf in clfs.items(): @@ -96,6 +97,18 @@ def test_predict_single_weighted_no_verbose(capsys): assert 'Calculating distances' not in capsys.readouterr().err assert prediction == 'c1' +def test_predict_single_independent_verbose(capsys): + """Verbosely predict a single observation sequence with independent warping""" + prediction = clfs['independent'].predict(x, verbose=True) + assert 'Calculating distances' in capsys.readouterr().err + assert prediction == 'c1' + +def test_predict_single_k1_no_verbose(capsys): + """Silently predict a single observation sequence with independent warping""" + prediction = clfs['independent'].predict(x, verbose=False) + assert 'Calculating distances' not in capsys.readouterr().err + assert prediction == 'c1' + def test_predict_multiple_k1_verbose(capsys): """Verbosely predict multiple observation sequences (k=1)""" predictions = clfs['k=1'].predict(X, verbose=True) @@ -124,25 +137,37 @@ def test_predict_multiple_k3_verbose(capsys): """Verbosely predict multiple observation sequences (k=3)""" predictions = clfs['k=3'].predict(X, verbose=True) assert 'Classifying examples' in capsys.readouterr().err - assert list(predictions) == ['c1', 'c1', 'c1', 'c0', 'c0', 'c0'] + assert list(predictions) == ['c1', 'c1', 'c1', 'c1', 'c0', 'c1'] def test_predict_multiple_k3_no_verbose(capsys): """Silently predict multiple observation sequences (k=3)""" predictions = clfs['k=3'].predict(X, verbose=False) assert 'Classifying examples' not in capsys.readouterr().err - assert list(predictions) == ['c1', 'c1', 'c1', 'c0', 'c0', 'c0'] + assert list(predictions) == ['c1', 'c1', 'c1', 'c1', 'c0', 'c1'] def test_predict_multiple_weighted_verbose(capsys): """Verbosely predict multiple observation sequences (weighted)""" predictions = clfs['weighted'].predict(X, verbose=True) assert 'Classifying examples' in capsys.readouterr().err - assert list(predictions) == ['c1', 'c1', 'c0', 'c0', 'c0', 'c1'] + assert list(predictions) == ['c1', 'c1', 'c0', 'c1', 'c0', 'c1'] def test_predict_multiple_weighted_no_verbose(capsys): """Silently predict multiple observation sequences (weighted)""" predictions = clfs['weighted'].predict(X, verbose=False) assert 'Classifying examples' not in capsys.readouterr().err - assert list(predictions) == ['c1', 'c1', 'c0', 'c0', 'c0', 'c1'] + assert list(predictions) == ['c1', 'c1', 'c0', 'c1', 'c0', 'c1'] + +def test_predict_multiple_independent_verbose(capsys): + """Verbosely predict multiple observation sequences with independent warping""" + predictions = clfs['independent'].predict(X, verbose=True) + assert 'Classifying examples' in capsys.readouterr().err + assert list(predictions) == ['c1', 'c1', 'c0', 'c1', 'c1', 'c0'] + +def test_predict_multiple_independent_no_verbose(capsys): + """Silently predict multiple observation sequences with independent warping""" + predictions = clfs['independent'].predict(X, verbose=False) + assert 'Classifying examples' not in capsys.readouterr().err + assert list(predictions) == ['c1', 'c1', 'c0', 'c1', 'c1', 'c0'] def test_predict_single(): """Predict a single observation sequence and don't return the original labels""" @@ -157,12 +182,12 @@ def test_predict_single_original_labels(): def test_predict_multiple(): """Predict multiple observation sequences and don't return the original labels""" predictions = clfs['k=3'].predict(X, verbose=False, original_labels=False) - assert list(predictions) == [1, 1, 1, 0, 0, 0] + assert list(predictions) == [1, 1, 1, 1, 0, 1] def test_predict_multiple_original_labels(): """Predict multiple observation sequences and return the original labels""" predictions = clfs['k=3'].predict(X, verbose=False, original_labels=True) - assert list(predictions) == ['c1', 'c1', 'c1', 'c0', 'c0', 'c0'] + assert list(predictions) == ['c1', 'c1', 'c1', 'c1', 'c0', 'c1'] # ======================== # # KNNClassifier.evaluate() # @@ -173,8 +198,8 @@ def test_evaluate(): acc, cm = clfs['k=3'].evaluate(X, y) assert acc == 0.5 assert_equal(cm, np.array([ - [1, 1, 0, 0, 0], - [2, 2, 0, 0, 0], + [0, 2, 0, 0, 0], + [1, 3, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] @@ -249,6 +274,7 @@ def test_load_valid_no_weighting(): assert list(clf._encoder.classes_) == classes assert clf._window == 1. assert clf._use_c == False + assert clf._independent == False assert deepcopy(clf._random_state).normal() == deepcopy(rng).normal() assert_all_equal(clf._X, X) assert_equal(clf._y, clf._encoder.transform(y)) @@ -271,6 +297,7 @@ def test_load_valid_weighting(): assert list(clf._encoder.classes_) == classes assert clf._window == 1. assert clf._use_c == False + assert clf._independent == False assert deepcopy(clf._random_state).normal() == deepcopy(rng).normal() assert_all_equal(clf._X, X) assert_equal(clf._y, clf._encoder.transform(y)) diff --git a/notebooks/Pen-Tip Trajectories (Example).ipynb b/notebooks/Pen-Tip Trajectories (Example).ipynb index 5e8aadb7..cf1e023a 100644 --- a/notebooks/Pen-Tip Trajectories (Example).ipynb +++ b/notebooks/Pen-Tip Trajectories (Example).ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -56,7 +56,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -93,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -120,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -142,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -184,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -218,7 +218,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -263,7 +263,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -293,7 +293,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -323,7 +323,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -344,7 +344,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -383,7 +383,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -403,13 +403,13 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "0f3bf4349086417dbba1fba33f5fff2a", + "model_id": "3ddd5bf499294bf0bc0963ab4dbb6ece", "version_major": 2, "version_minor": 0 }, @@ -426,7 +426,7 @@ "'w'" ] }, - "execution_count": 15, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -438,13 +438,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "2be0f98157f84e43af99b6895902c651", + "model_id": "c2f3a92e26114f1fbb4d45058698b747", "version_major": 2, "version_minor": 0 }, @@ -461,8 +461,8 @@ "text": [ "w c d e a e b h s v c y w e v v w v v b o e l c d c p n h p y p m h d a y d b n m m a g o g c n l y\n", "\n", - "CPU times: user 5.16 s, sys: 229 ms, total: 5.39 s\n", - "Wall time: 5.43 s\n" + "CPU times: user 1.68 s, sys: 195 ms, total: 1.88 s\n", + "Wall time: 1.98 s\n" ] } ], @@ -482,7 +482,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -491,8 +491,8 @@ "text": [ "w c d e a e b h s v c y w e v v w v v b o e l c d c p n h p y p m h d a y d b n m m a g o g c n l y\n", "\n", - "CPU times: user 705 ms, sys: 85.8 ms, total: 791 ms\n", - "Wall time: 5.1 s\n" + "CPU times: user 721 ms, sys: 90.5 ms, total: 811 ms\n", + "Wall time: 3.24 s\n" ] } ], @@ -512,7 +512,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "metadata": { "scrolled": true }, @@ -521,8 +521,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 576 ms, sys: 20 ms, total: 596 ms\n", - "Wall time: 40.4 s\n" + "CPU times: user 556 ms, sys: 17.3 ms, total: 573 ms\n", + "Wall time: 10.1 s\n" ] } ], @@ -533,12 +533,12 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -552,7 +552,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: 97.03%\n" + "Accuracy: 97.73%\n" ] } ], @@ -568,7 +568,7 @@ "\n", "While the fast C compiled functions in the [`dtaidistance`](https://github.com/wannesm/dtaidistance) package (along with the multiprocessing capabilities of Sequentia's `KNNClassifier`) help to speed up classification **a lot**, the practical use of $k$-NN becomes more limited as the dataset grows larger. \n", "\n", - "In this case, since our dataset is relatively small, classifying all test examples was completed in $\\approx40s$, which is even faster than the HMM classifier that we show below. " + "In this case, since our dataset is relatively small, classifying all test examples was completed in $\\approx10s$, which is even faster than the HMM classifier that we show below. " ] }, { @@ -599,13 +599,13 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6daa1c40652d4c539f9fda73cebb3076", + "model_id": "30052beed780408db9e7b1f1212b6404", "version_major": 2, "version_minor": 0 }, @@ -638,7 +638,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -648,26 +648,26 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 3min 20s, sys: 16.2 s, total: 3min 36s\n", - "Wall time: 2min 2s\n" + "CPU times: user 197 ms, sys: 13.5 ms, total: 210 ms\n", + "Wall time: 55.4 s\n" ] } ], "source": [ "%%time\n", - "acc, cm = clf.evaluate(X_test, y_test)" + "acc, cm = clf.evaluate(X_test, y_test, n_jobs=-1)" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 21, "metadata": {}, "outputs": [ { diff --git a/setup.py b/setup.py index aa862eae..063e68bc 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ 'joblib>=0.14,<1' ] -VERSION = '0.10.1' +VERSION = '0.10.2' with open('README.md', 'r') as fh: long_description = fh.read()