gitlabds 1.1.2__tar.gz → 2.1.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 (36) hide show
  1. gitlabds-2.1.0/PKG-INFO +1044 -0
  2. gitlabds-2.1.0/README.md +1024 -0
  3. gitlabds-2.1.0/gitlabds/__init__.py +12 -0
  4. gitlabds-2.1.0/gitlabds/baselines.py +352 -0
  5. gitlabds-2.1.0/gitlabds/config_generator.py +72 -0
  6. gitlabds-2.1.0/gitlabds/dummy.py +395 -0
  7. gitlabds-2.1.0/gitlabds/feature_reduction.py +528 -0
  8. gitlabds-2.1.0/gitlabds/memory_optimization.py +875 -0
  9. gitlabds-2.1.0/gitlabds/missing.py +365 -0
  10. gitlabds-2.1.0/gitlabds/model_evaluator.py +3519 -0
  11. gitlabds-2.1.0/gitlabds/monitoring_metrics.py +466 -0
  12. gitlabds-2.1.0/gitlabds/outliers.py +305 -0
  13. gitlabds-2.1.0/gitlabds/split_data.py +230 -0
  14. gitlabds-2.1.0/gitlabds/trends.py +485 -0
  15. gitlabds-2.1.0/gitlabds.egg-info/PKG-INFO +1044 -0
  16. {gitlabds-1.1.2 → gitlabds-2.1.0}/gitlabds.egg-info/SOURCES.txt +8 -3
  17. {gitlabds-1.1.2 → gitlabds-2.1.0}/gitlabds.egg-info/requires.txt +1 -0
  18. {gitlabds-1.1.2 → gitlabds-2.1.0}/setup.py +14 -1
  19. gitlabds-1.1.2/PKG-INFO +0 -444
  20. gitlabds-1.1.2/README.md +0 -433
  21. gitlabds-1.1.2/gitlabds/__init__.py +0 -9
  22. gitlabds-1.1.2/gitlabds/dummies.py +0 -236
  23. gitlabds-1.1.2/gitlabds/feature_reduction.py +0 -215
  24. gitlabds-1.1.2/gitlabds/memory_usage.py +0 -58
  25. gitlabds-1.1.2/gitlabds/model_metrics.py +0 -570
  26. gitlabds-1.1.2/gitlabds/outliers.py +0 -207
  27. gitlabds-1.1.2/gitlabds/split_data.py +0 -78
  28. gitlabds-1.1.2/gitlabds.egg-info/PKG-INFO +0 -444
  29. {gitlabds-1.1.2 → gitlabds-2.1.0}/LICENSE +0 -0
  30. {gitlabds-1.1.2 → gitlabds-2.1.0}/gitlabds/insights.py +0 -0
  31. {gitlabds-1.1.2 → gitlabds-2.1.0}/gitlabds/missing_check.py +0 -0
  32. {gitlabds-1.1.2 → gitlabds-2.1.0}/gitlabds/missing_fill.py +0 -0
  33. {gitlabds-1.1.2 → gitlabds-2.1.0}/gitlabds.egg-info/dependency_links.txt +0 -0
  34. {gitlabds-1.1.2 → gitlabds-2.1.0}/gitlabds.egg-info/top_level.txt +0 -0
  35. {gitlabds-1.1.2 → gitlabds-2.1.0}/setup.cfg +0 -0
  36. {gitlabds-1.1.2 → gitlabds-2.1.0}/tests/__init__.py +0 -0
@@ -0,0 +1,1044 @@
1
+ Metadata-Version: 2.1
2
+ Name: gitlabds
3
+ Version: 2.1.0
4
+ Summary: Gitlab Data Science and Modeling Tools
5
+ Home-page: https://gitlab.com/gitlab-data/gitlabds
6
+ Author: Kevin Dietz
7
+ Author-email: kdietz@gitlab.com
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
14
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Classifier: Topic :: Utilities
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+
21
+ [![PyPI version](https://badge.fury.io/py/gitlabds.svg)](https://badge.fury.io/py/gitlabds)
22
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
23
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
24
+
25
+ # gitlabds
26
+
27
+ ## What is it?
28
+ gitlabds is a Python toolkit that streamlines the machine learning workflows with specialized functions for data preparation, feature engineering, model evaluation, and deployment. It helps data scientists focus on providing consistent patterns for both experimentation and production pipelines.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install gitlabds
34
+ ```
35
+
36
+ ### Requirements
37
+
38
+ - Python 3.10 or later
39
+ - Core dependencies:
40
+ - pandas>=2.1.4
41
+ - numpy>=1.26.4
42
+ - scipy>=1.13.1
43
+ - scikit-learn>=1.5.1
44
+ - imbalanced-learn>=0.12.3
45
+ - seaborn>=0.13.2
46
+ - shap>=0.46.0
47
+ - tqdm>=4.66.1
48
+
49
+ ## Main Features by Category
50
+
51
+ ### Data Preparation
52
+
53
+ #### Outlier Detection and Treatment
54
+ <details><summary> MAD Outliers </summary>
55
+
56
+ #### Description
57
+ Median Absolute Deviation for outlier detection and correction. By default will windsor all numeric values in your dataframe that are more than 4 standard deviations above or below the median ('threshold').
58
+
59
+ `gitlabds.mad_outliers(df, dv=None, min_levels=10, columns='all', threshold=4.0, auto_adjust_skew=False, verbose=True, windsor_threshold=0.01):`
60
+
61
+ #### Parameters:
62
+ - **_df_** : your pandas dataframe
63
+ - **_dv_** : The column name of your outcome. Entering your outcome variable in will prevent it from being windsored. May be left blank there is no outcome variable.
64
+ - **_min_levels_** : Only include columns that have at least the number of levels specified.
65
+ - **_columns_** : Will examine at all numeric columns by default. To limit to just a subset of columns, pass a list of column names. Doing so will ignore any constraints put on by the 'dv' and 'min_levels' paramaters.
66
+ - **_threshold_** : Windsor values greater than this number of standard deviations from the median.
67
+ - **_auto_adjust_skew_** : Whether to adjust thresholds based on column skewness
68
+ - **_verbose_** : Set to `True` to print outputs of windsoring being done. Set to `False` to suppress.
69
+ - **_windsor_threshold_** : Only windsor values that affect less than this percentage of the population.
70
+
71
+ #### Returns
72
+ - Tuple containing:
73
+ - The transformed DataFrame by windsoring outliers
74
+ - Dictionary of outlier limits that can be used with apply_outliers()
75
+
76
+ #### Examples:
77
+
78
+ ```python
79
+ # Create a new df; only windsor selected columns; suppress verbose
80
+ import gitlabds
81
+ new_df, outlier_limits = gitlabds.mad_outliers(df=my_df, dv='my_outcome', columns=['colA', 'colB', 'colC'], verbose=False)
82
+ ```
83
+ ```python
84
+ # Windsor values with skew adjustment for highly skewed data
85
+ new_df, outlier_limits = gitlabds.mad_outliers(df=my_df, threshold=3.0, auto_adjust_skew=True)
86
+ ```
87
+ </details>
88
+
89
+ <details><summary> Apply Outliers </summary>
90
+
91
+ #### Description
92
+ Apply previously determined outlier limits to a dataframe. This is typically used to apply the same outlier treatment to new data that was applied during model training.
93
+
94
+ `gitlabds.apply_outliers(df, outlier_limits):`
95
+
96
+ #### Parameters:
97
+ - **_df_** : The dataframe to transform
98
+ - **_outlier_limits_** : dictionary of outlier limits previously generated by mad_outliers()
99
+
100
+ #### Returns
101
+ - DataFrame with outlier limits applied.
102
+
103
+ #### Examples:
104
+
105
+ ```python
106
+ # Find outliers in training data
107
+ train_df, outlier_limits = gitlabds.mad_outliers(df=train_data, dv='target', threshold=3.0)
108
+
109
+ # Apply same outlier limits to test data
110
+ test_df_transformed = gitlabds.apply_outliers(df=test_data, outlier_limits=outlier_limits)
111
+ ```
112
+ </details>
113
+
114
+ #### Missing Value Handling
115
+ <details><summary> Missing Values </summary>
116
+
117
+ #### Description
118
+ Detect and optionally fill missing values in a DataFrame, with support for various filling methods and detailed reporting.
119
+
120
+ `gitlabds.missing_values(df, threshold=0.0, method=None, columns="all", constant_value=None, verbose=True, operation="both")`
121
+
122
+ #### Parameters:
123
+ - **_df_** : Your pandas dataframe
124
+ - **_threshold_** : The percent of missing values at which a column is considered for processing. For example, threshold=0.10 will only process columns with more than 10% missing values.
125
+ - **_method_** : Method to fill missing values or dictionary mapping columns to methods. Options:
126
+ - "mean": Fill with column mean (numeric only)
127
+ - "median": Fill with column median (numeric only)
128
+ - "zero": Fill with 0
129
+ - "constant": Fill with the value specified in constant_value
130
+ - "random": Fill with random values sampled from the column's distribution
131
+ - "drop_column": Remove columns with missing values
132
+ - "drop_row": Remove rows with any missing values in specified columns
133
+ - **_columns_** : Columns to check and/or fill. If "all", processes all columns with missing values.
134
+ - **_constant_value_** : Value to use when method="constant" or when specified columns use the constant method.
135
+ - **_verbose_** : Whether to print detailed information about missing values and filling operations.
136
+ - **_operation_** : Operation mode:
137
+ - "check": Only check for missing values, don't fill
138
+ - "fill": Fill missing values and return filled dataframe
139
+ - "both": Check and fill missing values (default)
140
+
141
+ #### Returns
142
+ - If operation="check": List of column names with missing values (or None)
143
+ - If operation="fill" or "both": Tuple containing:
144
+ - DataFrame with missing values handled
145
+ - Dictionary with missing value information that can be used with apply_missing_fill()
146
+
147
+ #### Examples:
148
+ ```python
149
+ # Just check for missing values
150
+ missing_columns = gitlabds.missing_values(df, threshold=0.05, operation="check")
151
+
152
+ # Fill all columns with mean value
153
+ df_filled, missing_info = gitlabds.missing_values(df, method="mean")
154
+
155
+ # Fill different columns with different methods
156
+ df_filled, missing_info = gitlabds.missing_values(
157
+ df,
158
+ method={"numeric_col": "median", "string_col": "constant"},
159
+ constant_value="Unknown",
160
+ verbose=True
161
+ )
162
+ ```
163
+ </details>
164
+
165
+ <details><summary> Apply Missing Values </summary>
166
+
167
+ #### Description
168
+ Apply previously determined missing value handling to a dataframe.
169
+
170
+ `gitlabds.apply_missing_values(df, missing_info):`
171
+
172
+ #### Parameters:
173
+ - **_df_** : The dataframe to transform
174
+ - **_missing_info_** : Dictionary of missing value information previously generated by `missing_values()`
175
+
176
+ #### Returns
177
+ - DataFrame with missing values handled according to the provided information.
178
+
179
+ #### Examples:
180
+ ```python
181
+ # Generate missing value info from training data
182
+ _, missing_info = gitlabds.missing_values(train_df, method="mean")
183
+
184
+ # Apply to test data
185
+ test_df_filled = gitlabds.apply_missing_values(test_df, missing_info)
186
+ ```
187
+ </details>
188
+
189
+ #### Feature Engineering
190
+ <details><summary> Dummy Code </summary>
191
+
192
+ #### Description
193
+ Dummy code (AKA "one-hot encode") categorical and numeric columns based on the paremeters specificed below. Note: categorical columns will be dropped after they are dummy coded; numeric columns will not
194
+
195
+ `gitlabds.dummy_code(df, dv=None, columns='all', categorical=True, numeric=True, categorical_max_levels=20, numeric_max_levels=10, dummy_na=False, prefix_sep="_dummy_", verbose=True):`
196
+
197
+ #### Parameters:
198
+ - **_df_** : Your pandas dataframe
199
+ - **_dv_** : The column name of your outcome. Entering your outcome variable will prevent it from being dummy coded. May be left blank if there is no outcome variable.
200
+ - **_columns_** : Will examine all columns by default. To limit to just a subset of columns, pass a list of column names.
201
+ - **_categorical_** : Set to `True` to attempt to dummy code any categorical column passed via the `columns` parameter.
202
+ - **_numeric_** : Set to `True` to attempt to dummy code any numeric column passed via the `columns` parameter.
203
+ - **_categorical_max_levels_** : Maximum number of levels a categorical column can have to be eligible for dummy coding.
204
+ - **_numeric_max_levels_** : Maximum number of levels a numeric column can have to be eligible for dummy coding.
205
+ - **_dummy_na_** : Set to `True` to create a dummy coded column for missing values.
206
+ - **_prefix_sep_** : String to use as separator between column name and value in dummy column names. Default is "_dummy_".
207
+ - **_verbose_** : Set to `True` to print outputs of dummy coding being done. Set to `False` to suppress.
208
+
209
+ #### Returns
210
+ - A tuple containing:
211
+ - The transformed DataFrame with dummy-coded columns. Categorical columns that were dummy coded will be dropped from the dataframe.
212
+ - A dictionary containing information about dummy coding that can be used with `apply_dummy()` to transform new data consistently.
213
+
214
+ #### Examples:
215
+
216
+ ```python
217
+ # Dummy code only categorical columns with a maximum of 30 levels; suppress verbose output
218
+ import gitlabds
219
+ new_df, dummy_dict = gitlabds.dummy_code(
220
+ df=my_df,
221
+ dv='my_outcome',
222
+ columns='all',
223
+ categorical=True,
224
+ numeric=False,
225
+ categorical_max_levels=30,
226
+ verbose=False
227
+ )
228
+ ```
229
+
230
+ ```python
231
+ # Dummy code with custom separator
232
+ new_df, dummy_dict = gitlabds.dummy_code(
233
+ df=my_df,
234
+ columns=['colA', 'colB', 'colC'],
235
+ categorical=True,
236
+ numeric=True,
237
+ prefix_sep="_is_"
238
+ )
239
+ ```
240
+ </details>
241
+
242
+ <details><summary> Dummy Top </summary>
243
+
244
+ #### Description
245
+ Dummy codes only categorical levels above a certain threshold of the population. Useful when a column contains many levels but there is not a need or desire to dummy code every level. Currently only works for categorical columns.
246
+
247
+ `gitlabds.dummy_top(df, dv=None, columns='all', min_threshold=0.05, drop_categorical=True, prefix_sep="_dummy_", verbose=True):`
248
+
249
+ #### Parameters:
250
+ - **_df_** : Your pandas dataframe
251
+ - **_dv_** : The column name of your outcome. Entering your outcome variable will prevent it from being dummy coded. May be left blank if there is no outcome variable.
252
+ - **_columns_** : Will examine all columns by default. To limit to just a subset of columns, pass a list of column names.
253
+ - **_min_threshold_**: The threshold at which levels will be dummy coded. For example, the default value of `0.05` will dummy code any categorical level that is in at least 5% of all rows.
254
+ - **_drop_categorical_**: Set to `True` to drop categorical columns after they are considered for dummy coding. Set to `False` to keep the original categorical columns in the dataframe.
255
+ - **_prefix_sep_** : String to use as separator between column name and value in dummy column names. Default is "_dummy_".
256
+ - **_verbose_** : Set to `True` to print detailed list of all dummy columns being created. Set to `False` to suppress.
257
+
258
+ #### Returns
259
+ - A tuple containing:
260
+ - The transformed DataFrame with dummy-coded columns for high-frequency values.
261
+ - A dictionary containing information about dummy coding that can be used with `apply_dummy()` to transform new data consistently.
262
+
263
+ #### Examples:
264
+
265
+ ```python
266
+ # Dummy code all categorical levels from all categorical columns whose values are in at least 5% of all rows
267
+ import gitlabds
268
+ new_df, dummy_top_dict = gitlabds.dummy_top(
269
+ df=my_df,
270
+ dv='my_outcome',
271
+ columns='all',
272
+ min_threshold=0.05,
273
+ drop_categorical=True,
274
+ verbose=True
275
+ )
276
+ ```
277
+
278
+ ```python
279
+ # Dummy code all categorical levels from the selected columns whose values are in at least 10% of all rows;
280
+ # suppress verbose printout and retain original categorical columns
281
+ new_df, dummy_top_dict = gitlabds.dummy_top(
282
+ df=my_df,
283
+ dv='my_outcome',
284
+ columns=['colA', 'colB', 'colC'],
285
+ min_threshold=0.10,
286
+ drop_categorical=False,
287
+ verbose=False
288
+ )
289
+ ```
290
+ </details>
291
+
292
+ <details><summary> Apply Dummy </summary>
293
+
294
+ #### Description
295
+ Apply previously determined dummy coding to a new dataframe. This is typically used to apply the same dummy coding to new data that was created during model training.
296
+
297
+ `gitlabds.apply_dummy(df, dummy_info, drop_original=False):`
298
+
299
+ #### Parameters:
300
+ - **_df_** : The dataframe to transform
301
+ - **_dummy_info_** : Dictionary of dummy coding information previously generated by `dummy_code()` or `dummy_top()`
302
+ - **_drop_original_** : Whether to drop the original columns after dummy coding. Default is `False`.
303
+
304
+ #### Returns
305
+ - DataFrame with dummy coding applied according to the provided information.
306
+
307
+ #### Examples:
308
+
309
+ ```python
310
+ # Generate dummy coding information from training data
311
+ train_df, dummy_info = gitlabds.dummy_code(df=train_data, dv='target')
312
+
313
+ # Apply to test data
314
+ test_df_transformed = gitlabds.apply_dummy(
315
+ df=test_data,
316
+ dummy_info=dummy_info
317
+ )
318
+ ```
319
+ </details>
320
+
321
+ #### Feature Selection
322
+ <details><summary> Remove Low Variation </summary>
323
+
324
+ #### Description
325
+ Remove columns from a dataset that do not meet the variation threshold. That is, columns will be dropped that contain a high percentage of one value.
326
+
327
+ `gitlabds.remove_low_variation(df=None, dv=None, columns='all', threshold=.98, verbose=True):`
328
+
329
+ #### Parameters:
330
+ - _**df**_ : your pandas dataframe
331
+ - **_dv_** : The column name of your outcome. Entering your outcome variable in will prevent it from being removed due to low variation. May be left blank there is no outcome variable.
332
+ - **_columns_** : Will examine at all columns by default. To limit to just a subset of columns, pass a list of column names.
333
+ - **_threshold_**: The maximum percentage one value in a column can represent. columns that exceed this threshold will be dropped. For example, the default value of `0.98` will drop any column where one value is present in more than 98% of rows.
334
+ - **_verbose_** : Set to `True` to print outputs of columns being dropped. Set to `False` to suppress.
335
+
336
+ #### Returns
337
+ - DataFrame with low variation columns dropped.
338
+
339
+ #### Examples:
340
+ ```python
341
+ # Drop any columns (except for the outcome) where one value is present in more than 95% of rows.
342
+ new_df = gitlabds.remove_low_variation(df=my_df, dv='my_outcome', columns='all', threshold=.95)
343
+ ```
344
+ ```python
345
+ # Drop any of the selected columns where one value is present in more than 99% of rows.
346
+ new_df = gitlabds.remove_low_variation(df=my_df, dv=None, columns=['colA', 'colB', 'colC'], threshold=.99)
347
+ ```
348
+ </details>
349
+
350
+ <details><summary> Correlation Reduction </summary>
351
+
352
+ #### Description
353
+ Reduce the number of columns on a dataframe by dropping columns that are highly correlated with other columns. Note: only one of the two highly correlated columns will be dropped.
354
+
355
+ `gitlabds.correlation_reduction(df=None, dv=None, threshold=0.9, method="pearson", verbose=True):`
356
+
357
+ #### Parameters:
358
+ - _**df**_ : your pandas dataframe
359
+ - **_dv_** : The column name of your outcome. Entering your outcome variable will prevent it from being dropped. If provided, when choosing between correlated features, the one with higher correlation to the target will be kept.
360
+ - **_threshold_**: The threshold above which columns will be dropped. If two variables exceed this threshold, one will be dropped from the dataframe. For example, the default value of `0.90` will identify columns that have correlations greater than 90% to each other and drop one of those columns.
361
+ - **_method_**: The correlation method to use. Options are "pearson" (linear relationships), "spearman" (monotonic relationships), or "mutual_info" (any statistical dependency).
362
+ - **_verbose_** : Set to `True` to print outputs of columns being dropped. Set to `False` to suppress.
363
+
364
+ #### Returns
365
+ - DataFrame with redundant correlated columns dropped.
366
+
367
+ #### Examples:
368
+ ```python
369
+ # Perform column reduction via correlation using a threshold of 95%, excluding the outcome column.
370
+ new_df = gitlabds.correlation_reduction(df=my_df, dv='my_outcome', threshold=0.95, method="pearson")
371
+ ```
372
+ ```python
373
+ # Perform column reduction using Spearman rank correlation with a threshold of 90%.
374
+ new_df = gitlabds.correlation_reduction(df=my_df, dv=None, threshold=0.90, method="spearman")
375
+ ```
376
+ </details>
377
+
378
+ <details><summary> Remove Outcome Proxies </summary>
379
+
380
+ #### Description
381
+ Remove columns that are highly correlated with the outcome (target) column.
382
+
383
+ `gitlabds.remove_outcome_proxies(df, dv, threshold=.8, method="pearson", verbose=True):`
384
+
385
+ #### Parameters:
386
+ - _**df**_ : your pandas dataframe
387
+ - _**dv**_ : The column name of your outcome.
388
+ - _**threshold**_ : The correlation value to the outcome above which columns will be dropped. For example, the default value of `0.80` will identify and drop columns that have correlations greater than 80% to the outcome.
389
+ - **_method_**: The correlation method to use. Options are "pearson" (linear relationships), "spearman" (monotonic relationships), or "mutual_info" (any statistical dependency).
390
+ - **_verbose_** : Set to `True` to print outputs of columns being dropped. Set to `False` to suppress.
391
+
392
+ #### Returns
393
+ - DataFrame with outcome proxy columns dropped.
394
+
395
+ #### Examples:
396
+ ```python
397
+ # Drop columns with correlations to the outcome greater than 70%
398
+ new_df = gitlabds.remove_outcome_proxies(df=my_df, dv='my_outcome', threshold=.7)
399
+ ```
400
+ ```python
401
+ # Drop columns with correlations to the outcome greater than 80% using Spearman correlation
402
+ new_df = gitlabds.remove_outcome_proxies(df=my_df, dv='my_outcome', threshold=.8, method="spearman")
403
+ ```
404
+ </details>
405
+
406
+ <details><summary> Drop Categorical </summary>
407
+
408
+ #### Description
409
+ Drop all categorical columns from the dataframe. A useful step before regression modeling, as categorical variables are not used.
410
+
411
+ `gitlabds.drop_categorical(df):`
412
+
413
+ #### Parameters:
414
+ - _**df**_ : your pandas dataframe
415
+
416
+ #### Returns
417
+ - DataFrame with categorical columns dropped.
418
+
419
+ #### Examples:
420
+ ```python
421
+ # Dropping categorical columns
422
+ new_df = gitlabds.drop_categorical(df=my_df)
423
+ ```
424
+ </details>
425
+
426
+ #### Memory Optimization
427
+ <details><summary> Memory Optimization </summary>
428
+
429
+ #### Description
430
+ Apply multiple memory optimization techniques to dramatically reduce DataFrame memory usage.
431
+
432
+ `gitlabds.memory_optimization(df, apply_numeric_downcasting=True, apply_categorical=True, apply_sparse=True, precision_mode='balanced', verbose=True, exclude_columns=None, **kwargs):`
433
+
434
+ #### Parameters:
435
+ - **_df_** : Input pandas dataframe to optimize
436
+ - **_apply_numeric_downcasting_** : Whether to downcast numeric columns to smaller data types. Defaults to `True`.
437
+ - **_apply_categorical_** : Whether to convert string columns to categorical when beneficial. Defaults to `True`.
438
+ - **_apply_sparse_** : Whether to apply sparse encoding for columns with many repeated values. Defaults to `True`.
439
+ - **_precision_mode_**: str, default="balanced"
440
+ Controls aggressiveness of numeric downcasting:
441
+ - "aggressive": Maximum memory savings, may affect precision
442
+ - "balanced": Good memory savings while preserving most precision
443
+ - "safe": Conservative downcasting to preserve numeric precision
444
+ - **_verbose_** : Whether to print progress and memory statistics. Defaults to `True`.
445
+ - **_exclude_columns_** : List of columns to exclude from optimization. Defaults to `None`.
446
+ - **_**kwargs_** : Additional arguments for optimization techniques
447
+
448
+ #### Returns
449
+ - Memory-optimized pandas DataFrame.
450
+
451
+ #### Examples:
452
+
453
+ ```python
454
+ # Basic optimization with default settings
455
+ import gitlabds
456
+ df_optimized = gitlabds.memory_optimization(df)
457
+ ```
458
+ ```python
459
+ # Customize optimization approach
460
+ df_optimized = gitlabds.memory_optimization(
461
+ df,
462
+ apply_numeric_downcasting=True,
463
+ apply_categorical=True,
464
+ apply_sparse=False, # Skip sparse encoding
465
+ precision_mode='safe'
466
+ exclude_columns=['id', 'timestamp'],
467
+ verbose=True
468
+ )
469
+ ```
470
+ </details>
471
+
472
+ ### Model Development
473
+
474
+ #### Data Splitting and Sampling
475
+ <details><summary> Split Data </summary>
476
+
477
+ #### Description
478
+ This function splits your data into train and test datasets, separating the outcome from the rest of the file. It supports stratified sampling, balanced upsampling for imbalanced datasets, and provides model weights for compensating sampling adjustments.
479
+
480
+ `gitlabds.split_data(df, train_pct=0.7, dv=None, dv_threshold=0.0, random_state=5435, stratify=True, sampling_strategy=None, shuffle=True, verbose=True):`
481
+
482
+ #### Parameters:
483
+ - **_df_** : your pandas dataframe
484
+ - **_train_pct_** : The percentage of rows randomly assigned to the training dataset. Defaults to 0.7 (70% train, 30% test).
485
+ - **_dv_** : The column name of your outcome. If None, the function will return the entire dataframe split without separating features and target.
486
+ - **_dv_threshold_** : The minimum percentage of rows that must contain a positive instance (i.e. > 0) of the outcome. SMOTE/SMOTE-NC will be used to upsample positive instances until this threshold is reached. Can be disabled by setting to 0. Only accepts values 0 to 0.5.
487
+ - **_random_state_** : Random seed to use for splitting dataframe and for up-sampling (if needed).
488
+ - **_stratify_** : Controls stratified sampling. If True and dv is provided, stratifies by the outcome variable. If a list of column names, stratifies by those columns. If False, does not use stratified sampling.
489
+ - **_sampling_strategy_** : Sampling strategy for imbalanced data. If None, will use dv_threshold. See imblearn documentation for more details on acceptable values.
490
+ - **_shuffle_** : Whether to shuffle the data before splitting.
491
+ - **_verbose_** : Whether to print information about the splitting process.
492
+
493
+ #### Returns
494
+ - A tuple containing:
495
+ - x_train: Training features DataFrame
496
+ - y_train: Training target Series (if dv is provided, otherwise empty Series)
497
+ - x_test: Testing features DataFrame
498
+ - y_test: Testing target Series (if dv is provided, otherwise empty Series)
499
+ - model_weights: List of weights to use for modeling [negative_class_weight, positive_class_weight]
500
+
501
+ #### Examples:
502
+
503
+ ```python
504
+ # Basic split with default parameters (70% train, 30% test)
505
+ x_train, y_train, x_test, y_test, model_weights = gitlabds.split_data(
506
+ df=my_df,
507
+ dv='my_outcome'
508
+ )
509
+ ```
510
+
511
+ ```python
512
+ # Split with 80% training data and balancing for imbalanced target
513
+ x_train, y_train, x_test, y_test, model_weights = gitlabds.split_data(
514
+ df=my_df,
515
+ dv='my_outcome',
516
+ train_pct=0.80,
517
+ dv_threshold=0.3
518
+ )
519
+ ```
520
+
521
+ ```python
522
+ # Split with stratification on multiple variables
523
+ x_train, y_train, x_test, y_test, model_weights = gitlabds.split_data(
524
+ df=my_df,
525
+ dv='my_outcome',
526
+ stratify=['my_outcome', 'region', 'customer_segment']
527
+ )
528
+ ```
529
+
530
+ ```python
531
+ # Split entire dataframe without separating target
532
+ train_df, _, test_df, _, _ = gitlabds.split_data(
533
+ df=my_df,
534
+ dv=None,
535
+ train_pct=0.75
536
+ )
537
+ ```
538
+ </details>
539
+
540
+ #### Model Configuration
541
+ <details><summary> ConfigGenerator </summary>
542
+
543
+ #### Description
544
+ A simple, flexible configuration builder for creating YAML files with any structure. This utility allows you to build complex, nested configuration files programmatically without being constrained to a predefined structure.
545
+
546
+ `gitlabds.ConfigGenerator(**kwargs):`
547
+
548
+ #### Parameters:
549
+ - **_**kwargs_** : Initial configuration values to populate the configuration object with
550
+
551
+ #### Methods:
552
+
553
+ ##### `add(path, value)`
554
+ Add or update a value at a specific path in the configuration.
555
+
556
+ - **_path_**: String using dot-notation to specify the location (e.g., 'model.parameters.learning_rate')
557
+ - **_value_**: Any value to set at the specified path
558
+
559
+ ##### `to_yaml(file_path)`
560
+ Write the configuration to a YAML file.
561
+
562
+ - **_file_path_**: Path to the output YAML file
563
+
564
+ #### Returns
565
+ - ConfigGenerator object for method chaining
566
+
567
+ #### Examples:
568
+ ```python
569
+ # Initialize with some top-level parameters
570
+ config = ConfigGenerator(
571
+ model_name="churn_prediction",
572
+ version="1.0.0",
573
+ unique_id="customer_id"
574
+ )
575
+
576
+ # Add nested model parameters
577
+ config.add("model.file", "xgboost_model.pkl")
578
+ config.add("model.parameters.learning_rate", 0.01)
579
+ config.add("model.parameters.max_depth", 6)
580
+
581
+ # Add preprocessing information from outlier detection and dummy coding
582
+ config.add("preprocessing.outliers", outlier_info)
583
+ config.add("preprocessing.dummy_coding", dummy_info)
584
+
585
+ # Add query information
586
+ config.add("query_parameters.query_file", "customer_data.sql")
587
+ config.add("query_parameters.lookback_months", 12)
588
+
589
+ # Save to YAML
590
+ config.to_yaml("churn_model_config.yaml")
591
+ ```
592
+ </details>
593
+
594
+ ### Model Evaluation
595
+
596
+ <details><summary> ModelEvaluator </summary>
597
+
598
+ #### Description
599
+ A comprehensive framework for evaluating machine learning models, supporting both classification (binary and multi-class) and regression models. It provides extensive evaluation metrics, visualizations, and feature importance analysis.
600
+
601
+ `gitlabds.ModelEvaluator(model, x_train, y_train, x_test, y_test, x_oot=None, y_oot=None, classification=True, algo=None, f1_threshold=0.50, decile_n=10, top_features_n=20, show_all_classes=True, show_plots=True, save_plots=True, plot_dir='plots', plot_save_format='png', plot_save_dpi=300)`
602
+
603
+ #### Parameters:
604
+ - _**model**_ : The trained model to evaluate. Must have predict for regression and predict_proba method for classification
605
+ - _**x_train**_ : Training features DataFrame.
606
+ - _**y_train**_ : Training labels (Series or DataFrame).
607
+ - _**x_test**_ : Test features DataFrame.
608
+ - _**y_test**_ : Test labels (Series or DataFrame).
609
+ - _**x_oot**_ : Optional out-of-time validation features.
610
+ - _**y_oot**_ : Optional out-of-time validation labels.
611
+ - _**classification**_ : Whether this is a classification model. If False, regression metrics will be used.
612
+ - _**algo**_ : Algorithm type for feature importance calculation. Options: 'xgb', 'rf', 'mars'. For other algorithms, use `None`
613
+ - _**f1_threshold**_ : Threshold for binary classification.
614
+ - _**decile_n**_ : Number of n-tiles for lift calculation. Defaults to 10 for deciles
615
+ - _**top_features_n**_ : Number of top features to display in visualizations.
616
+ - _**show_all_classes**_ : Whether to show metrics for all classes in multi-class classification.
617
+ - _**show_plots**_ : Whether to display plots
618
+ - _**save_plots**_ : Whether to save plots locally
619
+ - _**plot_dir**_ : Directory to save plots
620
+ - _**plot_save_format**_ : Plot format
621
+ - _**plot_save_dpi**_ : Plot resolution
622
+
623
+ #### Returns
624
+ - ModelMetricsResult object containing all evaluation metrics and results.
625
+
626
+ #### Key Methods:
627
+ - **evaluate()** - Compute and return all metrics
628
+ - **evaluate_custom_metrics(custom_metrics)** - Evaluate with additional custom metrics
629
+ - **display_metrics(results=None)** - Display evaluation results in a formatted way
630
+ - **calibration_assessment()** - Assess model calibration for classification models
631
+ - **get_feature_descriptives(display_results=False)** - Generate descriptive statistics for features
632
+ - **plot_feature_importance(feature_importance, n_features=20)** - Plot feature importance
633
+ - **plot_shap_beeswarm(n_features=20, plot_type="beeswarm")** - Create SHAP visualization
634
+ - **plot_score_distribution(bins=None)** - Plot distribution of predicted values
635
+ - **plot_feature_interactions(feature_pairs=None, n_top_pairs=5)** - Plot feature interactions
636
+ - **plot_confusion_matrix()** - Plot confusion matrix for classification models
637
+ - **plot_lift_analysis()** - Plot comprehensive lift analysis
638
+ - **plot_performance_curves()** - Plot ROC and precision-recall curves
639
+ - **plot_learning_history()** - Plot learning curves for iterative models
640
+ - **plot_performance_comparison()** - Plot model performance for out-of-time validation
641
+
642
+ #### Examples:
643
+
644
+ ```python
645
+ # Create an evaluator for a classification model
646
+ from gitlabds import ModelEvaluator
647
+
648
+ evaluator = ModelEvaluator(
649
+ model=my_model,
650
+ x_train=x_train,
651
+ y_train=y_train,
652
+ x_test=x_test,
653
+ y_test=y_test,
654
+ classification=True,
655
+ algo='xgb'
656
+ )
657
+
658
+ # Get all evaluation metrics
659
+ results = evaluator.evaluate()
660
+
661
+ # Display metrics in a formatted way
662
+ evaluator.display_metrics(results)
663
+
664
+ # Create visualizations
665
+ evaluator.plot_feature_importance(results.feature_importance)
666
+ evaluator.plot_confusion_matrix()
667
+ evaluator.plot_performance_curves()
668
+
669
+ # Save results to file
670
+ results.metrics_df.to_csv("metrics.csv")
671
+ results.classification_metrics_df.to_csv("classification_metrics.csv")
672
+ results.feature_importance.to_csv("feature_importance.csv")
673
+ ```
674
+ </details>
675
+
676
+
677
+ ### Insight Generation
678
+ <details><summary> Marginal Effects </summary>
679
+
680
+ #### Description
681
+ Calculates and returns the marginal effects at the mean (MEM) for predictor fields.
682
+
683
+ `gitlabds.marginal_effects(model, x_test, dv_description, field_labels=None):`
684
+
685
+ #### Parameters:
686
+ - _**model**_ : model file from training
687
+ - _**x_test**_ : test "predictors" dataframe.
688
+ - _**dv_description**_ : Description of the outcome field to be used in text-based insights.
689
+ - _**field_labels**_ : Dict of field descriptions. The key is the field/feature/predictor name. The value is descriptive text of the field. This field is optional and by default will use the field name
690
+
691
+ #### Returns
692
+ - Dataframe of marginal effects.
693
+
694
+ #### Examples:
695
+ ```python
696
+ # Calculate marginal effects for a trained model
697
+ import gitlabds
698
+ effects_df = gitlabds.marginal_effects(
699
+ model=trained_model,
700
+ x_test=test_features,
701
+ dv_description="probability of churn",
702
+ field_labels={
703
+ "tenure": "Customer tenure in months",
704
+ "monthly_charges": "Average monthly bill amount",
705
+ "total_charges": "Total amount charged to customer"
706
+ }
707
+ )
708
+
709
+ # Display the marginal effects
710
+ display(effects_df)
711
+ ```
712
+ </details>
713
+
714
+ <details><summary> Prescriptions </summary>
715
+
716
+ #### Description
717
+ Return "actionable" prescriptions and explanatory insights for each scored record. Insights first list actionable prescriptions follow by explainatory insights. This approach is recommended or linear/logistic methodologies only. Caution should be used if using a black box approach, as manpulating more than one prescription at a time could change a record's model score in unintended ways.
718
+
719
+ `gitlabds.prescriptions(model, input_df, scored_df, actionable_fields, dv_description, field_labels=None, returned_insights=5, only_actionable=False, explanation_fields='all'):`
720
+
721
+ #### Parameters:
722
+ - _**model**_ : model file from training
723
+ - _**input_df**_ : train "predictors" dataframe.
724
+ - _**scored_df**_ : dataframe containing model scores.
725
+ - _**actionable_fields**_ : Dict of actionable fields. The key is the field/feature/predictor name. The value accepts one of 3 values: `Increasing` for prescriptions only when the field increases; `Decreasing` for prescriptions only when the field decreases; `Both` for when the field either increases or decreases.
726
+ - _**dv_description**_ : Description of the outcome field to be used in text-based insights.
727
+ - _**field_labels**_ : Dict of field descriptions. The key is the field/feature/predictor name. The value is descriptive text of the field. This field is optional and by default will use the field name
728
+ - _**returned_insights**_ : Number of insights per record to return. Defaults to 5
729
+ - _**only_actionable**_ : Only return actionable prescriptions
730
+ - _**explanation_fields**_ : List of explainable (non-actionable insights) fields to return insights for. Defaults to 'all'
731
+
732
+ #### Returns
733
+ - Dataframe of prescriptive actions. One row per record input.
734
+
735
+ #### Examples:
736
+ ```python
737
+ # Return prescriptions for the actionable fields of 'spend', 'returns', and 'emails_sent':
738
+ results = gitlabds.prescriptions(
739
+ model=model,
740
+ input_df=my_df,
741
+ scored_df=my_scores,
742
+ actionable_fields={
743
+ 'spend': 'Increasing',
744
+ 'returns': 'Decreasing',
745
+ 'emails_sent': 'Both'
746
+ },
747
+ dv_description='likelihood to churn',
748
+ field_labels={
749
+ 'spend': 'Dollars spent in last 6 months',
750
+ 'returns': 'Item returns in last 3 months',
751
+ 'emails_sent': 'Marketing emails sent in last month'
752
+ },
753
+ returned_insights=5,
754
+ only_actionable=True,
755
+ explanation_fields=['spend', 'returns']
756
+ )
757
+ ```
758
+ </details>
759
+
760
+ ### Model Monitoring
761
+
762
+ <details><summary> Generate Baseline Features </summary>
763
+
764
+ #### Description
765
+ Generate baseline feature distributions, importance scores, and drift thresholds in a single comprehensive artifact for model monitoring.
766
+
767
+ `gitlabds.generate_baseline_features(training_data, feature_importance_df, importance_method="shapley_values", n_bins=10, psi_warning=0.1, psi_critical=0.2, ks_warning=0.1, ks_critical=0.2, js_warning=0.05, js_critical=0.1, output_path="baseline_features.json"):`
768
+
769
+ #### Parameters:
770
+ - **_training_data_** : Training feature data DataFrame
771
+ - **_feature_importance_df_** : DataFrame with columns: feature, importance
772
+ - **_importance_method_** : Method used to calculate importance (default: "shapley_values")
773
+ - **_n_bins_** : Number of bins for numerical features (default: 10)
774
+ - **_psi_warning, psi_critical_** : PSI thresholds for warning and critical drift detection
775
+ - **_ks_warning, ks_critical_** : KS statistic thresholds for warning and critical drift detection
776
+ - **_js_warning, js_critical_** : JS divergence thresholds for warning and critical drift detection
777
+ - **_output_path_** : Path to save the JSON file
778
+
779
+ #### Returns
780
+ - None (saves baseline artifact to JSON file)
781
+
782
+ #### Examples:
783
+ ```python
784
+ # Generate baseline features with default thresholds
785
+ import gitlabds
786
+ gitlabds.generate_baseline_features(
787
+ training_data=train_df,
788
+ feature_importance_df=importance_df,
789
+ importance_method="shapley_values",
790
+ output_path="model_baseline_features.json"
791
+ )
792
+ ```
793
+
794
+ ```python
795
+ # Generate with custom drift thresholds
796
+ gitlabds.generate_baseline_features(
797
+ training_data=train_df,
798
+ feature_importance_df=importance_df,
799
+ n_bins=15,
800
+ psi_warning=0.15,
801
+ psi_critical=0.25,
802
+ output_path="custom_baseline_features.json"
803
+ )
804
+ ```
805
+ </details>
806
+
807
+ <details><summary> Generate Baseline Calibration </summary>
808
+
809
+ #### Description
810
+ Generate baseline calibration data with train + test curves, prediction statistics, and model configuration for monitoring model calibration drift.
811
+
812
+ `gitlabds.generate_baseline_calibration(train_predictions, train_actuals, test_predictions, test_actuals, model_configuration, n_bins=10, output_path="baseline_calibration.json"):`
813
+
814
+ #### Parameters:
815
+ - **_train_predictions_** : Training set predicted probabilities
816
+ - **_train_actuals_** : Training set actual binary outcomes (0/1)
817
+ - **_test_predictions_** : Test set predicted probabilities
818
+ - **_test_actuals_** : Test set actual binary outcomes (0/1)
819
+ - **_model_configuration_** : Dictionary of model configuration parameters
820
+ - **_n_bins_** : Number of bins for calibration curve (default: 10)
821
+ - **_output_path_** : Path to save the JSON file
822
+
823
+ #### Returns
824
+ - None (saves baseline calibration to JSON file)
825
+
826
+ #### Examples:
827
+ ```python
828
+ # Generate baseline calibration
829
+ import gitlabds
830
+ model_config = {'f1_threshold': 0.15, 'random_state': 42}
831
+
832
+ gitlabds.generate_baseline_calibration(
833
+ train_predictions=y_train_pred,
834
+ train_actuals=y_train,
835
+ test_predictions=y_test_pred,
836
+ test_actuals=y_test,
837
+ model_configuration=model_config,
838
+ output_path="model_baseline_calibration.json"
839
+ )
840
+ ```
841
+ </details>
842
+
843
+ <details><summary> Calculate Monitoring Metrics </summary>
844
+
845
+ #### Description
846
+ Calculate all monitoring metrics including feature drift, prediction drift, and health status for a model scoring run.
847
+
848
+ `gitlabds.calculate_monitoring_metrics(run_id, model_name, sub_model, model_version, scoring_date, feature_df, predictions, baseline_metrics, importance_threshold_pct=0.05):`
849
+
850
+ #### Parameters:
851
+ - **_run_id_** : Unique identifier for this scoring run
852
+ - **_model_name_** : Model name (e.g., "propensity_model")
853
+ - **_sub_model_** : Sub model identifier
854
+ - **_model_version_** : Model version (e.g., "2.1")
855
+ - **_scoring_date_** : Date of scoring
856
+ - **_feature_df_** : Feature data used for scoring
857
+ - **_predictions_** : Model predictions (probabilities 0-1)
858
+ - **_baseline_metrics_** : Dictionary containing baseline_features and baseline_calibration JSON data
859
+ - **_importance_threshold_pct_** : Percentage of total importance required for a feature to be considered "important"
860
+
861
+ #### Returns
862
+ - Dictionary containing DataFrames for each table:
863
+ - 'scoring_summary': model_scoring_summary table
864
+ - 'feature_drift': model_feature_drift table
865
+
866
+ #### Examples:
867
+ ```python
868
+ # Calculate monitoring metrics for a scoring run
869
+ import gitlabds
870
+ from datetime import datetime
871
+
872
+ # Load baseline metrics
873
+ with open('baseline_features.json', 'r') as f:
874
+ baseline_features = json.load(f)
875
+ with open('baseline_calibration.json', 'r') as f:
876
+ baseline_calibration = json.load(f)
877
+
878
+ baseline_metrics = {
879
+ 'baseline_features': baseline_features,
880
+ 'baseline_calibration': baseline_calibration
881
+ }
882
+
883
+ # Calculate metrics
884
+ results = gitlabds.calculate_monitoring_metrics(
885
+ run_id="scoring_run_123",
886
+ model_name="churn_prediction",
887
+ sub_model="high_value_customers",
888
+ model_version="2.1",
889
+ scoring_date=datetime.now(),
890
+ feature_df=current_features,
891
+ predictions=model_predictions,
892
+ baseline_metrics=baseline_metrics,
893
+ importance_threshold_pct=0.05
894
+ )
895
+
896
+ # Access results
897
+ scoring_summary = results['scoring_summary']
898
+ feature_drift = results['feature_drift']
899
+ ```
900
+ </details>
901
+
902
+ ### SQL and Trend Analysis
903
+
904
+ <details><summary> SQL Trend Query Generator </summary>
905
+
906
+ #### Description
907
+ Generate SQL for trend analysis across time periods. The generated SQL transforms regular data into a time-series format with columns for each time period, allowing for easy trend detection.
908
+
909
+ `gitlabds.generate_sql_trend_query(snapshot_date, date_field, date_unit='MONTH', periods=12, table_name=None, group_by_fields=None, metrics=None, filters=None, output_file=None):`
910
+
911
+ #### Parameters:
912
+ - **_snapshot_date_** : Reference date for analysis (e.g., '2025-04-08')
913
+ - **_date_field_** : Field name in the table that contains the date to analyze
914
+ - **_date_unit_** : Time unit for analysis: 'DAY', 'WEEK', 'MONTH', 'QUARTER', 'YEAR'
915
+ - **_periods_** : Number of time periods to analyze
916
+ - **_table_name_** : Table to query data from
917
+ - **_group_by_fields_** : Fields to group by (entity identifiers)
918
+ - **_metrics_** : Metrics to include in analysis with their properties. Each metric is a dict with:
919
+ - name: output column name prefix
920
+ - source: field name in the source table
921
+ - aggregation: function to apply (AVG, SUM, MAX, etc.)
922
+ - condition: optional WHERE condition
923
+ - cumulative: if True, calculate period-over-period differences
924
+ - is_case_expression: if True, the source is already a CASE WHEN expression
925
+ - is_expression: if True, the source is a complex expression
926
+ - **_filters_** : SQL WHERE clause conditions as a string
927
+ - **_output_file_** : If provided, save the generated SQL to this file
928
+
929
+ #### Returns:
930
+ - The generated SQL query as a string
931
+
932
+ #### Examples:
933
+ ```python
934
+ # Generate SQL for monthly trend analysis
935
+ import gitlabds
936
+
937
+ # Define metrics
938
+ metrics = [
939
+ {"name": "active_users", "source": "monthly_active_users", "aggregation": "AVG"},
940
+ {"name": "revenue", "source": "monthly_revenue", "aggregation": "SUM"},
941
+ {"name": "projects", "source": "projects_created", "aggregation": "MAX", "cumulative": True}
942
+ ]
943
+
944
+ # Generate SQL query
945
+ sql = gitlabds.generate_sql_trend_query(
946
+ snapshot_date='2025-04-08',
947
+ date_field='transaction_date',
948
+ date_unit='MONTH',
949
+ periods=12,
950
+ table_name='analytics.user_metrics',
951
+ group_by_fields=['account_id'],
952
+ metrics=metrics,
953
+ filters="is_active = TRUE",
954
+ output_file='trend_query.sql'
955
+ )
956
+ ```
957
+
958
+ ```python
959
+ # Generate SQL for daily trend analysis with custom conditions
960
+ metrics = [
961
+ {"name": "logins", "source": "user_logins", "aggregation": "SUM"},
962
+ {"name": "premium_logins", "source": "user_logins", "aggregation": "SUM",
963
+ "condition": "subscription_tier = 'premium'"}
964
+ ]
965
+
966
+ sql = gitlabds.generate_sql_trend_query(
967
+ snapshot_date='2025-04-08',
968
+ date_field='login_date',
969
+ date_unit='DAY',
970
+ periods=30,
971
+ table_name='analytics.daily_logins',
972
+ metrics=metrics
973
+ )
974
+ ```
975
+ </details>
976
+
977
+ <details><summary> Trend Analysis </summary>
978
+
979
+ #### Description
980
+ Calculate trend metrics for a dataframe produced by the SQL trend generator. This function analyzes time-series data to identify patterns like consecutive increases or decreases, proportion of periods with growth or decline, and average percentage changes.
981
+
982
+ `gitlabds.trend_analysis(df, metric_list=None, time_unit='month', periods=6, include_cumulative=True, exclude_fields=None, verbose=False):`
983
+
984
+ #### Parameters:
985
+ - **_df_** : Dataframe containing trend data with time-based columns
986
+ - **_metric_list_** : List of metric names to analyze. If None, auto-detects metrics from columns
987
+ - **_time_unit_** : Time unit used in the column names (month, day, week, etc.)
988
+ - **_periods_** : Number of time periods to analyze
989
+ - **_include_cumulative_** : Whether to use cumulative (event) metrics when available
990
+ - **_exclude_fields_** : List of fields to exclude from auto-detection
991
+ - **_verbose_** : Whether to display intermediate output
992
+
993
+ #### Returns:
994
+ - A dataframe containing trend metrics for each specified metric, including:
995
+ - Count of periods with decreases/increases
996
+ - Count of consecutive decreases/increases
997
+ - Average percentage change across periods
998
+
999
+ #### Examples:
1000
+ ```python
1001
+ # Run trend analysis on data from SQL trend query
1002
+ import gitlabds
1003
+
1004
+ # Run the SQL query to get trend data
1005
+ trend_data = run_sql_query(trend_sql) # Your function to execute SQL
1006
+ trend_data.set_index('account_id', inplace=True)
1007
+
1008
+ # Analyze trends for all metrics
1009
+ trends_df = gitlabds.trend_analysis(
1010
+ df=trend_data,
1011
+ time_unit='month',
1012
+ periods=12,
1013
+ verbose=True
1014
+ )
1015
+ ```
1016
+
1017
+ ```python
1018
+ # Analyze trends for specific metrics
1019
+ trends_df = gitlabds.trend_analysis(
1020
+ df=trend_data,
1021
+ metric_list=['active_users', 'revenue'],
1022
+ time_unit='month',
1023
+ periods=6,
1024
+ include_cumulative=True,
1025
+ exclude_fields=['has_data']
1026
+ )
1027
+
1028
+ # Use trend metrics for customer health scoring
1029
+ account_data['declining_usage'] = trends_df['consecutive_drop_active_users_period_6_months_cnt'] > 0
1030
+ account_data['growth_score'] = trends_df['avg_perc_change_revenue_period_6_months'] * 100
1031
+ ```
1032
+ </details>
1033
+
1034
+ ## Gitlab Data Science
1035
+
1036
+ The [handbook](https://handbook.gitlab.com/handbook/enterprise-data/organization/data-science/) is the single source of truth for all of our documentation.
1037
+
1038
+ ## Contributing
1039
+
1040
+ We welcome contributions and improvements, please see the [contribution guidelines](CONTRIBUTING.md).
1041
+
1042
+ ## License
1043
+
1044
+ This code is distributed under the MIT license, please see the [LICENSE](LICENSE) file.