perdix 0.3.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 (163) hide show
  1. perdix-0.3.0/CHANGELOG.md +222 -0
  2. perdix-0.3.0/COPYING +674 -0
  3. perdix-0.3.0/COPYING.LESSER +165 -0
  4. perdix-0.3.0/LICENSE +37 -0
  5. perdix-0.3.0/MANIFEST.in +3 -0
  6. perdix-0.3.0/PKG-INFO +261 -0
  7. perdix-0.3.0/README.md +217 -0
  8. perdix-0.3.0/perdix/__init__.py +3 -0
  9. perdix-0.3.0/perdix/__main__.py +3 -0
  10. perdix-0.3.0/perdix/core/__init__.py +6 -0
  11. perdix-0.3.0/perdix/core/ai.py +496 -0
  12. perdix-0.3.0/perdix/core/analysis.py +598 -0
  13. perdix-0.3.0/perdix/core/chunked.py +202 -0
  14. perdix-0.3.0/perdix/core/codegen.py +185 -0
  15. perdix-0.3.0/perdix/core/contract.py +124 -0
  16. perdix-0.3.0/perdix/core/demo.py +58 -0
  17. perdix-0.3.0/perdix/core/evaluate.py +264 -0
  18. perdix-0.3.0/perdix/core/export_sklearn.py +185 -0
  19. perdix-0.3.0/perdix/core/export_sql.py +309 -0
  20. perdix-0.3.0/perdix/core/gp.py +425 -0
  21. perdix-0.3.0/perdix/core/io.py +161 -0
  22. perdix-0.3.0/perdix/core/params.py +234 -0
  23. perdix-0.3.0/perdix/core/recipe.py +455 -0
  24. perdix-0.3.0/perdix/core/registry.py +348 -0
  25. perdix-0.3.0/perdix/core/search.py +418 -0
  26. perdix-0.3.0/perdix/core/sklearn_export.py +128 -0
  27. perdix-0.3.0/perdix/core/stability.py +188 -0
  28. perdix-0.3.0/perdix/core/steps/__init__.py +18 -0
  29. perdix-0.3.0/perdix/core/steps/_checks.py +50 -0
  30. perdix-0.3.0/perdix/core/steps/binning.py +133 -0
  31. perdix-0.3.0/perdix/core/steps/categories.py +174 -0
  32. perdix-0.3.0/perdix/core/steps/clean.py +429 -0
  33. perdix-0.3.0/perdix/core/steps/datetime.py +282 -0
  34. perdix-0.3.0/perdix/core/steps/encode.py +608 -0
  35. perdix-0.3.0/perdix/core/steps/frame.py +15 -0
  36. perdix-0.3.0/perdix/core/steps/generate.py +421 -0
  37. perdix-0.3.0/perdix/core/steps/geo.py +186 -0
  38. perdix-0.3.0/perdix/core/steps/impute.py +296 -0
  39. perdix-0.3.0/perdix/core/steps/join.py +242 -0
  40. perdix-0.3.0/perdix/core/steps/scale.py +128 -0
  41. perdix-0.3.0/perdix/core/steps/select.py +534 -0
  42. perdix-0.3.0/perdix/core/steps/text.py +301 -0
  43. perdix-0.3.0/perdix/core/steps/timeseries.py +943 -0
  44. perdix-0.3.0/perdix/core/steps/transform.py +260 -0
  45. perdix-0.3.0/perdix/core/suggest.py +256 -0
  46. perdix-0.3.0/perdix/core/tables.py +110 -0
  47. perdix-0.3.0/perdix/docs/ai.md +109 -0
  48. perdix-0.3.0/perdix/docs/analysis.md +173 -0
  49. perdix-0.3.0/perdix/docs/cli.md +309 -0
  50. perdix-0.3.0/perdix/docs/concepts.md +204 -0
  51. perdix-0.3.0/perdix/docs/evaluation.md +260 -0
  52. perdix-0.3.0/perdix/docs/exports.md +107 -0
  53. perdix-0.3.0/perdix/docs/extending.md +265 -0
  54. perdix-0.3.0/perdix/docs/file-formats.md +194 -0
  55. perdix-0.3.0/perdix/docs/getting-started.md +284 -0
  56. perdix-0.3.0/perdix/docs/index.md +59 -0
  57. perdix-0.3.0/perdix/docs/leakage.md +214 -0
  58. perdix-0.3.0/perdix/docs/theory/binning.md +82 -0
  59. perdix-0.3.0/perdix/docs/theory/cleaning.md +191 -0
  60. perdix-0.3.0/perdix/docs/theory/datetime.md +124 -0
  61. perdix-0.3.0/perdix/docs/theory/encoding.md +254 -0
  62. perdix-0.3.0/perdix/docs/theory/generation.md +154 -0
  63. perdix-0.3.0/perdix/docs/theory/geo.md +61 -0
  64. perdix-0.3.0/perdix/docs/theory/imputation.md +106 -0
  65. perdix-0.3.0/perdix/docs/theory/joins.md +43 -0
  66. perdix-0.3.0/perdix/docs/theory/scaling.md +78 -0
  67. perdix-0.3.0/perdix/docs/theory/selection.md +245 -0
  68. perdix-0.3.0/perdix/docs/theory/text.md +109 -0
  69. perdix-0.3.0/perdix/docs/theory/time-series.md +309 -0
  70. perdix-0.3.0/perdix/docs/theory/transforms.md +133 -0
  71. perdix-0.3.0/perdix/docs/tutorials/customer-churn.md +136 -0
  72. perdix-0.3.0/perdix/docs/tutorials/energy-demand.md +110 -0
  73. perdix-0.3.0/perdix/docs/tutorials/house-prices.md +152 -0
  74. perdix-0.3.0/perdix/docs/tutorials/index.md +37 -0
  75. perdix-0.3.0/perdix/docs/tutorials/machine-failure.md +141 -0
  76. perdix-0.3.0/perdix/docs/tutorials/retail-transactions.md +138 -0
  77. perdix-0.3.0/perdix/docs/tutorials/support-tickets.md +111 -0
  78. perdix-0.3.0/perdix/docs/tutorials/turbofan-engines.md +203 -0
  79. perdix-0.3.0/perdix/docs/web.md +58 -0
  80. perdix-0.3.0/perdix/examples/__init__.py +97 -0
  81. perdix-0.3.0/perdix/examples/cmapss.py +199 -0
  82. perdix-0.3.0/perdix/examples/customer-churn/data.csv +5001 -0
  83. perdix-0.3.0/perdix/examples/customer-churn/recipe.toml +74 -0
  84. perdix-0.3.0/perdix/examples/energy-demand/data.csv +6553 -0
  85. perdix-0.3.0/perdix/examples/energy-demand/recipe.toml +54 -0
  86. perdix-0.3.0/perdix/examples/generate.py +352 -0
  87. perdix-0.3.0/perdix/examples/house-prices/data.csv +3001 -0
  88. perdix-0.3.0/perdix/examples/house-prices/recipe.toml +84 -0
  89. perdix-0.3.0/perdix/examples/machine-failure/data.csv +4321 -0
  90. perdix-0.3.0/perdix/examples/machine-failure/recipe.toml +80 -0
  91. perdix-0.3.0/perdix/examples/retail-transactions/data.csv +5241 -0
  92. perdix-0.3.0/perdix/examples/retail-transactions/recipe.toml +71 -0
  93. perdix-0.3.0/perdix/examples/retail-transactions/transactions.csv +22677 -0
  94. perdix-0.3.0/perdix/examples/support-tickets/data.csv +4001 -0
  95. perdix-0.3.0/perdix/examples/support-tickets/recipe.toml +76 -0
  96. perdix-0.3.0/perdix/examples/turbofan-engines/recipe.toml +134 -0
  97. perdix-0.3.0/perdix/gui/__init__.py +1 -0
  98. perdix-0.3.0/perdix/gui/app.py +66 -0
  99. perdix-0.3.0/perdix/gui/assets/logo.svg +1 -0
  100. perdix-0.3.0/perdix/gui/dialogs.py +467 -0
  101. perdix-0.3.0/perdix/gui/docs_view.py +364 -0
  102. perdix-0.3.0/perdix/gui/evaluate_page.py +419 -0
  103. perdix-0.3.0/perdix/gui/icons.py +163 -0
  104. perdix-0.3.0/perdix/gui/leakwatch.py +90 -0
  105. perdix-0.3.0/perdix/gui/logo.py +29 -0
  106. perdix-0.3.0/perdix/gui/main_window.py +1342 -0
  107. perdix-0.3.0/perdix/gui/memo.py +60 -0
  108. perdix-0.3.0/perdix/gui/models.py +206 -0
  109. perdix-0.3.0/perdix/gui/pages.py +1528 -0
  110. perdix-0.3.0/perdix/gui/panels.py +1177 -0
  111. perdix-0.3.0/perdix/gui/plots.py +286 -0
  112. perdix-0.3.0/perdix/gui/session.py +666 -0
  113. perdix-0.3.0/perdix/gui/settings.py +193 -0
  114. perdix-0.3.0/perdix/gui/step_editor.py +635 -0
  115. perdix-0.3.0/perdix/gui/suggestions.py +46 -0
  116. perdix-0.3.0/perdix/gui/tasks.py +119 -0
  117. perdix-0.3.0/perdix/gui/theme.py +405 -0
  118. perdix-0.3.0/perdix/gui/widgets.py +364 -0
  119. perdix-0.3.0/perdix/main.py +633 -0
  120. perdix-0.3.0/perdix/web/__init__.py +1 -0
  121. perdix-0.3.0/perdix/web/api.py +441 -0
  122. perdix-0.3.0/perdix/web/app.html +737 -0
  123. perdix-0.3.0/perdix/web/build.py +79 -0
  124. perdix-0.3.0/perdix/web/worker.js +52 -0
  125. perdix-0.3.0/perdix.egg-info/PKG-INFO +261 -0
  126. perdix-0.3.0/perdix.egg-info/SOURCES.txt +161 -0
  127. perdix-0.3.0/perdix.egg-info/dependency_links.txt +1 -0
  128. perdix-0.3.0/perdix.egg-info/entry_points.txt +5 -0
  129. perdix-0.3.0/perdix.egg-info/requires.txt +35 -0
  130. perdix-0.3.0/perdix.egg-info/top_level.txt +1 -0
  131. perdix-0.3.0/perdix.sh +20 -0
  132. perdix-0.3.0/pyproject.toml +74 -0
  133. perdix-0.3.0/setup.cfg +4 -0
  134. perdix-0.3.0/tests/conftest.py +61 -0
  135. perdix-0.3.0/tests/stepcheck.py +96 -0
  136. perdix-0.3.0/tests/test_advanced_fixes.py +177 -0
  137. perdix-0.3.0/tests/test_ai.py +259 -0
  138. perdix-0.3.0/tests/test_analysis.py +157 -0
  139. perdix-0.3.0/tests/test_chunked.py +124 -0
  140. perdix-0.3.0/tests/test_cli.py +121 -0
  141. perdix-0.3.0/tests/test_contract.py +98 -0
  142. perdix-0.3.0/tests/test_core.py +125 -0
  143. perdix-0.3.0/tests/test_docs.py +113 -0
  144. perdix-0.3.0/tests/test_encoders_new.py +177 -0
  145. perdix-0.3.0/tests/test_evaluate.py +350 -0
  146. perdix-0.3.0/tests/test_examples.py +619 -0
  147. perdix-0.3.0/tests/test_export_targets.py +233 -0
  148. perdix-0.3.0/tests/test_gp.py +338 -0
  149. perdix-0.3.0/tests/test_gui.py +195 -0
  150. perdix-0.3.0/tests/test_gui_fixes.py +333 -0
  151. perdix-0.3.0/tests/test_gui_new.py +420 -0
  152. perdix-0.3.0/tests/test_gui_newcomer.py +305 -0
  153. perdix-0.3.0/tests/test_gui_wiring.py +269 -0
  154. perdix-0.3.0/tests/test_join.py +208 -0
  155. perdix-0.3.0/tests/test_plugins.py +121 -0
  156. perdix-0.3.0/tests/test_regressions.py +186 -0
  157. perdix-0.3.0/tests/test_rename.py +81 -0
  158. perdix-0.3.0/tests/test_selection_new.py +100 -0
  159. perdix-0.3.0/tests/test_step_fixes.py +240 -0
  160. perdix-0.3.0/tests/test_steps_advanced.py +342 -0
  161. perdix-0.3.0/tests/test_steps_basic.py +340 -0
  162. perdix-0.3.0/tests/test_ts_domain.py +192 -0
  163. perdix-0.3.0/tests/test_web.py +162 -0
@@ -0,0 +1,222 @@
1
+ # Changelog
2
+
3
+ ## 0.3.0 (2026-11-02)
4
+
5
+ The first release on PyPI (`pip install perdix`), and the first under the name
6
+ Perdix: the name FeatureLab was taken there. It adds a split by group,
7
+ formulas bred by genetic programming, Ask Claude in rounds, the app in a
8
+ browser, the turbofan engines example and a start for newcomers.
9
+
10
+ ### Added
11
+
12
+ - A license: Perdix is free software under the GNU LGPL, version 3 or
13
+ later. What it generates (exported scripts, SQL, recipe files, pipelines,
14
+ transformed data) may be used under any terms; see LICENSE.
15
+ - Ask Claude in rounds (*Rounds* in the dialog, `perdix propose
16
+ --rounds`). Each round after the first tells Claude what its earlier
17
+ proposals gained on the training rows, or why they were dropped; held-out
18
+ scores are never sent. The prompt is cached across rounds.
19
+ - Find features can breed formulas by genetic programming (*Candidates from:
20
+ Genetic programming*, `perdix search --generator gp`): + − × ÷, log,
21
+ sqrt and abs over the numeric columns, bred on part of the training rows and
22
+ screened on the rest like any other candidate. Each formula found is a
23
+ *Formula* step. At the 20,000-row cap the breeding takes about 5 s, and a
24
+ search about as long as one over the fixed list.
25
+ - Perdix in a browser: `perdix webapp` writes one HTML file (about
26
+ 0.3 MB) that runs the core with Pyodide. It loads data and recipes, edits
27
+ steps, evaluates, finds features, checks for leakage and downloads the
28
+ recipe, the script or the output. Pyodide and its packages come from the
29
+ jsDelivr CDN on first open; the data stays in the browser.
30
+ - A split by group (*Split: Group*, `split = "group"`): whole groups of the group
31
+ column go to the training or the held-out rows, in a seeded order, so no
32
+ engine, machine or customer has rows on both sides. *Find features* and Ask
33
+ Claude's rounds keep groups whole in their own check on the training rows
34
+ too. A step that makes new rows keeps the training groups. FeatureLab 0.2.0
35
+ cannot read a recipe with this split.
36
+ - A seventh example and tutorial, *Turbofan engines*, on NASA's C-MAPSS data
37
+ (subset FD001, 100 engines run to failure): the remaining useful life of
38
+ each engine, the split by engine, smoothing, each engine's own history and
39
+ drift features. A random split scores the same recipe R²
40
+ 0.989 instead of 0.933. On NASA's own test engines, scored as published
41
+ results are, the recipe and the plain model *Evaluate* uses reach RMSE 12.1
42
+ (score 238), within the range of published deep networks. NASA states no
43
+ license for the data, so Perdix does not ship them: *Settings* (new,
44
+ Ctrl+,) has a *Datasets* section that downloads NASA's archive from NASA's
45
+ page, checks it and installs it in `~/.perdix`, or installs a copy we
46
+ downloaded ourselves; `perdix examples download turbofan-engines` does
47
+ the same. The browser app leaves this example out.
48
+ - *Formula* has a new option, *Infinite results become missing*. A parameter
49
+ added after 0.2.0 is saved only when it differs from its default, so a
50
+ recipe that leaves the option off still opens in FeatureLab 0.2.0.
51
+
52
+ - A start for newcomers. A table opened for a recipe without steps starts at
53
+ *Fit on* 80 % (the earliest rows with a time column, else a random sample),
54
+ and *Time* is set when the table has exactly one date/time column. Before,
55
+ it started at 100 %, where Evaluate cannot score and the leakage report
56
+ warns. A note in the Dataset card asks for the target while none is set.
57
+ Undo takes it all back. The web app starts a CSV file the same way.
58
+ - The empty Recipe card lists the first three suggested steps, each with a
59
+ reason and a *+*. Before, the suggestions were only under Evaluate.
60
+ - The leakage checks run in the background after every change, on the
61
+ recipe's output (at most 50,000 rows). The Analysis tab shows how many
62
+ findings there are, for example *Analysis (2)*, and a new high-severity
63
+ finding comes as a notification. Before, they ran only on *Run analysis*.
64
+ - *Find features* has a button on the app bar. *Ask Claude* says in its
65
+ dialog when the `anthropic` package is missing, before anything is asked.
66
+ - *Clip outliers* has a new option, *Outliers*: `clip` (as before), `missing`
67
+ (they become missing values, for an imputation step to fill) or `drop_rows`
68
+ (rows with an outlier are removed; not in a scikit-learn pipeline). The SQL
69
+ export writes all three; the plain scikit-learn export only clipping.
70
+ - *Best k* can score by chi-square (*Score: chi2*), for counts and 0/1 columns
71
+ against a class target.
72
+ - A new step, *Optimize memory* (`clean.compact`): floats as float32, integers
73
+ in the smallest type that holds them, and text with few distinct values as
74
+ category. Its fitted values show the memory before and after.
75
+ - The suggestions propose *Mostly missing* for columns that miss more than
76
+ half of their values, and leave those columns out of every other rule.
77
+ - `perdix suggest -o RECIPE` writes the suggestions as a recipe to start
78
+ from, with the roles and the 80 % split. `perdix -h` lists the commands
79
+ in groups, in the order of the work, and every command's `-h` has a
80
+ description.
81
+
82
+ ### Fixed
83
+
84
+ - The Data page cut off the first letters of a new or changed column's name:
85
+ its width left out the *+* or the dot before the name.
86
+ - Opening the demo after working on another table kept that table's recipe,
87
+ cleared its target and set none, while the notification named
88
+ `failure_24h`. The demo now starts a new recipe with its roles, one undo
89
+ away from the old one; a recipe made for the demo's data is kept.
90
+ - Opening an example over another table warned that the old recipe's roles
91
+ were "not in the data" before the example's recipe replaced them, and the
92
+ Dataset card named the file `data.csv` instead of the example.
93
+ - A step that needs a target or a time column said so even when it was set.
94
+ The note now shows only while the role is unset, as a warning.
95
+ - The *Split* buttons in the Dataset card were cut off at the default window
96
+ size ("arlies", "andor"), and with DejaVu Sans, the font Linux falls back on
97
+ without Inter, Segoe UI or Roboto. The left column now widens to what its
98
+ content needs.
99
+ - *Run analysis* could end at "Not run yet" with nothing to show. The
100
+ recompute that follows opening a table or editing the recipe refreshed the
101
+ page while the analysis ran, and the refresh cancelled it even when the data
102
+ and the recipe were unchanged. A run now finishes unless they change.
103
+ - pandas 3 works. It stores text as a string dtype, not `object`, so date
104
+ columns were not recognised; text with several UTC offsets now raises
105
+ instead of giving objects; and short codes like `M01` or `Mar` parse as
106
+ dates in year 1. All three are handled, and results under pandas 2 are
107
+ unchanged, bit for bit. Found by the new CI job on Python 3.12.
108
+ - A rare crash: Python's cycle collector could run in a background thread and
109
+ free Qt objects there. It now runs from a timer in the GUI thread.
110
+ - Ties between equally frequent values were broken by whatever order
111
+ `value_counts` gave, which changes with the numpy version. *Impute missing
112
+ values* with *most frequent* now takes the smallest of the tied numbers (as
113
+ scikit-learn does) or the first tied text, and the analysis's top
114
+ categories list ties by text. On columns where most values occur once this
115
+ changes the filled value; everything else is unchanged.
116
+ - Ask Claude summarised the wrong rows after a step that makes new rows
117
+ (resampling): it took the raw table's training split, so held-out rows
118
+ entered the statistics sent to Claude and the rows proposals were checked
119
+ on. It now uses the training split of the recipe's own output.
120
+
121
+ ### Changed
122
+
123
+ - FeatureLab is now Perdix: another project already has the name
124
+ `featurelab` on PyPI. The package, the import and the commands are
125
+ `perdix` and `perdix-gui`, the launcher is `perdix.sh`, and the environment
126
+ variables are `PERDIX_PLUGINS`, `PERDIX_CACHE_MB` and `PERDIX_VENV`.
127
+ Plugins go in `~/.perdix/plugins`; move them there from
128
+ `~/.featurelab/plugins`. A recipe keeps its format version under `perdix`.
129
+ One saved before, under `featurelab`, opens as before, and FeatureLab 0.2.0
130
+ opens the new ones. On its first start the GUI takes over FeatureLab's
131
+ settings and autosaved session. A pipeline pickled by FeatureLab
132
+ (`featurelab pipeline`) refers to `featurelab` classes and does not load
133
+ under Perdix: export it again.
134
+ - *Try the demo dataset* opens the Machine failure example's data (the demo
135
+ and the example were the same data under two names) with an empty recipe,
136
+ and Getting started's walkthrough beside it. The demo's data now have a
137
+ file, so the session restores them on the next start.
138
+ - Suggestions leave out a column that nearly equals the target (a target
139
+ proxy in the leakage report) and suggest dropping it with the identifiers.
140
+ On the churn example they no longer one-hot encode `cancellation_reason`.
141
+ - Getting started puts the first recipe before the tour of the window and
142
+ has a section on opening your own data. The README installs `.[io]` for
143
+ users; `dev` is for working on Perdix.
144
+ - With no step selected, the catalog's description box shrinks to a line, and
145
+ the Tables hint in the Dataset card to one line, so more steps fit.
146
+ - Find features scores candidates by what they add to a model that already
147
+ has every column (*Model gain*, after OpenFE's feature boosting) instead of
148
+ by mutual information, which is still offered (*Score by*, `perdix
149
+ search --method mi`). A copy of an existing column, or a transform of one,
150
+ no longer ranks high.
151
+ - Evaluate, Find features and Ask Claude start from the output the GUI has
152
+ already computed instead of fitting the recipe again. Scoring a candidate
153
+ or a proposal fits only the step it adds. The scores are unchanged, bit for
154
+ bit. A feature search on an 86,400 × 291 frame took 54 s and now takes 36 s.
155
+
156
+ ## 0.2.0 (2026-10-20)
157
+
158
+ This release adds most of the roadmap. A recipe can now be scored, checked
159
+ for drift, extended with suggested or searched features, and exported as SQL.
160
+ Every result of 0.1.0 is unchanged, bit for bit, unless a fix below says
161
+ otherwise.
162
+
163
+ ### Added
164
+
165
+ - Evaluation. `featurelab evaluate` and the *Evaluate* page score a recipe on
166
+ held-out rows with a gradient-boosting model, step by step, so we see
167
+ which steps earn their place.
168
+ - Stability. Population stability index per feature and adversarial
169
+ validation between training and held-out rows (`featurelab stability`, the
170
+ *Stability* tab under Analysis).
171
+ - Suggestions and search. `featurelab suggest` proposes steps from the data,
172
+ shown on the *Evaluate* page; `featurelab search` tries candidate features
173
+ and keeps those that score (*Features → Find features…*).
174
+ - Ask Claude (`featurelab propose`, *Features → Ask Claude for features…*).
175
+ Claude proposes features from a summary of the columns, never the rows.
176
+ Each proposal is checked and scored before it can be added. It needs `ANTHROPIC_API_KEY`
177
+ and the `ai` extra.
178
+ - Data contracts. `featurelab validate` checks new data against the types,
179
+ ranges and categories the recipe was fitted on.
180
+ - Second tables, listed under *Tables* in the dataset panel, and a
181
+ point-in-time aggregate step (`join.aggregate`) that joins them without
182
+ looking into the future.
183
+ - Geo steps: `geo.distance`, `geo.bearing` and `geo.geohash`.
184
+ - Encoders: weight of evidence, James–Stein, ordered target, rare-label
185
+ grouping and similarity encoding.
186
+ - Steps: `clean.fuzzy_group`, `ts.catch22`, `ts.decompose`, a forecast
187
+ `horizon` on the time-series steps, `datetime.holidays`, `text.embed`, and
188
+ the selectors `select.boruta`, `select.mrmr`, `select.permutation` and
189
+ `select.stability`. There are now 68 steps in 13 categories.
190
+ - Plugins. Steps in a plugin folder are loaded at start (`featurelab plugins`).
191
+ - Exports. `featurelab export-sql` writes a recipe as a SQL query, and
192
+ `featurelab export-sklearn` writes a plain scikit-learn pipeline. Both
193
+ cover a subset of the steps and say which ones they cannot export.
194
+ - Large data. `featurelab apply --chunksize` transforms a file in chunks. In
195
+ the GUI we can work on a sample: the first rows, a random sample, or the
196
+ earliest or latest rows by time.
197
+ - Documentation for all of the above, and a changelog.
198
+
199
+ ### Changed
200
+
201
+ - Run analysis no longer refits the recipe to find the training rows: the
202
+ session keeps them with each step's output. Mutual information runs on
203
+ threads. On an 86,400 × 291 frame the analysis took 26 s and now takes 15 s.
204
+ - k-means is bit-reproducible: it runs single-threaded under a lock.
205
+ - Steps and the GUI are faster (shallow copies, partial sorts for KNN,
206
+ segment indexers for rolling and expanding windows, deduplicated text).
207
+ - The GUI has a new design: an app bar, cards, a welcome screen, toasts and
208
+ a logo.
209
+ - scikit-learn 1.5 or newer is required.
210
+
211
+ ### Fixed
212
+
213
+ - About 70 bugs from five reviews. Among them: the training split with
214
+ repeated index labels, missing times and resampled bins; parsing of times
215
+ around daylight-saving changes; several encoders; focus in the step editor.
216
+
217
+ ## 0.1.0 (2026-10-20)
218
+
219
+ First release. A recipe engine with typed step parameters, a step registry,
220
+ training splits and exact pandas code generation; exports to a Python script
221
+ and a scikit-learn pipeline; profiling, correlation, VIF, target relevance and
222
+ a leakage report; a command line and a PySide6 GUI.