som 7.2.4 → 7.3.0
raw patch · 4 files changed
+172/−2 lines, 4 filesdep +containersPVP ok
version bump matches the API change (PVP)
Dependencies added: containers
API changes (from Hackage documentation)
+ Data.Datamining.Clustering.SSOM: Gaussian :: a -> a -> a -> Gaussian a
+ Data.Datamining.Clustering.SSOM: SSOM :: Map k p -> f -> t -> SSOM f t k p
+ Data.Datamining.Clustering.SSOM: counter :: SSOM f t k p -> t
+ Data.Datamining.Clustering.SSOM: data Gaussian a
+ Data.Datamining.Clustering.SSOM: data SSOM f t k p
+ Data.Datamining.Clustering.SSOM: learningFunction :: SSOM f t k p -> f
+ Data.Datamining.Clustering.SSOM: sMap :: SSOM f t k p -> Map k p
+ Data.Datamining.Clustering.SSOM: toMap :: SSOM f t k p -> Map k p
+ Data.Datamining.Clustering.SSOM: trainNode :: (Pattern p, LearningFunction f, Metric p ~ LearningRate f, Num (LearningRate f), Ord k, Integral t) => SSOM f t k p -> k -> p -> SSOM f t k p
+ Data.Datamining.Clustering.SSOMInternal: Gaussian :: a -> a -> a -> Gaussian a
+ Data.Datamining.Clustering.SSOMInternal: SSOM :: Map k p -> f -> t -> SSOM f t k p
+ Data.Datamining.Clustering.SSOMInternal: class LearningFunction f where type family LearningRate f
+ Data.Datamining.Clustering.SSOMInternal: counter :: SSOM f t k p -> t
+ Data.Datamining.Clustering.SSOMInternal: data Gaussian a
+ Data.Datamining.Clustering.SSOMInternal: data SSOM f t k p
+ Data.Datamining.Clustering.SSOMInternal: incrementCounter :: Num t => SSOM f t k p -> SSOM f t k p
+ Data.Datamining.Clustering.SSOMInternal: instance (Eq f, Eq t, Eq k, Eq p) => Eq (SSOM f t k p)
+ Data.Datamining.Clustering.SSOMInternal: instance (Floating a, Fractional a, Num a) => LearningFunction (Gaussian a)
+ Data.Datamining.Clustering.SSOMInternal: instance (Pattern p, Ord (Metric p), LearningFunction f, Metric p ~ LearningRate f, Num (LearningRate f), Ord k, Integral t) => Classifier (SSOM f t) k p
+ Data.Datamining.Clustering.SSOMInternal: instance (Show f, Show t, Show k, Show p) => Show (SSOM f t k p)
+ Data.Datamining.Clustering.SSOMInternal: instance Constructor C1_0Gaussian
+ Data.Datamining.Clustering.SSOMInternal: instance Constructor C1_0SSOM
+ Data.Datamining.Clustering.SSOMInternal: instance Datatype D1Gaussian
+ Data.Datamining.Clustering.SSOMInternal: instance Datatype D1SSOM
+ Data.Datamining.Clustering.SSOMInternal: instance Eq a => Eq (Gaussian a)
+ Data.Datamining.Clustering.SSOMInternal: instance Generic (Gaussian a)
+ Data.Datamining.Clustering.SSOMInternal: instance Generic (SSOM f t k p)
+ Data.Datamining.Clustering.SSOMInternal: instance Selector S1_0_0SSOM
+ Data.Datamining.Clustering.SSOMInternal: instance Selector S1_0_1SSOM
+ Data.Datamining.Clustering.SSOMInternal: instance Selector S1_0_2SSOM
+ Data.Datamining.Clustering.SSOMInternal: instance Show a => Show (Gaussian a)
+ Data.Datamining.Clustering.SSOMInternal: justTrain :: (Ord (Metric p), Pattern p, LearningFunction f, Metric p ~ LearningRate f, Num (LearningRate f), Ord k, Integral t) => SSOM f t k p -> p -> SSOM f t k p
+ Data.Datamining.Clustering.SSOMInternal: learningFunction :: SSOM f t k p -> f
+ Data.Datamining.Clustering.SSOMInternal: rate :: LearningFunction f => f -> LearningRate f -> LearningRate f
+ Data.Datamining.Clustering.SSOMInternal: sMap :: SSOM f t k p -> Map k p
+ Data.Datamining.Clustering.SSOMInternal: toMap :: SSOM f t k p -> Map k p
+ Data.Datamining.Clustering.SSOMInternal: trainNode :: (Pattern p, LearningFunction f, Metric p ~ LearningRate f, Num (LearningRate f), Ord k, Integral t) => SSOM f t k p -> k -> p -> SSOM f t k p
Files
- som.cabal +6/−2
- src/Data/Datamining/Clustering/SSOM.hs +46/−0
- src/Data/Datamining/Clustering/SSOMInternal.hs +118/−0
- test/Main.hs +2/−0
som.cabal view
@@ -1,5 +1,5 @@ Name: som-Version: 7.2.4+Version: 7.3.0 Stability: experimental Synopsis: Self-Organising Maps. Description: A Kohonen Self-organising Map (SOM) maps input patterns @@ -33,12 +33,13 @@ source-repository this type: git location: https://github.com/mhwombat/som.git- tag: 7.2.4+ tag: 7.3.0 library hs-source-dirs: src build-depends: base ==4.*,+ containers ==0.5.*, grid ==7.*, MonadRandom ==0.3.* ghc-options: -Wall@@ -46,6 +47,8 @@ Data.Datamining.Clustering.SOMInternal, Data.Datamining.Clustering.DSOM, Data.Datamining.Clustering.DSOMInternal,+ Data.Datamining.Clustering.SSOM,+ Data.Datamining.Clustering.SSOMInternal, Data.Datamining.Clustering.Classifier, Data.Datamining.Pattern @@ -56,6 +59,7 @@ QuickCheck ==2.7.*, test-framework ==0.8.*, som,+ containers ==0.5.*, grid ==7.*, MonadRandom ==0.3.*, random ==1.1.*
+ src/Data/Datamining/Clustering/SSOM.hs view
@@ -0,0 +1,46 @@+------------------------------------------------------------------------+-- |+-- Module : Data.Datamining.Clustering.SSOM+-- Copyright : (c) Amy de Buitléir 2012-2014+-- License : BSD-style+-- Maintainer : amy@nualeargais.ie+-- Stability : experimental+-- Portability : portable+--+-- A Simplified Self-organising Map (SSOM). An SSOM maps input patterns+-- onto a set, where each element in the set is a model of the input+-- data. An SSOM is like a Kohonen Self-organising Map (SOM), except+-- that instead of a grid, it uses a simple set of unconnected models.+-- Since the models are unconnected, only the model that best matches+-- the input is ever updated. This makes it faster, however,+-- topological relationships within the input data are not preserved.+-- This implementation supports the use of non-numeric patterns.+--+-- In layman's terms, a SSOM can be useful when you you want to build+-- a set of models on some data. A tutorial is available at+-- <https://github.com/mhwombat/som/wiki>.+--+-- References:+--+-- * de Buitléir, Amy, Russell, Michael and Daly, Mark. (2012). Wains:+-- A pattern-seeking artificial life species. Artificial Life, 18 (4),+-- 399-423. +-- +-- * Kohonen, T. (1982). Self-organized formation of topologically +-- correct feature maps. Biological Cybernetics, 43 (1), 59–69.+------------------------------------------------------------------------++module Data.Datamining.Clustering.SSOM+ (+ -- * Construction+ SSOM(..),+ Gaussian(..),+ -- * Deconstruction+ toMap,+ -- * Advanced control+ trainNode,+ ) where++import Data.Datamining.Clustering.SSOMInternal (SSOM(..),+ Gaussian(..), toMap, trainNode)+
+ src/Data/Datamining/Clustering/SSOMInternal.hs view
@@ -0,0 +1,118 @@+------------------------------------------------------------------------+-- |+-- Module : Data.Datamining.Clustering.SSOMInternal+-- Copyright : (c) Amy de Buitléir 2012-2014+-- License : BSD-style+-- Maintainer : amy@nualeargais.ie+-- Stability : experimental+-- Portability : portable+--+-- A module containing private @SSOM@ internals. Most developers should+-- use @SSOM@ instead. This module is subject to change without notice.+--+------------------------------------------------------------------------+{-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances,+ MultiParamTypeClasses, DeriveGeneric #-}++module Data.Datamining.Clustering.SSOMInternal where++import Data.List (foldl', minimumBy)+import Data.Ord (comparing)+import Data.Datamining.Pattern (Pattern(..))+import Data.Datamining.Clustering.Classifier(Classifier(..))+import qualified Data.Map.Strict as M+import GHC.Generics (Generic)+import Prelude hiding (lookup)++-- | A function used to adjust the models in a classifier.+class LearningFunction f where+ type LearningRate f+ -- | @'rate' f t@ returns the learning rate for a node.+ -- The parameter @f@ is the learning function.+ -- The parameter @t@ indicates how many patterns (or pattern+ -- batches) have previously been presented to the classifier.+ -- Typically this is used to make the learning rate decay over time.+ -- The output is the learning rate for that node (the amount by+ -- which the node's model should be updated to match the target).+ -- The learning rate should be between zero and one.+ rate :: f -> LearningRate f -> LearningRate f++-- | A typical learning function for classifiers.+-- @'Gaussian' r0 rf tf@ returns a gaussian function. At time zero,+-- the learning rate is @r0@. Over time the learning rate tapers off,+-- until at time @tf@, the learning rate is @rf@. Normally the+-- parameters should be chosen such that:+--+-- * 0 < rf << r0 < 1+--+-- * 0 < tf+--+-- where << means "is much smaller than" (not the Haskell @<<@+-- operator!)+data Gaussian a = Gaussian a a a+ deriving (Eq, Show, Generic)++instance (Floating a, Fractional a, Num a)+ => LearningFunction (Gaussian a) where+ type LearningRate (Gaussian a) = a+ rate (Gaussian r0 rf tf) t = r0 * ((rf/r0)**(t/tf))++-- | A Simplified Self-Organising Map (SSOM).+data SSOM f t k p = SSOM+ {+ -- | Maps patterns to nodes.+ sMap :: M.Map k p,+ -- | The function used to update the nodes.+ learningFunction :: f,+ -- | A counter used as a "time" parameter.+ -- If you create the SSOM with a counter value @0@, and don't+ -- directly modify it, then the counter will represent the number+ -- of patterns that this SSOM has classified.+ counter :: t+ } deriving (Eq, Show, Generic)++-- | Extracts the current models from the SSOM.+-- A synonym for @'sMap'@.+toMap :: SSOM f t k p -> M.Map k p+toMap = sMap++-- | Trains the specified node and the neighbourood around it to better+-- match a target.+-- Most users should use @train@, which automatically determines+-- the BMU and trains it and its neighbourhood.+trainNode+ :: (Pattern p, LearningFunction f, Metric p ~ LearningRate f,+ Num (LearningRate f), Ord k, Integral t)+ => SSOM f t k p -> k -> p -> SSOM f t k p+trainNode s k target = s { sMap=gm' }+ where gm = sMap s+ gm' = M.adjust (makeSimilar target r) k gm+ r = rate (learningFunction s) (fromIntegral $ counter s)++incrementCounter :: Num t => SSOM f t k p -> SSOM f t k p+incrementCounter s = s { counter=counter s + 1}++justTrain+ :: (Ord (Metric p), Pattern p, LearningFunction f,+ Metric p ~ LearningRate f, Num (LearningRate f), Ord k, Integral t)+ => SSOM f t k p -> p -> SSOM f t k p+justTrain s p = trainNode s bmu p+ where ds = M.toList . M.map (p `difference`) . toMap $ s+ bmu = f ds+ f [] = error "SSOM has no models"+ f xs = fst $ minimumBy (comparing snd) xs++instance+ (Pattern p, Ord (Metric p), LearningFunction f,+ Metric p ~ LearningRate f, Num (LearningRate f), Ord k, Integral t)+ => Classifier (SSOM f t) k p where+ toList = M.toList . toMap+ -- TODO: If the # of models is fixed, make more efficient+ numModels = length . M.keys . sMap+ models = M.elems . toMap+ differences s p = M.toList . M.map (p `difference`) $ toMap s+ trainBatch s = incrementCounter . foldl' justTrain s+ reportAndTrain s p = (bmu, ds, s')+ where ds = differences s p+ bmu = fst $ minimumBy (comparing snd) ds+ s' = incrementCounter . trainNode s bmu $ p
test/Main.hs view
@@ -15,6 +15,7 @@ import Data.Datamining.PatternQC ( test ) import Data.Datamining.Clustering.SOMQC ( test )+import Data.Datamining.Clustering.SSOMQC ( test ) import Data.Datamining.Clustering.DSOMQC ( test ) import Test.Framework as TF ( defaultMain, Test )@@ -23,6 +24,7 @@ tests = [ Data.Datamining.PatternQC.test,+ Data.Datamining.Clustering.SSOMQC.test, Data.Datamining.Clustering.SOMQC.test, Data.Datamining.Clustering.DSOMQC.test ]