API reference¶
The package exports the classifier and its explanation types from subspaceknn. Plotting lives in subspaceknn.plotting and needs the optional plot extra.
SubspaceKNNClassifier ¶
SubspaceKNNClassifier(
*,
n_neighbors: int = 5,
subspace_size: int | Sequence[int] = 2,
n_subspaces: int | None = 5,
selection: Selection = "complementary",
max_votes: int = 50,
balance_classes: bool = True,
max_candidates: int | None = 1000,
voting: Voting = "soft",
weighting: Weighting = "score",
cv: Literal["loo"] | int | BaseCrossValidator = "loo",
scoring: str | Callable[..., float] = "f1_macro",
knn_weights: Literal["uniform", "distance"] = "uniform",
metric: str = "minkowski",
n_jobs: int | None = None,
)
Weighted vote of k-nearest-neighbour classifiers fitted on small feature subspaces.
The estimator fits a
KNeighborsClassifier on every
subset of subspace_size features (or every subset of each size when a
sequence of sizes is given) and computes each subset's out-of-fold class
probabilities on the training data, by exact leave-one-out by default. It then
chooses at most n_subspaces of them to vote on new samples.
The default, complementary selection, builds the ensemble greedily: at every step it adds the subspace that most reduces the class-balanced Brier score of the ensemble's out-of-fold probabilities, allowing a subspace to be added again, and keeps the best ensemble found. A subspace therefore earns its place by what it adds to the others, not by how well it does alone, and its weight is the number of times it was chosen. Ranked selection instead keeps the subspaces with the best individual scores, as ikNN does.
Because the members of the ensemble live in spaces of one, two or three
features, every prediction can be explained by looking at the neighbourhoods
that produced it; see explain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_neighbors
|
int
|
Number of neighbours used by every subspace model. |
5
|
subspace_size
|
int or sequence of int
|
Number of features in each subspace. A sequence enumerates subspaces of every listed size. Sizes larger than the number of features are ignored. |
2
|
n_subspaces
|
int or None
|
Maximum number of distinct subspaces used for prediction, that is, the
number of pictures an explanation contains. Complementary selection may
use fewer when more would not improve the ensemble. |
5
|
selection
|
('complementary', 'ranked')
|
|
"complementary"
|
max_votes
|
int
|
Number of greedy steps of complementary selection. Each step casts one
vote and the best ensemble over all steps is kept, so the weights are
multiples of |
50
|
balance_classes
|
bool
|
Whether the Brier score minimised by complementary selection weights each
sample inversely to its class frequency, so that every class counts
equally. |
True
|
max_candidates
|
int or None
|
Soft cap on the number of candidate subspaces. When the number of subsets
exceeds it, features are first screened by the |
1000
|
voting
|
('soft', 'hard')
|
|
"soft"
|
weighting
|
('score', 'uniform')
|
Weights of ranked selection: |
"score"
|
cv
|
"loo", int or cross-validation generator
|
How the out-of-fold probabilities are computed. |
"loo"
|
scoring
|
str or callable
|
Any scikit-learn scorer, evaluated on each subspace's out-of-fold predictions. It screens features, ranks subspaces under ranked selection, and is reported as each subspace's score. Higher must be better. |
"f1_macro"
|
knn_weights
|
('uniform', 'distance')
|
Neighbour weighting passed to the subspace models. |
"uniform"
|
metric
|
str
|
Distance metric passed to the subspace models. |
"minkowski"
|
n_jobs
|
int or None
|
Parallelism of the neighbour queries, or of the cross-validation when
|
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
classes_ |
ndarray of shape (n_classes,)
|
Class labels. |
n_features_in_ |
int
|
Number of features seen during |
feature_names_in_ |
ndarray of shape (n_features_in_,)
|
Feature names, only when |
screened_features_ |
ndarray of shape (n_screened,)
|
Indices of the features retained after screening, all features when no screening was necessary. |
feature_screening_scores_ |
ndarray of shape (n_features_in_,) or None
|
Out-of-fold score of each feature's one-dimensional model, only when screening took place. |
candidate_subspaces_ |
list of tuple of int
|
Every subspace that was evaluated, in enumeration order. |
candidate_scores_ |
ndarray of shape (n_candidates,)
|
Out-of-fold score of each candidate subspace on its own. |
subspaces_ |
list of tuple of int
|
Subspaces used for prediction, from the highest to the lowest weight. |
subspace_scores_ |
ndarray of shape (n_selected,)
|
Individual scores of the selected subspaces. |
subspace_weights_ |
ndarray of shape (n_selected,)
|
Normalised voting weights of the selected subspaces; they sum to one. |
selection_path_ |
list of tuple or None
|
Under complementary selection, one |
estimators_ |
list of KNeighborsClassifier
|
Fitted subspace models, aligned with |
feature_scores_ |
ndarray of shape (n_features_in_,)
|
Mean score of the selected subspaces containing each feature, zero for features that appear in none. A coarse measure of feature relevance. |
Examples:
>>> from sklearn.datasets import load_iris
>>> from subspaceknn import SubspaceKNNClassifier
>>> X, y = load_iris(return_X_y=True)
>>> clf = SubspaceKNNClassifier(subspace_size=(1, 2)).fit(X, y)
>>> clf.subspaces_[0]
(2, 3)
>>> clf.explain(X[:1])[0].votes[0].feature_names
('x2', 'x3')
fit ¶
fit(X: ArrayLike, y: ArrayLike) -> SubspaceKNNClassifier
Evaluate every candidate subspace and select the ensemble.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
array-like of shape (n_samples, n_features)
|
Training data. |
required |
y
|
array-like of shape (n_samples,)
|
Class labels. |
required |
Returns:
| Type | Description |
|---|---|
self
|
The fitted estimator. |
predict_proba ¶
Return the weighted average of the subspace models' class probabilities.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
array-like of shape (n_samples, n_features)
|
Samples to classify. |
required |
Returns:
| Type | Description |
|---|---|
ndarray of shape (n_samples, n_classes)
|
Class probabilities aligned with |
predict ¶
Return the class with the highest ensemble probability for each sample.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
array-like of shape (n_samples, n_features)
|
Samples to classify. |
required |
Returns:
| Type | Description |
|---|---|
ndarray of shape (n_samples,)
|
Predicted class labels. |
explain ¶
explain(X: ArrayLike) -> list[Explanation]
Explain the prediction for every sample in X.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
array-like of shape (n_samples, n_features)
|
Samples to explain. |
required |
Returns:
| Type | Description |
|---|---|
list of Explanation
|
One explanation per sample, each listing the vote of every subspace used by the ensemble, ordered from the highest to the lowest weight. |
Explanation
dataclass
¶
Explanation(
prediction: Any,
probabilities: NDArray[float64],
classes: NDArray[Any],
votes: tuple[SubspaceVote, ...],
)
How the ensemble arrived at the prediction for one sample.
Attributes:
| Name | Type | Description |
|---|---|---|
prediction |
Any
|
Class label predicted by the ensemble. |
probabilities |
ndarray of shape (n_classes,)
|
Ensemble class probabilities, the weighted average of the votes. |
classes |
ndarray of shape (n_classes,)
|
Class labels, in the order used by |
votes |
tuple of SubspaceVote
|
One entry per subspace used for prediction, ordered from the highest to the lowest weight. |
agreement ¶
agreement() -> float
Return the weighted fraction of subspaces that voted for the ensemble prediction.
to_records ¶
Return the votes as plain dictionaries, one per subspace.
The result is suitable for pandas.DataFrame.from_records and contains,
for every vote, the feature names, the subspace score and weight, the
subspace prediction, whether it agrees with the ensemble, and one
p(<class>) column per class.
SubspaceVote
dataclass
¶
SubspaceVote(
features: tuple[int, ...],
feature_names: tuple[str, ...],
score: float,
weight: float,
probabilities: NDArray[float64],
prediction: Any,
)
The contribution of one feature subspace to a single prediction.
Attributes:
| Name | Type | Description |
|---|---|---|
features |
tuple of int
|
Column indices of the features that span the subspace. |
feature_names |
tuple of str
|
Names of those features, taken from |
score |
float
|
Cross-validated score of the subspace on the training data. |
weight |
float
|
Normalised weight of the subspace in the ensemble vote. Weights sum to one across the subspaces used for prediction. |
probabilities |
ndarray of shape (n_classes,)
|
Class probabilities produced by this subspace alone, aligned with
|
prediction |
Any
|
Class label predicted by this subspace alone. |
plot_subspaces ¶
plot_subspaces(
estimator: SubspaceKNNClassifier,
X: ArrayLike,
y: ArrayLike,
*,
sample: ArrayLike | None = None,
n_subspaces: int | None = None,
grid_resolution: int = 100,
panel_size: float = 4.0,
) -> Figure
Draw the training data in the best subspaces, with decision regions where possible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
estimator
|
SubspaceKNNClassifier
|
A fitted estimator. |
required |
X
|
array-like of shape (n_samples, n_features)
|
Data to draw, usually the training data. |
required |
y
|
array-like of shape (n_samples,)
|
Class labels of |
required |
sample
|
array-like of shape (n_features,)
|
A single sample to highlight with a star in every panel, for example a test point whose prediction is being explained. |
None
|
n_subspaces
|
int
|
Number of panels, from the best subspace onwards. Defaults to all subspaces used for prediction. |
None
|
grid_resolution
|
int
|
Number of grid points per axis for the decision regions of one- and two-dimensional subspaces. |
100
|
panel_size
|
float
|
Width and height of each panel in inches. |
4.0
|
Returns:
| Type | Description |
|---|---|
Figure
|
The figure; it is not shown or saved. |
Raises:
| Type | Description |
|---|---|
ImportError
|
If matplotlib is not installed. |