module MachineLearning.Classification.MultiClass
(
Classifier(..)
, MultiClassModel(..)
, processOutput
, Regularization(..)
, ccostReg
, cgradientReg
)
where
import MachineLearning.Types
import MachineLearning.Model
import MachineLearning.Regularization (Regularization(..))
import qualified MachineLearning as ML
import qualified Data.Vector.Storable as V
import qualified Numeric.LinearAlgebra as LA
class Classifier a where
cscore :: a -> Matrix -> Matrix -> Matrix
chypothesis :: a -> Matrix -> Matrix -> Vector
ccost :: a -> Regularization -> Matrix -> Vector -> Matrix -> R
cgradient :: a -> Regularization -> Matrix -> Vector -> Matrix -> Matrix
cnumClasses :: a -> Int
data MultiClassModel m = MultiClass m
instance (Classifier a) => Model (MultiClassModel a) where
hypothesis (MultiClass m) x theta = chypothesis m x theta'
where theta' = unflatten (cnumClasses m) theta
cost (MultiClass m) lambda x y theta = ccost m lambda x y theta'
where theta' = unflatten (cnumClasses m) theta
gradient (MultiClass m) lambda x y theta = LA.flatten $ cgradient m lambda x y theta'
where theta' = unflatten (cnumClasses m) theta
unflatten :: Int -> Vector -> Matrix
unflatten nLabels v = LA.reshape cols v
where cols = (V.length v) `div` nLabels
processOutput :: (Classifier c) => c -> Vector -> Matrix
processOutput c y = LA.fromColumns $ map f [0 .. (cnumClasses c)-1]
where f sample = V.map (\a -> if round a == sample then 1 else 0) y
ccostReg :: Regularization -> Matrix -> R
ccostReg RegNone _ = 0
ccostReg (L2 lambda) theta = (LA.norm_2 thetaReg) * 0.5 * lambda
where thetaReg = ML.removeBiasDimension theta
cgradientReg :: Regularization -> Matrix -> Matrix
cgradientReg RegNone _ = 0
cgradientReg (L2 lambda) theta = ((LA.scalar lambda) * thetaReg)
where thetaReg = 0 LA.||| (ML.removeBiasDimension theta)