| 1 |  |  | # from collections import Counter, OrderedDict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | # import attr | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | # @attr.s | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | # class Grouping: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | #     """A Cluster is basically a group of objects""" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | #     members = attr.ib(init=True, converter=tuple) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | #     def __str__(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | #         return f'len {len(self.members)}' | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 13 |  |  | #     def __len__(self): | 
            
                                                                        
                            
            
                                    
            
            
                | 14 |  |  | #         return len(list(self.members)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | #     def __iter__(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | #         return iter(self.members) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | #     def gen_members(self, **kwargs): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | #         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | #         Accepts 'sort' True/False and 'reverse': True/False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | #         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | #         return iter({True: sorted, False: self.__pass}[kwargs.pop('sort', False)](self.members, **kwargs)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | #     def __pass(self, x, **kwargs): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | #         return x | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | # @attr.s | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  | # class BaseCluster(Grouping): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | #     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | #     An instance of this class encapsuates the behaviour of a single (one group) cluster estimated on some data. The object contains | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | #     essentially a "list" of objects | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | #     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | #     def alphabetical(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  | #         return self.gen_members(sort=True) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  | # def _is_coordinate_value(self, attribute, value): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  | #     if value < 0: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  | #         raise ValueError("Expected the input coordinate to be a positive number.") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  | #     if int(value) != value: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  | #         raise ValueError(f"Expected the input coordinate to be an integer number; instead {value} was given. Expected an integer for the coordinates. Self-organising map clusters the datapoints by putting the into distrete points on the x-y latice. These points have rounded/integer coordinates") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  | # @attr.s | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  | # class PositiveIntegerCoordinates: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  | #     """A base class to encapsulate objects behaving as 2D (x, y) coordinates | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  | #      Args: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  | #         x (number): equal to the distance from the vertical axis at x=0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  | #         y (number): equal to the distance from the horizontal axis at y=0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  | #     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  | #     x = attr.ib(init=True, validator=_is_coordinate_value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  | #     y = attr.ib(init=True, validator=_is_coordinate_value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  | #     @staticmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  | #     def from_duo(two_element_list_like): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  | #         return SomClusterMemberCoordinates(*list(iter(two_element_list_like))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  | # @attr.s | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  | # class SOMCluster(BaseCluster): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  | #     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  | #     An instance of this class encapsulates the behaviour of a clustering computed on a self-organizing map. A cluster computed on | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  | #     a trained SOM, is located on a neuron | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  | #     is located on one of the neurons (bmus) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  | #     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  | #     # coordinates = attr.ib(init=True, converter=Coordinates.from_duo) | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 70 |  |  | #     id = attr.ib(init=True, default=None) | 
            
                                                        
            
                                    
            
            
                | 71 |  |  |  |