pub struct SVC<F, K> {
pub kernel: K,
pub c: F,
pub tol: F,
pub max_iter: usize,
pub cache_size: usize,
pub shrinking: bool,
pub decision_function_shape: SvmDecisionShape,
pub break_ties: bool,
pub class_weight: ClassWeight<F>,
pub probability: bool,
}Expand description
Support Vector Classifier.
Uses Sequential Minimal Optimization (SMO) to solve the dual QP. Supports multiclass via one-vs-one strategy.
§Type Parameters
F: The floating-point type (f32orf64).K: The kernel type (e.g.,LinearKernel,RbfKernel).
Fields§
§kernel: KThe kernel function.
c: FRegularization parameter (penalty for misclassification).
tol: FConvergence tolerance.
max_iter: usizeMaximum number of SMO iterations. 0 is the sklearn max_iter=-1
sentinel meaning no iteration limit (the SMO runs to convergence);
a non-zero value caps the iteration count
(sklearn/svm/_classes.py, max_iter default -1).
cache_size: usizeSize of the kernel evaluation LRU cache (perf-only; default 200 to
match sklearn’s cache_size=200).
shrinking: boolWhether to use libsvm’s shrinking heuristic
(sklearn/svm/_base.py:339, _classes.py shrinking=True).
ferrolearn’s SMO has no shrinking heuristic: shrinking is a libsvm
performance optimization that does NOT change the converged optimum
(R-DEV-7). This flag is accepted for API parity (default true,
matching sklearn) but DOES NOT alter the fitted result — the converged
α/dual_coef_/intercept_ are shrinking-invariant.
decision_function_shape: SvmDecisionShapeThe multiclass decision_function shape convention
(sklearn/svm/_base.py:778-781); default
SvmDecisionShape::Ovr (sklearn’s decision_function_shape='ovr').
break_ties: boolWhether predict breaks ties by the one-vs-rest decision confidence
instead of the libsvm vote (break_ties, sklearn/svm/_classes.py
default False; semantics in BaseSVC.predict,
sklearn/svm/_base.py:801-814).
When true AND SvmDecisionShape::Ovr AND n_classes > 2,
predict = argmax(decision_function(X)) (the ovr decision, which breaks
ties by confidence); otherwise the libsvm ovo vote (with lower-index
tie-break) is used. break_ties=true with SvmDecisionShape::Ovo is
rejected at predict time (InvalidParameter), matching sklearn
(_base.py:801-804).
class_weight: ClassWeight<F>Per-class scaling of C (class_weight, sklearn/svm/_classes.py:118-124).
Default ClassWeight::None (all classes weighted 1.0). For an ovo
pair (a, b) with a < b, the C of the y=+1 group (class b) is
C·class_weight_[b] and the C of the y=-1 group (class a) is
C·class_weight_[a]; the weights are computed ONCE over the full y
by [compute_class_weight] (_base.py:740).
probability: boolWhether to enable Platt-scaling probability estimates
(probability, sklearn/svm/_classes.py, default False).
When true, Fit::fit runs an internal 5-fold cross-validation per
one-vs-one pair, fits a sigmoid 1/(1+exp(A·f+B)) over the out-of-fold
decision values ([sigmoid_train], libsvm svm_binary_svc_probability,
svm.cpp:2107-2203), and stores the per-pair (A, B) so
FittedSVC::predict_proba/FittedSVC::predict_log_proba are
available. When false (the default) predict_proba returns an error
(_base.py:820-827).
RNG boundary (documented divergence). libsvm’s
svm_binary_svc_probability shuffles the CV fold assignment with an
RNG seeded by random_state, so sklearn’s probA_/probB_ (and hence
the exact predict_proba values) are NON-DETERMINISTIC across
random_state — the docstring itself warns “the results can be slightly
different than those obtained by predict”. ferrolearn instead uses a
DETERMINISTIC 5-fold split (contiguous folds, no RNG shuffle), so it
CANNOT and DOES NOT bit-match sklearn’s predict_proba values. What is
reproduced exactly is the DETERMINISTIC machinery ([sigmoid_train],
[sigmoid_predict], [multiclass_probability]) and the STRUCTURAL
contract (rows sum to 1, entries in [0, 1], monotone in the binary
decision value, the raise-when-probability=false). This is analogous
to the SGD shuffle boundary already documented in this codebase.
Implementations§
Source§impl<F: Float, K: Kernel<F>> SVC<F, K>
impl<F: Float, K: Kernel<F>> SVC<F, K>
Sourcepub fn new(kernel: K) -> Self
pub fn new(kernel: K) -> Self
Create a new SVC with the given kernel and default hyperparameters
matching sklearn (sklearn/svm/_classes.py SVC.__init__).
Defaults: C = 1.0, tol = 1e-3, max_iter = 0 (= sklearn -1, no
iteration limit), cache_size = 200, shrinking = true,
decision_function_shape = Ovr, break_ties = false,
class_weight = None, probability = false.
Sourcepub fn with_probability(self, probability: bool) -> Self
pub fn with_probability(self, probability: bool) -> Self
Enable/disable Platt-scaling probability estimates (sklearn
probability, default false). When true, Fit::fit runs the
internal per-pair 5-fold CV + [sigmoid_train] so
FittedSVC::predict_proba/FittedSVC::predict_log_proba are
available; when false they return an error.
See the SVC::probability field doc for the documented RNG-CV
exact-value boundary (sklearn is non-deterministic across
random_state; only the deterministic machinery + structural
invariants + the raise contract are reproduced).
Sourcepub fn with_class_weight(self, class_weight: ClassWeight<F>) -> Self
pub fn with_class_weight(self, class_weight: ClassWeight<F>) -> Self
Set the per-class C scaling (sklearn class_weight,
_classes.py:118-124). ClassWeight::None (default) leaves every
class at 1.0; ClassWeight::Balanced uses
n_samples / (n_classes · count_c); ClassWeight::Explicit takes a
(label, weight) map (unlisted classes default to 1.0).
Sourcepub fn with_shrinking(self, shrinking: bool) -> Self
pub fn with_shrinking(self, shrinking: bool) -> Self
Set the shrinking flag (sklearn shrinking, default true).
Accepted for API parity; does NOT alter the converged optimum (ferrolearn’s SMO has no shrinking heuristic — R-DEV-7).
Sourcepub fn with_break_ties(self, break_ties: bool) -> Self
pub fn with_break_ties(self, break_ties: bool) -> Self
Set the break_ties flag (sklearn break_ties, default false,
sklearn/svm/_base.py:801-814).
Sourcepub fn with_decision_function_shape(self, shape: SvmDecisionShape) -> Self
pub fn with_decision_function_shape(self, shape: SvmDecisionShape) -> Self
Set the multiclass decision_function shape convention
('ovr' default / 'ovo', sklearn/svm/_base.py:778-781).
Sourcepub fn with_max_iter(self, max_iter: usize) -> Self
pub fn with_max_iter(self, max_iter: usize) -> Self
Set the maximum number of SMO iterations.
Sourcepub fn with_cache_size(self, cache_size: usize) -> Self
pub fn with_cache_size(self, cache_size: usize) -> Self
Set the kernel cache size.
Trait Implementations§
Source§impl<F: Float + Send + Sync + ScalarOperand + 'static, K: Kernel<F> + 'static> Fit<ArrayBase<OwnedRepr<F>, Dim<[usize; 2]>>, ArrayBase<OwnedRepr<usize>, Dim<[usize; 1]>>> for SVC<F, K>
impl<F: Float + Send + Sync + ScalarOperand + 'static, K: Kernel<F> + 'static> Fit<ArrayBase<OwnedRepr<F>, Dim<[usize; 2]>>, ArrayBase<OwnedRepr<usize>, Dim<[usize; 1]>>> for SVC<F, K>
Source§fn fit(
&self,
x: &Array2<F>,
y: &Array1<usize>,
) -> Result<FittedSVC<F, K>, FerroError>
fn fit( &self, x: &Array2<F>, y: &Array1<usize>, ) -> Result<FittedSVC<F, K>, FerroError>
Fit the SVC model using SMO.
§Errors
Returns FerroError::ShapeMismatch if x and y have different
sample counts.
Returns FerroError::InvalidParameter if C is not positive.
Returns FerroError::InsufficientSamples if fewer than 2 classes.
Source§type Error = FerroError
type Error = FerroError
fit.Auto Trait Implementations§
impl<F, K> Freeze for SVC<F, K>
impl<F, K> RefUnwindSafe for SVC<F, K>where
K: RefUnwindSafe,
F: RefUnwindSafe,
impl<F, K> Send for SVC<F, K>
impl<F, K> Sync for SVC<F, K>
impl<F, K> Unpin for SVC<F, K>
impl<F, K> UnsafeUnpin for SVC<F, K>where
K: UnsafeUnpin,
F: UnsafeUnpin,
impl<F, K> UnwindSafe for SVC<F, K>where
K: UnwindSafe,
F: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more