mclovin 1.0.0__py3-none-any.whl

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.
mclovin/__init__.py ADDED
@@ -0,0 +1,118 @@
1
+ """
2
+ mclovin
3
+ =======
4
+
5
+ Trustworthy features from messy tabular data.
6
+
7
+ This package started life as basketball code. What survived the move to a
8
+ general-purpose library is the part that was never really about basketball:
9
+ resolving whatever a dataset calls its columns, saying honestly how reliable
10
+ each derived number is, correcting rates computed on small samples, and
11
+ building panel features that do not leak the future into the past.
12
+
13
+ Design principles
14
+ -----------------
15
+ 1. **Schema-flexible.** Functions resolve canonical names against whatever
16
+ your DataFrame actually calls them, via :class:`SchemaResolver` pointed at
17
+ a :class:`~mclovin.vocab.Vocabulary`. Point it at a new dataset, extend the
18
+ vocabulary, and everything downstream works unchanged.
19
+
20
+ 2. **Honest about provenance.** Many derived quantities need context columns
21
+ (team totals, station baselines, cohort aggregates) that a given dataset
22
+ may not carry. Rather than quietly approximating, every metric declares
23
+ what it needed and reports a reliability tier -- EXACT, APPROXIMATED,
24
+ PASSTHROUGH, DERIVED or UNAVAILABLE -- so you know which numbers can bear
25
+ weight.
26
+
27
+ 3. **Leakage-resistant by default.** Rolling windows require a full window,
28
+ horizon joins match on the key rather than on position, and splits are
29
+ chronological. The defaults are the careful choice, not the convenient one.
30
+
31
+ Modules
32
+ -------
33
+ `schema` Canonical-name resolution and dataset coverage auditing
34
+ `vocab` Domain vocabularies: aliases, context markers, rate ceilings
35
+ `core` Shared helpers; the provenance and reliability-tier system
36
+ `panel` Lags, deltas, rolling windows, horizon joins, temporal splits
37
+ `quality` Rate validation, artifact detection, robust standardisation
38
+ `shrinkage` Empirical-Bayes and James-Stein small-sample correction
39
+ `similarity` PCA decomposition, GMM soft archetypes, Mahalanobis neighbours
40
+ `survival` Kaplan-Meier, Cox, and censoring-aware label construction
41
+ `units` Detect and harmonise mixed per-period / cumulative columns
42
+ `evaluation` Shared regression and classification scoring helpers
43
+ `basketball` The original domain pack: Four Factors, BPM/PER, draft features
44
+
45
+ Quick start
46
+ -----------
47
+ import pandas as pd
48
+ from mclovin import SchemaResolver, ComputationReport
49
+ from mclovin.vocab import Vocabulary
50
+
51
+ WEATHER = Vocabulary(
52
+ name="weather",
53
+ aliases={"TEMP_MAX": ["temperature_2m_max", "tmax"]},
54
+ )
55
+
56
+ df = pd.read_csv("daily.csv")
57
+ resolver = SchemaResolver(df.columns, vocabulary=WEATHER)
58
+ print(resolver.coverage().query("available"))
59
+
60
+ The basketball metrics that were moneyBBall live on in `mclovin.basketball`
61
+ and are unchanged:
62
+
63
+ import mclovin.basketball as bb
64
+
65
+ resolver = bb.resolver(df.columns)
66
+ df = bb.draft.add_prospect_features(df, resolver=resolver)
67
+
68
+ A caution on interpretation
69
+ ---------------------------
70
+ A composite that summarises what already happened is not the same thing as a
71
+ predictor of what happens next, and the two are easy to confuse because they
72
+ are computed from the same columns. Check the reliability tier, check what
73
+ the metric needed, and do not mistake a good description for a good forecast.
74
+ """
75
+
76
+ from importlib.metadata import PackageNotFoundError, version
77
+
78
+ try:
79
+ __version__ = version("mclovin")
80
+ except PackageNotFoundError: # pragma: no cover - local/dev install
81
+ __version__ = "0.0.0-dev"
82
+
83
+ from . import (
84
+ core,
85
+ evaluation,
86
+ panel,
87
+ quality,
88
+ schema,
89
+ shrinkage,
90
+ similarity,
91
+ survival,
92
+ units,
93
+ vocab,
94
+ )
95
+ from .core import ComputationReport, MetricSpec, Reliability
96
+ from .schema import SchemaResolver
97
+ from .vocab import Vocabulary
98
+
99
+ __all__ = [
100
+ # modules
101
+ "schema",
102
+ "vocab",
103
+ "core",
104
+ "panel",
105
+ "quality",
106
+ "shrinkage",
107
+ "similarity",
108
+ "survival",
109
+ "units",
110
+ "evaluation",
111
+ # most-used names
112
+ "SchemaResolver",
113
+ "Vocabulary",
114
+ "ComputationReport",
115
+ "MetricSpec",
116
+ "Reliability",
117
+ "__version__",
118
+ ]
@@ -0,0 +1,65 @@
1
+ """Basketball metrics -- the domain pack.
2
+
3
+ Everything here is basketball and only basketball: Oliver's Four Factors,
4
+ possession estimation, the box-score composites (BPM, PER, Game Score, PIE,
5
+ VORP), the NCAA-to-NBA draft features, and reconstruction of counting stats
6
+ from rate-only college exports.
7
+
8
+ It sits on top of the generic machinery in :mod:`mclovin` rather than being
9
+ mixed into it. Nothing in the core imports this subpackage, which is the
10
+ property that lets the core be used on data that has nothing to do with sport.
11
+
12
+ Provenance and formula citations are unchanged from moneyBBall 0.6.2:
13
+ Oliver's *Basketball on Paper*, Kubatko et al. (2007) in *JQAS*, Myers' BPM
14
+ 2.0, Hollinger's PER, Sill's RAPM regularisation, Pelton's age adjustment.
15
+
16
+ import pandas as pd
17
+ import mclovin.basketball as bb
18
+
19
+ df = pd.read_csv("train.csv", encoding="latin1")
20
+ resolver = bb.resolver(df.columns) # basketball vocabulary supplied
21
+ df = bb.draft.add_prospect_features(df, resolver=resolver)
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ from typing import Iterable
27
+
28
+ from ..schema import SchemaResolver
29
+ from ..vocab import register
30
+ from ..vocab.basketball import BASKETBALL
31
+ from . import box_metrics, draft, four_factors, possessions, reconstruct
32
+ from .identities import verify_scoring_identity
33
+ from .coefficients import (
34
+ FTA_POSSESSION_COEFFICIENT_NBA,
35
+ FTA_POSSESSION_COEFFICIENT_NCAA,
36
+ fta_coefficient,
37
+ )
38
+
39
+ register(BASKETBALL)
40
+
41
+
42
+ def resolver(columns: Iterable[str], **kwargs) -> SchemaResolver:
43
+ """A :class:`~mclovin.schema.SchemaResolver` loaded with the basketball
44
+ vocabulary.
45
+
46
+ Shorthand for ``SchemaResolver(columns, vocabulary=BASKETBALL)``. Pass
47
+ ``extra_aliases=`` to handle a dataset-specific quirk, exactly as before.
48
+ """
49
+ kwargs.setdefault("vocabulary", BASKETBALL)
50
+ return SchemaResolver(columns, **kwargs)
51
+
52
+
53
+ __all__ = [
54
+ "box_metrics",
55
+ "draft",
56
+ "four_factors",
57
+ "possessions",
58
+ "reconstruct",
59
+ "verify_scoring_identity",
60
+ "resolver",
61
+ "BASKETBALL",
62
+ "fta_coefficient",
63
+ "FTA_POSSESSION_COEFFICIENT_NBA",
64
+ "FTA_POSSESSION_COEFFICIENT_NCAA",
65
+ ]