Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/releases/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ The `dummy` module is now fully type-annotated.
## tree

- Added handling for division by zero in `tree.hoeffding_tree` for leaf size estimation.

## neighbors

- Added function in nearest-neighbor engines to gather relevant classes/targets from the window.
- Added a virtual function to the base engine class; New NN engines need to override `refresh_targets` function
- Classifier KNN now calls this engine-specific function under `clean_up_classes()`
14 changes: 14 additions & 0 deletions river/neighbors/ann/swinn.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,3 +491,17 @@ def connectivity(self) -> list[int]:
forest.add(frozenset(u))

return [len(tree) for tree in forest]

def refresh_targets(self) -> set:
"""Refresh the set of classes in the window. Used by classifiers where labels are added as [1] in the vertex tuple.

This is used to clean up classes that are no longer in the window, and
ensure we do not consider "None" a class. It is called every `cleanup_every`
step, or can be called manually.

"""
return {
vertex.item[1]
for vertex in self._data
if vertex is not None and vertex.item[1] is not None
}
Comment thread
smastelini marked this conversation as resolved.
4 changes: 4 additions & 0 deletions river/neighbors/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ def append(self, item: typing.Any, **kwargs) -> None:
@abc.abstractmethod
def search(self, item: typing.Any, n_neighbors: int, **kwargs) -> tuple[list, list]:
pass

@abc.abstractmethod
def refresh_targets(self) -> set:
pass
Comment thread
smastelini marked this conversation as resolved.
2 changes: 1 addition & 1 deletion river/neighbors/knn_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def clean_up_classes(self):
`cleanup_every` step, or can be called manually.

"""
self.classes = {x for x in self.window if x[0][1] is not None}
self.classes = self._nn.refresh_targets()

def learn_one(self, x, y):
# Update the data buffer
Expand Down
12 changes: 12 additions & 0 deletions river/neighbors/lazy.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,15 @@ def search(self, item: typing.Any, n_neighbors: int, **kwargs):

# Return the k closest points
return tuple(map(list, zip(*sorted(points, key=operator.itemgetter(-1))[:n_neighbors])))

def refresh_targets(self) -> set:
"""Refresh the set of classes in the window. Used by classifiers where labels are added as [1] in the vertex tuple.

This is used to clean up classes that are no longer in the window, and
ensure we do not consider "None" a class. It is called every `cleanup_every`
step, or can be called manually.

"""
return { # self.window is a deque of items, where each item is a tuple (x, y)
pos.item[1] for pos in self.window if pos is not None and pos.item[1] is not None
}
Comment thread
smastelini marked this conversation as resolved.
Loading