cb-demo / src /models /svm_classifier.py
DimmingLight's picture
Upload folder using huggingface_hub
9e77d3a verified
Raw
History Blame Contribute Delete
2.19 kB
"""Linear SVM classifier - single-stage binary cyberbullying detection.
Uses ``LinearSVC`` wrapped in ``CalibratedClassifierCV(method='sigmoid', cv=5)`` so
that ``predict_proba`` returns proper probabilities (Platt scaling). RBF kernel
is deferred - see README.md § Models.
"""
from __future__ import annotations
import logging
from pathlib import Path
import joblib
import numpy as np
from sklearn.calibration import CalibratedClassifierCV
from sklearn.svm import LinearSVC
logger = logging.getLogger(__name__)
class SVMModel:
"""Linear SVM with Platt-calibrated probabilities."""
# Target hyperparams to sweep during tuning:
# C ∈ [0.1, 1, 10] (RBF + gamma sweep deferred)
def __init__(
self,
C: float = 1.0,
class_weight: str = "balanced",
random_state: int = 42,
max_iter: int = 10000,
calibration_cv: int = 5,
) -> None:
base = LinearSVC(
C=C,
class_weight=class_weight,
random_state=random_state,
max_iter=max_iter,
)
self.model = CalibratedClassifierCV(base, method="sigmoid", cv=calibration_cv)
def fit(self, X_train, y_train, X_val=None, y_val=None) -> None:
"""Fit on TF-IDF features. ``X_val``/``y_val`` accepted for API parity but unused."""
self.model.fit(X_train, y_train)
logger.info("LinearSVC (calibrated) fitted on %d samples", X_train.shape[0])
def predict(self, X) -> np.ndarray:
"""Predict 0/1 labels."""
return self.model.predict(X)
def predict_proba(self, X) -> np.ndarray:
"""Predict Platt-scaled class probabilities; shape ``(n, 2)``."""
return self.model.predict_proba(X)
def save(self, path: Path) -> None:
"""Persist the fitted estimator to ``path`` via joblib."""
joblib.dump(self.model, str(path))
@classmethod
def load(cls, path: Path) -> "SVMModel":
"""Load a previously saved estimator and return a fresh wrapper."""
instance = cls.__new__(cls)
instance.model = joblib.load(str(path))
return instance