module NLP.Scores
(
sum
, mean
, accuracy
, recipRank
, avgPrecision
, jaccard
)
where
import Data.List hiding (sum)
import qualified Data.Set as Set
import Prelude hiding (sum)
sum :: (Num a) => [a] -> a
sum = foldl' (+) 0
mean :: (Fractional n, Real a) => [a] -> n
mean xs =
let (sum,len) = foldl' (\(!s,!l) x -> (s+x,l+1)) (0,0) xs
in realToFrac sum/len
accuracy :: (Eq a, Fractional n) => [a] -> [a] -> n
accuracy xs = mean . map fromEnum . zipWith (==) xs
recipRank :: (Eq a, Fractional n) => a -> [a] -> n
recipRank y ys =
case [ r | (r,y') <- zip [1..] ys , y' == y ] of
[] -> 0
r:_ -> 1/fromIntegral r
avgPrecision :: (Fractional n, Ord a) => Set.Set a -> [a] -> n
avgPrecision gold _ | Set.size gold == 0 = 0
avgPrecision gold xs =
(/fromIntegral (Set.size gold))
. sum
. map (\(r,rel,cum) -> if rel == 0
then 0
else fromIntegral cum / fromIntegral r)
. takeWhile (\(_,_,cum) -> cum <= Set.size gold)
. snd
. mapAccumL (\z (r,rel) -> (z+rel,(r,rel,z+rel))) 0
$ [ (r,fromEnum $ x `Set.member` gold) | (x,r) <- zip xs [1..]]
jaccard :: (Fractional n, Ord a) => Set.Set a -> Set.Set a -> n
jaccard a b =
fromIntegral (Set.size (Set.intersection a b))
/
fromIntegral (Set.size (Set.union a b))