packages feed

som 10.1.0 → 10.1.1

raw patch · 7 files changed

+71/−48 lines, 7 files

Files

ChangeLog.md view
@@ -1,5 +1,7 @@ # Changelog for som +10.0.2 Fixed a warning.+       Added more documentation. 10.0.1 Upgraded to Stackage lts-12.16. 10.0.0 Revamped to work with Stack v1.7.1. 
som.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 4a51f13415d0fcbda9b5fbf306f56b17839c4b559ff620f78bc562de163dc9c4+-- hash: 5821eed6b940eb4034165c9ddfccc442441bba7ee1f8f61c9d11022f811eba6d  name:           som-version:        10.1.0+version:        10.1.1 synopsis:       Self-Organising Maps description:    Please see the README on GitHub at <https://github.com/mhwombat/som#readme> category:       Math
src/Data/Datamining/Clustering/DSOMInternal.hs view
@@ -12,7 +12,8 @@ -- ------------------------------------------------------------------------ {-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances,-    MultiParamTypeClasses, DeriveAnyClass, DeriveGeneric #-}+    MultiParamTypeClasses, DeriveAnyClass, DeriveGeneric,+    UndecidableInstances #-}  module Data.Datamining.Clustering.DSOMInternal where @@ -46,7 +47,7 @@     gridMap :: gm p,     -- | A function which determines the how quickly the SOM learns.     learningRate :: (x -> x -> x -> x),-    -- | A function which compares two patterns and returns a +    -- | A function which compares two patterns and returns a     --   /non-negative/ number representing how different the patterns     --   are.     --   A result of @0@ indicates that the patterns are identical.@@ -92,6 +93,7 @@   alter f k = withGridMap (GM.alter f k)   filterWithKey f = withGridMap (GM.filterWithKey f) +-- | Internal method. withGridMap :: (gm p -> gm p) -> DSOM gm x k p -> DSOM gm x k p withGridMap f s = s { gridMap=gm' }     where gm = gridMap s@@ -101,10 +103,11 @@ toGridMap :: GM.GridMap gm p => DSOM gm x k p -> gm p toGridMap = gridMap +-- | Internal method. adjustNode   :: (G.FiniteGrid (gm p), GM.GridMap gm p,       k ~ G.Index (gm p), k ~ G.Index (GM.BaseGrid gm p),-      Ord k, Num x, Fractional x) => +      Ord k, Num x, Fractional x) =>      gm p -> (p -> x -> p -> p) -> (p -> p -> x) -> (x -> x -> x) -> p -> k -> k        -> (p -> p) adjustNode gm fms fd fr target bmu k = fms target amount@@ -113,6 +116,7 @@                  (G.maxPossibleDistance gm)         amount = fr diff dist +-- | Internal method. scaleDistance :: (Num a, Fractional a) => Int -> Int -> a scaleDistance d dMax   | dMax == 0  = 0@@ -125,7 +129,7 @@ trainNeighbourhood   :: (G.FiniteGrid (gm p), GM.GridMap gm p,       k ~ G.Index (gm p), k ~ G.Index (GM.BaseGrid gm p),-      Ord k, Num x, Fractional x) => +      Ord k, Num x, Fractional x) =>       DSOM gm x t p -> k -> p -> DSOM gm x k p trainNeighbourhood s bmu target = s { gridMap=gm' }   where gm = gridMap s@@ -135,11 +139,12 @@         fr = (learningRate s) bmuDiff         bmuDiff = (difference s) (gm GM.! bmu) target +-- | Internal method. justTrain   :: (G.FiniteGrid (gm p), GM.GridMap gm p, GM.GridMap gm x,       k ~ G.Index (gm p), k ~ G.Index (gm x),       k ~ G.Index (GM.BaseGrid gm p), k ~ G.Index (GM.BaseGrid gm x),-      Ord k, Ord x, Num x, Fractional x) => +      Ord k, Ord x, Num x, Fractional x) =>      DSOM gm x t p -> p -> DSOM gm x k p justTrain s p = trainNeighbourhood s bmu p   where ds = GM.toList . GM.map (difference s p) $ gridMap s@@ -148,7 +153,7 @@         f xs = fst $ minimumBy (comparing snd) xs  instance-  (GM.GridMap gm p, k ~ G.Index (GM.BaseGrid gm p), +  (GM.GridMap gm p, k ~ G.Index (GM.BaseGrid gm p),     G.FiniteGrid (gm p), GM.GridMap gm x, k ~ G.Index (gm p),     k ~ G.Index (gm x), k ~ G.Index (GM.BaseGrid gm x), Ord k, Ord x,     Num x, Fractional x) =>@@ -179,5 +184,5 @@ rougierLearningFunction r p bmuDiff diff dist   | bmuDiff == 0         = 0   | otherwise           = r * abs diff * exp (-k*k)-  where k = dist/(p*abs bmuDiff) +  where k = dist/(p*abs bmuDiff) 
src/Data/Datamining/Clustering/SGM2Internal.hs view
@@ -77,16 +77,16 @@     nextIndex :: k   } deriving (Generic, NFData) --- @'makeSGM' lr n diff ms@ creates a new SGM that does not (yet)--- contain any models.--- It will learn at the rate determined by the learning function @lr@,--- and will be able to hold up to @n@ models.--- It will create a new model based on a pattern presented to it when--- the SGM is not at capacity, or a less useful model can be replaced.--- It will use the function @diff@ to measure the similarity between--- an input pattern and a model.--- It will use the function @ms@ to adjust models as needed to make--- them more similar to input patterns.+-- | @'makeSGM' lr n diff ms@ creates a new SGM that does not (yet)+--   contain any models.+--   It will learn at the rate determined by the learning function @lr@,+--   and will be able to hold up to @n@ models.+--   It will create a new model based on a pattern presented to it when+--   the SGM is not at capacity, or a less useful model can be replaced.+--   It will use the function @diff@ to measure the similarity between+--   an input pattern and a model.+--   It will use the function @ms@ to adjust models as needed to make+--   them more similar to input patterns. makeSGM   :: Bounded k     => (t -> x) -> Int -> (p -> p -> x) -> (p -> x -> p -> p) -> SGM t x k p@@ -148,6 +148,7 @@         k = nextIndex s         gm' = M.insert k (p, 0) gm +-- | Increments the counter. incrementCounter :: (Num t, Ord k) => k -> SGM t x k p -> SGM t x k p incrementCounter k s = s { toMap=gm' }   where gm = toMap s@@ -209,6 +210,8 @@         gm' = M.adjust f k $ M.delete k gm         f (p, _) = (p, c1 + c2) +-- | Set the model for a node.+--   Useful when merging two models and replacing one. setModel :: (Num t, Ord k) => SGM t x k p -> k -> p -> SGM t x k p setModel s k p   | M.member k gm = error "node already exists"@@ -216,13 +219,14 @@   where gm = toMap s         gm' = M.insert k (p, 0) gm -addModel-  :: (Num t, Ord t, Enum k, Ord k)-    => p -> SGM t x k p -> SGM t x k p-addModel p s-  | size s >= capacity s = error "SGM at capacity"-  | otherwise           = addNode p s+-- addModel+--   :: (Num t, Ord t, Enum k, Ord k)+--     => p -> SGM t x k p -> SGM t x k p+-- addModel p s+--   | size s >= capacity s = error "SGM at capacity"+--   | otherwise           = addNode p s +-- | Add a new node, making room for it by merging two existing nodes. mergeAddModel   :: (Num t, Ord t, Ord k) => SGM t x k p -> k -> k -> p -> SGM t x k p mergeAddModel s k1 k2 p = s3@@ -250,9 +254,8 @@           = head . sortBy matchOrder . map (\(k, (_, x)) -> (k, x))               . M.toList $ report --- We want the model with the lowest difference from the input pattern.--- If two models have the same difference, return the model that was--- created earlier (has the lower label #).+-- | Order models by ascending difference from the input pattern,+--   then by creation order (label number). matchOrder :: (Ord a, Ord b) => (a, b) -> (a, b) -> Ordering matchOrder (a, b) (c, d) = compare (b, a) (d, c) @@ -278,6 +281,7 @@         s3 = mergeAddModel s k1 k2 p         (bmu4, _, report4, s4) = trainAndClassify' s3 p +-- | Internal method. -- NOTE: This function will adjust the model and update the match -- for the BMU. trainAndClassify'@@ -289,11 +293,12 @@         s3 = trainNode s2 bmu p         (bmu2, _, report) = classify s3 p +-- | Internal method. addModelTrainAndClassify   :: (Num t, Ord t, Num x, Ord x, Enum k, Ord k)     => SGM t x k p -> p -> (k, x, M.Map k (p, x), SGM t x k p) addModelTrainAndClassify s p = (bmu, 1, report, s')-  where (bmu, _, report, s') = trainAndClassify' (addModel p s) p+  where (bmu, _, report, s') = trainAndClassify' (addNode p s) p  -- | @'train' s p@ identifies the model in @s@ that most closely --   matches @p@, and updates it to be a somewhat better match.
src/Data/Datamining/Clustering/SGMInternal.hs view
@@ -82,18 +82,18 @@     nextIndex :: k   } deriving (Generic, NFData) --- @'makeSGM' lr n dt diff ms@ creates a new SGM that does not (yet)--- contain any models.--- It will learn at the rate determined by the learning function @lr@,--- and will be able to hold up to @n@ models.--- It will create a new model based on a pattern presented to it when--- (1) the SGM contains no models, or--- (2) the difference between the pattern and the closest matching--- model exceeds the threshold @dt@.--- It will use the function @diff@ to measure the similarity between--- an input pattern and a model.--- It will use the function @ms@ to adjust models as needed to make--- them more similar to input patterns.+-- | @'makeSGM' lr n dt diff ms@ creates a new SGM that does not (yet)+--   contain any models.+--   It will learn at the rate determined by the learning function @lr@,+--   and will be able to hold up to @n@ models.+--   It will create a new model based on a pattern presented to it when+--   (1) the SGM contains no models, or+--   (2) the difference between the pattern and the closest matching+--   model exceeds the threshold @dt@.+--   It will use the function @diff@ to measure the similarity between+--   an input pattern and a model.+--   It will use the function @ms@ to adjust models as needed to make+--   them more similar to input patterns. makeSGM   :: Bounded k     => (t -> x) -> Int -> x -> Bool -> (p -> p -> x)@@ -161,6 +161,7 @@                 then M.delete k gm                 else error "no such node" +-- | Increment the match counter. incrementCounter :: (Num t, Ord k) => k -> SGM t x k p -> SGM t x k p incrementCounter k s = s { toMap=gm' }   where gm = toMap s@@ -181,16 +182,20 @@         r = (learningRate s) (time s)         tweakModel (p, t) = (makeSimilar s target r p, t) +-- | Returns the node that has been the BMU least often. leastUsefulNode :: Ord t => SGM t x k p -> k leastUsefulNode s = if isEmpty s                       then error "SGM has no nodes"                       else fst . minimumBy (comparing (snd . snd))                              . M.toList . toMap $ s +-- | Deletes the node that has been the BMU least often. deleteLeastUsefulNode :: (Ord t, Ord k) => SGM t x k p -> SGM t x k p deleteLeastUsefulNode s = deleteNode k s   where k = leastUsefulNode s +-- | Adds a new node to the SGM, deleting the least useful+--   node/model if necessary to make room. addModel   :: (Num t, Ord t, Enum k, Ord k)     => p -> SGM t x k p -> SGM t x k p@@ -216,6 +221,7 @@         (bmu, bmuDiff, report, _) = classify' sFull p  +-- | Internal method. -- NOTE: This function may create a new model, but it does not modify -- existing models. classify'@@ -234,9 +240,8 @@               . M.toList $ report         s' = incrementCounter bmu s --- We want the model with the lowest difference from the input pattern.--- If two models have the same difference, return the model that was--- created earlier (has the lower label #).+-- | Order models by ascending difference from the input pattern,+--   then by creation order (label number). matchOrder :: (Ord a, Ord b) => (a, b) -> (a, b) -> Ordering matchOrder (a, b) (c, d) = compare (b, a) (d, c) 
src/Data/Datamining/Clustering/SOMInternal.hs view
@@ -93,7 +93,7 @@     --   which the node's model should be updated to match the target).     --   The learning rate should be between zero and one.     learningRate :: t -> d -> x,-    -- | A function which compares two patterns and returns a +    -- | A function which compares two patterns and returns a     --   /non-negative/ number representing how different the patterns     --   are.     --   A result of @0@ indicates that the patterns are identical.@@ -143,14 +143,14 @@   alter f k = withGridMap (GM.alter f k)   filterWithKey f = withGridMap (GM.filterWithKey f) +-- | Internal method. withGridMap :: (gm p -> gm p) -> SOM t d gm x k p -> SOM t d gm x k p withGridMap f s = s { gridMap=gm' }     where gm = gridMap s           gm' = f gm -currentLearningFunction-  :: (Num t)-    => SOM t d gm x k p -> (d -> x)+-- | Returns the learning function currently being used by the SOM.+currentLearningFunction :: (Num t) => SOM t d gm x k p -> (d -> x) currentLearningFunction s   = (learningRate s) (counter s) @@ -159,6 +159,7 @@ toGridMap :: GM.GridMap gm p => SOM t d gm x k p -> gm p toGridMap = gridMap +-- | Internal method. adjustNode   :: (G.Grid g, k ~ G.Index g, Num t) =>      g -> (t -> x) -> (p -> x -> p -> p) -> p -> k -> k -> p -> p@@ -180,9 +181,11 @@         f1 = currentLearningFunction s         f2 = makeSimilar s +-- | Increment the match counter. incrementCounter :: Num t => SOM t d gm x k p -> SOM t d gm x k p incrementCounter s = s { counter=counter s + 1} +-- | Internal method. justTrain   :: (Ord x, G.Grid (gm p), GM.GridMap gm x, GM.GridMap gm p,       G.Index (GM.BaseGrid gm x) ~ G.Index (gm p),
src/Data/Datamining/Pattern.hs view
@@ -37,9 +37,11 @@ -- Using numbers as patterns. -- +-- | Returns the absolute difference between two numbers. absDifference :: Num a => a -> a -> a absDifference x y = abs (x - y) +-- | Adjusts a number to make it more similar to the target. adjustNum :: (Num a, Ord a, Eq a) => a -> a -> a -> a adjustNum target r x   | r < 0     = error "Negative learning rate"@@ -54,6 +56,7 @@ -- Using numeric vectors as patterns. -- +-- | Returns the sum of the squares of the elements of a vector. magnitudeSquared :: Num a => [a] -> a magnitudeSquared xs =  sum $ map (\x -> x*x) xs