vistaar 0.3.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.
Files changed (117) hide show
  1. vistaar-0.3.1/LICENSE +21 -0
  2. vistaar-0.3.1/MANIFEST.in +24 -0
  3. vistaar-0.3.1/PKG-INFO +237 -0
  4. vistaar-0.3.1/README.md +181 -0
  5. vistaar-0.3.1/VISTAAR_User_Guide.md +606 -0
  6. vistaar-0.3.1/VISTAAR_User_Guide.pdf +0 -0
  7. vistaar-0.3.1/docs/branding.md +27 -0
  8. vistaar-0.3.1/docs/databricks.md +51 -0
  9. vistaar-0.3.1/docs/installation.md +70 -0
  10. vistaar-0.3.1/docs/methodology.md +153 -0
  11. vistaar-0.3.1/docs/telco_churn.md +84 -0
  12. vistaar-0.3.1/examples/01_quickstart.ipynb +133 -0
  13. vistaar-0.3.1/examples/02_segmentation.ipynb +73 -0
  14. vistaar-0.3.1/examples/03_shap.ipynb +82 -0
  15. vistaar-0.3.1/examples/04_databricks.ipynb +69 -0
  16. vistaar-0.3.1/examples/05_telco_churn.ipynb +189 -0
  17. vistaar-0.3.1/examples/VISTAAR_end_to_end.ipynb +776 -0
  18. vistaar-0.3.1/examples/VISTAAR_end_to_end_clean.ipynb +776 -0
  19. vistaar-0.3.1/pyproject.toml +71 -0
  20. vistaar-0.3.1/setup.cfg +4 -0
  21. vistaar-0.3.1/tests/test_campaigns.py +132 -0
  22. vistaar-0.3.1/tests/test_engine.py +271 -0
  23. vistaar-0.3.1/tests/test_quickstart.py +33 -0
  24. vistaar-0.3.1/tests/test_round2.py +259 -0
  25. vistaar-0.3.1/tests/test_round3.py +185 -0
  26. vistaar-0.3.1/tests/test_statistics.py +107 -0
  27. vistaar-0.3.1/tests/test_telco_patterns.py +96 -0
  28. vistaar-0.3.1/vistaar/__init__.py +72 -0
  29. vistaar-0.3.1/vistaar/anomaly/__init__.py +6 -0
  30. vistaar-0.3.1/vistaar/anomaly/anomaly.py +58 -0
  31. vistaar-0.3.1/vistaar/anomaly/drift.py +157 -0
  32. vistaar-0.3.1/vistaar/causal/__init__.py +5 -0
  33. vistaar-0.3.1/vistaar/causal/effects.py +195 -0
  34. vistaar-0.3.1/vistaar/conversion/__init__.py +6 -0
  35. vistaar-0.3.1/vistaar/conversion/opportunities.py +37 -0
  36. vistaar-0.3.1/vistaar/conversion/ranking.py +149 -0
  37. vistaar-0.3.1/vistaar/core/__init__.py +6 -0
  38. vistaar-0.3.1/vistaar/core/config.py +255 -0
  39. vistaar-0.3.1/vistaar/core/data_validator.py +149 -0
  40. vistaar-0.3.1/vistaar/core/engine.py +1017 -0
  41. vistaar-0.3.1/vistaar/core/exceptions.py +27 -0
  42. vistaar-0.3.1/vistaar/core/logging.py +25 -0
  43. vistaar-0.3.1/vistaar/core/results.py +584 -0
  44. vistaar-0.3.1/vistaar/customer/__init__.py +5 -0
  45. vistaar-0.3.1/vistaar/customer/intelligence.py +115 -0
  46. vistaar-0.3.1/vistaar/data/conversion_sample.csv +8013 -0
  47. vistaar-0.3.1/vistaar/datasets.py +339 -0
  48. vistaar-0.3.1/vistaar/discovery/__init__.py +9 -0
  49. vistaar-0.3.1/vistaar/discovery/ask.py +208 -0
  50. vistaar-0.3.1/vistaar/discovery/explore.py +134 -0
  51. vistaar-0.3.1/vistaar/discovery/guidance.py +113 -0
  52. vistaar-0.3.1/vistaar/discovery/insights.py +289 -0
  53. vistaar-0.3.1/vistaar/discovery/interactions.py +152 -0
  54. vistaar-0.3.1/vistaar/discovery/simpsons.py +174 -0
  55. vistaar-0.3.1/vistaar/explainability/__init__.py +6 -0
  56. vistaar-0.3.1/vistaar/explainability/feature_importance.py +246 -0
  57. vistaar-0.3.1/vistaar/explainability/shap_engine.py +279 -0
  58. vistaar-0.3.1/vistaar/funnel/__init__.py +5 -0
  59. vistaar-0.3.1/vistaar/funnel/funnel.py +68 -0
  60. vistaar-0.3.1/vistaar/monitoring/__init__.py +15 -0
  61. vistaar-0.3.1/vistaar/monitoring/bundle.py +130 -0
  62. vistaar-0.3.1/vistaar/monitoring/calibration.py +121 -0
  63. vistaar-0.3.1/vistaar/monitoring/monitor.py +104 -0
  64. vistaar-0.3.1/vistaar/predictive/__init__.py +5 -0
  65. vistaar-0.3.1/vistaar/predictive/classification.py +466 -0
  66. vistaar-0.3.1/vistaar/predictive/evaluation.py +57 -0
  67. vistaar-0.3.1/vistaar/predictive/metrics.py +129 -0
  68. vistaar-0.3.1/vistaar/predictive/prune.py +85 -0
  69. vistaar-0.3.1/vistaar/predictive/reasons.py +98 -0
  70. vistaar-0.3.1/vistaar/predictive/selection.py +238 -0
  71. vistaar-0.3.1/vistaar/predictive/woe.py +84 -0
  72. vistaar-0.3.1/vistaar/profiling/__init__.py +5 -0
  73. vistaar-0.3.1/vistaar/profiling/diagnostics.py +129 -0
  74. vistaar-0.3.1/vistaar/profiling/profiler.py +322 -0
  75. vistaar-0.3.1/vistaar/py.typed +0 -0
  76. vistaar-0.3.1/vistaar/registry.py +278 -0
  77. vistaar-0.3.1/vistaar/reporting/__init__.py +6 -0
  78. vistaar-0.3.1/vistaar/reporting/assets/hdfc_bank_logo.svg +37 -0
  79. vistaar-0.3.1/vistaar/reporting/exporters.py +148 -0
  80. vistaar-0.3.1/vistaar/reporting/html_report.py +481 -0
  81. vistaar-0.3.1/vistaar/reporting/theme.py +112 -0
  82. vistaar-0.3.1/vistaar/sampling/__init__.py +5 -0
  83. vistaar-0.3.1/vistaar/sampling/stratified.py +351 -0
  84. vistaar-0.3.1/vistaar/segmentation/__init__.py +5 -0
  85. vistaar-0.3.1/vistaar/segmentation/clustering.py +277 -0
  86. vistaar-0.3.1/vistaar/segmentation/micro_segments.py +589 -0
  87. vistaar-0.3.1/vistaar/segmentation/portfolio.py +150 -0
  88. vistaar-0.3.1/vistaar/segmentation/rule_discovery.py +185 -0
  89. vistaar-0.3.1/vistaar/segmentation/subgroup.py +183 -0
  90. vistaar-0.3.1/vistaar/spark/__init__.py +5 -0
  91. vistaar-0.3.1/vistaar/spark/adapter.py +146 -0
  92. vistaar-0.3.1/vistaar/statistics/__init__.py +28 -0
  93. vistaar-0.3.1/vistaar/statistics/confidence_intervals.py +178 -0
  94. vistaar-0.3.1/vistaar/statistics/lift.py +176 -0
  95. vistaar-0.3.1/vistaar/statistics/significance.py +158 -0
  96. vistaar-0.3.1/vistaar/targeting/__init__.py +12 -0
  97. vistaar-0.3.1/vistaar/targeting/campaign.py +210 -0
  98. vistaar-0.3.1/vistaar/targeting/decile_segments.py +136 -0
  99. vistaar-0.3.1/vistaar/targeting/deciles.py +127 -0
  100. vistaar-0.3.1/vistaar/targeting/profit.py +181 -0
  101. vistaar-0.3.1/vistaar/timebased/__init__.py +5 -0
  102. vistaar-0.3.1/vistaar/timebased/trends.py +60 -0
  103. vistaar-0.3.1/vistaar/uplift/__init__.py +5 -0
  104. vistaar-0.3.1/vistaar/uplift/models.py +295 -0
  105. vistaar-0.3.1/vistaar/utils/__init__.py +1 -0
  106. vistaar-0.3.1/vistaar/utils/helpers.py +172 -0
  107. vistaar-0.3.1/vistaar/utils/lazy.py +29 -0
  108. vistaar-0.3.1/vistaar/utils/progress.py +119 -0
  109. vistaar-0.3.1/vistaar/version.py +3 -0
  110. vistaar-0.3.1/vistaar/visualization/__init__.py +5 -0
  111. vistaar-0.3.1/vistaar/visualization/dashboards.py +52 -0
  112. vistaar-0.3.1/vistaar/visualization/plots.py +343 -0
  113. vistaar-0.3.1/vistaar.egg-info/PKG-INFO +237 -0
  114. vistaar-0.3.1/vistaar.egg-info/SOURCES.txt +115 -0
  115. vistaar-0.3.1/vistaar.egg-info/dependency_links.txt +1 -0
  116. vistaar-0.3.1/vistaar.egg-info/requires.txt +36 -0
  117. vistaar-0.3.1/vistaar.egg-info/top_level.txt +1 -0
vistaar-0.3.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MyDataIQ contributors
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.
@@ -0,0 +1,24 @@
1
+ include LICENSE
2
+ include README.md
3
+ include pyproject.toml
4
+ include VISTAAR_User_Guide.md
5
+ include VISTAAR_User_Guide.pdf
6
+ recursive-include docs *.md
7
+ recursive-include examples *.ipynb
8
+ recursive-include tests *.py
9
+ recursive-include vistaar *.py *.csv *.svg *.typed
10
+
11
+ prune dist
12
+ prune uploads
13
+ prune reports
14
+ prune .venv
15
+ global-exclude *.html
16
+ global-exclude *.xlsx
17
+ global-exclude *.xls
18
+ global-exclude *.joblib
19
+ global-exclude *.png
20
+ global-exclude *.whl
21
+ global-exclude *.tar.gz
22
+ global-exclude *.pyc
23
+ global-exclude .DS_Store
24
+ recursive-exclude * __pycache__
vistaar-0.3.1/PKG-INFO ADDED
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: vistaar
3
+ Version: 0.3.1
4
+ Summary: Automated profiling, micro-segmentation, conversion lift, and model explanations for tabular data.
5
+ Author-email: Chinmay Anand <mail@chinmayanand.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/thechinmayanand/vistaar
8
+ Project-URL: Source, https://github.com/thechinmayanand/vistaar
9
+ Project-URL: Release, https://github.com/thechinmayanand/vistaar/releases/tag/v0.3.1
10
+ Keywords: analytics,segmentation,conversion,lift,shap,campaign,uplift
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: numpy>=1.24
26
+ Requires-Dist: pandas>=2.0
27
+ Requires-Dist: scipy>=1.10
28
+ Requires-Dist: scikit-learn>=1.3
29
+ Requires-Dist: statsmodels>=0.14
30
+ Requires-Dist: plotly>=5.18
31
+ Requires-Dist: openpyxl>=3.1
32
+ Requires-Dist: tqdm>=4.66
33
+ Provides-Extra: ml
34
+ Requires-Dist: xgboost>=2.0; extra == "ml"
35
+ Requires-Dist: lightgbm>=4.0; extra == "ml"
36
+ Requires-Dist: catboost>=1.2; extra == "ml"
37
+ Provides-Extra: shap
38
+ Requires-Dist: shap>=0.44; extra == "shap"
39
+ Provides-Extra: spark
40
+ Requires-Dist: pyspark>=3.4; extra == "spark"
41
+ Provides-Extra: hdbscan
42
+ Requires-Dist: hdbscan>=0.8.33; extra == "hdbscan"
43
+ Provides-Extra: all
44
+ Requires-Dist: xgboost>=2.0; extra == "all"
45
+ Requires-Dist: lightgbm>=4.0; extra == "all"
46
+ Requires-Dist: catboost>=1.2; extra == "all"
47
+ Requires-Dist: shap>=0.44; extra == "all"
48
+ Requires-Dist: pyspark>=3.4; extra == "all"
49
+ Requires-Dist: hdbscan>=0.8.33; extra == "all"
50
+ Provides-Extra: dev
51
+ Requires-Dist: pytest>=8; extra == "dev"
52
+ Requires-Dist: nbformat>=5; extra == "dev"
53
+ Requires-Dist: build>=1.0; extra == "dev"
54
+ Requires-Dist: twine>=5; extra == "dev"
55
+ Dynamic: license-file
56
+
57
+ # VISTAAR
58
+
59
+ VISTAAR profiles a conversion table, finds interpretable micro-segments, and reports lift, significance, and ranked opportunities. Pass a pandas or PySpark DataFrame and a binary target. The library stays local: no API key, no cloud service.
60
+
61
+ The numbers are observational. Relative lift is a segment's conversion rate divided by the overall baseline. Hypothesis tests compare the segment with its complement (everyone else), not with a baseline that includes the segment. A holdout split is used whenever the table is large enough, so the significance flag is not computed on the same rows that chose the rule. Scenario sizing is arithmetic. None of this is a causal effect.
62
+
63
+ ## Install
64
+
65
+ ```bash
66
+ pip install vistaar
67
+ pip install "vistaar[all]"
68
+ ```
69
+
70
+ Optional extras:
71
+
72
+ | Extra | What it adds |
73
+ | --- | --- |
74
+ | `shap` | SHAP explanations |
75
+ | `ml` | XGBoost, LightGBM, CatBoost |
76
+ | `hdbscan` | Density clustering |
77
+ | `spark` | PySpark, for machines that do not already have it |
78
+ | `all` | All of the above |
79
+
80
+ ```bash
81
+ pip install "vistaar[shap]"
82
+ ```
83
+
84
+ Python 3.10 or newer. Core dependencies are pandas, NumPy, SciPy, scikit-learn, statsmodels, Plotly, openpyxl, and tqdm. SHAP, gradient-boosted libraries, HDBSCAN, and PySpark are imported only when you use them.
85
+
86
+ From git, with every optional extra:
87
+
88
+ ```bash
89
+ pip install "git+https://github.com/thechinmayanand/vistaar.git#egg=vistaar[all]"
90
+ ```
91
+
92
+ GitHub release (wheel and sdist): https://github.com/thechinmayanand/vistaar/releases/tag/v0.3.1
93
+
94
+ From a clone, after `python -m build`:
95
+
96
+ ```bash
97
+ pip install dist/vistaar-*.whl
98
+ ```
99
+
100
+ Databricks notes are in [docs/databricks.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/databricks.md). Formulas are in [docs/methodology.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/methodology.md).
101
+
102
+ ## Quickstart
103
+
104
+ ```python
105
+ import vistaar as vt
106
+
107
+ df = vt.datasets.load_conversion()
108
+ engine = vt.Analytics(data=df, target="converted", id_column="customer_id")
109
+ results = engine.run()
110
+
111
+ results.summary()
112
+ results.segments()
113
+ results.lift()
114
+ results.opportunities()
115
+ results.shap()
116
+ results.deciles()
117
+ results.campaign(strategy="mass", top_deciles=2)
118
+ results.campaign(strategy="precision", target_precision=0.75, min_customers=100)
119
+ results.plot()
120
+ results.export("analytics_report.html")
121
+ ```
122
+
123
+ `run()` prints a stage bar (tqdm in a notebook or a TTY, one line per stage otherwise) and a timing summary. Pass `progress=False` to silence it. Reports and charts use the `vistaar` palette by default (navy, teal, and grey, no logo). `theme="hdfc"` opts into one built-in corporate theme. See [docs/branding.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/branding.md) and [docs/telco_churn.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/telco_churn.md).
124
+
125
+ Version 0.3.1 makes that neutral palette the default. Version 0.3 is the campaign autopilot: stratified sampling with a representativeness card, model choice on top-20% capture, a non-overlapping segment portfolio, and an audit trail of each automatic decision. Version 0.2 remains the profit cut, calibration, monitoring, registry, and uplift. The worked notebook is [examples/VISTAAR_end_to_end.ipynb](https://github.com/thechinmayanand/vistaar/blob/main/examples/VISTAAR_end_to_end.ipynb). The reference is [VISTAAR_User_Guide.md](https://github.com/thechinmayanand/vistaar/blob/main/VISTAAR_User_Guide.md).
126
+
127
+ ```python
128
+ inside = results.decile_segments(top_deciles=2)
129
+ profit = results.profit_curve(cost_per_contact=50, value_column="MonthlyCharges", value_multiplier=12)
130
+ results.optimal_cut(cost_per_contact=50, value_per_conversion=400)
131
+ calibration = results.calibration()
132
+ results.save_model("model.joblib")
133
+ loaded = vt.load_model("model.joblib")
134
+ loaded.monitor(new_month, actuals=new_month["churn"])
135
+ registry = vt.Registry("registry")
136
+ registry.register(results, model="catboost")
137
+ registry.promote(challenger, champion=champion)
138
+ uplift = results.uplift() # needs treatment_column= on Analytics
139
+ results.representativeness()
140
+ results.portfolio()
141
+ results.decisions()
142
+ results.reason_codes(df.head(200))
143
+ ```
144
+
145
+ `load_conversion()` returns a bundled synthetic table (about 8,000 customers) with a planted device × customer-type reversal, an organic × returning interaction, a confounded campaign flag, funnel steps, and leakage columns (`revenue`, `post_purchase_score`, `checkout_started`). Those leakage columns are detected and kept out of segmentation and models.
146
+
147
+ The same run also supports:
148
+
149
+ ```python
150
+ results.conversion_opportunities()
151
+ results.recommendations()
152
+ results.explore() # ranked surprises, with the numbers attached
153
+ results.ask("which segments convert best?")
154
+ results.what_if(target_rate=0.25, definition_contains="returning")
155
+ engine.compare(other_df) # PSI and KS
156
+ engine.estimate_effect() # only if treatment_column= was set
157
+ ```
158
+
159
+ Individual steps: `engine.profile()`, `engine.segment()`, `engine.calculate_lift(by="device")`, `engine.find_best_conversions()`, `engine.feature_importance()`, `engine.explain_with_shap()`, `engine.detect_anomalies()`, `engine.find_interactions()`, `engine.detect_simpsons()`, `engine.generate_insights()`.
160
+
161
+ An HTML report with the same sections:
162
+
163
+ ```python
164
+ report = engine.create_report(
165
+ output="html",
166
+ include=["profiling", "segmentation", "lift", "opportunities", "shap", "recommendations"],
167
+ )
168
+ report.save("analytics_report.html")
169
+ ```
170
+
171
+ `results.export` also writes `.xlsx`, `.csv` (the segment table), `.json`, `.md`, and `.png` (PNG needs `kaleido`).
172
+
173
+ ## What a segment row means
174
+
175
+ | Column | Meaning |
176
+ | --- | --- |
177
+ | `conversion_rate`, `n`, `conversions` | Full-sample description of this table |
178
+ | `baseline_rate` | Overall conversion rate in that same table |
179
+ | `absolute_lift` | Segment rate minus the baseline rate |
180
+ | `relative_lift` | Segment rate / baseline rate |
181
+ | `index` | `100 * relative_lift` |
182
+ | `p_value`, `p_value_adjusted`, `significant` | Holdout test against the complement, then Benjamini–Hochberg, when a holdout was used |
183
+ | `wilson_low`, `wilson_high` | Wilson interval for the full-sample rate |
184
+ | `replicates` | The holdout lift has the same sign as the training lift, with enough holdout rows |
185
+ | `observed_excess_conversions` | `(rate - baseline) * n`. Observed contrast, not incremental conversions |
186
+ | `inference` | `holdout_confirmation`, `holdout_underpowered`, `in_sample_post_selection`, or `density_cluster_descriptive` |
187
+
188
+ The opportunity score is a ranking heuristic. Weights, the min-max scaling, and the 0.35 confidence penalty for non-significant segments are written on the result (`opportunity_methodology`) and in the report. `scenario_extra_conversions_to_baseline` is what the count would be if the rate moved to the baseline. It is not a forecast.
189
+
190
+ ## Configuration
191
+
192
+ ```python
193
+ engine = vt.Analytics(
194
+ data=df,
195
+ target="converted",
196
+ id_column="customer_id",
197
+ positive_label=1, # inferred when omitted
198
+ value_column="cart_value", # pre-outcome value; leaked revenue is not used
199
+ date_column="signup_date",
200
+ treatment_column=None, # set this to run propensity matching
201
+ min_segment_size=None, # default max(50, 2% of rows)
202
+ max_combination_depth=2, # 1, 2, or 3
203
+ random_state=42,
204
+ test_size=0.30,
205
+ cv_folds=5,
206
+ n_bootstrap=200,
207
+ enable_shap=True, # skipped with a clear message if shap is absent
208
+ model_names=("logreg", "random_forest"),
209
+ spark_sample_limit=100_000,
210
+ llm_narrative=False, # True requires an llm_fn you supply
211
+ )
212
+ ```
213
+
214
+ `llm_narrative=True` calls your function with the computed insights. The library never contacts an LLM API on its own. `results.ask()` answers from the computed tables by keyword. Pass `use_llm=True` only when `llm_fn` is set.
215
+
216
+ ## Notebooks
217
+
218
+ - `examples/01_quickstart.ipynb`
219
+ - `examples/02_segmentation.ipynb`
220
+ - `examples/03_shap.ipynb`
221
+ - `examples/04_databricks.ipynb`
222
+ - `examples/05_telco_churn.ipynb` — IBM Telco churn check. Findings are in [docs/telco_churn.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/telco_churn.md). The CSV is downloaded, not vendored.
223
+ - `examples/VISTAAR_end_to_end.ipynb` — the 0.2 tour: deciles, segments inside the cut, profit, calibration, monitoring, champion/challenger, and Hillstrom uplift.
224
+
225
+ ## Development
226
+
227
+ ```bash
228
+ pip install -e ".[dev,shap]"
229
+ pytest
230
+ ```
231
+
232
+ The wheel build:
233
+
234
+ ```bash
235
+ python -m build
236
+ pip install dist/vistaar-*.whl
237
+ ```
@@ -0,0 +1,181 @@
1
+ # VISTAAR
2
+
3
+ VISTAAR profiles a conversion table, finds interpretable micro-segments, and reports lift, significance, and ranked opportunities. Pass a pandas or PySpark DataFrame and a binary target. The library stays local: no API key, no cloud service.
4
+
5
+ The numbers are observational. Relative lift is a segment's conversion rate divided by the overall baseline. Hypothesis tests compare the segment with its complement (everyone else), not with a baseline that includes the segment. A holdout split is used whenever the table is large enough, so the significance flag is not computed on the same rows that chose the rule. Scenario sizing is arithmetic. None of this is a causal effect.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install vistaar
11
+ pip install "vistaar[all]"
12
+ ```
13
+
14
+ Optional extras:
15
+
16
+ | Extra | What it adds |
17
+ | --- | --- |
18
+ | `shap` | SHAP explanations |
19
+ | `ml` | XGBoost, LightGBM, CatBoost |
20
+ | `hdbscan` | Density clustering |
21
+ | `spark` | PySpark, for machines that do not already have it |
22
+ | `all` | All of the above |
23
+
24
+ ```bash
25
+ pip install "vistaar[shap]"
26
+ ```
27
+
28
+ Python 3.10 or newer. Core dependencies are pandas, NumPy, SciPy, scikit-learn, statsmodels, Plotly, openpyxl, and tqdm. SHAP, gradient-boosted libraries, HDBSCAN, and PySpark are imported only when you use them.
29
+
30
+ From git, with every optional extra:
31
+
32
+ ```bash
33
+ pip install "git+https://github.com/thechinmayanand/vistaar.git#egg=vistaar[all]"
34
+ ```
35
+
36
+ GitHub release (wheel and sdist): https://github.com/thechinmayanand/vistaar/releases/tag/v0.3.1
37
+
38
+ From a clone, after `python -m build`:
39
+
40
+ ```bash
41
+ pip install dist/vistaar-*.whl
42
+ ```
43
+
44
+ Databricks notes are in [docs/databricks.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/databricks.md). Formulas are in [docs/methodology.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/methodology.md).
45
+
46
+ ## Quickstart
47
+
48
+ ```python
49
+ import vistaar as vt
50
+
51
+ df = vt.datasets.load_conversion()
52
+ engine = vt.Analytics(data=df, target="converted", id_column="customer_id")
53
+ results = engine.run()
54
+
55
+ results.summary()
56
+ results.segments()
57
+ results.lift()
58
+ results.opportunities()
59
+ results.shap()
60
+ results.deciles()
61
+ results.campaign(strategy="mass", top_deciles=2)
62
+ results.campaign(strategy="precision", target_precision=0.75, min_customers=100)
63
+ results.plot()
64
+ results.export("analytics_report.html")
65
+ ```
66
+
67
+ `run()` prints a stage bar (tqdm in a notebook or a TTY, one line per stage otherwise) and a timing summary. Pass `progress=False` to silence it. Reports and charts use the `vistaar` palette by default (navy, teal, and grey, no logo). `theme="hdfc"` opts into one built-in corporate theme. See [docs/branding.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/branding.md) and [docs/telco_churn.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/telco_churn.md).
68
+
69
+ Version 0.3.1 makes that neutral palette the default. Version 0.3 is the campaign autopilot: stratified sampling with a representativeness card, model choice on top-20% capture, a non-overlapping segment portfolio, and an audit trail of each automatic decision. Version 0.2 remains the profit cut, calibration, monitoring, registry, and uplift. The worked notebook is [examples/VISTAAR_end_to_end.ipynb](https://github.com/thechinmayanand/vistaar/blob/main/examples/VISTAAR_end_to_end.ipynb). The reference is [VISTAAR_User_Guide.md](https://github.com/thechinmayanand/vistaar/blob/main/VISTAAR_User_Guide.md).
70
+
71
+ ```python
72
+ inside = results.decile_segments(top_deciles=2)
73
+ profit = results.profit_curve(cost_per_contact=50, value_column="MonthlyCharges", value_multiplier=12)
74
+ results.optimal_cut(cost_per_contact=50, value_per_conversion=400)
75
+ calibration = results.calibration()
76
+ results.save_model("model.joblib")
77
+ loaded = vt.load_model("model.joblib")
78
+ loaded.monitor(new_month, actuals=new_month["churn"])
79
+ registry = vt.Registry("registry")
80
+ registry.register(results, model="catboost")
81
+ registry.promote(challenger, champion=champion)
82
+ uplift = results.uplift() # needs treatment_column= on Analytics
83
+ results.representativeness()
84
+ results.portfolio()
85
+ results.decisions()
86
+ results.reason_codes(df.head(200))
87
+ ```
88
+
89
+ `load_conversion()` returns a bundled synthetic table (about 8,000 customers) with a planted device × customer-type reversal, an organic × returning interaction, a confounded campaign flag, funnel steps, and leakage columns (`revenue`, `post_purchase_score`, `checkout_started`). Those leakage columns are detected and kept out of segmentation and models.
90
+
91
+ The same run also supports:
92
+
93
+ ```python
94
+ results.conversion_opportunities()
95
+ results.recommendations()
96
+ results.explore() # ranked surprises, with the numbers attached
97
+ results.ask("which segments convert best?")
98
+ results.what_if(target_rate=0.25, definition_contains="returning")
99
+ engine.compare(other_df) # PSI and KS
100
+ engine.estimate_effect() # only if treatment_column= was set
101
+ ```
102
+
103
+ Individual steps: `engine.profile()`, `engine.segment()`, `engine.calculate_lift(by="device")`, `engine.find_best_conversions()`, `engine.feature_importance()`, `engine.explain_with_shap()`, `engine.detect_anomalies()`, `engine.find_interactions()`, `engine.detect_simpsons()`, `engine.generate_insights()`.
104
+
105
+ An HTML report with the same sections:
106
+
107
+ ```python
108
+ report = engine.create_report(
109
+ output="html",
110
+ include=["profiling", "segmentation", "lift", "opportunities", "shap", "recommendations"],
111
+ )
112
+ report.save("analytics_report.html")
113
+ ```
114
+
115
+ `results.export` also writes `.xlsx`, `.csv` (the segment table), `.json`, `.md`, and `.png` (PNG needs `kaleido`).
116
+
117
+ ## What a segment row means
118
+
119
+ | Column | Meaning |
120
+ | --- | --- |
121
+ | `conversion_rate`, `n`, `conversions` | Full-sample description of this table |
122
+ | `baseline_rate` | Overall conversion rate in that same table |
123
+ | `absolute_lift` | Segment rate minus the baseline rate |
124
+ | `relative_lift` | Segment rate / baseline rate |
125
+ | `index` | `100 * relative_lift` |
126
+ | `p_value`, `p_value_adjusted`, `significant` | Holdout test against the complement, then Benjamini–Hochberg, when a holdout was used |
127
+ | `wilson_low`, `wilson_high` | Wilson interval for the full-sample rate |
128
+ | `replicates` | The holdout lift has the same sign as the training lift, with enough holdout rows |
129
+ | `observed_excess_conversions` | `(rate - baseline) * n`. Observed contrast, not incremental conversions |
130
+ | `inference` | `holdout_confirmation`, `holdout_underpowered`, `in_sample_post_selection`, or `density_cluster_descriptive` |
131
+
132
+ The opportunity score is a ranking heuristic. Weights, the min-max scaling, and the 0.35 confidence penalty for non-significant segments are written on the result (`opportunity_methodology`) and in the report. `scenario_extra_conversions_to_baseline` is what the count would be if the rate moved to the baseline. It is not a forecast.
133
+
134
+ ## Configuration
135
+
136
+ ```python
137
+ engine = vt.Analytics(
138
+ data=df,
139
+ target="converted",
140
+ id_column="customer_id",
141
+ positive_label=1, # inferred when omitted
142
+ value_column="cart_value", # pre-outcome value; leaked revenue is not used
143
+ date_column="signup_date",
144
+ treatment_column=None, # set this to run propensity matching
145
+ min_segment_size=None, # default max(50, 2% of rows)
146
+ max_combination_depth=2, # 1, 2, or 3
147
+ random_state=42,
148
+ test_size=0.30,
149
+ cv_folds=5,
150
+ n_bootstrap=200,
151
+ enable_shap=True, # skipped with a clear message if shap is absent
152
+ model_names=("logreg", "random_forest"),
153
+ spark_sample_limit=100_000,
154
+ llm_narrative=False, # True requires an llm_fn you supply
155
+ )
156
+ ```
157
+
158
+ `llm_narrative=True` calls your function with the computed insights. The library never contacts an LLM API on its own. `results.ask()` answers from the computed tables by keyword. Pass `use_llm=True` only when `llm_fn` is set.
159
+
160
+ ## Notebooks
161
+
162
+ - `examples/01_quickstart.ipynb`
163
+ - `examples/02_segmentation.ipynb`
164
+ - `examples/03_shap.ipynb`
165
+ - `examples/04_databricks.ipynb`
166
+ - `examples/05_telco_churn.ipynb` — IBM Telco churn check. Findings are in [docs/telco_churn.md](https://github.com/thechinmayanand/vistaar/blob/main/docs/telco_churn.md). The CSV is downloaded, not vendored.
167
+ - `examples/VISTAAR_end_to_end.ipynb` — the 0.2 tour: deciles, segments inside the cut, profit, calibration, monitoring, champion/challenger, and Hillstrom uplift.
168
+
169
+ ## Development
170
+
171
+ ```bash
172
+ pip install -e ".[dev,shap]"
173
+ pytest
174
+ ```
175
+
176
+ The wheel build:
177
+
178
+ ```bash
179
+ python -m build
180
+ pip install dist/vistaar-*.whl
181
+ ```