Advertisement
Guest User

Untitled

a guest
Aug 8th, 2016
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.04 KB | None | 0 0
  1. {-# LANGUAGE OverloadedStrings #-}
  2.  
  3. module Main where
  4.  
  5. {-
  6. This is the main entry point for the multi label correlation coefficient
  7. microservice which listens to RPC calls for applications which need to work
  8. with computed data about the label correlation coefficients, i.e. data viz
  9. in dashboards and such. The data is fetched from a MySQL database.
  10. -}
  11.  
  12. import Data.Word
  13. import Data.List.Split
  14. import System.Environment as SE
  15. import Control.Exception
  16. import System.IO.Error
  17. import Database.MySQL.Simple
  18. import Database.MySQL.Simple.QueryResults
  19. import Database.MySQL.Simple.Result
  20. import Control.Monad.Reader
  21. import Data.MessagePack
  22. import Network.MessagePack.Server
  23. import Statistics.Matrix
  24. import Statistics.Correlation
  25.  
  26. data Label = Label { jointLabels :: String } deriving Show
  27.  
  28. instance QueryResults Label where
  29. convertResults [fa] [va] = Label { jointLabels = a }
  30. where a = convert fa va
  31. convertResults fs vs = convertError fs vs 2
  32.  
  33. {-|
  34. Transforms a label as returned from the database to an array of binary
  35. indicators, one for each label.
  36. -}
  37. toArray :: Label -> [Double]
  38. toArray l = Prelude.map (\x -> read x :: Double)
  39. $ splitOn "," (jointLabels l)
  40.  
  41. {-|
  42. This function fetches the labels from the database.
  43. -}
  44. fetchLabels :: Connection -> IO [Label]
  45. fetchLabels conn = query_ conn
  46. "select joint_labels from annotated_search_labels"
  47.  
  48. {-|
  49. This function filters rows from a matrix which can be interpreted as a
  50. constant function.
  51.  
  52. The background is that the pearson correlation (as defined by
  53. `pearsonMatByRow`) where each row is a random variable is undefined for
  54. constant functions and therefore returns NaN. This ought to be prevented.
  55. -}
  56. filterLabels :: [[Double]] -> [[Double]]
  57. filterLabels = filter (\x -> 0 < sum x && sum x < fromIntegral (length x))
  58.  
  59. {-|
  60. Computes the pearson correlation of a matrix where each column represents
  61. a random variable.
  62.  
  63. For n columns a matrix of `(n,n)` is returned.
  64. -}
  65. pearsonMatByCol :: Matrix -> Matrix
  66. pearsonMatByCol = transpose . pearsonMatByRow . transpose
  67.  
  68. {-|
  69. Implements correlation coefficients between columns of a matrix. Each row
  70. represents an observation, whereas a column represents a variable.
  71. -}
  72. correlationCoefficients :: Connection -> IO [[Double]]
  73. correlationCoefficients conn = do
  74. labels <- query_ conn "select joint_labels from annotated_search_labels"
  75. let arr = Prelude.map toArray labels;
  76. let mat = fromRowLists arr;
  77. return (toRowLists $ pearsonMatByCol mat)
  78.  
  79. {-|
  80. Convenience wrapper to generate a ConnectInfo object from variables
  81. provided by the environment
  82. -}
  83. getConnectInfo :: String -> Word16 -> String -> String -> String -> ConnectInfo
  84. getConnectInfo host port user pass db = ConnectInfo { connectHost = host,
  85. connectPort = port,
  86. connectUser = user,
  87. connectPassword = pass,
  88. connectDatabase = db,
  89. connectOptions = [],
  90. connectPath = "",
  91. connectSSL = Nothing }
  92.  
  93. add :: Int -> Int -> Server Int
  94. add x y = return $ x + y
  95.  
  96. main :: IO ()
  97. main = do
  98. host <- SE.getEnv "MYSQL_HOST"
  99. -- supplied as String, needed as Int
  100. port <- read <$> SE.getEnv "MYSQL_PORT"
  101. user <- SE.getEnv "MYSQL_USER"
  102. pass <- SE.getEnv "MYSQL_PASS"
  103. db <- SE.getEnv "MYSQL_DB"
  104.  
  105. --res <- fetchLabels conn
  106. conn <- connect $ getConnectInfo host port user pass db
  107. let fn = correlationCoefficients conn
  108.  
  109. --let labels = filterLabels $ Prelude.map toArray res
  110. --print $ show (fromRowLists labels)
  111. --print . pearsonMatByCol $ fromRowLists labels
  112.  
  113. putStrLn "listening on 127.0.0.1:18800"
  114. serve 18800 [ method "correlationCoefficients"
  115. (correlationCoefficients conn) ]
  116.  
  117. -- serve 18800 [ method "add" add ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement