ts2net 0.7.1__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.
ts2net-0.7.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Kyle T. Jones
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
ts2net-0.7.1/PKG-INFO ADDED
@@ -0,0 +1,403 @@
1
+ Metadata-Version: 2.4
2
+ Name: ts2net
3
+ Version: 0.7.1
4
+ Classifier: Programming Language :: Python :: 3
5
+ Classifier: Programming Language :: Python :: 3.12
6
+ Classifier: Programming Language :: Python :: 3.13
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Topic :: Scientific/Engineering
10
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
11
+ Classifier: Intended Audience :: Science/Research
12
+ Requires-Dist: numpy>=1.23
13
+ Requires-Dist: networkx>=3.0
14
+ Requires-Dist: pandas>=1.5
15
+ Requires-Dist: pyyaml>=6.0
16
+ Requires-Dist: matplotlib>=3.8
17
+ Requires-Dist: scipy>=1.9
18
+ Requires-Dist: joblib>=1.0
19
+ Requires-Dist: click>=8.0
20
+ Requires-Dist: scikit-learn>=1.0
21
+ Requires-Dist: statsmodels>=0.14
22
+ Requires-Dist: pyarrow>=12.0
23
+ Requires-Dist: fastparquet>=2023.0.0
24
+ Requires-Dist: polars>=0.20
25
+ Requires-Dist: pynndescent ; extra == 'approx'
26
+ Requires-Dist: torch>=2.0 ; extra == 'cnn'
27
+ Requires-Dist: pytest>=7.0 ; extra == 'dev'
28
+ Requires-Dist: pytest-cov>=4.0 ; extra == 'dev'
29
+ Requires-Dist: black>=23.0 ; extra == 'dev'
30
+ Requires-Dist: flake8>=6.0 ; extra == 'dev'
31
+ Requires-Dist: mypy>=1.0 ; extra == 'dev'
32
+ Requires-Dist: isort>=5.12 ; extra == 'dev'
33
+ Requires-Dist: pyyaml>=6.0 ; extra == 'dev'
34
+ Requires-Dist: torch>=2.0 ; extra == 'dev'
35
+ Requires-Dist: tslearn ; extra == 'dtw'
36
+ Requires-Dist: pandas-datareader ; extra == 'examples'
37
+ Requires-Dist: signalplot ; extra == 'examples'
38
+ Requires-Dist: cudtw ; extra == 'gpu'
39
+ Requires-Dist: minepy ; extra == 'mic'
40
+ Requires-Dist: pyreadr ; extra == 'rdata'
41
+ Requires-Dist: numba ; extra == 'speed'
42
+ Provides-Extra: approx
43
+ Provides-Extra: cnn
44
+ Provides-Extra: dev
45
+ Provides-Extra: dtw
46
+ Provides-Extra: examples
47
+ Provides-Extra: gpu
48
+ Provides-Extra: mic
49
+ Provides-Extra: rdata
50
+ Provides-Extra: speed
51
+ License-File: LICENSE
52
+ Summary: Time series to network conversion and analysis
53
+ Author-email: "Kyle T. Jones" <kyle@kyletjones.com>
54
+ Requires-Python: >=3.12
55
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
56
+ Project-URL: Documentation, https://ts2net.readthedocs.io
57
+ Project-URL: Homepage, https://github.com/kylejones200/ts2net
58
+ Project-URL: Issues, https://github.com/kylejones200/ts2net/issues
59
+ Project-URL: Repository, https://github.com/kylejones200/ts2net
60
+
61
+ # ts2net
62
+
63
+ [![PyPI version](https://badge.fury.io/py/ts2net.svg)](https://badge.fury.io/py/ts2net)
64
+ [![Documentation Status](https://readthedocs.org/projects/ts2net/badge/?version=latest)](https://ts2net.readthedocs.io/en/latest/?badge=latest)
65
+ [![Tests](https://github.com/kylejones200/ts2net/workflows/Tests/badge.svg)](https://github.com/kylejones200/ts2net/actions)
66
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
67
+
68
+ Time series to networks. Clean API for visibility graphs, recurrence networks, and transition networks.
69
+
70
+ ## Install
71
+
72
+ ### Basic Installation
73
+
74
+ ```bash
75
+ pip install ts2net
76
+ ```
77
+
78
+ ### Optional Dependencies
79
+
80
+ Install with optional features:
81
+
82
+ ```bash
83
+ # Performance acceleration (Numba)
84
+ pip install ts2net[speed]
85
+
86
+ # BSTS decomposition (statsmodels)
87
+ pip install ts2net[bsts]
88
+
89
+ # Temporal CNN embeddings (PyTorch)
90
+ pip install ts2net[cnn]
91
+
92
+ # All optional features
93
+ pip install ts2net[all]
94
+
95
+ # Development dependencies
96
+ pip install ts2net[dev]
97
+ ```
98
+
99
+ ### Verify Installation
100
+
101
+ ```python
102
+ import ts2net
103
+ print(ts2net.__version__)
104
+
105
+ from ts2net import HVG
106
+ import numpy as np
107
+ x = np.random.randn(100)
108
+ hvg = HVG()
109
+ hvg.build(x)
110
+ print(f"✓ Installation successful: {hvg.n_nodes} nodes, {hvg.n_edges} edges")
111
+ ```
112
+
113
+ ## Quick Start
114
+
115
+ ```python
116
+ import numpy as np
117
+ from ts2net import HVG
118
+
119
+ x = np.random.randn(1000)
120
+
121
+ hvg = HVG()
122
+ hvg.build(x)
123
+
124
+ print(hvg.n_nodes, hvg.n_edges)
125
+ print(hvg.degree_sequence())
126
+ ```
127
+
128
+ ## Adjacency Matrix
129
+
130
+ ```python
131
+ A = hvg.adjacency_matrix()
132
+ print(A.shape) # (1000, 1000)
133
+ ```
134
+
135
+ ## NetworkX (Optional)
136
+
137
+ NetworkX is optional. Convert only if needed:
138
+
139
+ ```python
140
+ G = hvg.as_networkx()
141
+ import networkx as nx
142
+ print(nx.average_clustering(G))
143
+ ```
144
+
145
+ ## Structural Decomposition and Residual Topology
146
+
147
+ For time series with predictable structure (seasonality, trends), decompose first, then analyze the residual:
148
+
149
+ ```python
150
+ from ts2net.bsts import features, BSTSSpec
151
+
152
+ # Decompose and analyze residual in one pass
153
+ spec = BSTSSpec(
154
+ level=True,
155
+ trend=False,
156
+ seasonal_periods=[24, 168] # Daily and weekly for hourly data
157
+ )
158
+
159
+ result = features(x, methods=['hvg', 'transition'], bsts=spec)
160
+
161
+ # Access three feature blocks
162
+ raw_stats = result.raw_stats # Basic series statistics
163
+ structural_stats = result.structural_stats # Component variances, seasonal strength
164
+ residual_network_stats = result.residual_network_stats # Network features from residual
165
+ ```
166
+
167
+ **Use cases:**
168
+ - Compare meters/wells without seasonal confounds
169
+ - Flag series where structural model fails (high residual complexity)
170
+ - Separate predictable structure from irregular dynamics
171
+
172
+ **Installation:**
173
+ ```bash
174
+ pip install ts2net[bsts] # Installs statsmodels
175
+ ```
176
+
177
+ See `examples/bsts_features.py` for complete examples.
178
+
179
+ ## Large Series
180
+
181
+ For large series, use output modes to control memory usage:
182
+
183
+ ```python
184
+ # Degrees only (most memory efficient)
185
+ hvg = HVG(output="degrees")
186
+ hvg.build(x)
187
+ degrees = hvg.degree_sequence() # Fast, no edge storage
188
+
189
+ # Stats only (summary statistics without edges)
190
+ hvg = HVG(output="stats")
191
+ hvg.build(x)
192
+ stats = hvg.stats() # n_nodes, n_edges, avg_degree, etc.
193
+
194
+ # Full edges (default, use for small-medium series)
195
+ hvg = HVG(output="edges")
196
+ hvg.build(x)
197
+ edges = hvg.edges # Full edge list
198
+ ```
199
+
200
+ ### Scale Guidelines
201
+
202
+ | Series Length | Method | Recommended Settings | Memory Risk |
203
+ |--------------|--------|---------------------|-------------|
204
+ | n < 10k | All methods | `output="edges"` | Safe |
205
+ | 10k < n < 100k | HVG | `output="edges"` or `output="degrees"` | Safe with sparse |
206
+ | 10k < n < 100k | NVG | `limit=2000-5000`, `output="degrees"` | **Use horizon limit** |
207
+ | 10k < n < 100k | Recurrence | `rule='knn'`, `k=10-30` | **Avoid exact all-pairs** |
208
+ | n > 100k | HVG | `output="degrees"` or `output="stats"` | Safe |
209
+ | n > 100k | NVG | `limit=2000-5000`, `max_edges=1e6`, `output="degrees"` | **Required limits** |
210
+ | n > 100k | Recurrence | `rule='knn'`, `k=10-30`, `output="degrees"` | **kNN only** |
211
+
212
+ **Critical Warnings:**
213
+ - **Dense adjacency matrices are disabled by default** for n > 50k (prevents 63GB+ memory blowup)
214
+ - **NVG without `limit` can create millions of edges** for smooth series
215
+ - **Recurrence exact all-pairs is O(n²) memory** - use kNN for large n
216
+ - **NetworkX conversion refused** for n > 200k (use `force=True` to override)
217
+
218
+ **Memory Estimates:**
219
+ - Dense adjacency: ~8 * n² bytes (e.g., 90k nodes = 63 GB)
220
+ - Sparse adjacency: ~16 * m bytes where m = edges (e.g., 100k edges = 1.6 MB)
221
+ - Edge list: ~16 * m bytes (similar to sparse)
222
+ - Degrees only: ~8 * n bytes (e.g., 90k nodes = 720 KB)
223
+
224
+ ## Methods
225
+
226
+ ### Visibility Graphs
227
+
228
+ **HVG** - Horizontal Visibility Graph
229
+ ```python
230
+ from ts2net import HVG
231
+
232
+ hvg = HVG(weighted=False, limit=None)
233
+ hvg.build(x)
234
+ ```
235
+
236
+ **NVG** - Natural Visibility Graph
237
+ ```python
238
+ from ts2net import NVG
239
+
240
+ # For large series, use horizon limit and bounded work
241
+ nvg = NVG(weighted=False, limit=5000, max_edges=1_000_000, output="degrees")
242
+ nvg.build(x)
243
+
244
+ # Or with memory limit
245
+ nvg = NVG(limit=2000, max_memory_mb=100) # Caps at ~100MB
246
+ nvg.build(x)
247
+ ```
248
+
249
+ ### Recurrence Networks
250
+
251
+ Phase space recurrence:
252
+
253
+ ```python
254
+ from ts2net import RecurrenceNetwork
255
+
256
+ rn = RecurrenceNetwork(m=3, tau=1, rule='knn', k=5)
257
+ rn.build(x)
258
+ ```
259
+
260
+ Parameters:
261
+ - `m`: embedding dimension (None = auto via FNN)
262
+ - `tau`: time delay
263
+ - `rule`: 'knn', 'epsilon', 'radius'
264
+ - `k`: neighbors for k-NN
265
+ - `epsilon`: threshold for epsilon-recurrence
266
+
267
+ ### Transition Networks
268
+
269
+ Symbolic dynamics:
270
+
271
+ ```python
272
+ from ts2net import TransitionNetwork
273
+
274
+ tn = TransitionNetwork(symbolizer='ordinal', order=3)
275
+ tn.build(x)
276
+ ```
277
+
278
+ Symbolizers:
279
+ - `'ordinal'`: ordinal patterns
280
+ - `'equal_width'`: equal-width bins
281
+ - `'equal_freq'`: equal-frequency bins (quantiles)
282
+ - `'kmeans'`: k-means clustering
283
+
284
+ ## Compare Methods
285
+
286
+ ```python
287
+ from ts2net import build_network
288
+
289
+ x = np.random.randn(1000)
290
+
291
+ for method in ['hvg', 'nvg', 'recurrence', 'transition']:
292
+ if method == 'recurrence':
293
+ g = build_network(x, method, m=3, rule='knn', k=5)
294
+ elif method == 'transition':
295
+ g = build_network(x, method, symbolizer='ordinal', order=3)
296
+ else:
297
+ g = build_network(x, method)
298
+
299
+ print(f"{method}: {g.n_edges} edges")
300
+ ```
301
+
302
+ Output:
303
+ ```
304
+ hvg: 1979 edges
305
+ nvg: 2931 edges
306
+ recurrence: 3159 edges
307
+ transition: 18 edges
308
+ ```
309
+
310
+ ## Multivariate
311
+
312
+ Multiple time series → network where nodes = time series:
313
+
314
+ ```python
315
+ from ts2net.multivariate import ts_dist, net_knn
316
+
317
+ X = np.random.randn(30, 1000) # 30 series, 1000 points each
318
+
319
+ D = ts_dist(X, method='dtw', n_jobs=-1)
320
+ G = net_knn(D, k=5)
321
+
322
+ print(G.n_nodes, G.n_edges)
323
+ ```
324
+
325
+ Distance methods: `'correlation'`, `'dtw'`, `'nmi'`, `'voi'`, `'es'`, `'vr'`
326
+
327
+ Network builders: `net_knn`, `net_enn`, `net_weighted`
328
+
329
+ ## Performance
330
+
331
+ With Numba (recommended):
332
+
333
+ ```bash
334
+ pip install numba
335
+ ```
336
+
337
+ Speedups:
338
+ - HVG: 100x faster
339
+ - NVG: 180x faster
340
+ - Recurrence: 10x faster
341
+
342
+ ## API
343
+
344
+ All methods follow the same pattern:
345
+
346
+ ```python
347
+ builder = Method(**params)
348
+ builder.build(x)
349
+
350
+ # Access results
351
+ builder.n_nodes
352
+ builder.n_edges
353
+ builder.edges # list of tuples
354
+ builder.degree_sequence() # numpy array
355
+ builder.adjacency_matrix() # numpy array
356
+ builder.as_networkx() # optional conversion
357
+ ```
358
+
359
+ ## Troubleshooting
360
+
361
+ ### Common Issues
362
+
363
+ **Memory errors with large time series:**
364
+ - Use `output="degrees"` or `output="stats"` instead of `output="edges"`
365
+ - For NVG, always set `limit` parameter (e.g., `limit=5000`)
366
+ - For recurrence networks, use `rule='knn'` with small `k` (10-30) instead of exact all-pairs
367
+
368
+ **Slow performance:**
369
+ - Install Numba: `pip install numba` (100-180x speedup for visibility graphs)
370
+ - Use `output="degrees"` if you don't need full edge lists
371
+ - For multivariate, use `n_jobs=-1` for parallel distance computation
372
+
373
+ **Import errors:**
374
+ - Ensure you're using Python 3.12+
375
+ - If Rust extension fails to build, install Rust: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
376
+ - For development, run `maturin develop --release` after installing Rust
377
+
378
+ **NetworkX conversion refused:**
379
+ - For very large graphs (n > 200k), NetworkX conversion is disabled by default
380
+ - Use `force=True` to override: `hvg.as_networkx(force=True)`
381
+ - Consider using `output="degrees"` or `output="stats"` instead
382
+
383
+ ### Getting Help
384
+
385
+ - 📖 [Full Documentation](https://ts2net.readthedocs.io)
386
+ - 💬 [Open an Issue](https://github.com/kylejones200/ts2net/issues)
387
+ - 📝 [Examples](https://github.com/kylejones200/ts2net/tree/main/examples)
388
+
389
+ ## Citation
390
+
391
+ Multivariate methods based on:
392
+
393
+ Ferreira, L.N. (2024). From time series to networks in R with the ts2net package. *Applied Network Science*, 9(1), 32. https://doi.org/10.1007/s41109-024-00642-2
394
+
395
+ ## Contributing
396
+
397
+ Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
398
+
399
+ ## License
400
+
401
+ MIT
402
+
403
+