svm-simple 0.2.6 → 0.2.7
raw patch · 6 files changed
+203/−235 lines, 6 filesdep +deepseqdep +monad-pardep ~containersdep ~directorydep ~mwc-random
Dependencies added: deepseq, monad-par
Dependency ranges changed: containers, directory, mwc-random
Files
- AI/SVM/Base.hs +81/−66
- AI/SVM/Simple.hs +89/−34
- Examples/Plot.hs +0/−39
- Examples/PlotOneClass.hs +0/−37
- Examples/SmokeTest.hs +0/−51
- svm-simple.cabal +33/−8
AI/SVM/Base.hs view
@@ -42,6 +42,7 @@ import Control.Exception import Control.Monad import Data.Binary+import Data.Foldable(Foldable) import Data.IORef import Data.List import Data.Map (Map)@@ -60,7 +61,9 @@ import System.IO.Unsafe import Unsafe.Coerce import qualified Data.ByteString.Lazy as B+import qualified Data.Foldable as F import qualified Data.Map as Map+import qualified Data.Vector.Unboxed as UV import qualified Data.Vector as GV import qualified Data.Vector.Storable as V import qualified Foreign.Concurrent as C@@ -82,6 +85,9 @@ instance SVMVector (GV.Vector Double) where convert = convertDense . GV.convert +instance SVMVector (UV.Vector Double) where+ convert = convertDense . UV.convert+ instance SVMVector [Double] where convert = convertDense . V.fromList @@ -122,7 +128,7 @@ offsetPtrs addr = take dim [addr `plusPtr` (idx * sizeOf (C'svm_node undefined undefined)) | idx <- scanl (+) 0 lengths]- y = map (realToFrac . fst) v+ y = map (double2CDouble . fst) v xs = concatMap (V.toList . snd) v deleteProblem (C'svm_problem l class_array offset_array , node_array) =@@ -186,7 +192,7 @@ realToFrac <$> V.unsafeWith nodes (c'svm_predict modelPtr) -defaultParamers = C'svm_parameter {+defaultParameters = C'svm_parameter { c'svm_parameter'svm_type = c'C_SVC , c'svm_parameter'kernel_type = c'LINEAR , c'svm_parameter'degree = 3@@ -212,40 +218,40 @@ put cint = put (realToFrac cint :: Double) get = realToFrac <$> (get :: Get Double) -encodeParams C'svm_parameter{..} = do- put c'svm_parameter'svm_type - put c'svm_parameter'kernel_type - put c'svm_parameter'degree - put c'svm_parameter'gamma - put c'svm_parameter'coef0 - put c'svm_parameter'cache_size - put c'svm_parameter'eps - put c'svm_parameter'C - put c'svm_parameter'nr_weight - --put c'svm_parameter'weight_label = nullPtr- --put c'svm_parameter'weight = nullPtr- put c'svm_parameter'nu - put c'svm_parameter'p - put c'svm_parameter'shrinking- put c'svm_parameter'probability +--encodeParams C'svm_parameter{..} = do+-- put c'svm_parameter'svm_type +-- put c'svm_parameter'kernel_type +-- put c'svm_parameter'degree +-- put c'svm_parameter'gamma +-- put c'svm_parameter'coef0 +-- put c'svm_parameter'cache_size +-- put c'svm_parameter'eps +-- put c'svm_parameter'C +-- put c'svm_parameter'nr_weight +-- --put c'svm_parameter'weight_label = nullPtr+-- --put c'svm_parameter'weight = nullPtr+-- put c'svm_parameter'nu +-- put c'svm_parameter'p +-- put c'svm_parameter'shrinking+-- put c'svm_parameter'probability -decodeParams b = do - c'svm_parameter'svm_type <- get- c'svm_parameter'kernel_type <- get- c'svm_parameter'degree <- get - c'svm_parameter'gamma <- get - c'svm_parameter'coef0 <- get- c'svm_parameter'cache_size <- get - c'svm_parameter'eps <- get- c'svm_parameter'C <- get- c'svm_parameter'nr_weight <- get- c'svm_parameter'nu <- get- c'svm_parameter'p <- get- c'svm_parameter'shrinking <- get- c'svm_parameter'probability <- get- let c'svm_parameter'weight_label = nullPtr- c'svm_parameter'weight = nullPtr- return C'svm_parameter{..}+--decodeParams b = do +-- c'svm_parameter'svm_type <- get+-- c'svm_parameter'kernel_type <- get+-- c'svm_parameter'degree <- get +-- c'svm_parameter'gamma <- get +-- c'svm_parameter'coef0 <- get+-- c'svm_parameter'cache_size <- get +-- c'svm_parameter'eps <- get+-- c'svm_parameter'C <- get+-- c'svm_parameter'nr_weight <- get+-- c'svm_parameter'nu <- get+-- c'svm_parameter'p <- get+-- c'svm_parameter'shrinking <- get+-- c'svm_parameter'probability <- get+-- let c'svm_parameter'weight_label = nullPtr+-- c'svm_parameter'weight = nullPtr+-- return C'svm_parameter{..} @@ -304,11 +310,21 @@ ,c'svm_parameter'svm_type=c'NU_SVR} -setParameters svm kernel = parameters- where +withParameters svm kernel ws op = do+ ptr_parameters <- malloc + weight_labels <- newArray (map (fromIntegral.fst) ws)+ weights <- newArray (map (double2CDouble.snd) ws)+ let no_weights = fromIntegral $ length ws+ poke ptr_parameters parameters{c'svm_parameter'weight_label=weight_labels,c'svm_parameter'weight=weights,c'svm_parameter'nr_weight=no_weights}+ r <- op ptr_parameters+ free ptr_parameters + free weights+ free weight_labels+ return r+ where parameters = setTypeParameters svm . setKernelParameters kernel - $ defaultParamers+ $ defaultParameters -- Other params that currently cannot be passed: -- epsilon -- termination 0.001@@ -320,53 +336,52 @@ foreign import ccall "wrapper" wrapPrintF :: (CString -> IO ()) -> IO (FunPtr (CString -> IO ())) +{-#RULES+ "listToList" F.toList = id #-}+ -- |Create an SVM from the training data-{-#SPECIALIZE trainSVM :: SVMType -> Kernel -> [(Double,SVMNodes)] -> IO (String,SVM) #-}-trainSVM :: (SVMVector a) => SVMType -> Kernel -> [(Double, a)] -> IO (String, SVM)-trainSVM svm kernel (map (second convert) -> dataSet) = do+{-# SPECIALIZE trainSVM :: (SVMVector a) => SVMType -> Kernel -> [(Int,Double)] -> [(Double, a)] -> IO (String, SVM) #-}+{-# SPECIALIZE trainSVM :: (SVMVector a) => SVMType -> Kernel -> GV.Vector (Int,Double) -> GV.Vector (Double, a) -> IO (String, SVM) #-}+trainSVM :: (Foldable f, SVMVector a) => SVMType -> Kernel -> f (Int,Double) -> f (Double, a) -> IO (String, SVM)+trainSVM svm kernel (F.toList -> ws) (map (second convert) . F.toList -> dataSet) = do messages <- newIORef [] let append x = modifyIORef messages (x:) pf <- wrapPrintF (peekCString >=> append) + c'svm_set_print_string_function pf (problem, ptr_nodes) <- createProblem dataSet- ptr_parameters <- malloc - poke ptr_parameters (setParameters svm kernel)- modelPtr <- with problem $ \ptr_problem -> - c'svm_train ptr_problem ptr_parameters- message <- unlines . reverse <$> readIORef messages - (message ,) . SVM <$> C.newForeignPtr modelPtr - (free ptr_parameters- >>deleteProblem (problem, ptr_nodes)- >>modelFinalizer modelPtr) + withParameters svm kernel ws $ \ptr_parameters -> do+ modelPtr <- with problem $ \ptr_problem -> + c'svm_train ptr_problem ptr_parameters+ message <- unlines . reverse <$> readIORef messages + (message ,) . SVM <$> C.newForeignPtr modelPtr + (deleteProblem (problem, ptr_nodes)+ >>modelFinalizer modelPtr) -- |Cross validate SVM. This is faster than training and predicting for each fold -- separately, since there are no extra conversions done between libsvm and haskell. {-#SPECIALIZE crossvalidate :: SVMType -> Kernel -> Int -> [(Double,SVMNodes)] -> IO (String,[Double]) #-}+{-#SPECIALIZE crossvalidate :: SVMType -> Kernel -> Int -> GV.Vector (Double,SVMNodes) -> IO (String,[Double]) #-} crossvalidate- :: (SVMVector b) => SVMType -> Kernel -> Int -> [(Double, b)] -> IO (String, [Double])-crossvalidate svm kernel folds (map (second convert) -> dataSet) = do+ :: (Foldable f, SVMVector b) => SVMType -> Kernel -> Int -> f (Double, b) -> IO (String, [Double])+crossvalidate svm kernel folds (map (second convert) . F.toList -> dataSet) = do messages <- newIORef []- let append x = modifyIORef messages (x:)+ let append x = return ()-- modifyIORef messages (x:) pf <- wrapPrintF (peekCString >=> append) - -- The above is just a test. Realistically at that point there- -- should be an ioref that captures the output which would then- -- be returned from this function. c'svm_set_print_string_function pf (problem, ptr_nodes) <- createProblem dataSet- ptr_parameters <- malloc - poke ptr_parameters (setParameters svm kernel)- - result_ptr :: Ptr CDouble <- mallocArray (length dataSet)+ withParameters svm kernel [] $ \ptr_parameters-> do+ result_ptr :: Ptr CDouble <- mallocArray (length dataSet) - with problem $ \ptr_problem -> - c'svm_cross_validation ptr_problem ptr_parameters (fromIntegral folds) result_ptr + with problem $ \ptr_problem -> + c'svm_cross_validation ptr_problem ptr_parameters (fromIntegral folds) result_ptr - res <- peekArray (length dataSet) result_ptr- message <- unlines . reverse <$> readIORef messages + res <- peekArray (length dataSet) result_ptr+ message <- unlines . reverse <$> readIORef messages - free result_ptr >> free ptr_parameters >> deleteProblem (problem,ptr_nodes)+ free result_ptr >> deleteProblem (problem,ptr_nodes) - return (message,map realToFrac res)+ return (message,map realToFrac res)
AI/SVM/Simple.hs view
@@ -12,7 +12,7 @@ -- Notes : The module is currently not robust to inputs of wrong dimensionality -- and is affected by security risks inherent in libsvm model loading. ----- Important TODO-items: +-- Important TODO-items: -- * Handle the issue of crashing the system by passing vectors of dimension to the SVMs -- * Split this library into high and low level parts -- * Saving and loading SVMs@@ -20,7 +20,7 @@ ------------------------------------------------------------------------------- -- This module presents a high level interface for libsvm toolkit. There are three -- main uses cases for it:--- +-- -- 1. You have vectors of reals associated with labels and you wish to assign labels -- to unlabeled vectors. (Classifier machines) --@@ -39,29 +39,36 @@ ,Kernel(..) ,SVMOneClass(), SVMClassifier(), SVMRegressor() -- * Classifier machines- ,trainClassifier, crossvalidateClassifier, classify + ,trainClassifier, trainWtdClassifier, crossvalidateClassifier, classify+ ,chehLin, ChehLinResult(..) -- * One class machines ,trainOneClass, inSet, OneClassResult(..) -- * Regression machines ,trainRegressor, crossvalidateRegressor, predictRegression- -- * Unfortunate utilities+ -- * Unfortunate utilities ,Persisting(..) ) where import AI.SVM.Base+import AI.SVM.Common import Control.Applicative-import Control.Arrow (second, (***), (&&&))+import Control.Arrow (first, second, (***), (&&&))+import Control.DeepSeq import Control.Monad import Data.Binary+import Data.Foldable (Foldable)+import Data.Function import Data.List import Data.Map (Map)+import Data.Monoid import Data.Tuple+import Foreign.C.Types (CInt(..)) import System.Directory import System.IO.Unsafe+import qualified Control.Monad.Par as P import qualified Data.ByteString.Lazy as B+import qualified Data.Foldable as F import qualified Data.Map as Map-import Foreign.C.Types (CInt)-import AI.SVM.Common -- | Supported SVM classifiers@@ -77,12 +84,16 @@ deriving (Show) data SVMClassifier a = SVMClassifier SVM (Map a Double) (Map Double a)-newtype SVMRegressor = SVMRegressor SVM -newtype SVMOneClass = SVMOneClass SVM +newtype SVMRegressor = SVMRegressor SVM+newtype SVMOneClass = SVMOneClass SVM ++instance NFData a => NFData (SVMClassifier a) where+ rnf (SVMClassifier fp m1 m2) = m1 `deepseq` m2 `seq` ()+ instance (Ord a, Binary a) => Binary (SVMClassifier a) where put (SVMClassifier svm a b) = put svm >> put a >> put b- get = SVMClassifier <$> get <*> get <*> get + get = SVMClassifier <$> get <*> get <*> get instance Binary SVMRegressor where put (SVMRegressor r) = put r@@ -123,38 +134,53 @@ save fp (SVMOneClass a) = saveSVM fp a load fp = SVMOneClass <$> loadSVM fp --- | Train an SVM classifier of given type. +-- | Train an SVM classifier of given type. trainClassifier- :: (SVMVector b, Ord a) =>+ :: (SVMVector b, Ord a, Foldable f) => ClassifierType -- ^ The type of the classifier -> Kernel -- ^ Kernel- -> [(a, b)] -- ^ Training data+ -> f (a, b) -- ^ Training data -> (String, SVMClassifier a) trainClassifier ctype kernel dataset = unsafePerformIO $ do- let (to,from, doubleDataSet) = convertToDouble dataset - (m,svm) <- trainSVM (generalizeClassifier ctype) kernel doubleDataSet+ let (to,from, doubleDataSet) = convertToDouble (F.toList dataset)+ (m,svm) <- trainSVM (generalizeClassifier ctype) kernel [] doubleDataSet return . (m,) $ SVMClassifier svm to from -convertToDouble dataset = let +-- | Train an SVM classifier of given type.+trainWtdClassifier+ :: (Foldable f, SVMVector b, Ord a) =>+ ClassifierType -- ^ The type of the classifier+ -> Kernel -- ^ Kernel+ -> f (a, Double) -- ^ Training weights+ -> f (a, b) -- ^ Training data+ -> (String, SVMClassifier a)+trainWtdClassifier ctype kernel ws dataset = unsafePerformIO $ do+ let (to,from, doubleDataSet) = convertToDouble (F.toList dataset)+ cw = map (first conv) (F.toList ws)+ conv i = round $ to Map.! i+ (m,svm) <- trainSVM (generalizeClassifier ctype) kernel cw doubleDataSet+ return . (m,) $ SVMClassifier svm to from++convertToDouble dataset = let l = zip (nub . map fst $ dataset) [1..] to = Map.fromList l from = Map.fromList $ map swap l- in (to,from, map ((to Map.!) *** convert) dataset) + in (to,from, map ((to Map.!) *** convert) dataset) -- | Perform n-foldl cross validation for given set of SVM parameters-crossvalidateClassifier :: (SVMVector b, Ord a) =>+crossvalidateClassifier :: (Foldable f, SVMVector b, Ord a) => ClassifierType -- ^ The type of classifier- -> Kernel -- ^ Classifier kernel + -> Kernel -- ^ Classifier kernel -> Int -- ^ Number of folds to use- -> [(a, b)] -- ^ Dataset+ -> f (a, b) -- ^ Dataset -> Int -- ^ Seed value. The crossvalidation randomly partitions the data into subsets using this seed value -> (String, [a]) crossvalidateClassifier ctype kernel folds dataset seed = unsafePerformIO $ do- let (to,from, doubleDataSet) = convertToDouble dataset + let (to,from, doubleDataSet) = convertToDouble (F.toList dataset) c_srand (fromIntegral seed) (m,res :: [Double]) <- crossvalidate (generalizeClassifier ctype) kernel folds doubleDataSet return . (m,) $ map (from Map.!) res- where + where labels = map fst @@ -165,8 +191,8 @@ -- | Train an one class classifier trainOneClass :: SVMVector a => Double -> Kernel -> [a] -> (String, SVMOneClass) trainOneClass nu kernel dataset = unsafePerformIO $ do- let doubleDataSet = map (const 1 &&& convert) dataset - (m,svm) <- trainSVM (ONE_CLASS nu) kernel doubleDataSet+ let doubleDataSet = map (const 1 &&& convert) dataset+ (m,svm) <- trainSVM (ONE_CLASS nu) kernel [] doubleDataSet return . (m,) $ SVMOneClass svm -- | The result type of one class svm. The prediction is that point is either `In`the@@ -175,36 +201,65 @@ -- | Predict wether given point belongs to the region defined by the oneclass svm inSet :: SVMVector a => SVMOneClass -> a -> OneClassResult-inSet (SVMOneClass svm) vector = if predict svm vector <0 +inSet (SVMOneClass svm) vector = if predict svm vector <0 then Out else In -- | Train an SVM regression machine trainRegressor- :: (SVMVector b') =>- RegressorType -> Kernel -> [(Double, b')] -> (String, SVMRegressor)+ :: (Foldable f, Functor f, SVMVector b') =>+ RegressorType -> Kernel -> f (Double, b') -> (String, SVMRegressor) trainRegressor rtype kernel dataset = unsafePerformIO $ do- let doubleDataSet = map (second convert) dataset - (m,svm) <- trainSVM (generalizeRegressor rtype) kernel doubleDataSet+ let doubleDataSet = fmap (second convert) (F.toList dataset)+ (m,svm) <- trainSVM (generalizeRegressor rtype) kernel [] doubleDataSet return . (m,) $ SVMRegressor svm -crossvalidateRegressor :: (SVMVector b) =>+crossvalidateRegressor :: (Foldable f, SVMVector b) => RegressorType -- ^ The type of the regressor- -> Kernel -- ^ Kernel + -> Kernel -- ^ Kernel -> Int -- ^ Number of folds to use- -> [(Double, b)] -- ^ Dataset+ -> f (Double, b) -- ^ Dataset -> Int -- ^ Seed value. The crossvalidation randomly partitions the data into subsets using this seed value -> (String, [Double])+ crossvalidateRegressor rtype kernel folds dataset seed = unsafePerformIO $ do- let doubleDataSet = map (second convert) dataset + let doubleDataSet = map (second convert) (F.toList dataset) c_srand (fromIntegral seed) (m,res) <- crossvalidate (generalizeRegressor rtype) kernel folds doubleDataSet return (m,res) +data ChehLinResult = Result {cValue, gammaValue, cvAccuracy :: !Double }+instance NFData ChehLinResult ++-- | Train an RBF classifier using crossvalidation and parameter grid search. This is the+-- recommended way of building classifiers for small to medium size datasets. +chehLin :: (Foldable f, SVMVector b, NFData a, Ord a) =>+ f (a,b) -> (ChehLinResult,SVMClassifier a)+chehLin v = (Result c s a,clf)+ where experiments = [ Result c sigma acc+ | c <- pows 2 (-5) 15+ , sigma <- pows 2 (-15) 3+ , let res = snd $ crossvalidateClassifier (C c) (RBF sigma) 10 listSet 1231+ , let acc = accuracy trainingClasses res+ ]+ trainingClasses = map fst . F.toList $ v+ eq = uncurry (==)+ accuracy as bs = fromIntegral (count eq $ zip as bs) / genericLength as+ count :: (Eq a) => (a -> Bool) -> [a] -> Int+ count p = length . filter p+ listSet = F.toList v+ pows base start end = [base ** i | i <- [start..end]]+ results = P.runPar . P.parMap id $ experiments+ (Result c s a) = maximumBy (compare `on` measure) results+ (msg,clf) = trainClassifier (C c) (RBF s) v++measure (Result _ _ f) = f++ -- | Predict value for given vector via regression predictRegression :: SVMVector a => SVMRegressor -> a -> Double predictRegression (SVMRegressor svm) (convert -> v) = predict svm v- + foreign import ccall "srand" c_srand :: CInt -> IO ()
− Examples/Plot.hs
@@ -1,39 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface, BangPatterns, ScopedTypeVariables, TupleSections, - RecordWildCards, NoMonomorphismRestriction #-}-module Main where--import AI.SVM.Simple-import qualified Data.Vector.Storable as V-import Diagrams.Prelude-import Diagrams.Backend.Cairo.CmdLine-import Diagrams.Backend.Cairo----main = do- let trainingData = [('r', V.fromList [0,0])- ,('r', V.fromList [1,1])- ,('b', V.fromList [0,1])- ,('b', V.fromList [1,0])- ,('i', V.fromList [0.5,0.5::Double])- ]- let (m,svm2) = trainClassifier (C 1) (RBF 4) trainingData- let plot = - (circle # fc green # scale 5 5 )- `atop` - (circle # fc green # scale 5 5- `atop` circle # scale 100 100 # lineWidth 5) # translate (200,200) - `atop` - (circle # fc green # scale 5 5 # translate (400,400) )- `atop` - foldl (atop) (circle # scale 1 1)- [circle # scale 5 5 # translate (400*x,400*y) # fc (color svm2 (x,y))- | x <- [0,0.025..1], y <- [0,0.025..1]] - fst $ renderDia Cairo (CairoOptions ("test.png") (PNG (400,400))) plot- where- color svm (x,y) = case classify svm [x,y] of- 'r' -> red- 'b' -> blue- 'i' -> indigo- -between a x b = a <= x && x <= b
− Examples/PlotOneClass.hs
@@ -1,37 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface, BangPatterns, ScopedTypeVariables, TupleSections, - RecordWildCards, NoMonomorphismRestriction #-}-module Main where--import AI.SVM.Simple-import qualified Data.Vector.Storable as V-import Diagrams.Prelude-import Diagrams.Backend.Cairo.CmdLine-import Diagrams.Backend.Cairo-import System.Random.MWC-import Control.Applicative-import Control.Monad---scaledN g = (+0.5) . (/10) <$> normal g--main = do- pts ::[(Double,Double)] - <- withSystemRandom $ \g -> zip <$> replicateM 30 (scaledN g :: IO Double)- <*> replicateM 30 (scaledN g :: IO Double)- let (msg, svm2) = trainOneClass 0.01 (RBF 1) pts- putStrLn msg- let plot = - foldl (atop) (circle # scale 0.025)- [circle # scale 0.022 # translate (x,y) # fc green- | (x,y) <- pts ] - `atop` - foldl (atop) (circle # scale 0.025)- [circle # scale 0.012 # translate (x,y) # fc (color svm2 (x,y))- | x <- [0,0.025..1], y <- [0,0.025..1]] - fst $ renderDia Cairo (CairoOptions ("test.png") (PNG (400,400))) (plot # lineWidth 0.002)- where- color svm pt = case inSet svm pt of - In -> red- Out -> black- -between a x b = a <= x && x <= b
− Examples/SmokeTest.hs
@@ -1,51 +0,0 @@-{-# LANGUAGE ForeignFunctionInterface, BangPatterns, ScopedTypeVariables, TupleSections, - RecordWildCards #-}-module Main where--import AI.SVM.Simple-import qualified Data.Vector.Storable as V--main = do- svm <- loadSVM "model"- let positiveSample, negativeSample :: V.Vector Double- positiveSample = V.fromList - [0.708333, 1, 1, -0.320755, -0.105023, -1- , 1, -0.419847, -1, -0.225806, 1, -1]- negativeSample = V.fromList- [0.583333 ,-1 ,0.333333 ,-0.603774 ,1 ,-1- ,1 ,0.358779 ,-1 ,-0.483871 ,-1 ,1]-- let - pos, neg :: Double - pos = predict svm positiveSample- neg = predict svm negativeSample - print "Testing a loaded model. Expect (1,-1)."- print (pos,neg)- print "Training"- let trainingData = [(-1, V.fromList [0,1])- ,(-1, V.fromList [1,0])- ,(1, V.fromList [1,1])- ,(-1, V.fromList [1,0])- ,(1, V.fromList [1,1])- ,(-1, V.fromList [1,0])- ,(1, V.fromList [1,1])- ,(-1, V.fromList [1,0])- ,(1, V.fromList [1,1])- ,(-1, V.fromList [1,0])- ,(1, V.fromList [1,1])- ,(-1, V.fromList [1,0])- ,(1, V.fromList [1,1])- ,(-1, V.fromList [1,0])- ,(1, V.fromList [1,1])- ,(1, V.fromList [0,0::Double])- ]- (msg, r) <- crossvalidate (C_SVC 1) (RBF 1) 2 trainingData- print ("cval",msg, r)-- (msg,svm2) <- trainSVM (C_SVC 1) (RBF 1) trainingData- print $ predict svm2 $ [0,1::Double]- print $ predict svm2 $ [1,0::Double]- print $ predict svm2 $ [0.5,0.5::Double]- print $ predict svm2 $ [1,1::Double]--
svm-simple.cabal view
@@ -1,12 +1,15 @@ name: svm-simple-version: 0.2.6+version: 0.2.7 synopsis: Medium level, simplified, bindings to libsvm description: This is a set of simplified bindings to libsvm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/> suite of support vector machines. This package provides tools for classification, one-class classification and support vector regression. .+ Changes in version 0.2.6.1 .+ * Bumped dependencies+ . Changes in version 0.2.6 . * Fixed a critical bug with training and crossvalidation @@ -44,13 +47,17 @@ build-type: Simple cabal-version: >= 1.8++-- Flag benchmark+-- Description: Compile the benchmarking system+-- Default: False -extra-source-files:- Examples/SmokeTest.hs- Examples/Plot.hs- Examples/PlotOneClass.hs library+-- extra-source-files:+-- Examples/SmokeTest.hs+-- Examples/Plot.hs+-- Examples/PlotOneClass.hs other-modules: AI.SVM.Common Exposed-modules:@@ -61,7 +68,25 @@ bytestring >= 0.9.1 && < 0.10, bindings-svm >= 0.2.0 && < 0.3, binary >= 0.5 && < 0.6,- mwc-random >= 0.8 && < 0.9,+ mwc-random >= 0.8 && < 0.13, vector >= 0.7.0.1 && < 1.1,- directory >= 1.1.0.0 && < 1.2,- containers >= 0.4.0.0 && < 0.5+ directory >= 1.1.0.0 && < 1.4,+ containers >= 0.4.2.0 && < 0.5,+ deepseq >= 1.1 && < 1.6,+ monad-par >= 0.1.0.3 && < 0.1.1++-- executable svm-benchmark+-- if !flag(benchmark)+-- buildable: False+-- main-is: Benchmark.hs+-- build-depends:+-- base >= 4 && < 5,+-- bytestring >= 0.9.1 && < 0.10,+-- bindings-svm >= 0.2.0 && < 0.3,+-- binary >= 0.5 && < 0.6,+-- mwc-random >= 0.8 && < 0.12,+-- vector >= 0.7.0.1 && < 1.1,+-- directory >= 1.1.0.0 && < 1.4,+-- containers >= 0.4.2.0 && < 0.5,+-- deepseq >= 1.1 && < 1.6,+-- criterion >= 0.6 && < 1.0