pychronicles 0.1.5__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pychronicles-0.1.5/pychronicles.egg-info → pychronicles-0.2.0}/PKG-INFO +88 -79
- pychronicles-0.2.0/README.md +362 -0
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles/__init__.py +3 -2
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles/abstraction.py +59 -25
- pychronicles-0.2.0/pychronicles/chronicle.py +1268 -0
- pychronicles-0.2.0/pychronicles/fchronicle.py +504 -0
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles/mtlformula.py +48 -7
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles/pandas_tpatterns.py +149 -87
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles/timedsequence.py +61 -22
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles/utils.py +38 -24
- {pychronicles-0.1.5 → pychronicles-0.2.0/pychronicles.egg-info}/PKG-INFO +88 -79
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles.egg-info/SOURCES.txt +7 -2
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles.egg-info/requires.txt +1 -0
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pyproject.toml +20 -4
- pychronicles-0.2.0/setup.py +7 -0
- pychronicles-0.2.0/tests/test_abstraction.py +138 -0
- pychronicles-0.2.0/tests/test_chronicle.py +1012 -0
- pychronicles-0.2.0/tests/test_fchronicle.py +312 -0
- pychronicles-0.2.0/tests/test_mtlformula.py +52 -0
- pychronicles-0.2.0/tests/test_pandas_tpatterns.py +226 -0
- pychronicles-0.2.0/tests/test_projection.py +60 -0
- pychronicles-0.2.0/tests/test_timedsequences.py +154 -0
- pychronicles-0.2.0/tests/test_utils_crs.py +95 -0
- pychronicles-0.1.5/README.md +0 -360
- pychronicles-0.1.5/pychronicles/chronicle.py +0 -1135
- pychronicles-0.1.5/pychronicles/fchronicle.py +0 -357
- pychronicles-0.1.5/tests/test_abstraction.py +0 -50
- pychronicles-0.1.5/tests/test_pandas.py +0 -51
- pychronicles-0.1.5/tests/test_projection.py +0 -60
- pychronicles-0.1.5/tests/test_timedsequences.py +0 -147
- {pychronicles-0.1.5 → pychronicles-0.2.0}/LICENCE.txt +0 -0
- {pychronicles-0.1.5 → pychronicles-0.2.0}/MANIFEST.in +0 -0
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles.egg-info/dependency_links.txt +0 -0
- {pychronicles-0.1.5 → pychronicles-0.2.0}/pychronicles.egg-info/top_level.txt +0 -0
- {pychronicles-0.1.5 → pychronicles-0.2.0}/setup.cfg +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pychronicles
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A package for chronicle recognition
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A package for chronicle recognition.
|
|
5
5
|
Author-email: Thomas Guyet <thomas.guyet@inria.fr>
|
|
6
6
|
Maintainer-email: Thomas Guyet <thomas.guyet@inria.fr>
|
|
7
7
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
@@ -177,6 +177,11 @@ Keywords: data analysis,pattern,timed sequence,temporal data
|
|
|
177
177
|
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
|
|
178
178
|
Classifier: Programming Language :: Python
|
|
179
179
|
Classifier: Programming Language :: Python :: 3
|
|
180
|
+
Classifier: Programming Language :: Python :: 3
|
|
181
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
182
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
183
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
184
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
180
185
|
Classifier: Operating System :: OS Independent
|
|
181
186
|
Requires-Python: >=3.7
|
|
182
187
|
Description-Content-Type: text/markdown
|
|
@@ -197,6 +202,8 @@ Requires-Dist: build; extra == "build"
|
|
|
197
202
|
Requires-Dist: twine; extra == "build"
|
|
198
203
|
Provides-Extra: dev
|
|
199
204
|
Requires-Dist: pytest; extra == "dev"
|
|
205
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
206
|
+
Dynamic: license-file
|
|
200
207
|
|
|
201
208
|
---
|
|
202
209
|
title: README
|
|
@@ -206,18 +213,19 @@ author: Thomas Guyet
|
|
|
206
213
|
[](https://badge.fury.io/py/pychronicles)
|
|
207
214
|
[](https://pepy.tech/project/pychronicles)
|
|
208
215
|
[](https://www.gnu.org/licenses/lgpl-3.0.txt)
|
|
209
|
-
|
|
216
|
+
[](https://gitlab.inria.fr/tguyet/pychronicles/-/commits/master)
|
|
217
|
+
[](https://mybinder.org/v2/git/https%3A%2F%2Fgitlab.inria.fr%2Ftguyet%2Fpychronicles/HEAD?labpath=examples%2Fcarepathway_example.ipynb)
|
|
210
218
|
|
|
211
219
|
# PyChronicles package
|
|
212
220
|
|
|
213
|
-
A chronicle is a specification of
|
|
214
|
-
It can be used to recognize complex behaviors in
|
|
215
|
-
|
|
221
|
+
A chronicle is a specification of complex temporal behaviors as a graph of temporal constraints. More specifically, a chronicle is a multiset of events and a set of temporal constraints specifying that the occurrences of pairs of events must occur within given temporal intervals.
|
|
222
|
+
It can be used to recognize complex behaviors in sequences of temporal events.
|
|
223
|
+
PyChronicles is now compatible with Pandas and makes chronicle features [available on dataframes](#dataframe-accessor) representing timed sequences.
|
|
216
224
|
|
|
217
|
-
This library
|
|
218
|
-
The Abstracter class
|
|
225
|
+
This library provides Python classes to define timed sequences and chronicles, and to read/save chronicles in the standard CRS format. The main functionality for chronicles is their efficient matching in timed sequences, or in pandas dataframes (through an accessor).
|
|
226
|
+
The `Abstracter` class makes it possible to create a chronicle from a collection of sequences.
|
|
219
227
|
|
|
220
|
-
For more details about the usage of this package, have a look at the [documentation](https://tguyet.gitlabpages.inria.fr/pychronicles/).
|
|
228
|
+
For more details about the usage of this package, have a look at the [documentation](https://tguyet.gitlabpages.inria.fr/pychronicles/). For more (formal) information about the temporal model of chronicles, see our [book](https://link.springer.com/book/10.1007/978-3-031-33693-5):
|
|
221
229
|
~~~bibtex
|
|
222
230
|
@book{chroniclesbook,
|
|
223
231
|
title = {Chronicles: Formalization of a Temporal Model},
|
|
@@ -230,7 +238,7 @@ For more details about the usage of this package, have a look at the [documentat
|
|
|
230
238
|
|
|
231
239
|
## Package installation
|
|
232
240
|
|
|
233
|
-
The [PyChronicles package](https://pypi.org/project/
|
|
241
|
+
The [PyChronicles package](https://pypi.org/project/pychronicles) is available in the [Python Package Index](https://pypi.org/) and can be installed using any standard Python package manager.
|
|
234
242
|
~~~sh
|
|
235
243
|
pip install pychronicles
|
|
236
244
|
~~~
|
|
@@ -244,14 +252,14 @@ pip install -r requirements.txt
|
|
|
244
252
|
pip install --upgrade .
|
|
245
253
|
~~~
|
|
246
254
|
|
|
247
|
-
|
|
255
|
+
Alternatively, you can install the repository from sources with pip only:
|
|
248
256
|
~~~sh
|
|
249
257
|
git clone --recursive https://gitlab.inria.fr/tguyet/pychronicles
|
|
250
258
|
cd pychronicles
|
|
251
259
|
pip install .
|
|
252
260
|
~~~
|
|
253
261
|
|
|
254
|
-
In case you want to visualize chronicles, you
|
|
262
|
+
In case you want to visualize chronicles, you need to install `networkx` and `matplotlib` manually. By default, they are not installed and the plotting function is disabled.
|
|
255
263
|
~~~sh
|
|
256
264
|
pip install networkx matplotlib
|
|
257
265
|
~~~
|
|
@@ -259,20 +267,21 @@ pip install networkx matplotlib
|
|
|
259
267
|
## Basic Usage Example
|
|
260
268
|
|
|
261
269
|
```python
|
|
262
|
-
import
|
|
270
|
+
import numpy as np
|
|
271
|
+
from pychronicles import TimedSequence, Chronicle
|
|
263
272
|
|
|
264
273
|
# create a timed sequence
|
|
265
274
|
seq = [('a',1),('c',2),('b',3),('a',8)]
|
|
266
|
-
ts = TimedSequence(np.array([e[
|
|
275
|
+
ts = TimedSequence(np.array([e[1] for e in seq], dtype='float'), np.array([e[0] for e in seq]))
|
|
267
276
|
|
|
268
|
-
#create a chronicle
|
|
277
|
+
# create a chronicle
|
|
269
278
|
c=Chronicle()
|
|
270
279
|
c.add_event(0,'a')
|
|
271
280
|
c.add_event(1,'b')
|
|
272
281
|
c.add_constraint(0,1, (0.4,2.3))
|
|
273
282
|
|
|
274
283
|
reco=c.match(ts)
|
|
275
|
-
print(f"Does the chronicle
|
|
284
|
+
print(f"Does the chronicle match the sequence? [{reco}]")
|
|
276
285
|
|
|
277
286
|
reco=c.recognize(ts)
|
|
278
287
|
print(f"What are the occurrences of the chronicle in the sequence? [{reco}]")
|
|
@@ -281,46 +290,46 @@ print(f"What are the occurrences of the chronicle in the sequence? [{reco}]")
|
|
|
281
290
|
|
|
282
291
|
## Efficient chronicle recognition
|
|
283
292
|
|
|
284
|
-
The chronicle recognition package is a pure
|
|
293
|
+
The chronicle recognition package is a pure Python package implemented using numpy features.
|
|
285
294
|
|
|
286
295
|
### Timed Sequences
|
|
287
296
|
|
|
288
|
-
A timed sequence is
|
|
289
|
-
* a pair of lists containing the events and the dates.
|
|
290
|
-
* a simple list of items (`str`, `int` or `None`) with implicit timestamps : `['a', 'b', ..., None, 'c', None, 'd']`. In this case, `None` means that there is no event at the corresponding time instant.
|
|
291
|
-
* a list of explicitly timestamped items (`str` or `int`) : `[ (1,'a'), (23,'b'), (30,'c'), (45, 'd')]`
|
|
297
|
+
A timed sequence is created from a pair of arrays: a numpy array containing the dates, and an array containing the events (with the same length).
|
|
292
298
|
|
|
293
|
-
The dates can be represented with dates (only with `np.datetime64` type) or floats.
|
|
299
|
+
The dates can be represented with dates (only with the `np.datetime64` type) or with floats. Integer dates must be converted into floats (the pandas accessor does it automatically).
|
|
294
300
|
|
|
295
|
-
The type of events must be `str` or `int`.
|
|
301
|
+
The type of the events must be `str` or `int`.
|
|
296
302
|
|
|
297
303
|
_Usage Example_:
|
|
298
304
|
```python
|
|
299
305
|
>>> seq = [('a',1),('c',2),('b',3),('a',8),('a',10),('b',12),('a',15),('c',17), ('b',20),('c',23),('c',25),('b',26),('c',28),('b',30)]
|
|
300
306
|
>>> dates = np.array([np.datetime64('1970-01-01') + np.timedelta64(e[1],'D') for e in seq], dtype='datetime64')
|
|
301
307
|
>>> data = np.array([e[0] for e in seq])
|
|
302
|
-
>>>
|
|
308
|
+
>>> ts = TimedSequence(dates, data)
|
|
303
309
|
```
|
|
304
310
|
|
|
305
311
|
### Chronicles
|
|
306
312
|
|
|
307
|
-
The core of
|
|
313
|
+
The core of this package is the `Chronicle` class, which represents the chronicle temporal model and offers efficient matching functionalities.
|
|
308
314
|
|
|
309
315
|
|
|
310
|
-
|
|
311
|
-
*
|
|
312
|
-
*
|
|
316
|
+
Chronicles handle two models of time (which must be consistent with the model of time of the timed sequences):
|
|
317
|
+
* numerical timestamps using floats,
|
|
318
|
+
* dates using the `datetime64` format. In this case, the temporal constraints of a chronicle must be defined using `np.timedelta64` values.
|
|
313
319
|
|
|
314
|
-
A chronicle
|
|
320
|
+
A chronicle cannot combine constraints of the two different kinds. The first defined constraint defines the model of time of the chronicle.
|
|
315
321
|
|
|
316
322
|
<br>
|
|
317
323
|
|
|
318
|
-
The package implements efficient algorithms to recognize
|
|
324
|
+
The package implements efficient algorithms to recognize chronicles. There are three different ways to _recognize_ a chronicle in a sequence of events:
|
|
325
|
+
|
|
326
|
+
* the absence/presence recognition (`c.match(seq)`): its result is a boolean stating whether the chronicle occurs at least once in the sequence. This is the most efficient algorithm, as it stops as soon as an occurrence is found.
|
|
327
|
+
* the occurrence enumeration (`c.recognize(seq)`): its result is the list of the occurrences of the chronicle in the sequence. Contrary to the first function, it looks for all the possible combinations of events. Thus, it is less efficient, but more informative.
|
|
328
|
+
* the lazy occurrence enumeration (`c.iter_recognize(seq)`): it returns an iterator over the same occurrences, which are computed on demand. This is useful to process the occurrences one at a time, or to stop the enumeration early.
|
|
319
329
|
|
|
320
|
-
|
|
321
|
-
* the occurrence enumeration (`c.recognize(seq)`): its result is a list of occurrences of the chronicle in a sequence. Contrary to the first function, it looks for all possible combination of events. Thus it is less efficient, but more informative.
|
|
330
|
+
In an occurrence, two identical events of a chronicle cannot match the same event of the sequence.
|
|
322
331
|
|
|
323
|
-
Note that a chronicle is somehow similar to a simple temporal network and the set of constraints may be inconsistent or redundant. It is possible to _minimize_ the temporal constraints of a chronicle using the corresponding function.
|
|
332
|
+
Note that a chronicle is somehow similar to a simple temporal network, and the set of constraints may be inconsistent or redundant. It is possible to _minimize_ the temporal constraints of a chronicle using the corresponding function.
|
|
324
333
|
|
|
325
334
|
```python
|
|
326
335
|
>>> c=Chronicle()
|
|
@@ -353,16 +362,16 @@ You can also depict a chronicle as a matplotlib graph:
|
|
|
353
362
|
|
|
354
363
|
### Fuzzy chronicles
|
|
355
364
|
|
|
356
|
-
The `FuzzyChronicle` class
|
|
357
|
-
The temporal model is enriched with the modeling of
|
|
365
|
+
The `FuzzyChronicle` class enables the approximate recognition of a chronicle. A fuzzy chronicle is defined in the same way as a chronicle.
|
|
366
|
+
The temporal model is enriched with the modeling of the fuzziness of the temporal constraints (`lbda` parameter).
|
|
358
367
|
|
|
359
|
-
In addition to the matching
|
|
368
|
+
In addition to the matching functions presented above, it provides a `cmp` function that finds all the occurrences of a chronicle whose degree of matching is above a threshold (parameter `threshold`), together with their similarity. The `iter_cmp` function is its lazy version.
|
|
360
369
|
|
|
361
|
-
More details about fuzzy
|
|
370
|
+
More details about fuzzy chronicles are available in the [article](https://inria.hal.science/hal-02422796v1) (in French):
|
|
362
371
|
```bibtex
|
|
363
372
|
@inproceedings{fchronicles,
|
|
364
373
|
title = {{\'E}num{\'e}ration des occurrences d'une chronique},
|
|
365
|
-
author = {Guyet, Thomas and Besnard, Philippe and
|
|
374
|
+
author = {Guyet, Thomas and Besnard, Philippe and Samet, Ahmed and Ben Salha, Nasreddine and Lachiche, Nicolas},
|
|
366
375
|
booktitle = {Actes de la conférence Extraction et Gestion des Connaissances},
|
|
367
376
|
publisher = {{\'E}ditions RNTI},
|
|
368
377
|
pages = {253--260},
|
|
@@ -372,29 +381,29 @@ More details about fuzzy chroniclesis available in the [article](https://hal.arc
|
|
|
372
381
|
|
|
373
382
|
# Dataframe accessor
|
|
374
383
|
|
|
375
|
-
The `pychronicles` package
|
|
376
|
-
This accessor
|
|
384
|
+
The `pychronicles` package includes a new accessor for pandas dataframes.
|
|
385
|
+
This accessor, denoted `tpattern`, makes it possible to use chronicle functionalities directly with pandas. In this case, you do not even need to manage your timed sequences by hand: everything can be done directly with pandas.
|
|
377
386
|
|
|
378
387
|
The pandas accessor enables:
|
|
379
388
|
|
|
380
389
|
* to match or enumerate occurrences of a chronicle
|
|
381
|
-
* to match
|
|
390
|
+
* to match a Metric Temporal Logic (MTL) formula
|
|
382
391
|
* to abstract a collection of sequences
|
|
383
392
|
* to extract the delays of matching occurrences of a chronicle
|
|
384
393
|
|
|
385
394
|
|
|
386
395
|
## Spirit of the accessor
|
|
387
396
|
|
|
388
|
-
The spirit of our accessor is to use a pandas dataframe to encode a sequence or a collection of
|
|
397
|
+
The spirit of our accessor is to use a pandas dataframe to encode a sequence or a collection of sequences. The index of the dataframe models the time: it can be an integer, float or date index.
|
|
389
398
|
|
|
390
|
-
A column of the dataframe
|
|
399
|
+
A column of the dataframe can be defined to specify the identifier of the sequences. In the following example, the column named `id` denotes this identifier. Intuitively, it can be used to make `groupby` operations, to process a collection of timed sequences.
|
|
391
400
|
|
|
392
|
-
The important feature of our package is that any other column can be added to the dataframe. The idea behind this modeling is that the dataframe
|
|
401
|
+
The important feature of our package is that any other column can be added to the dataframe. The idea behind this modeling is that the dataframe gathers all the information about the events. The columns describe each event (and can contain `None`).
|
|
393
402
|
|
|
394
403
|
|
|
395
|
-
The example below illustrates the representation of a collection of sequences with a Pandas dataframe.
|
|
396
|
-
The basic sequence is repeated three times to create a collection of three timed sequences.
|
|
397
|
-
The event names of the basic sequence feed the column `label`, and we added
|
|
404
|
+
The example below illustrates the representation of a collection of sequences with a Pandas dataframe.
|
|
405
|
+
The basic sequence is repeated three times to create a collection of three timed sequences. In this case, the index of the dataframe is defined with dates.
|
|
406
|
+
The event names of the basic sequence feed the column `label`, and we added three columns:
|
|
398
407
|
|
|
399
408
|
|
|
400
409
|
* a column `str_val` with the string values (twice the label)
|
|
@@ -402,7 +411,7 @@ The event names of the basic sequence feed the column `label`, and we added two
|
|
|
402
411
|
* a column `id` that represents the identifier of a sequence.
|
|
403
412
|
|
|
404
413
|
```python
|
|
405
|
-
#create a basic sequence
|
|
414
|
+
# create a basic sequence
|
|
406
415
|
seq = [('a',1),('c',2),('b',3),('a',8),('a',10),('b',12),('a',15),('c',17)]
|
|
407
416
|
df = pd.DataFrame({
|
|
408
417
|
"label": [e[0] for e in seq]*3,
|
|
@@ -416,19 +425,19 @@ df = pd.DataFrame({
|
|
|
416
425
|
|
|
417
426
|
<br>
|
|
418
427
|
|
|
419
|
-
Then, the
|
|
420
|
-
When used with pandas
|
|
428
|
+
Then, the events of a chronicle are no longer event names, but descriptions of the events of interest through their features.
|
|
429
|
+
When used with pandas dataframes, the events of a chronicle are queries on the dataframe.
|
|
421
430
|
In the example above, an event could be defined by "`label=='a' & num_val>3`".
|
|
422
431
|
|
|
423
|
-
|
|
432
|
+
For the time being, our framework handles string and number attributes. The specification of an event uses the classical operators defined in the [Pandas documentation](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.query.html).
|
|
424
433
|
|
|
425
|
-
## Matching /
|
|
434
|
+
## Matching / enumerating the occurrences of a chronicle
|
|
426
435
|
|
|
427
|
-
Let us now use a dataframe defined as explained in the previous section with chronicle.
|
|
436
|
+
Let us now use a dataframe defined as explained in the previous section with a chronicle.
|
|
428
437
|
|
|
429
|
-
For that, we first need to define a chronicle. It works exactly as before but
|
|
438
|
+
For that, we first need to define a chronicle. It works exactly as before, but the chronicle's events are defined by queries.
|
|
430
439
|
|
|
431
|
-
For instance, the following example illustrates the definition a simple chronicle that uses queries as
|
|
440
|
+
For instance, the following example illustrates the definition of a simple chronicle that uses queries as events:
|
|
432
441
|
```python
|
|
433
442
|
c=Chronicle()
|
|
434
443
|
c.add_event(0,'label=="a"')
|
|
@@ -438,24 +447,24 @@ c.add_constraint(0,1, (np.timedelta64(4,'D'),np.timedelta64(10,'D')))
|
|
|
438
447
|
|
|
439
448
|
For more details about the syntax of queries, please refer to the [Pandas documentation](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.query.html).
|
|
440
449
|
|
|
441
|
-
This chronicle is semantically sound
|
|
450
|
+
This chronicle is semantically sound to be used with the dataframe defined in the example of the previous section.
|
|
442
451
|
|
|
443
452
|
### Dataframe representing a sequence
|
|
444
453
|
|
|
445
454
|
In this section, we consider that the dataframe represents a unique sequence (for instance, we selected the first sequence of the previous dataframe with `df[df.id==1]`).
|
|
446
455
|
|
|
447
|
-
The recognition functionalities are now accessible
|
|
456
|
+
The recognition functionalities are now accessible through the Pandas dataframe:
|
|
448
457
|
|
|
449
|
-
* `df.tpattern.match(c)`
|
|
450
|
-
* `df.tpattern.recognize(c)`
|
|
451
|
-
* `df.tpattern.project(c)`
|
|
458
|
+
* `df.tpattern.match(c)` returns a boolean indicating whether the chronicle occurs in the sequence or not
|
|
459
|
+
* `df.tpattern.recognize(c)` returns the list of the occurrences of `c` in the sequence (`df.tpattern.iter_recognize(c)` is its lazy version)
|
|
460
|
+
* `df.tpattern.project(c)` returns a dataframe with the delays of the temporal constraints of the chronicle `c` in each of its occurrences
|
|
452
461
|
|
|
453
462
|
Note that the `tpattern` keyword gives access to the features of our package.
|
|
454
463
|
|
|
455
464
|
<br>
|
|
456
465
|
|
|
457
|
-
Using chronicles becomes very easy with Pandas
|
|
458
|
-
We keep good computational efficiency of the recognition algorithms thanks to the
|
|
466
|
+
Using chronicles becomes very easy with Pandas dataframes, and they also gain in expressivity thanks to the use of queries as events.
|
|
467
|
+
We keep a good computational efficiency of the recognition algorithms thanks to the rewriting principle developed with semantic chronicles (see the reference below).
|
|
459
468
|
|
|
460
469
|
```bibtex
|
|
461
470
|
@inproceedings{semantic_chronicles,
|
|
@@ -469,20 +478,20 @@ We keep good computational efficiency of the recognition algorithms thanks to th
|
|
|
469
478
|
|
|
470
479
|
### Dataframe representing a collection of sequences
|
|
471
480
|
|
|
472
|
-
To
|
|
481
|
+
To process a dataframe containing several sequences, you can use the following idiom based on `apply`:
|
|
473
482
|
|
|
474
483
|
```python
|
|
475
484
|
reco=df.groupby('id').apply(lambda d: d.tpattern.match(c))
|
|
476
485
|
```
|
|
477
486
|
|
|
478
487
|
In this case, the attribute `id` is used to select the events for each sequence, and then the `match` algorithm is applied to this selection.
|
|
479
|
-
The result is a
|
|
488
|
+
The result is a pandas series containing a boolean value for each sequence id.
|
|
480
489
|
|
|
481
|
-
The same applies
|
|
490
|
+
The same applies to the `recognize` function.
|
|
482
491
|
|
|
483
|
-
## Use of MTL
|
|
492
|
+
## Use of MTL formulas
|
|
484
493
|
|
|
485
|
-
For situation
|
|
494
|
+
For situation recognition, there are strong connections between chronicles and metric temporal logics such as MTL or TPTL. See the [article](https://hal.archives-ouvertes.fr/hal-03777471):
|
|
486
495
|
~~~bibtex
|
|
487
496
|
@inproceedings{chronicle_templogics,
|
|
488
497
|
title = {Logical forms of chronicles},
|
|
@@ -493,12 +502,12 @@ For situation recognitinon, there are strong connection between chronicles and m
|
|
|
493
502
|
}
|
|
494
503
|
~~~
|
|
495
504
|
|
|
496
|
-
To illustrate that the principle of semantic chronicles can be broader, we extended it to the case of MTL
|
|
505
|
+
To illustrate that the principle of semantic chronicles can be broader, we extended it to the case of MTL formulas. This means that our framework makes it possible to express MTL formulas using queries as events.
|
|
497
506
|
|
|
498
507
|
|
|
499
|
-
The `tpattern` accessor provides a function `match_mtl` that is dedicated to the recognition of
|
|
508
|
+
The `tpattern` accessor provides a function `match_mtl` that is dedicated to the recognition of an MTL formula in the timed sequence (only for dataframes indexed by floats or integers). This function returns a boolean value. There is no equivalent to the enumeration of the occurrences of a chronicle.
|
|
500
509
|
|
|
501
|
-
The syntax of an MTL formula is based on the two operators `F` (eventually) and `G` (globally). These operators can be specified with temporal constraints (in brackets). They
|
|
510
|
+
The syntax of an MTL formula is based on the two operators `F` (eventually) and `G` (globally). These operators can be specified with temporal constraints (in brackets). They combine events defined in the same way as chronicle events.
|
|
502
511
|
|
|
503
512
|
```python
|
|
504
513
|
query = ' F(label=="a" & F[2.9,5]( label=="b" & num_val>5 ))'
|
|
@@ -509,13 +518,13 @@ This feature is based on the [Python implementation of MTL](https://github.com/m
|
|
|
509
518
|
|
|
510
519
|
## Abstraction of a sequence
|
|
511
520
|
|
|
512
|
-
Finally, we also provide a function that
|
|
521
|
+
Finally, we also provide a function that abstracts a collection of sequences into a chronicle.
|
|
513
522
|
|
|
514
|
-
Contrary to the recognition functions that can handle several columns, the abstraction requires
|
|
515
|
-
Then, the function, named `abstract
|
|
523
|
+
Contrary to the recognition functions that can handle several columns, the abstraction requires a column that corresponds to the event names. In addition, it requires the name of the attribute that corresponds to the identifier of the sequences.
|
|
524
|
+
Then, the function, named `abstract`, takes these two arguments and outputs a single chronicle that occurs in all the sequences.
|
|
516
525
|
|
|
517
526
|
|
|
518
|
-
The following example extracts a chronicle from the dataframe introduced above.
|
|
527
|
+
The following example extracts a chronicle from the dataframe introduced above. Its events are based on the `label` attribute.
|
|
519
528
|
```python
|
|
520
529
|
chro = df.tpattern.abstract('label', 'id')
|
|
521
530
|
```
|
|
@@ -524,7 +533,7 @@ chro = df.tpattern.abstract('label', 'id')
|
|
|
524
533
|
|
|
525
534
|
## Export / import of chronicles
|
|
526
535
|
|
|
527
|
-
It is possible to specify chronicles using the CRS format. The following code
|
|
536
|
+
It is possible to specify chronicles using the CRS format (see the functions `load` and `to_crs` of the `pychronicles.utils` module). The following code illustrates the syntax for specifying a chronicle in this format.
|
|
528
537
|
|
|
529
538
|
```
|
|
530
539
|
chronicle C27_sub_0[]()
|
|
@@ -545,16 +554,16 @@ chronicle C27_sub_0[]()
|
|
|
545
554
|
|
|
546
555
|
* implementation of chronicle mining algorithms
|
|
547
556
|
* graphical chronicle editor
|
|
548
|
-
*
|
|
557
|
+
* compile the recognition (e.g. with Cython)
|
|
549
558
|
* optimized matching of several chronicles at the same time
|
|
550
559
|
|
|
551
560
|
|
|
552
|
-
If you think that this package can be improved
|
|
561
|
+
If you think that this package can be improved, do not hesitate to contact the author to request additional features. He will do his best to maintain the code and improve it continuously.
|
|
553
562
|
|
|
554
563
|
|
|
555
564
|
# Authorship
|
|
556
565
|
|
|
557
566
|
* **Author:** Thomas Guyet
|
|
558
567
|
* **Institution:** Inria/AIstroSight
|
|
559
|
-
* **date:**
|
|
568
|
+
* **date:** 10/2026
|
|
560
569
|
|