Spaces:
Sleeping
Sleeping
| """Frank & Hall (2001) ordinal decomposition with balanced HistGBT. | |
| This class must be importable for joblib to deserialize v3 FrankHall models. | |
| The class definition must match exactly what was used during training. | |
| """ | |
| import numpy as np | |
| from sklearn.ensemble import HistGradientBoostingClassifier | |
| class FrankHallOrdinal: | |
| """Ordinal classifier using K-1 binary decomposition. | |
| Trains K-1 binary classifiers: P(Y > k) for k=1..K-1. | |
| Each gets class_weight='balanced' automatically. | |
| """ | |
| def __init__(self, max_depth=4, learning_rate=0.1, max_iter=200): | |
| self.max_depth = max_depth | |
| self.learning_rate = learning_rate | |
| self.max_iter = max_iter | |
| self.clfs = [] | |
| self.classes_ = None | |
| def fit(self, X, y, sample_weight=None): | |
| self.classes_ = np.sort(np.unique(y)) | |
| self.clfs = [] | |
| for k in self.classes_[:-1]: | |
| binary_y = (y > k).astype(int) | |
| clf = HistGradientBoostingClassifier( | |
| max_depth=self.max_depth, | |
| learning_rate=self.learning_rate, | |
| max_iter=self.max_iter, | |
| class_weight='balanced', | |
| random_state=42, | |
| ) | |
| clf.fit(X, binary_y, sample_weight=sample_weight) | |
| self.clfs.append(clf) | |
| return self | |
| def predict_proba(self, X): | |
| cum = np.column_stack([c.predict_proba(X)[:, 1] for c in self.clfs]) | |
| p = np.zeros((X.shape[0], len(self.classes_))) | |
| p[:, 0] = 1 - cum[:, 0] | |
| for k in range(1, len(self.classes_) - 1): | |
| p[:, k] = cum[:, k - 1] - cum[:, k] | |
| p[:, -1] = cum[:, -1] | |
| return np.clip(p, 0, 1) | |
| def predict(self, X): | |
| return self.classes_[np.argmax(self.predict_proba(X), axis=1)] | |