packages feed

Learning (empty) → 0.0.0

raw patch · 8 files changed

+268/−0 lines, 8 filesdep +Learningdep +basedep +hmatrixsetup-changed

Dependencies added: Learning, base, hmatrix, vector

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for Learning++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Bogdan Penkovsky (c) 2018++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Bogdan Penkovsky nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Learning.cabal view
@@ -0,0 +1,70 @@+-- This file has been generated from package.yaml by hpack version 0.20.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: cc0645cca2baee4a686a5bc4eebc313fda168d1efe6b0301bccb1ec7e7543c25++name:           Learning+version:        0.0.0+synopsis:       Most frequently used machine learning tools+description:    Please see the README on Github at <https://github.com/masterdezign/Learning#readme>+category:       ML+homepage:       https://github.com/masterdezign/Learning#readme+bug-reports:    https://github.com/masterdezign/Learning/issues+author:         Bogdan Penkovsky+maintainer:     dev at penkovsky [dot] com+copyright:      Bogdan Penkovsky+license:        BSD3+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.10++extra-source-files:+    ChangeLog.md+    README.md++source-repository head+  type: git+  location: https://github.com/masterdezign/Learning++library+  hs-source-dirs:+      src+  build-depends:+      base >=4.7 && <5+    , hmatrix >=0.18.0.0+    , vector+  exposed-modules:+      Learning+  other-modules:+      Paths_Learning+  default-language: Haskell2010++executable Learning-exe+  main-is: Main.hs+  hs-source-dirs:+      app+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      Learning+    , base >=4.7 && <5+    , hmatrix >=0.18.0.0+    , vector+  other-modules:+      Paths_Learning+  default-language: Haskell2010++test-suite Learning-test+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      Learning+    , base >=4.7 && <5+    , hmatrix >=0.18.0.0+    , vector+  other-modules:+      Paths_Learning+  default-language: Haskell2010
+ README.md view
@@ -0,0 +1,4 @@+# Learning++A micro library containing the most common machine learning tools+written in Haskell.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,4 @@+module Main where++main :: IO ()+main = putStrLn "No demo yet"
+ src/Learning.hs view
@@ -0,0 +1,153 @@+-- |+-- = Machine learning utilities+-- +-- A micro library containing the most common machine learning tools.+-- Check also the mltool package https://hackage.haskell.org/package/mltool.++{-# LANGUAGE UnicodeSyntax #-}+module Learning (+  -- * Datasets+  Dataset (..)++  -- * Principal component analysis+  , PCA (..)+  , pca++  -- * Supervised learning+  , Classifier+  , learn+  , learn'+  , teacher+  , scores+  , winnerTakesAll++  -- * Evaluation+  , errors+  , errorRate+  ) where++import           Numeric.LinearAlgebra+import qualified Data.Vector.Storable as V++-- Supervised dataset+data Dataset a b = Dataset { _samples :: [a], _labels :: [b] }++-- | Computes "covariance matrix", alternative to (snd. meanCov).+-- Source: https://hackage.haskell.org/package/mltool-0.1.0.2/docs/src/MachineLearning.PCA.html+-- covarianceMatrix :: Matrix Double -> Matrix Double+-- covarianceMatrix x = ((tr x) <> x) / (fromIntegral $ rows x)++-- | Produces a compression matrix u'+pca' :: Int -> [Vector Double] -> Matrix Double+pca' maxDim xs = tr u ? [0..maxDim - 1]+  where+    xs' = fromBlocks $ map ((: []). tr. reshape 1) xs+    -- Covariance matrix Sigma+    sigma = snd $ meanCov xs'+    -- Eigenvectors matrix U+    (u, _, _) = svd $ unSym sigma++data PCA = PCA+  { _u :: Matrix Double  -- Compression matrix U+  , _compress :: Vector Double -> Matrix Double+  , _decompress :: Matrix Double -> Vector Double+  }++-- | Principal component analysis (PCA)+pca :: Int+    -> [Vector Double]+    -> PCA+pca maxDim xs = let u' = pca' maxDim xs+                    u = tr u'+                in PCA+                   { _u = u+                   , _compress = (u' <>). reshape 1+                   , _decompress = flatten. (u <>)+                   }++type Classifier a = (Matrix Double -> a)++-- | Perform supervised learning to create a linear classifier.+-- The ridge regression is run with regularization parameter mu=1e-4.+learn+  :: V.Storable a =>+     Vector a+     -> Matrix Double+     -> Matrix Double+     -> Either String (Classifier a)+learn klasses xs teacher' =+  case learn' xs teacher' of+    Just readout -> Right (classify readout klasses)+    Nothing -> Left "Couldn't learn: check `xs` matrix properties"+{-# SPECIALIZE learn+  :: Vector Int+     -> Matrix Double+     -> Matrix Double+     -> Either String (Classifier Int) #-}++-- | Create a linear readout using the ridge regression+learn'+  :: Matrix Double+     -> Matrix Double+     -> Maybe (Matrix Double)+learn' a b = case ridgeRegression 1e-4 a b of+    (Just x) -> Just (tr x)+    _ -> Nothing++-- | Teacher matrix+teacher :: Int -> Int -> Int -> Matrix Double+teacher nLabels correctIndex repeatNo = fromBlocks. map f $ [0..nLabels-1]+  where ones = konst 1.0 (1, repeatNo)+        zeros = konst 0.0 (1, repeatNo)+        f i | i == correctIndex = [ones]+            | otherwise = [zeros]++-- | Performs the supervised training that results in a linear readout.+-- See https://en.wikipedia.org/wiki/Tikhonov_regularization+ridgeRegression :: +  Double  -- ^ Regularization constant+  -> Matrix Double+  -> Matrix Double +  -> Maybe (Matrix Double)+ridgeRegression μ tA tB = linearSolve oA oB+  where+    oA = (tA <> tr tA) + (scalar μ * ident (rows tA))+    oB = tA <> tr tB+    _f Nothing = Nothing+    _f (Just x) = Just (tr x)++-- | Winner-takes-all classification method+winnerTakesAll+  :: V.Storable a+  => Matrix Double  -- ^ Transposed readout matrix+  -> Vector a  -- ^ Vector of possible classes+  -> Classifier a  -- ^ `Classifier`+winnerTakesAll readout klasses response = klasses V.! klass+  where klass = maxIndex $ scores readout response++-- | Evaluate the network state (nonlinear response) according+-- to some readout matrix trW.+scores :: Matrix Double -> Matrix Double -> Vector Double+scores trW response = evalScores+  where w = trW <> response+        -- Sum the elements in each row+        evalScores = w #> vector (replicate (cols w) 1.0)++classify+  :: V.Storable a+     => Matrix Double -> Vector a -> Classifier a+classify = winnerTakesAll+{-# SPECIALIZE classify+  :: Matrix Double -> Vector Int -> Classifier Int+  #-}++-- | Calculates the error rate in %+errorRate :: (Eq a, Fractional err) => [a] -> [a] -> err+errorRate tgtLbls cLbls = 100 * fromIntegral errNo / fromIntegral (length tgtLbls)+  where errNo = length $ errors $ zip tgtLbls cLbls+{-# SPECIALIZE errorRate :: [Int] → [Int] → Double #-}++-- | Returns the misclassified cases+errors :: Eq a => [(a, a)] -> [(a, a)]+errors = filter (uncurry (/=))+{-# SPECIALIZE errors :: [(Int, Int)] -> [(Int, Int)] #-}
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"