Domain-free GLM factor binning, grouping, and model design tools.
Project description
glm-factor-optimizer
Simple GLM tools for factor binning, grouping, model screening, and workflow automation. The package is domain-free: it works for count-rate, positive continuous, and other small GLM modeling problems.
Full project documentation is included in the source distribution under docs/
and published at
csabar.github.io/glm-factor-optimizer.
The docs are organized as tutorials, how-to guides, reference, and explanation.
Release notes are maintained in CHANGELOG.md.
Minimal runnable example:
import pandas as pd
from glm_factor_optimizer import RateGLM, split
df = pd.DataFrame(
[
{
"events": int((index % 7 == 0) + (index % 10 > 6)),
"hours": 1.0 + 0.5 * (index % 4),
"score": (index % 10) / 10,
"segment": ["standard", "plus", "premium"][index % 3],
}
for index in range(60)
]
)
train, valid, _ = split(df, seed=42)
glm = RateGLM(target="events", exposure="hours")
score_spec = glm.bins(train, "score", bins=4)
train = glm.apply(train, score_spec)
valid = glm.apply(valid, score_spec)
model = glm.fit(train, factors=[score_spec["output"], "segment"])
valid = glm.predict(valid, model)
print(glm.report(valid)["summary"])
Use RateGLM for count-rate models:
- count target, like
events - exposure column, like
hours - numeric or categorical factors
from glm_factor_optimizer import RateGLM, split
train, valid, holdout = split(df)
glm = RateGLM(target="events", exposure="hours")
score_spec = glm.bins(train, "score", bins=5)
train = glm.apply(train, score_spec)
valid = glm.apply(valid, score_spec)
model = glm.fit(train, factors=[score_spec["output"], "segment"])
valid = glm.predict(valid, model)
report = glm.report(valid)
print(report["summary"])
Use GLM for other families, such as Gamma cost or duration models:
from glm_factor_optimizer import GLM
glm = GLM(target="severity", family="gamma", prediction="predicted_severity")
age_spec = glm.bins(train, "machine_age", bins=6)
train = glm.apply(train, age_spec)
valid = glm.apply(valid, age_spec)
model = glm.fit(train, factors=[age_spec["output"], "equipment_type"])
valid = glm.predict(valid, model)
Optimize one factor manually:
result = glm.optimize(
train,
valid,
"score",
fixed_factors=["segment"],
trials=50,
)
train = glm.apply(train, result.spec)
valid = glm.apply(valid, result.spec)
model = glm.fit(train, factors=[result.output, "segment"])
The same optimizer is also exposed as optimize_bins:
from glm_factor_optimizer import optimize_bins
result = optimize_bins(
train,
valid,
target="events",
exposure="hours",
factor="score",
)
Add custom penalties with lambdas or named functions:
from glm_factor_optimizer import small_bin_size_penalty, small_count_penalty
result = glm.optimize(
train,
valid,
"score",
penalties={
"small_count": small_count_penalty(min_count=5, penalty=0.02),
"many_bins": lambda c: 0.01 * max(c["bin_count"] - 6, 0),
"gap": lambda c: max(c["validation_deviance"] - c["train_deviance"], 0),
},
)
Penalty callables receive a context dictionary with the selected spec, the
training bin_table, train/validation deviance, predictions, transformed
dataframes, factor name, kind, and fixed factors.
Rank candidate factors before detailed optimization:
ranking = glm.rank(
train,
valid,
["score", "segment", "region"],
factor_kinds={"segment": "categorical", "region": "categorical"},
)
print(ranking[["factor", "deviance_improvement"]])
Run a higher-level sequential workflow with optional ranking, logging, and interaction diagnostics:
from glm_factor_optimizer import GLMWorkflow
workflow = GLMWorkflow(
target="events",
family="poisson",
exposure="hours",
factor_kinds={"segment": "categorical"},
trials=50,
rank_candidates=True,
top_n=5,
interaction_diagnostics=True,
output_dir="runs",
)
result = workflow.fit(df, factors=["score", "segment"])
print(result.validation_report["summary"])
print(result.coefficients)
For notebook-style iterative model design, use GLMStudy:
from glm_factor_optimizer import GLMStudy
study = GLMStudy(
df,
target="events",
exposure="hours",
prediction="predicted_count",
factor_kinds={"segment": "categorical"},
)
study.split(seed=42)
ranking = study.rank_candidates(["score", "segment", "region"])
score = study.factor("score")
score.coarse_bins(bins=10)
score.optimize(trials=100, max_bins=6)
score.compare()
score.accept(comment="score bins looked consistent")
study.fit_main_effects()
study.validation_report()
refined = study.refine_factor("score", trials=200)
refined.accept(comment="full-model refinement")
study.find_interactions()
study.finalize()
study.save("runs")
Useful helper modules are available for manual workflows:
from glm_factor_optimizer.aggregation import aggregate_rate_table
from glm_factor_optimizer.diagnostics import find_interactions
from glm_factor_optimizer.runs import RunLogger
from glm_factor_optimizer.sampling import stratified_sample
Example synthetic datasets live under examples/ and are not part of the
installable package API. The examples cover general event-rate, severity, and
Spark-style workflows across operational and service settings.
Use the optional Spark backend in PySpark environments:
from glm_factor_optimizer.spark import SparkGLM, SparkGLMWorkflow
glm = SparkGLM(
target="events",
family="poisson",
exposure="hours",
prediction="predicted_count",
)
score_spec = glm.bins(train_sdf, "score", bins=8)
train_sdf = glm.apply(train_sdf, score_spec)
valid_sdf = glm.apply(valid_sdf, score_spec)
model = glm.fit(train_sdf, factors=[score_spec["output"], "segment"])
valid_sdf = glm.predict(valid_sdf, model)
The top-level notebook helpers also dispatch on Spark dataframes:
from glm_factor_optimizer import RateGLM
glm = RateGLM(target_col="events", exposure_col="hours")
model = glm.fit(train_sdf, factors=["score", "segment"])
valid_sdf = glm.predict(valid_sdf, model)
Spark Optuna optimization runs Optuna on the driver and Spark GLM jobs inside each trial:
result = glm.optimize(
train_sdf,
valid_sdf,
"score",
fixed_factors=["segment"],
trials=30,
cache_input=True,
cache_trials=False,
)
For a Spark-native factor screening workflow, keep the data in Spark:
from glm_factor_optimizer import RateGLM, split
sdf = spark.table("catalog.schema.modeling_table")
train, valid, holdout = split(sdf)
candidate_factors = [
"event_type",
"region",
"service_channel",
"equipment_type",
]
glm = RateGLM(
candidate_factors=candidate_factors,
target_col="events",
exposure_col="hours",
family="poisson",
prediction_col="predicted_events",
top_n=10,
)
glm.fit(train, validation_df=valid)
display(glm.identified_factors_)
scored_holdout = glm.predict(holdout)
This path keeps the modeling table as a Spark dataframe and fits with Spark ML generalized linear regression.
Install locally with Spark support using:
pip install "glm-factor-optimizer[spark]"
All binning and grouping specs are plain JSON-serializable dictionaries.
Contributing
Development setup, test commands, coverage, and release notes are documented in
CONTRIBUTING.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file glm_factor_optimizer-0.1.1.tar.gz.
File metadata
- Download URL: glm_factor_optimizer-0.1.1.tar.gz
- Upload date:
- Size: 76.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d046048ae4d62e2c26bdae17c128a3ff07a0feec311c7af7f4fafc2f981845f
|
|
| MD5 |
e66bed5002080b3c0e96051170cfa888
|
|
| BLAKE2b-256 |
4c02c764e3d10bad1b0bf8a46d055f8b7c636abab97d9efc866ee8e0a3330b20
|
Provenance
The following attestation bundles were made for glm_factor_optimizer-0.1.1.tar.gz:
Publisher:
release.yml on csabar/glm-factor-optimizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
glm_factor_optimizer-0.1.1.tar.gz -
Subject digest:
9d046048ae4d62e2c26bdae17c128a3ff07a0feec311c7af7f4fafc2f981845f - Sigstore transparency entry: 1489346891
- Sigstore integration time:
-
Permalink:
csabar/glm-factor-optimizer@fc96f08240e915a5aabb3a4bf32f6f799e0a0c09 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/csabar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fc96f08240e915a5aabb3a4bf32f6f799e0a0c09 -
Trigger Event:
push
-
Statement type:
File details
Details for the file glm_factor_optimizer-0.1.1-py3-none-any.whl.
File metadata
- Download URL: glm_factor_optimizer-0.1.1-py3-none-any.whl
- Upload date:
- Size: 71.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
989a48321294c3ee2aae278bd9a993252cbb652902a05ba5201d6f43d0655215
|
|
| MD5 |
af9a1488338b53e302400fad68b536fe
|
|
| BLAKE2b-256 |
cbdcf851f5cd36d260f30e08959c381d3c8a7bdc6e84bd9d01c1432686e90316
|
Provenance
The following attestation bundles were made for glm_factor_optimizer-0.1.1-py3-none-any.whl:
Publisher:
release.yml on csabar/glm-factor-optimizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
glm_factor_optimizer-0.1.1-py3-none-any.whl -
Subject digest:
989a48321294c3ee2aae278bd9a993252cbb652902a05ba5201d6f43d0655215 - Sigstore transparency entry: 1489346973
- Sigstore integration time:
-
Permalink:
csabar/glm-factor-optimizer@fc96f08240e915a5aabb3a4bf32f6f799e0a0c09 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/csabar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fc96f08240e915a5aabb3a4bf32f6f799e0a0c09 -
Trigger Event:
push
-
Statement type: