Commit fde6d32d authored by Alexandre Delanoë's avatar Alexandre Delanoë

[PHYLO] overlapping of periodes in history enabled and FIS computed accordingly.

parent 97d5140c
......@@ -107,7 +107,7 @@ variance xs = mean $ map (\x -> (x - m) ** 2) xs where
deviation :: [Double] -> Double
deviation = sqrt . variance
movingAverage :: Fractional b => Int -> [b] -> [b]
movingAverage :: (Eq b, Fractional b) => Int -> [b] -> [b]
movingAverage steps xs = map mean $ chunkAlong steps 1 xs
ma :: [Double] -> [Double]
......@@ -120,21 +120,29 @@ splitEvery n xs =
let (h,t) = L.splitAt n xs
in h : splitEvery n t
type Grain = Int
type Step = Int
-- | Function to split a range into chunks
chunkAlong :: Int -> Int -> [a] -> [[a]]
chunkAlong a b l = only (while dropAlong)
chunkAlong :: Eq a => Grain -> Step -> [a] -> [[a]]
chunkAlong a b l = case a > 0 && b > 0 && a >= b of
True -> chunkAlong_ a b l
False -> panic "ChunkAlong: Parameters should be > 0 and Grain > Step"
chunkAlong_ :: Eq a => Int -> Int -> [a] -> [[a]]
chunkAlong_ a b l = filter (/= []) $ only (while dropAlong)
where
only = map (take a)
while = takeWhile (\x -> length x >= a)
dropAlong = L.scanl (\x _y -> drop b x) l ([1..] :: [Integer])
only = map (take a)
while = takeWhile (\x -> length x >= a)
dropAlong = L.scanl (\x _y -> drop b x) l ([1..] :: [Integer])
-- | Optimized version (Vector)
chunkAlong' :: Int -> Int -> V.Vector a -> V.Vector (V.Vector a)
chunkAlong' a b l = only (while dropAlong)
where
only = V.map (V.take a)
while = V.takeWhile (\x -> V.length x >= a)
dropAlong = V.scanl (\x _y -> V.drop b x) l (V.fromList [1..])
only = V.map (V.take a)
while = V.takeWhile (\x -> V.length x >= a)
dropAlong = V.scanl (\x _y -> V.drop b x) l (V.fromList [1..])
-- | TODO Inverse of chunk ? unchunkAlong ?
-- unchunkAlong :: Int -> Int -> [[a]] -> [a]
......
{-|
Module : Gargantext.Viz.Phylo
Description : Phylomemy definitions and types.
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
Specifications of Phylomemy format.
Phylomemy can be described as a Temporal Graph with different scale of
granularity of group of ngrams (terms and multi-terms).
The main type is Phylo which is synonym of Phylomemy (only difference is
the number of chars).
References:
Chavalarias, D., Cointet, J.-P., 2013. Phylomemetic patterns
in science evolution — the rise and fall of scientific fields. PloS
one 8, e54847.
-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell #-}
module Gargantext.Viz.Phylo where
import Data.Aeson.TH (deriveJSON)
import Data.Maybe (Maybe)
import Data.Text (Text)
import Data.Time.Clock.POSIX (POSIXTime)
import GHC.Generics (Generic)
import Gargantext.Core.Utils.Prefix (unPrefix)
import Gargantext.Prelude
------------------------------------------------------------------------
-- | Phylo datatype descriptor of a phylomemy
-- Duration : time Segment of the whole phylomemy (start,end)
-- Ngrams : list of all (possible) terms contained in the phylomemy (with their id)
-- Steps : list of all steps to build the phylomemy
data Phylo =
Phylo { _phylo_Duration :: (Start, End)
, _phylo_Ngrams :: [Ngram]
, _phylo_Periods :: [PhyloPeriod]
}
deriving (Generic)
-- | UTCTime in seconds since UNIX epoch
type Start = POSIXTime
type End = POSIXTime
-- | Indexed Ngram
type Ngram = (NgramId, Text)
type NgramId = Int
-- | PhyloStep : steps of phylomemy on temporal axis
-- Period: tuple (start date, end date) of the step of the phylomemy
-- Levels: levels of granularity
data PhyloPeriod =
PhyloPeriod { _phylo_PeriodId :: PhyloPeriodId
, _phylo_PeriodLevels :: [PhyloLevel]
}
deriving (Generic)
type PhyloPeriodId = (Start, End)
-- | PhyloLevel : levels of phylomemy on level axis
-- Levels description:
-- Level -1: Ngram equals itself (by identity) == _phylo_Ngrams
-- Level 0: Group of synonyms (by stems + by qualitative expert meaning)
-- Level 1: First level of clustering
-- Level N: Nth level of clustering
data PhyloLevel =
PhyloLevel { _phylo_LevelId :: PhyloLevelId
, _phylo_LevelGroups :: [PhyloGroup]
}
deriving (Generic)
type PhyloLevelId = (PhyloPeriodId, Int)
-- | PhyloGroup : group of ngrams at each level and step
-- Label : maybe has a label as text
-- Ngrams: set of terms that build the group
-- Period Parents|Childs: weighted link to Parents|Childs (Temporal Period axis)
-- Level Parents|Childs: weighted link to Parents|Childs (Level Granularity axis)
data PhyloGroup =
PhyloGroup { _phylo_GroupId :: PhyloGroupId
, _phylo_GroupLabel :: Maybe Text
, _phylo_GroupNgrams :: [NgramId]
, _phylo_GroupPeriodParents :: [Edge]
, _phylo_GroupPeriodChilds :: [Edge]
, _phylo_GroupLevelParents :: [Edge]
, _phylo_GroupLevelChilds :: [Edge]
}
deriving (Generic)
type PhyloGroupId = (PhyloLevelId, Int)
type Edge = (PhyloGroupId, Weight)
type Weight = Double
-- | JSON instances
$(deriveJSON (unPrefix "_phylo_" ) ''Phylo )
$(deriveJSON (unPrefix "_phylo_Period" ) ''PhyloPeriod )
$(deriveJSON (unPrefix "_phylo_Level" ) ''PhyloLevel )
$(deriveJSON (unPrefix "_phylo_Group" ) ''PhyloGroup )
{-|
Module : Gargantext.Viz.Phylo.Example
Description : Phylomemy example based on history of Cleopatre.
Copyright : (c) CNRS, 2017-Present
License : AGPL + CECILL v3
Maintainer : team@gargantext.org
Stability : experimental
Portability : POSIX
-- | Cesar et Cleôpatre
-- Exemple de phylomemie
-- French without accents
-- TODO: chevauchement
-- reverse history: antechronologique
-- occurrence de chaque terme
--
-- data with occurrence de chaque terme
-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Gargantext.Viz.Phylo.Example where
import qualified Data.List as DL
import Data.String (String)
import Data.Text (Text, pack, unwords, toLower, words)
import Data.Text (Text, unwords, toLower, words)
import Data.Tuple.Extra (both)
import Data.Map (Map)
......@@ -23,11 +32,11 @@ import qualified Data.Map as DM
import Data.Set (Set)
import Gargantext.Text.Metrics.FrequentItemSet (fisWithSizePolyMap, Size(..))
import Gargantext.Text.Terms.Mono (monoTexts)
import Gargantext.Text.Terms.Mono (monoTexts)
import Gargantext.Prelude
------------------------------------------------------------------------
type Histoire = [Event]
type History = [Event]
data Event = Event {date:: Double, text :: Text}
deriving (Show)
......@@ -35,71 +44,50 @@ data Event = Event {date:: Double, text :: Text}
type MapList = [Text]
type PeriodeSize = Int
-- data Periodes b a = Map (b,b) a
------------------------------------------------------------------------
------------------------------------------------------------------------
-- | TODO FIS on monotexts
phyloFIS :: Map (Double, Double) [Event] -> Map (Double, Double) (Map (Set Text) Int)
phyloFIS = DM.map (\n -> fisWithSizePolyMap (Segment 5 20) 1 (map (words . text) n))
phyloFIS = DM.map (\n -> fisWithSizePolyMap (Segment 1 20) 1 (map (words . text) n))
history :: History
history = cleanHistory mapList phyloCorpus
phyloTerms :: Map (Double, Double) [Event]
phyloTerms = toPeriodes date 5 $ cleanHistoire mapList phyloCorpus
phyloTerms = toPeriodes date 5 3 $ cleanHistory mapList phyloCorpus
------------------------------------------------------------------------
-- TODO rajouter le décalage de la fenêtre temporelle
toPeriodes :: (Enum b, Fractional b, Ord b) => (t -> b) -> b -> [t] -> Map (b, b) [t]
toPeriodes _ _ [] = panic $ pack "Empty history can not have any periode"
toPeriodes f s hs = periodes f st hs
where
hs' = DL.sortOn f hs
st = steps s $ both f (DL.head hs', DL.last hs')
periodes :: Ord b => (t -> b) -> [(b, b)] -> [t] -> Map (b, b) [t]
periodes f ds h = DM.fromList $ zip ds $ periodes' f ds h
periodes' :: Ord b => (t -> b) -> [(b, b)] -> [t] -> [[t]]
periodes' _ [] _ = []
periodes' f [a] h = [x] <> [y]
where
(x,y) = periode f a h
periodes' f (a:b:bs) h = [x] <> periodes' f (b:bs) y
toPeriodes :: (Ord date, Enum date) => (event -> date)
-> Grain -> Step -> [event] -> Map (date, date) [event]
toPeriodes _ _ _ [] = panic "Empty history can not have any periods"
toPeriodes f s o as = DM.fromList $ zip hs $ map (inPeriode f as) hs
where
(x,y) = periode f a h
periode :: Ord b => (t -> b) -> (b, b) -> [t] -> ([t],[t])
periode f (start,end) h = DL.partition (\d -> f d >= start && f d <= end) h
hs = steps s o $ both f (DL.head as, DL.last as)
inPeriode :: Ord b => (t -> b) -> [t] -> (b, b) -> [t]
inPeriode f h (start,end) =
fst $ DL.partition (\d -> f d >= start && f d <= end) h
------------------------------------------------------------------------
steps :: (Ord a, Fractional a, Enum a) => a -> (a, a) -> [(a, a)]
steps s (b,e) = zip (DL.init ss) (DL.tail ss)
where
ss = steps' s (b,e)
steps' :: (Enum b, Fractional b, Ord b) => b -> (b, b) -> [b]
steps' s (b,e) = case s > 0 of
False -> panic $ pack "Steps size can not be < 0"
True -> steps'' s (b,e)
steps'' :: (Fractional b, Enum b) => b -> (b, b) -> [b]
steps'' s (start,end) = map (\s' -> s' * s + start) $ [0 .. end']
where
end' = ((end + 1)- start) / s
-- | Steps of linear and homogenous time of integer as granalurity measure
-- chunkAlong deals with [] case (not error with head and last then)
steps :: (Eq date, Enum date) => Grain -> Step -> (date, date) -> [(date, date)]
steps s o (start,end) = map (\l -> (DL.head l, DL.last l))
$ chunkAlong s o [start .. end]
------------------------------------------------------------------------
cleanHistoire :: MapList -> Histoire -> Histoire
cleanHistoire ml = map (\(Event d t) -> Event d (unwords $ filter (\x -> elem x ml) $ monoTexts t))
cleanHistory :: MapList -> History -> History
cleanHistory ml = map (\(Event d t) -> Event d (unwords $ filter (\x -> elem x ml) $ monoTexts t))
mapList :: [Text]
mapList = map (toLower . pack) actants
mapList = map toLower actants
actants :: [String]
actants :: [Text]
actants = [ "Cleopatre" , "Ptolemee", "Ptolemee-XIII", "Ptolemee-XIV"
, "Marc-Antoine", "Cesar" , "Antoine" , "Octave" , "Rome"
, "Alexandrie" , "Auguste" , "Pompee" , "Cassius" , "Brutus"]
phyloCorpus :: Histoire
phyloCorpus = map (\(d,t) -> Event d (pack t)) corpus
phyloCorpus :: History
phyloCorpus = map (\(d,t) -> Event d t) corpus
corpus :: [(Double, String)]
------------------------------------------------------------------------
corpus :: [(Double, Text)]
corpus = DL.sortOn fst [ (-51,"Cleopatre règne sur l’egypte entre 51 et 30 av. J.-C. avec ses frères-epoux Ptolemee-XIII et Ptolemee-XIV, puis aux côtes du general romain Marc-Antoine. Elle est celèbre pour avoir ete la compagne de Jules Cesar puis d'Antoine, avec lesquels elle a eu plusieurs enfants. Partie prenante dans la guerre civile opposant Antoine à Octave, elle est vaincue à la bataille d'Actium en 31 av. J.-C. Sa defaite va permettre aux Romains de mener à bien la conquête de l’egypte, evenement qui marquera la fin de l'epoque hellenistique."), (-40,"Il existe relativement peu d'informations sur son sejour à Rome, au lendemain de l'assassinat de Cesar, ou sur la periode passee à Alexandrie durant l'absence d'Antoine, entre -40 et -37."), (-48,"L'historiographie antique lui est globalement defavorable car inspiree par son vainqueur, l'empereur Auguste, et par son entourage, dont l'interêt est de la noircir, afin d'en faire l'adversaire malfaisant de Rome et le mauvais genie d'Antoine. On observe par ailleurs que Cesar ne fait aucune mention de sa liaison avec elle dans les Commentaires sur la Guerre civile"), (-69,"Cleopatre est nee au cours de l'hiver -69/-686 probablement à Alexandrie."), (-48,"Pompee a en effet ete le protecteur de Ptolemee XII, le père de Cleopatre et de Ptolemee-XIII dont il se considère comme le tuteur."), (-48,"Ptolemee-XIII et Cleopatre auraient d'ailleurs aide Pompee par l'envoi d'une flotte de soixante navires."), (-48,"Mais le jeune roi Ptolemee-XIII et ses conseillers jugent sa cause perdue et pensent s'attirer les bonnes graces du vainqueur en le faisant assassiner à peine a-t-il pose le pied sur le sol egyptien, près de Peluse, le 30 juillet 48 av. J.-C., sous les yeux de son entourage."), (-48,"Cesar fait enterrer la tête de Pompee dans le bosquet de Nemesis en bordure du mur est de l'enceinte d'Alexandrie. Pour autant la mort de Pompee est une aubaine pour Cesar qui tente par ailleurs de profiter des querelles dynastiques pour annexer l’egypte."), (-48,"Il est difficile de se prononcer clairement sur les raisons qui ont pousse Cesar à s'attarder à Alexandrie. Il y a des raisons politiques, mais aussi des raisons plus sentimentales (Cleopatre ?). Il tente d'abord d'obtenir le remboursement de dettes que Ptolemee XII"), (-46,"Les deux souverains sont convoques par Cesar au palais royal d'Alexandrie. Ptolemee-XIII s'y rend après diverses tergiversations ainsi que Cleopatre."), (-47,"A Rome, Cleopatre epouse alors un autre de ses frères cadets, à Alexandrie, Ptolemee-XIV, sur l'injonction de Jules Cesar"), (-46,"Cesar a-t-il comme objectif de montrer ce qu'il en coûte de se revolter contre Rome en faisant figurer dans son triomphe la sœur de Cleopatre et de Ptolemee-XIV, Arsinoe, qui s'est fait reconnaître reine par les troupes de Ptolemee-XIII ?"), (-44,"Au debut de l'annee -44, Cesar est assassine par Brutus. Profitant de la situation confuse qui s'ensuit, Cleopatre quitte alors Rome à la mi-avril, faisant escale en Grèce. Elle parvient à Alexandrie en juillet -44."), (-44,"La guerre que se livrent les assassins de Cesar, Cassius et Brutus et ses heritiers, Octave et Marc-Antoine, oblige Cleopatre à des contorsions diplomatiques."), (-41,"Nous ignorons depuis quand Cleopatre, agee de 29 ans en -41, et Marc-Antoine, qui a une quarantaine d'annees, se connaissent. Marc-Antoine est l'un des officiers qui ont participe au retablissement de Ptolemee XII. Il est plus vraisemblable qu'ils se soient frequentes lors du sejour à Rome de Cleopatre."), (-42,"Brutus tient la Grèce tandis que Cassius s'installe en Syrie. Le gouverneur de Cleopatre à Chypre, Serapion, vient en aide à Cassius."), (-42,"Cassius aurait envisage de s'emparer d'Alexandrie quand le 'debarquement' en Grèce d'Antoine et d'Octave l'oblige à renoncer à ses projets")]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment