2
2
import copy
3
3
4
4
from capymoa .stream import Stream
5
+ from capymoa .stream ._stream import Schema
6
+ from moa .streams import InstanceStream
5
7
from moa .streams .generators import RandomTreeGenerator as MOA_RandomTreeGenerator
6
8
from moa .streams .generators import SEAGenerator as MOA_SEAGenerator
7
9
from moa .streams .generators import HyperplaneGenerator as MOA_HyperplaneGenerator
8
10
from moa .streams .generators import HyperplaneGeneratorForRegression as MOA_HyperplaneGeneratorForRegression
9
11
from moa .streams .generators import RandomRBFGeneratorDrift as MOA_RandomRBFGeneratorDrift
12
+ from moa .streams .generators import AgrawalGenerator as MOA_AgrawalGenerator
13
+ from moa .streams .generators import LEDGenerator as MOA_LEDGenerator
10
14
from capymoa ._utils import build_cli_str_from_mapping_and_locals
11
15
12
16
@@ -460,4 +464,149 @@ def __str__(self):
460
464
),
461
465
]
462
466
non_default_attributes = [attr for attr in attributes if attr is not None ]
463
- return f"RandomRBFGeneratorDrift({ ', ' .join (non_default_attributes )} )"
467
+ return f"RandomRBFGeneratorDrift({ ', ' .join (non_default_attributes )} )"
468
+
469
+
470
+ class AgrawalGenerator (Stream ):
471
+ """
472
+ An Agrawal Generator
473
+
474
+ >>> from capymoa.stream.generator import AgrawalGenerator
475
+ ...
476
+ >>> stream = AgrawalGenerator()
477
+ >>> stream.next_instance()
478
+ LabeledInstance(
479
+ Schema(generators.AgrawalGenerator ),
480
+ x=ndarray(..., 9),
481
+ y_index=1,
482
+ y_label='groupB'
483
+ )
484
+ >>> stream.next_instance().x
485
+ array([1.40893779e+05, 0.00000000e+00, 4.40000000e+01, 4.00000000e+00,
486
+ 1.90000000e+01, 7.00000000e+00, 1.35000000e+05, 2.00000000e+00,
487
+ 3.95015339e+05])
488
+ """
489
+
490
+ def __init__ (
491
+ self ,
492
+ instance_random_seed : int = 1 ,
493
+ classification_function : int = 1 ,
494
+ peturbation : float = 0.05 ,
495
+ balance_classes : bool = False
496
+ ):
497
+ """ Construct an Agrawal Generator
498
+
499
+ :param instance_random_seed: Seed for random generation of instances.
500
+ :param classification_function: Classification function used, as defined in the original paper.
501
+ :param peturbation: The amount of peturbation (noise) introduced to numeric values
502
+ :param balance: Balance the number of instances of each class.
503
+ """
504
+ self .__init_args_kwargs__ = copy .copy (locals ()) # save init args for recreation. not a deep copy to avoid unnecessary use of memory
505
+
506
+ self .moa_stream = MOA_AgrawalGenerator ()
507
+
508
+ self .instance_random_seed = instance_random_seed
509
+ self .classification_function = classification_function
510
+ self .peturbation = peturbation
511
+ self .balance_classes = balance_classes
512
+
513
+ self .CLI = f"-i { self .instance_random_seed } -f { self .classification_function } \
514
+ -p { self .peturbation } { '-b' if self .balance_classes else '' } "
515
+
516
+ super ().__init__ (CLI = self .CLI , moa_stream = self .moa_stream )
517
+
518
+
519
+ def __str__ (self ):
520
+ attributes = [
521
+ (
522
+ f"instance_random_seed={ self .instance_random_seed } "
523
+ if self .instance_random_seed != 1
524
+ else None
525
+ ),
526
+ (
527
+ f"classification_function={ self .classification_function } "
528
+ ),
529
+ (
530
+ f"peturbation={ self .peturbation } "
531
+ if self .peturbation != 0.05
532
+ else None
533
+ ),
534
+ (
535
+ f"balance={ self .balance } "
536
+ if self .balance
537
+ else None
538
+ )
539
+ ]
540
+
541
+ non_default_attributes = [attr for attr in attributes if attr is not None ]
542
+ return f"AgrawalGenerator({ ', ' .join (non_default_attributes )} )"
543
+
544
+
545
+ class LEDGenerator (Stream ):
546
+ """
547
+ An LED Generator
548
+
549
+ >>> from capymoa.stream.generator import LEDGenerator
550
+ ...
551
+ >>> stream = LEDGenerator()
552
+ >>> stream.next_instance()
553
+ LabeledInstance(
554
+ Schema(generators.LEDGenerator ),
555
+ x=ndarray(..., 24),
556
+ y_index=5,
557
+ y_label='5'
558
+ )
559
+ >>> stream.next_instance().x
560
+ array([1., 1., 1., 0., 1., 1., 0., 0., 0., 1., 0., 1., 0., 1., 1., 0., 1.,
561
+ 0., 0., 1., 1., 0., 1., 1.])
562
+ """
563
+
564
+ def __init__ (
565
+ self ,
566
+ instance_random_seed : int = 1 ,
567
+ percentage : int = 10 ,
568
+ reduce_data : bool = False ,
569
+ ):
570
+ """ Construct an LED Generator
571
+
572
+ :param instance_random_seed: Seed for random generation of instances.
573
+ :param percentage: Percentage of noise to add to the data
574
+ :param reduce_data: Reduce the data to only contain 7 relevant binary attributes
575
+ """
576
+ self .__init_args_kwargs__ = copy .copy (locals ())
577
+ # save init args for recreation. not a deep copy to avoid unnecessary use of memory
578
+
579
+ self .moa_stream = MOA_LEDGenerator ()
580
+
581
+ self .instance_random_seed = instance_random_seed
582
+ self .percentage = percentage
583
+ self .reduce_data = reduce_data
584
+
585
+ # In Moa it is an int, In CapyMoa it is a float
586
+ self .CLI = f"-i { self .instance_random_seed } -n { self .percentage } \
587
+ { '-s' if self .reduce_data else '' } "
588
+
589
+ super ().__init__ (CLI = self .CLI , moa_stream = self .moa_stream )
590
+
591
+
592
+ def __str__ (self ):
593
+ attributes = [
594
+ (
595
+ f"instance_random_seed={ self .instance_random_seed } "
596
+ if self .instance_random_seed != 1
597
+ else None
598
+ ),
599
+ (
600
+ f"percentage={ self .percentage } "
601
+ if self .percentage != 10
602
+ else None
603
+ ),
604
+ (
605
+ f"reduce_data={ self .reduce_data } "
606
+ if self .reduce_data
607
+ else None
608
+ )
609
+ ]
610
+
611
+ non_default_attributes = [attr for attr in attributes if attr is not None ]
612
+ return f"LEDGenerator({ ', ' .join (non_default_attributes )} )"
0 commit comments