priorityx 0.1.1__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.
Files changed (40) hide show
  1. {priorityx-0.1.1 → priorityx-0.2.0}/Makefile +4 -0
  2. {priorityx-0.1.1 → priorityx-0.2.0}/PKG-INFO +27 -12
  3. priorityx-0.2.0/README.md +60 -0
  4. {priorityx-0.1.1 → priorityx-0.2.0}/docs/api-reference.md +84 -8
  5. {priorityx-0.1.1 → priorityx-0.2.0}/docs/methodology.md +4 -2
  6. priorityx-0.2.0/docs/priority_classification.md +41 -0
  7. {priorityx-0.1.1 → priorityx-0.2.0}/docs/quickstart.md +22 -7
  8. priorityx-0.2.0/examples/README.md +36 -0
  9. priorityx-0.2.0/examples/bugs/bugs_monitoring.py +41 -0
  10. priorityx-0.2.0/examples/incidents/incident_monitoring.py +151 -0
  11. priorityx-0.2.0/examples/violations/violations_monitoring.py +128 -0
  12. {priorityx-0.1.1 → priorityx-0.2.0}/pyproject.toml +9 -5
  13. {priorityx-0.1.1 → priorityx-0.2.0}/scripts/version.py +29 -18
  14. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/__init__.py +1 -1
  15. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/core/filters.py +55 -60
  16. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/core/glmm.py +146 -129
  17. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/core/quadrants.py +6 -7
  18. priorityx-0.2.0/src/priorityx/tracking/drivers.py +634 -0
  19. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/tracking/movement.py +47 -56
  20. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/tracking/transitions.py +91 -6
  21. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/utils/helpers.py +104 -31
  22. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/viz/matrix.py +52 -28
  23. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/viz/timeline.py +128 -32
  24. priorityx-0.2.0/src/priorityx/viz/trajectory.py +289 -0
  25. priorityx-0.2.0/tests/test_drivers.py +118 -0
  26. {priorityx-0.1.1 → priorityx-0.2.0}/tests/test_glmm.py +48 -24
  27. {priorityx-0.1.1 → priorityx-0.2.0}/tests/test_quadrants.py +9 -1
  28. {priorityx-0.1.1 → priorityx-0.2.0}/tests/test_transitions.py +20 -16
  29. {priorityx-0.1.1 → priorityx-0.2.0}/uv.lock +90 -1282
  30. priorityx-0.1.1/README.md +0 -43
  31. priorityx-0.1.1/src/priorityx/viz/trajectory.py +0 -231
  32. {priorityx-0.1.1 → priorityx-0.2.0}/.github/workflows/release.yml +0 -0
  33. {priorityx-0.1.1 → priorityx-0.2.0}/.github/workflows/test.yml +0 -0
  34. {priorityx-0.1.1 → priorityx-0.2.0}/.gitignore +0 -0
  35. {priorityx-0.1.1 → priorityx-0.2.0}/LICENSE +0 -0
  36. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/core/__init__.py +0 -0
  37. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/drivers/__init__.py +0 -0
  38. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/tracking/__init__.py +0 -0
  39. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/utils/__init__.py +0 -0
  40. {priorityx-0.1.1 → priorityx-0.2.0}/src/priorityx/viz/__init__.py +0 -0
@@ -1,4 +1,8 @@
1
1
  # Version management for priorityx
2
+ # Semantic versioning: MAJOR.MINOR.PATCH
3
+ # - patch: bug fixes (0.1.1 -> 0.1.2)
4
+ # - minor: new features, backward compatible (0.1.2 -> 0.2.0)
5
+ # - major: breaking changes (0.2.0 -> 1.0.0)
2
6
 
3
7
  .PHONY: release release-patch release-minor release-major test
4
8
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: priorityx
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: Entity prioritization and escalation detection using GLMM statistical models
5
5
  Project-URL: Homepage, https://github.com/okkymabruri/priorityx
6
6
  Project-URL: Repository, https://github.com/okkymabruri/priorityx
@@ -9,7 +9,7 @@ Author-email: Okky Mabruri <okkymbrur@gmail.com>
9
9
  License: MIT
10
10
  License-File: LICENSE
11
11
  Keywords: escalation-detection,glmm,prioritization,risk-analysis,statistical-modeling
12
- Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Intended Audience :: Science/Research
15
15
  Classifier: License :: OSI Approved :: MIT License
@@ -19,17 +19,23 @@ Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Topic :: Scientific/Engineering
21
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
- Requires-Python: >=3.9
22
+ Requires-Python: >=3.10
23
23
  Requires-Dist: adjusttext>=1.3.0
24
24
  Requires-Dist: matplotlib>=3.9.4
25
25
  Requires-Dist: pandas>=2.3.3
26
- Requires-Dist: polars>=1.35.1
27
- Requires-Dist: pyarrow>=21.0.0
28
26
  Requires-Dist: statsmodels>=0.14.5
29
27
  Description-Content-Type: text/markdown
30
28
 
31
29
  # Priorityx: Entity prioritization and escalation detection using GLMM statistical models
32
30
 
31
+ [![PyPI version](https://badge.fury.io/py/priorityx.svg)](https://badge.fury.io/py/priorityx)
32
+ [![Downloads](https://static.pepy.tech/badge/priorityx)](https://pepy.tech/project/priorityx)
33
+ [![Tests](https://github.com/okkymabruri/priorityx/workflows/Tests/badge.svg)](https://github.com/okkymabruri/priorityx/actions)
34
+ [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
35
+ [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
36
+
37
+ Entity prioritization and escalation detection using GLMM statistical models
38
+
33
39
  ## Installation
34
40
 
35
41
  ```bash
@@ -38,12 +44,20 @@ pip install priorityx
38
44
 
39
45
  ## Quick Start
40
46
 
47
+ ### Deterministic runs
48
+
49
+ Set `PRIORITYX_GLMM_SEED` (or call `set_glmm_random_seed()`) before running analyses to obtain repeatable GLMM estimates during debugging or CI checks:
50
+
51
+ ```bash
52
+ PRIORITYX_GLMM_SEED=1234 python tmp/complaints_analysis.py
53
+ ```
54
+
41
55
  ```python
42
- import polars as pl
56
+ import pandas as pd
43
57
  from priorityx.core.glmm import fit_priority_matrix
44
58
  from priorityx.viz.matrix import plot_priority_matrix
45
59
 
46
- df = pl.read_csv("data.csv")
60
+ df = pd.read_csv("data.csv")
47
61
 
48
62
  results, stats = fit_priority_matrix(
49
63
  df,
@@ -57,10 +71,10 @@ plot_priority_matrix(results, entity_name="Service", save_plot=True)
57
71
 
58
72
  ## Features
59
73
 
60
- - GLMM-based priority classification (Q1-Q4 quadrants)
61
- - Transition detection over time
62
- - Movement tracking
63
- - Visualization
74
+ - GLMM-based priority matrix (Q1–Q4) with entity-level intercept/slope insights
75
+ - Priority-based transition timeline (Crisis / Investigate / Monitor / Low) with spike markers (`*X`, `*Y`, `*XY`)
76
+ - Cumulative movement tracking and trajectory visualizations
77
+ - Deterministic seeding option for reproducible GLMM runs (set `PRIORITYX_GLMM_SEED`)
64
78
 
65
79
  ## Use Cases
66
80
 
@@ -70,4 +84,5 @@ IT incidents, software bugs, compliance violations, performance monitoring.
70
84
 
71
85
  - [Quick Start](docs/quickstart.md)
72
86
  - [API Reference](docs/api-reference.md)
73
- - [Methodology](docs/methodology.md)
87
+ - [Methodology](docs/methodology.md)
88
+ - [Priority Classification](docs/priority_classification.md)
@@ -0,0 +1,60 @@
1
+ # Priorityx: Entity prioritization and escalation detection using GLMM statistical models
2
+
3
+ [![PyPI version](https://badge.fury.io/py/priorityx.svg)](https://badge.fury.io/py/priorityx)
4
+ [![Downloads](https://static.pepy.tech/badge/priorityx)](https://pepy.tech/project/priorityx)
5
+ [![Tests](https://github.com/okkymabruri/priorityx/workflows/Tests/badge.svg)](https://github.com/okkymabruri/priorityx/actions)
6
+ [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
7
+ [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ Entity prioritization and escalation detection using GLMM statistical models
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install priorityx
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ### Deterministic runs
20
+
21
+ Set `PRIORITYX_GLMM_SEED` (or call `set_glmm_random_seed()`) before running analyses to obtain repeatable GLMM estimates during debugging or CI checks:
22
+
23
+ ```bash
24
+ PRIORITYX_GLMM_SEED=1234 python tmp/complaints_analysis.py
25
+ ```
26
+
27
+ ```python
28
+ import pandas as pd
29
+ from priorityx.core.glmm import fit_priority_matrix
30
+ from priorityx.viz.matrix import plot_priority_matrix
31
+
32
+ df = pd.read_csv("data.csv")
33
+
34
+ results, stats = fit_priority_matrix(
35
+ df,
36
+ entity_col="service",
37
+ timestamp_col="date",
38
+ temporal_granularity="quarterly"
39
+ )
40
+
41
+ plot_priority_matrix(results, entity_name="Service", save_plot=True)
42
+ ```
43
+
44
+ ## Features
45
+
46
+ - GLMM-based priority matrix (Q1–Q4) with entity-level intercept/slope insights
47
+ - Priority-based transition timeline (Crisis / Investigate / Monitor / Low) with spike markers (`*X`, `*Y`, `*XY`)
48
+ - Cumulative movement tracking and trajectory visualizations
49
+ - Deterministic seeding option for reproducible GLMM runs (set `PRIORITYX_GLMM_SEED`)
50
+
51
+ ## Use Cases
52
+
53
+ IT incidents, software bugs, compliance violations, performance monitoring.
54
+
55
+ ## Documentation
56
+
57
+ - [Quick Start](docs/quickstart.md)
58
+ - [API Reference](docs/api-reference.md)
59
+ - [Methodology](docs/methodology.md)
60
+ - [Priority Classification](docs/priority_classification.md)
@@ -25,7 +25,7 @@ results, stats = fit_priority_matrix(
25
25
  Fits Poisson GLMM to classify entities into priority quadrants.
26
26
 
27
27
  **Parameters:**
28
- - `df`: polars DataFrame
28
+ - `df`: pandas DataFrame
29
29
  - `entity_col`: Entity identifier column name
30
30
  - `timestamp_col`: Date column name
31
31
  - `count_col`: Count metric column (optional, defaults to row count)
@@ -41,6 +41,8 @@ Fits Poisson GLMM to classify entities into priority quadrants.
41
41
  - `results`: DataFrame with entity, Random_Intercept, Random_Slope, count, quadrant
42
42
  - `stats`: Dictionary with model statistics
43
43
 
44
+ > **Reproducibility:** set the environment variable `PRIORITYX_GLMM_SEED` or call `set_glmm_random_seed(value)` before invoking `fit_priority_matrix` to obtain deterministic variational Bayes estimates.
45
+
44
46
  ---
45
47
 
46
48
  ## Tracking Functions
@@ -85,6 +87,60 @@ Extracts quadrant transitions from movement data.
85
87
  **Returns:**
86
88
  - DataFrame with transition details and risk levels
87
89
 
90
+ ### extract_transition_drivers
91
+
92
+ ```python
93
+ from priorityx.tracking.drivers import extract_transition_drivers
94
+
95
+ analysis = extract_transition_drivers(
96
+ movement_df,
97
+ df_raw,
98
+ entity_name="Service A",
99
+ quarter_from="2024-Q2",
100
+ quarter_to="2024-Q3",
101
+ entity_col="service",
102
+ timestamp_col="date",
103
+ subcategory_cols=["type", "category"], # Optional
104
+ text_col="description" # Optional
105
+ )
106
+ ```
107
+
108
+ Analyzes root causes of a quadrant transition.
109
+
110
+ **Parameters:**
111
+ - `movement_df`: Output from track_cumulative_movement()
112
+ - `df_raw`: Raw event data (pandas DataFrame)
113
+ - `entity_name`: Entity to analyze
114
+ - `quarter_from`: Starting quarter (e.g., "2024-Q2")
115
+ - `quarter_to`: Ending quarter (e.g., "2024-Q3")
116
+ - `entity_col`: Entity column name
117
+ - `timestamp_col`: Timestamp column name
118
+ - `subcategory_cols`: Optional list of subcategory columns
119
+ - `text_col`: Optional text column for keyword analysis
120
+
121
+ **Returns:**
122
+ - Dictionary with transition overview, magnitude metrics, subcategory drivers, keyword drivers, and priority classification
123
+
124
+ ### classify_priority
125
+
126
+ ```python
127
+ from priorityx.tracking.drivers import classify_priority
128
+
129
+ priority, reason, spike_axis = classify_priority(
130
+ from_quadrant="Q3",
131
+ to_quadrant="Q1",
132
+ x=0.5, y=0.6,
133
+ x_delta=0.5, y_delta=0.5,
134
+ count_delta=100,
135
+ percent_change=200
136
+ )
137
+ ```
138
+
139
+ Classifies supervisory priority (1=Critical, 2=Investigate, 3=Monitor, 4=Low).
140
+
141
+ **Returns:**
142
+ - Tuple of (priority, reason, spike_axis)
143
+
88
144
  ---
89
145
 
90
146
  ## Visualization Functions
@@ -118,18 +174,19 @@ fig = plot_transition_timeline(
118
174
  filter_risk_levels=["critical", "high"],
119
175
  max_entities=20,
120
176
  save_plot=False,
121
- output_dir="plot"
177
+ output_dir="plot",
178
+ movement_df=movement_df
122
179
  )
123
180
  ```
124
181
 
125
- Creates timeline heatmap of transitions.
182
+ Creates timeline heatmap of transitions. Passing `movement_df` is required to compute the Crisis/Investigate/Monitor/Low priority tiers and spike markers (`*X`, `*Y`, `*XY`). Omitting it falls back to legacy risk-level tags.
126
183
 
127
- ### plot_movement_trajectories
184
+ ### plot_entity_trajectories
128
185
 
129
186
  ```python
130
- from priorityx.viz.trajectory import plot_movement_trajectories
187
+ from priorityx.viz.trajectory import plot_entity_trajectories
131
188
 
132
- fig = plot_movement_trajectories(
189
+ fig = plot_entity_trajectories(
133
190
  movement_df,
134
191
  entity_name="Entity",
135
192
  max_entities=10,
@@ -138,7 +195,7 @@ fig = plot_movement_trajectories(
138
195
  )
139
196
  ```
140
197
 
141
- Creates trajectory plot showing movement through priority space.
198
+ Creates trajectory plot showing entity paths through priority space.
142
199
 
143
200
  ---
144
201
 
@@ -147,10 +204,29 @@ Creates trajectory plot showing movement through priority space.
147
204
  ### Display Summaries
148
205
 
149
206
  ```python
150
- from priorityx.utils.helpers import display_quadrant_summary, display_transition_summary
207
+ from priorityx.utils.helpers import (
208
+ display_quadrant_summary,
209
+ display_transition_summary,
210
+ display_movement_summary
211
+ )
151
212
 
152
213
  display_quadrant_summary(results_df, entity_name="Service")
153
214
  display_transition_summary(transitions_df, entity_name="Service")
215
+ display_movement_summary(movement_df, entity_name="Service")
154
216
  ```
155
217
 
156
218
  Prints formatted summaries of analysis results.
219
+
220
+ ### display_transition_drivers
221
+
222
+ ```python
223
+ from priorityx.tracking.drivers import display_transition_drivers
224
+
225
+ display_transition_drivers(analysis, show_keywords=True)
226
+ ```
227
+
228
+ Prints transition driver analysis in human-readable format.
229
+
230
+ **Parameters:**
231
+ - `analysis`: Output from extract_transition_drivers()
232
+ - `show_keywords`: Whether to show keyword analysis (default: False)
@@ -29,7 +29,7 @@ count ~ time + seasonal_effects + (1 + time | entity)
29
29
 
30
30
  Entities classified based on random effects:
31
31
 
32
- **Q1 (Crisis):** intercept > 0, slope > 0, count ≥ 50
32
+ **Q1 (Critical):** intercept > 0, slope > 0, count ≥ 50
33
33
  - High volume, accelerating growth
34
34
  - Requires immediate attention
35
35
 
@@ -45,7 +45,9 @@ Entities classified based on random effects:
45
45
  - High volume but not accelerating
46
46
  - Persistent baseline issues
47
47
 
48
- The count threshold for Q1 prevents low-volume entities from being mislabeled as Crisis.
48
+ The count threshold for Q1 prevents low-volume entities from being mislabeled as Critical.
49
+
50
+ Priority tiers applied in the transition timeline build on these quadrants with velocity-based rules (see `docs/priority_classification.md`) to differentiate Crisis, Investigate, Monitor, and Low responses.
49
51
 
50
52
  ## Movement Tracking
51
53
 
@@ -0,0 +1,41 @@
1
+ # Priority Classification Overview
2
+
3
+ A four-tier priority system ranks quadrant transitions by urgency using movement velocity, magnitude, and spike detection. Priorities are computed inside `plot_transition_timeline(..., movement_df=...)` and saved in transition CSVs.
4
+
5
+ ## Priority Tiers
6
+
7
+ | Priority | Label & Color | Main Triggers | Recommended Action |
8
+ |----------|---------------|---------------|--------------------|
9
+ | **1 – Crisis** 🔴 | Explosion requiring immediate response | ΔX ≥ 0.40 or ΔY ≥ 0.40 (≈3σ); volume jump ≥ 50 with ≥500 % growth; both axes spiking (`*XY`) | Launch crisis playbook, staff war room, monitor daily |
10
+ | **2 – Investigate** 🟠 | Rapid escalation needing urgent review | |ΔX > 0.15 or |ΔY > 0.15; entry into Q1 with strong position; ≥100 % growth with ≥5 new complaints | Trigger early warning, assign analysts, tighten monitoring cadence |
11
+ | **3 – Monitor** 🟡 | Borderline movement worth watching | Position within ±0.10 of quadrant boundary; gentle Q1 entry | Track trend, document findings, review quarterly |
12
+ | **4 – Low** 🟢 | Stable or improving | No conditions above met | Maintain routine oversight |
13
+
14
+ ## Spike Indicators
15
+
16
+ | Marker | Meaning | Threshold |
17
+ |--------|---------|-----------|
18
+ | `*Y` | Growth spike | ΔY ≥ 0.40 |
19
+ | `*X` | Volume spike | ΔX ≥ 0.40 |
20
+ | `*XY` | Simultaneous spikes | ΔX ≥ 0.40 **and** ΔY ≥ 0.40 |
21
+
22
+ ## Threshold Reference
23
+
24
+ | Metric | Cut-off | Notes |
25
+ |--------|---------|-------|
26
+ | Crisis spike | ±0.40 | ≈2.74σ, highlights extreme moves |
27
+ | Velocity trigger | ±0.15 | Sustained acceleration worth investigation |
28
+ | Growth shock | ≥100 % **and** ≥5 complaints | Filters out noise from tiny bases |
29
+ | Explosion | ≥500 % **and** ≥50 complaints | High-volume surges escalated to Crisis |
30
+ | Borderline band | ±0.10 | Used for Monitor prioritization |
31
+
32
+ ## Usage Guidelines
33
+
34
+ 1. **Always supply movement data**: `plot_transition_timeline(transitions, movement_df=movement)` is required for priority scoring; omitting it defaults to Priority 2.
35
+ 2. **Filter by priority**: e.g. `transitions[transitions["priority"] == 1]` to summarize crises; risk_level is retained for backward compatibility only.
36
+ 3. **Inspect spike markers**: `*X`, `*Y`, `*XY` signal urgent within-quadrant acceleration that may precede cross-quadrant jumps.
37
+ 4. **Adjust tracking range deliberately**: longer histories surface more transitions; short windows emphasize recent moves.
38
+
39
+ ## Changelog
40
+
41
+ - **2024-11-09** – Introduced priority classification, spike markers, and timeline integration.
@@ -9,12 +9,13 @@ pip install priorityx
9
9
  ## Basic Usage
10
10
 
11
11
  ```python
12
- import polars as pl
12
+ import pandas as pd
13
13
  from priorityx.core.glmm import fit_priority_matrix
14
14
  from priorityx.viz.matrix import plot_priority_matrix
15
15
 
16
16
  # load your data
17
- df = pl.read_csv("your_data.csv")
17
+ df = pd.read_csv("your_data.csv")
18
+ df["date"] = pd.to_datetime(df["date"])
18
19
 
19
20
  # fit priority matrix
20
21
  results, stats = fit_priority_matrix(
@@ -34,6 +35,7 @@ plot_priority_matrix(results, entity_name="Service", save_plot=True)
34
35
  ```python
35
36
  from priorityx.tracking.movement import track_cumulative_movement
36
37
  from priorityx.tracking.transitions import extract_transitions
38
+ from priorityx.tracking.drivers import extract_transition_drivers, display_transition_drivers
37
39
  from priorityx.viz.timeline import plot_transition_timeline
38
40
 
39
41
  # track movement over time
@@ -49,6 +51,20 @@ transitions = extract_transitions(movement)
49
51
 
50
52
  # visualize transitions
51
53
  plot_transition_timeline(transitions, entity_name="Service", save_plot=True)
54
+
55
+ # analyze drivers for specific transition
56
+ if not transitions.empty:
57
+ first_transition = transitions.iloc[0]
58
+ analysis = extract_transition_drivers(
59
+ movement_df=movement,
60
+ df_raw=df,
61
+ entity_name=first_transition["entity"],
62
+ quarter_from=first_transition["from_quarter"],
63
+ quarter_to=first_transition["transition_quarter"],
64
+ entity_col="service",
65
+ timestamp_col="date"
66
+ )
67
+ display_transition_drivers(analysis)
52
68
  ```
53
69
 
54
70
  ## Data Requirements
@@ -60,9 +76,8 @@ Your data needs:
60
76
 
61
77
  ## Output
62
78
 
63
- Results include:
64
- - Priority matrix: CSV + scatter plot
65
- - Transitions: CSV + timeline heatmap
66
- - Movement: CSV + trajectory plot
79
+ By default, outputs saved to:
80
+ - **`plot/`** - All PNG visualizations (priority matrix, transitions, trajectories)
81
+ - **`results/`** - All CSV data files (entity scores, transitions, movement tracking)
67
82
 
68
- Outputs saved to `plot/` and `results/` directories.
83
+ You can customize output directories using the `output_dir` parameter in visualization functions.
@@ -0,0 +1,36 @@
1
+ # Examples
2
+
3
+ These examples demonstrate priorityx usage with different datasets.
4
+
5
+ ## Prerequisites
6
+
7
+ Install priorityx from PyPI:
8
+ ```bash
9
+ pip install priorityx
10
+ ```
11
+
12
+ Or install latest from source:
13
+ ```bash
14
+ pip install git+https://github.com/okkymabruri/priorityx.git
15
+ ```
16
+
17
+ ## Running Examples
18
+
19
+ **IT Incidents** (1,621 incidents, 10 services)
20
+ ```bash
21
+ python examples/incidents/incident_monitoring.py
22
+ ```
23
+
24
+ **Compliance Violations** (495 violations, 10 departments)
25
+ ```bash
26
+ python examples/violations/violations_monitoring.py
27
+ ```
28
+
29
+ **Software Bugs** (576 bugs, 10 components)
30
+ Pre-generated CSV only. Use as input for your own analysis.
31
+
32
+ ## Output
33
+
34
+ Results saved to:
35
+ - `plot/` - Visualizations (PNG files)
36
+ - `results/` - Data tables (CSV files)
@@ -0,0 +1,41 @@
1
+ # software bug tracking example
2
+
3
+ import pandas as pd
4
+
5
+ from priorityx.core.glmm import fit_priority_matrix
6
+ from priorityx.viz.matrix import plot_priority_matrix
7
+
8
+ # load bug reports
9
+ df = pd.read_csv("examples/bugs/bugs.csv")
10
+
11
+ # parse date column
12
+ df["date"] = pd.to_datetime(df["reported_date"])
13
+
14
+ # fit priority matrix
15
+ temporal_granularity = "quarterly"
16
+ entity_name = "Component"
17
+ results, stats = fit_priority_matrix(
18
+ df,
19
+ entity_col="component",
20
+ timestamp_col="date",
21
+ temporal_granularity=temporal_granularity,
22
+ min_observations=4,
23
+ )
24
+
25
+ # display results
26
+ print("Software Bug Priority Matrix:")
27
+ print(results[["entity", "Random_Intercept", "Random_Slope", "count", "quadrant"]])
28
+
29
+ # visualize
30
+ plot_priority_matrix(
31
+ results,
32
+ entity_name=entity_name,
33
+ show_quadrant_labels=True,
34
+ save_plot=True,
35
+ save_csv=True,
36
+ output_dir="examples/bugs/plot",
37
+ )
38
+ print()
39
+ print("Outputs saved to examples/bugs/plot/ and examples/bugs/results/")
40
+
41
+ # %%
@@ -0,0 +1,151 @@
1
+ # it incident monitoring example
2
+
3
+ import pandas as pd
4
+
5
+ from priorityx.core.glmm import fit_priority_matrix
6
+ from priorityx.tracking.movement import track_cumulative_movement
7
+ from priorityx.tracking.transitions import extract_transitions
8
+ from priorityx.tracking.drivers import (
9
+ extract_transition_drivers,
10
+ display_transition_drivers,
11
+ )
12
+ from priorityx.viz.matrix import plot_priority_matrix
13
+ from priorityx.viz.timeline import plot_transition_timeline
14
+ from priorityx.viz.trajectory import plot_entity_trajectories
15
+ from priorityx.utils.helpers import (
16
+ display_quadrant_summary,
17
+ display_transition_summary,
18
+ save_dataframe_to_csv,
19
+ )
20
+
21
+ # load data
22
+ df = pd.read_csv("examples/incidents/incidents.csv")
23
+ df["date"] = pd.to_datetime(df["date"])
24
+
25
+ print(f"Loaded {len(df)} incidents for {df['service'].nunique()} services")
26
+ print(f"Date range: {df['date'].min()} to {df['date'].max()}")
27
+
28
+ # fit priority matrix
29
+ print()
30
+ print("PRIORITY MATRIX ANALYSIS")
31
+
32
+ temporal_granularity = "quarterly"
33
+ entity_name = "Service"
34
+ results, stats = fit_priority_matrix(
35
+ df,
36
+ entity_col="service",
37
+ timestamp_col="date",
38
+ temporal_granularity=temporal_granularity,
39
+ min_observations=8,
40
+ min_total_count=20,
41
+ )
42
+
43
+ print(f"\nAnalyzed {len(results)} services")
44
+ print(results[["entity", "Random_Intercept", "Random_Slope", "count", "quadrant"]])
45
+
46
+ display_quadrant_summary(results, entity_name=entity_name, min_count=0)
47
+
48
+ # visualize
49
+ plot_priority_matrix(
50
+ results,
51
+ entity_name=entity_name,
52
+ show_quadrant_labels=True,
53
+ save_plot=True,
54
+ save_csv=True,
55
+ output_dir="examples/incidents/plot",
56
+ )
57
+
58
+ # track movement
59
+ print()
60
+ print("CUMULATIVE MOVEMENT TRACKING")
61
+
62
+ movement, meta = track_cumulative_movement(
63
+ df,
64
+ entity_col="service",
65
+ timestamp_col="date",
66
+ quarters=["2022-01-01", "2025-01-01"],
67
+ min_total_count=20,
68
+ temporal_granularity=temporal_granularity,
69
+ )
70
+
71
+ print(
72
+ f"\nTracked {meta['entities_tracked']} services over {meta['quarters_analyzed']} quarters"
73
+ )
74
+
75
+ # save movement
76
+ movement_path = save_dataframe_to_csv(
77
+ movement,
78
+ artifact="trajectories",
79
+ entity_name=entity_name,
80
+ temporal_granularity=temporal_granularity,
81
+ output_dir="examples/incidents/results",
82
+ )
83
+ print(f"Movement CSV saved: {movement_path}")
84
+
85
+ # visualize entity trajectories
86
+ plot_entity_trajectories(
87
+ movement,
88
+ entity_name=entity_name,
89
+ max_entities=5,
90
+ save_plot=True,
91
+ save_csv=True,
92
+ output_dir="examples/incidents/plot",
93
+ results_dir="examples/incidents/results",
94
+ )
95
+
96
+ # detect transitions
97
+ transitions = extract_transitions(movement, focus_risk_increasing=True)
98
+
99
+ print(f"\nDetected {len(transitions)} risk-increasing transitions")
100
+ display_transition_summary(transitions, entity_name=entity_name)
101
+
102
+ plot_transition_timeline(
103
+ transitions,
104
+ entity_name=entity_name,
105
+ save_plot=True,
106
+ save_csv=True,
107
+ output_dir="examples/incidents/plot",
108
+ movement_df=movement,
109
+ )
110
+
111
+ critical_transitions = transitions[transitions["risk_level"] == "critical"]
112
+ if len(critical_transitions) > 0:
113
+ trans = critical_transitions.iloc[0]
114
+
115
+ print()
116
+ print("DRIVER ANALYSIS EXAMPLE")
117
+ print(f"Analyzing: {trans['entity']}")
118
+ print(f"Transition: {trans['from_quadrant']} -> {trans['to_quadrant']}")
119
+ print(f"Quarter: {trans['transition_quarter']}")
120
+
121
+ entity_movement = (
122
+ movement[movement["entity"] == trans["entity"]]
123
+ .sort_values("quarter")
124
+ .reset_index(drop=True)
125
+ )
126
+ trans_idx = entity_movement[
127
+ entity_movement["quarter"] == trans["transition_quarter"]
128
+ ].index[0]
129
+ prev_quarter = (
130
+ entity_movement.loc[trans_idx - 1, "quarter"] if trans_idx > 0 else None
131
+ )
132
+
133
+ if prev_quarter:
134
+ driver_analysis = extract_transition_drivers(
135
+ movement_df=movement,
136
+ df_raw=df,
137
+ entity_name=trans["entity"],
138
+ quarter_from=prev_quarter,
139
+ quarter_to=trans["transition_quarter"],
140
+ entity_col="service",
141
+ timestamp_col="date",
142
+ )
143
+
144
+ display_transition_drivers(driver_analysis)
145
+
146
+ print()
147
+ print(
148
+ "Analysis complete. Check examples/incidents/plot/ and examples/incidents/results/"
149
+ )
150
+
151
+ # %%