packages feed

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 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