|
1 | 1 | from typing import Optional
|
| 2 | +from typing import Any, Dict, Union |
2 | 3 |
|
3 | 4 | import pandas as pd
|
4 | 5 | import numpy as np
|
|
9 | 10 | import os
|
10 | 11 |
|
11 | 12 | from capymoa.stream import Schema, Stream
|
12 |
| -from capymoa.base import ( |
13 |
| - AnomalyDetector, |
14 |
| - ClassifierSSL, |
15 |
| - MOAPredictionIntervalLearner |
16 |
| -) |
| 13 | +from capymoa.base import AnomalyDetector, ClassifierSSL, MOAPredictionIntervalLearner |
17 | 14 |
|
18 | 15 | from capymoa.evaluation.results import PrequentialResults
|
19 | 16 | from capymoa._utils import _translate_metric_name
|
| 17 | +from capymoa.base import Classifier, Regressor |
20 | 18 |
|
21 | 19 | from com.yahoo.labs.samoa.instances import Instances, Attribute, DenseInstance
|
22 | 20 | from moa.core import InstanceExample
|
@@ -820,25 +818,51 @@ def stop_time_measuring(start_wallclock_time, start_cpu_time):
|
820 | 818 |
|
821 | 819 |
|
822 | 820 | def prequential_evaluation(
|
823 |
| - stream, |
824 |
| - learner, |
825 |
| - max_instances=None, |
826 |
| - window_size=1000, |
827 |
| - store_predictions=False, |
828 |
| - store_y=False, |
829 |
| - optimise=True |
830 |
| -): |
831 |
| - """ |
832 |
| - Calculates the metrics cumulatively (i.e. test-then-train) and in a window-fashion (i.e. windowed prequential |
833 |
| - evaluation). Returns both evaluators so that the user has access to metrics from both evaluators. |
| 821 | + stream: Stream, |
| 822 | + learner: Union[Classifier, Regressor], |
| 823 | + max_instances: Optional[int] = None, |
| 824 | + window_size: int = 1000, |
| 825 | + store_predictions: bool = False, |
| 826 | + store_y: bool = False, |
| 827 | + optimise: bool = True, |
| 828 | + restart_stream: bool = True, |
| 829 | +) -> PrequentialResults: |
| 830 | + """Run and evaluate a learner on a stream using prequential evaluation. |
| 831 | +
|
| 832 | + Calculates the metrics cumulatively (i.e. test-then-train) and in a |
| 833 | + window-fashion (i.e. windowed prequential evaluation). Returns both |
| 834 | + evaluators so that the user has access to metrics from both evaluators. |
| 835 | +
|
| 836 | + :param stream: A data stream to evaluate the learner on. Will be restarted if |
| 837 | + ``restart_stream`` is True. |
| 838 | + :param learner: The learner to evaluate. |
| 839 | + :param max_instances: The number of instances to evaluate before exiting. If |
| 840 | + None, the evaluation will continue until the stream is empty. |
| 841 | + :param window_size: The size of the window used for windowed evaluation, |
| 842 | + defaults to 1000 |
| 843 | + :param store_predictions: Store the learner's prediction in a list, defaults |
| 844 | + to False |
| 845 | + :param store_y: Store the ground truth targets in a list, defaults to False |
| 846 | + :param optimise: If True and the learner is compatible, the evaluator will |
| 847 | + use a Java native evaluation loop, defaults to True. |
| 848 | + :param restart_stream: If False, evaluation will continue from the current |
| 849 | + position in the stream, defaults to True. Not restarting the stream is |
| 850 | + useful for switching between learners or evaluators, without starting |
| 851 | + from the beginning of the stream. |
| 852 | + :return: An object containing the results of the evaluation windowed metrics, |
| 853 | + cumulative metrics, ground truth targets, and predictions. |
834 | 854 | """
|
835 |
| - stream.restart() |
| 855 | + if restart_stream: |
| 856 | + stream.restart() |
836 | 857 | if _is_fast_mode_compilable(stream, learner, optimise):
|
837 |
| - return _prequential_evaluation_fast(stream, learner, |
838 |
| - max_instances, |
839 |
| - window_size, |
840 |
| - store_y=store_y, |
841 |
| - store_predictions=store_predictions) |
| 858 | + return _prequential_evaluation_fast( |
| 859 | + stream, |
| 860 | + learner, |
| 861 | + max_instances, |
| 862 | + window_size, |
| 863 | + store_y=store_y, |
| 864 | + store_predictions=store_predictions, |
| 865 | + ) |
842 | 866 |
|
843 | 867 | predictions = None
|
844 | 868 | if store_predictions:
|
@@ -880,7 +904,7 @@ def prequential_evaluation(
|
880 | 904 | schema=stream.get_schema(), window_size=window_size
|
881 | 905 | )
|
882 | 906 | while stream.has_more_instances() and (
|
883 |
| - max_instances is None or instancesProcessed <= max_instances |
| 907 | + max_instances is None or instancesProcessed <= max_instances |
884 | 908 | ):
|
885 | 909 | instance = stream.next_instance()
|
886 | 910 |
|
@@ -933,25 +957,55 @@ def prequential_evaluation(
|
933 | 957 | return results
|
934 | 958 |
|
935 | 959 |
|
936 |
| -# TODO: Include store_predictions and store_y logic |
937 | 960 | def prequential_ssl_evaluation(
|
938 |
| - stream, |
939 |
| - learner, |
940 |
| - max_instances=None, |
941 |
| - window_size=1000, |
942 |
| - initial_window_size=0, |
943 |
| - delay_length=0, |
944 |
| - label_probability=0.01, |
945 |
| - random_seed=1, |
946 |
| - store_predictions=False, |
947 |
| - store_y=False, |
948 |
| - optimise=True, |
| 961 | + stream: Stream, |
| 962 | + learner: Union[ClassifierSSL, Classifier], |
| 963 | + max_instances: Optional[int] = None, |
| 964 | + window_size: int = 1000, |
| 965 | + initial_window_size: int = 0, |
| 966 | + delay_length: int = 0, |
| 967 | + label_probability: float = 0.01, |
| 968 | + random_seed: int = 1, |
| 969 | + store_predictions: bool = False, |
| 970 | + store_y: bool = False, |
| 971 | + optimise: bool = True, |
| 972 | + restart_stream: bool = True, |
949 | 973 | ):
|
950 |
| - """ |
951 |
| - If the learner is not an SSL learner, then it will be trained only on the labeled instances. |
| 974 | + """Run and evaluate a learner on a semi-supervised stream using prequential evaluation. |
| 975 | +
|
| 976 | + :param stream: A data stream to evaluate the learner on. Will be restarted if |
| 977 | + ``restart_stream`` is True. |
| 978 | + :param learner: The learner to evaluate. If the learner is an SSL learner, |
| 979 | + it will be trained on both labeled and unlabeled instances. If the |
| 980 | + learner is not an SSL learner, then it will be trained only on the |
| 981 | + labeled instances. |
| 982 | + :param max_instances: The number of instances to evaluate before exiting. |
| 983 | + If None, the evaluation will continue until the stream is empty. |
| 984 | + :param window_size: The size of the window used for windowed evaluation, |
| 985 | + defaults to 1000 |
| 986 | + :param initial_window_size: Not implemented yet |
| 987 | + :param delay_length: If greater than zero the labeled (``label_probability``%) |
| 988 | + instances will appear as unlabeled before reappearing as labeled after |
| 989 | + ``delay_length`` instances, defaults to 0 |
| 990 | + :param label_probability: The proportion of instances that will be labeled, |
| 991 | + must be in the range [0, 1], defaults to 0.01 |
| 992 | + :param random_seed: A random seed to define the random state that decides |
| 993 | + which instances are labeled and which are not, defaults to 1. |
| 994 | + :param store_predictions: Store the learner's prediction in a list, defaults |
| 995 | + to False |
| 996 | + :param store_y: Store the ground truth targets in a list, defaults to False |
| 997 | + :param optimise: If True and the learner is compatible, the evaluator will |
| 998 | + use a Java native evaluation loop, defaults to True. |
| 999 | + :param restart_stream: If False, evaluation will continue from the current |
| 1000 | + position in the stream, defaults to True. Not restarting the stream is |
| 1001 | + useful for switching between learners or evaluators, without starting |
| 1002 | + from the beginning of the stream. |
| 1003 | + :return: An object containing the results of the evaluation windowed metrics, |
| 1004 | + cumulative metrics, ground truth targets, and predictions. |
952 | 1005 | """
|
953 | 1006 |
|
954 |
| - stream.restart() |
| 1007 | + if restart_stream: |
| 1008 | + stream.restart() |
955 | 1009 |
|
956 | 1010 | if _is_fast_mode_compilable(stream, learner, optimise):
|
957 | 1011 | return _prequential_ssl_evaluation_fast(stream,
|
|
0 commit comments