crf-chain1-constrained 0.5.0 → 0.6.0
raw patch · 3 files changed
+93/−27 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.CRF.Chain1.Constrained.DAG.Train: dagProb :: DAG a (X, Y) -> Double
+ Data.CRF.Chain1.Constrained.DAG.Train: Cyclic :: Error
+ Data.CRF.Chain1.Constrained.DAG.Train: Malformed :: Error
+ Data.CRF.Chain1.Constrained.DAG.Train: SeveralSources :: [NodeID] -> Error
+ Data.CRF.Chain1.Constrained.DAG.Train: SeveralTargets :: [NodeID] -> Error
+ Data.CRF.Chain1.Constrained.DAG.Train: WrongBalance :: [NodeID] -> Error
+ Data.CRF.Chain1.Constrained.DAG.Train: data Error
+ Data.CRF.Chain1.Constrained.DAG.Train: instance GHC.Classes.Eq Data.CRF.Chain1.Constrained.DAG.Train.Error
+ Data.CRF.Chain1.Constrained.DAG.Train: instance GHC.Classes.Ord Data.CRF.Chain1.Constrained.DAG.Train.Error
+ Data.CRF.Chain1.Constrained.DAG.Train: instance GHC.Show.Show Data.CRF.Chain1.Constrained.DAG.Train.Error
+ Data.CRF.Chain1.Constrained.DAG.Train: verifyDAG :: DAG a (X, Y) -> Maybe Error
- Data.CRF.Chain1.Constrained: mkWordL :: (Ord b) => Word a b -> Prob b -> WordL a b
+ Data.CRF.Chain1.Constrained: mkWordL :: Ord b => Word a b -> Prob b -> WordL a b
- Data.CRF.Chain1.Constrained.DAG: mkWordL :: (Ord b) => Word a b -> Prob b -> WordL a b
+ Data.CRF.Chain1.Constrained.DAG: mkWordL :: Ord b => Word a b -> Prob b -> WordL a b
- Data.CRF.Chain1.Constrained.DAG.Dataset.External: mkWordL :: (Ord b) => Word a b -> Prob b -> WordL a b
+ Data.CRF.Chain1.Constrained.DAG.Dataset.External: mkWordL :: Ord b => Word a b -> Prob b -> WordL a b
- Data.CRF.Chain1.Constrained.Dataset.External: mkWordL :: (Ord b) => Word a b -> Prob b -> WordL a b
+ Data.CRF.Chain1.Constrained.Dataset.External: mkWordL :: Ord b => Word a b -> Prob b -> WordL a b
Files
- changelog +7/−0
- crf-chain1-constrained.cabal +3/−1
- src/Data/CRF/Chain1/Constrained/DAG/Train.hs +83/−26
+ changelog view
@@ -0,0 +1,7 @@+-*-change-log-*-++0.6.0 Oct 2018+ * DAG verification improved++0.5.0 Sep 2018+ * Blacklisting tags (guessing)
crf-chain1-constrained.cabal view
@@ -1,5 +1,5 @@ name: crf-chain1-constrained-version: 0.5.0+version: 0.6.0 synopsis: First-order, constrained, linear-chain conditional random fields description: The library provides efficient implementation of the first-order,@@ -31,6 +31,8 @@ category: Math homepage: https://github.com/kawu/crf-chain1-constrained build-type: Simple++extra-source-files: changelog library hs-source-dirs: src
src/Data/CRF/Chain1/Constrained/DAG/Train.hs view
@@ -20,15 +20,18 @@ , anyInterps -- * Utils-, dagProb+, verifyDAG+, Error(..)+-- , dagProb ) where import Control.Applicative ((<$>), (<*>)) -- import qualified Control.Arrow as Arr-import Control.Monad (when)+import Control.Monad (when, guard) import System.IO (hSetBuffering, stdout, BufferMode (..)) import Data.Binary (Binary, put, get)+-- import Data.Maybe (fromJust) import qualified Data.Set as S import qualified Data.Map as M -- import qualified Data.Vector as V@@ -186,36 +189,90 @@ ------------------------------------------------------ --- | Compute the probability of the DAG, based on the probabilities assigned to--- different edges and their labels.-dagProb :: DAG a (X, Y) -> Double-dagProb dag = sum- [ fromEdge edgeID- | edgeID <- DAG.dagEdges dag- , DAG.isInitialEdge edgeID dag ]- where- fromEdge =- Memo.wrap DAG.EdgeID DAG.unEdgeID Memo.integral fromEdge'- fromEdge' edgeID- = edgeProb edgeID- * fromNode (DAG.endsWith edgeID dag)- edgeProb edgeID =- let (_x, y) = DAG.edgeLabel edgeID dag- in sum . map snd $ C.unY y- fromNode nodeID =- case DAG.outgoingEdges nodeID dag of- [] -> 1- xs -> sum (map fromEdge xs)+-- -- | Compute the probability of the DAG, based on the probabilities assigned to+-- -- different edges and their labels.+-- TODO: This implementation is not correct!+-- dagProb :: DAG a (X, Y) -> Double+-- dagProb dag = sum+-- [ fromEdge edgeID+-- | edgeID <- DAG.dagEdges dag+-- , DAG.isInitialEdge edgeID dag ]+-- where+-- fromEdge =+-- Memo.wrap DAG.EdgeID DAG.unEdgeID Memo.integral fromEdge'+-- fromEdge' edgeID+-- = edgeProb edgeID+-- * fromNode (DAG.endsWith edgeID dag)+-- edgeProb edgeID =+-- let (_x, y) = DAG.edgeLabel edgeID dag+-- in sum . map snd $ C.unY y+-- fromNode nodeID =+-- case DAG.outgoingEdges nodeID dag of+-- [] -> 1+-- xs -> sum (map fromEdge xs) --- | Filter out the sentences with `dagProb` < 1.+-- | Filter incorrect sentences. verifyDataset :: [DAG a (X, Y)] -> [DAG a (X, Y)] verifyDataset = filter verify where- verify dag =- let p = dagProb dag- in p >= 1 - eps && p <= 1 + eps+ verify dag = verifyDAG dag == Nothing+-- verify dag =+-- let p = dagProb dag+-- in p >= 1 - eps && p <= 1 + eps+-- eps = 1e-9+++-- | Verification error.+data Error+ = Malformed+ | Cyclic+ | SeveralSources [DAG.NodeID]+ | SeveralTargets [DAG.NodeID]+ | WrongBalance [DAG.NodeID]+ -- ^ Nodes for which the total sum of the incoming probabilities does not+ -- equal the total sum of the outgoing probabilities+ deriving (Show, Eq, Ord)+++-- | Check if the DAG satisfies all the desirable properties.+verifyDAG :: DAG a (X, Y) -> Maybe Error+verifyDAG dag+ | not (DAG.isOK dag) = Just Malformed+ | not (DAG.isDAG dag) = Just Cyclic+ | length sources /= 1 = Just $ SeveralSources sources+ | length targets /= 1 = Just $ SeveralTargets targets+ | length wrong > 1 = Just $ WrongBalance wrong+ | otherwise = Nothing+ where+ sources = do+ node <- DAG.dagNodes dag+ guard . null $ DAG.ingoingEdges node dag+ return node+ targets = do+ node <- DAG.dagNodes dag+ guard . null $ DAG.outgoingEdges node dag+ return node+ wrong = do+ node <- DAG.dagNodes dag+ let ing = DAG.ingoingEdges node dag+ out = DAG.outgoingEdges node dag+ ingBalance =+ if node `elem` sources+ then 1+ else sum (map edgeProb ing)+ outBalance =+ if node `elem` targets+ then 1+ else sum (map edgeProb out)+ guard . not $ equal ingBalance outBalance+ return node+ edgeProb edgeID =+ let (_x, y) = DAG.edgeLabel edgeID dag+ in sum . map snd $ C.unY y+ equal x y =+ x - eps <= y && x + eps >= y eps = 1e-9