Using SelfOrganizing map som from hackage for List of Lists

99 Views Asked by At

i wanted to use the som package from http://hackage.haskell.org/package/som to test some things with my own Data. I have looked up the example https://github.com/mhwombat/som/blob/master/examples/housePrices.hs

and i have to rewrite the code for my use case which is Data Like Float or Double Lists in a List

let myData = [[1.2,1.3,4.1],[1.2,1.3,3.1] ...]

I would appreciate any help or any hint for another som package for List of Lists as inputs.

Edit: The complete Code

import Control.Monad (foldM_, forM_, unless, replicateM)
import Control.Monad.Random (evalRandIO, Rand, RandomGen, getRandomR)
import Data.Datamining.Pattern (adjustVector,  euclideanDistanceSquared)
import Data.Datamining.Clustering.SOM (SOM(..), toGridMap, decayingGaussian)
import Data.Datamining.Clustering.Classifier (Classifier, train, trainBatch)

import Data.List (foldl')
import Data.Word (Word8)
import Data.Array.IArray (elems)
import Data.Array.Unboxed (UArray)
import Data.Array.ST (runSTArray)
import GHC.Arr (listArray, readSTArray, thawSTArray, writeSTArray)
import Math.Geometry.Grid 
import Math.Geometry.Grid.Square (RectSquareGrid, rectSquareGrid)
import qualified Math.Geometry.GridMap as GM 
import Math.Geometry.GridMap.Lazy (LGridMap, lazyGridMap)
import Numeric (showHex)
import System.Directory (doesFileExist) 

main :: IO ()
main = do
  c <- evalRandIO $ buildSOM (length myTestDataInput)
  putStr . show . map round . GM.elems . toGridMap $ c
  foldM_ trainAndPrint c myTestDataInput

trainAndPrint c x = do
   let c2 = train c x
   putStr . show . map round . GM.elems . toGridMap $ c2
   putStrLn $ " after training with " ++ show (round x)
   return c2


 buildSOM n = do     
    let g = rectSquareGrid 3 3  
    let gm = lazyGridMap g ownWeights
    let n' = fromIntegral n
    let lrf = decayingGaussian 0.5 0.1 0.3 0.1 n' 
    return $ SOM gm lrf absD adjustNum 0


ownWeights = [[1.2,1.3],[1.2,1.3],[1.2,1.3],[1.2,1.3],[1.2,4.3],[1.2,1.5],[6.2,1.3]]
myTestDataInput  = [[1.2,1.3],[1.2,1.3],[1.3,3.1],[1.2,2.3],[4.3,3.1],[1.5,3.1],[6.2,1.3]]

absD _ [] = []
absD [] _ = []
absD (x:xs) (y:ys) = abs (x-y) : absD xs ys

adjustNum [] _ _ = []
adjustNum (target:tarL) r (x:xs)
  | r < 0     = error "Negative learning rate"
  | r > 1     = error "Learning rate > 1"
  | otherwise = x + r*(target - x) : adjustNum tarL r xs

Full Error:

C:\NN\SOM.hs:65:28: error:

* Occurs check: cannot construct the infinite type: a0 ~ [a0]
  Expected type: [a0] -> [a0] -> [a0] -> [a0]
    Actual type: [a0] -> a0 -> [a0] -> [a0]
* In the fourth argument of `SOM', namely `adjustNum'
  In the second argument of `($)', namely
    `SOM gm lrf absD adjustNum 0'
  In a stmt of a 'do' block: return $ SOM gm lrf absD adjustNum 0
* Relevant bindings include
    lrf :: [a0] -> [a0] -> [a0] (bound at C:\\NN\SOM.hs:64:7)
    n' :: [a0] (bound at C:\\NN\SOM.hs:63:7)
    gm :: LGridMap RectSquareGrid [a0] (bound at C:\\NN\SOM.hs:62:7)
    buildSOM :: Int
                -> Control.Monad.Trans.Random.Lazy.RandT
                     System.Random.StdGen
                     Data.Functor.Identity.Identity
                     (SOM [a0] [a0] (LGridMap RectSquareGrid) [a0] (Int, Int) [a0])
      (bound at C:\\NN\SOM.hs:56:1)
 | 65 | return $ SOM gm lrf absD adjustNum 0 | ^^^^^^^^^ Failed, no modules loaded. Prelude>
1

There are 1 best solutions below

0
On BEST ANSWER

I found my answer for this problem after checking and trying out the other exmple given in https://github.com/mhwombat/som/blob/master/examples/colours.hs

Using the function euclideanDistanceSquared and adjustVector provided by the som lib instead of my defined ones worked for me.