hierarchical-spectral-clustering 0.2.1.1 → 0.2.2.0
raw patch · 4 files changed
+99/−15 lines, 4 filesdep ~modularitydep ~spectral-clusteringPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: modularity, spectral-clustering
API changes (from Hackage documentation)
- Math.Clustering.Hierarchical.Spectral.Dense: type AdjacencyMatrix = Matrix Double
+ Math.Clustering.Hierarchical.Spectral.Dense: B :: Matrix Double -> B
+ Math.Clustering.Hierarchical.Spectral.Dense: [unB] :: B -> Matrix Double
+ Math.Clustering.Hierarchical.Spectral.Dense: hierarchicalSpectralClusterAdj :: Show a => EigenGroup -> Maybe NumEigen -> Maybe Int -> Maybe Q -> Items a -> AdjacencyMatrix -> ClusteringTree a
+ Math.Clustering.Hierarchical.Spectral.Dense: newtype B
+ Math.Clustering.Hierarchical.Spectral.Dense: type FeatureMatrix = Matrix Double
+ Math.Clustering.Hierarchical.Spectral.Dense: type ShowB = ((Int, Int), [(Int, Int, Double)])
- Math.Clustering.Hierarchical.Spectral.Dense: hierarchicalSpectralCluster :: Show a => EigenGroup -> Maybe NumEigen -> Maybe Int -> Maybe Q -> Items a -> AdjacencyMatrix -> ClusteringTree a
+ Math.Clustering.Hierarchical.Spectral.Dense: hierarchicalSpectralCluster :: EigenGroup -> NormalizeFlag -> Maybe NumEigen -> Maybe Int -> Maybe Q -> Items a -> Either FeatureMatrix B -> ClusteringTree a
Files
- app/Main.hs +1/−1
- hierarchical-spectral-clustering.cabal +4/−4
- src/Math/Clustering/Hierarchical/Spectral/Dense.hs +68/−8
- src/Math/Clustering/Hierarchical/Spectral/Test.hs +26/−2
app/Main.hs view
@@ -135,7 +135,7 @@ Dense -> do (items, mat) <- readDenseAdjMatrix decodeOpt stdin - let cluster items = HD.hierarchicalSpectralCluster+ let cluster items = HD.hierarchicalSpectralClusterAdj eigenGroup' (fmap unNumEigen numEigen') (fmap unMinSize minSize')
hierarchical-spectral-clustering.cabal view
@@ -1,9 +1,9 @@ cabal-version: >=1.10 name: hierarchical-spectral-clustering-version: 0.2.1.1+version: 0.2.2.0 license: GPL-3 license-file: LICENSE-copyright: 2018 Gregory W. Schwartz+copyright: 2019 Gregory W. Schwartz maintainer: gsch@pennmedicine.upenn.edu author: Gregory W. Schwartz homepage: http://github.com/GregorySchwartz/hierarchical-spectral-clustering#readme@@ -44,11 +44,11 @@ hmatrix >=0.19.0.0, fgl >=5.6.0.0, managed >=1.0.6,- modularity >=0.2.0.3,+ modularity >=0.2.1.0, mtl >=2.2.2, safe >=0.3.17, sparse-linear-algebra >=0.3.1,- spectral-clustering >=0.2.1.2,+ spectral-clustering >=0.2.2.0, streaming >=0.2.1.0, streaming-bytestring >=0.1.6, streaming-cassava >=0.1.0.1,
src/Math/Clustering/Hierarchical/Spectral/Dense.hs view
@@ -8,8 +8,11 @@ module Math.Clustering.Hierarchical.Spectral.Dense ( hierarchicalSpectralCluster- , AdjacencyMatrix (..)+ , hierarchicalSpectralClusterAdj+ , FeatureMatrix (..)+ , B (..) , Items (..)+ , ShowB (..) ) where -- Remote@@ -17,8 +20,8 @@ import Data.Clustering.Hierarchical (Dendrogram (..)) import Data.Maybe (fromMaybe) import Data.Tree (Tree (..))-import Math.Clustering.Spectral.Dense (spectralClusterNorm, spectralClusterKNorm)-import Math.Modularity.Dense (getModularity)+import Math.Clustering.Spectral.Dense (B (..), AdjacencyMatrix (..), getB, spectralCluster, spectralClusterK, spectralClusterNorm, spectralClusterKNorm)+import Math.Modularity.Dense (getModularity, getBModularity) import Math.Modularity.Types (Q (..)) import qualified Data.Foldable as F import qualified Data.Set as Set@@ -30,24 +33,81 @@ import Math.Clustering.Hierarchical.Spectral.Types import Math.Clustering.Hierarchical.Spectral.Utility -type AdjacencyMatrix = H.Matrix Double+type FeatureMatrix = H.Matrix Double type Items a = V.Vector a+type ShowB = ((Int, Int), [(Int, Int, Double)])+type NormalizeFlag = Bool -- | Check if there is more than one cluster. hasMultipleClusters :: H.Vector Double -> Bool hasMultipleClusters = (> 1) . Set.size . Set.fromList . H.toList -- | Generates a tree through divisive hierarchical clustering using+-- Newman-Girvan modularity as a stopping criteria. Can use minimum number of+-- observations in a cluster as a stopping criteria. Assumes the feature matrix+-- has column features and row observations. Items correspond to rows. Can+-- use FeatureMatrix or a pre-generated B matrix. See Shu et al., "Efficient+-- Spectral Neighborhood Blocking for Entity Resolution", 2011.+hierarchicalSpectralCluster :: EigenGroup+ -> NormalizeFlag+ -> Maybe NumEigen+ -> Maybe Int+ -> Maybe Q+ -> Items a+ -> Either FeatureMatrix B+ -> ClusteringTree a+hierarchicalSpectralCluster eigenGroup normFlag numEigenMay minSizeMay minModMay initItems initMat =+ go initItems initB+ where+ initB = either (getB normFlag) id $ initMat+ minMod = fromMaybe (Q 0) minModMay+ minSize = fromMaybe 1 minSizeMay+ numEigen = fromMaybe 1 numEigenMay+ go :: Items a -> B -> ClusteringTree a+ go !items !b =+ if (H.rows $ unB b) > 1+ && hasMultipleClusters clusters+ && ngMod > minMod+ && H.rows (unB left) >= minSize+ && H.rows (unB right) >= minSize+ then+ Node { rootLabel = vertex+ , subForest = [ go (subsetVector items leftIdxs) left+ , go (subsetVector items rightIdxs) right+ ]+ }++ else+ Node {rootLabel = vertex, subForest = []}+ where+ vertex = ClusteringVertex+ { _clusteringItems = items+ , _ngMod = ngMod+ }+ clusters :: H.Vector Double+ clusters = spectralClustering eigenGroup b+ spectralClustering :: EigenGroup -> B -> H.Vector Double+ spectralClustering SignGroup = spectralCluster+ spectralClustering KMeansGroup = spectralClusterK numEigen 2+ ngMod :: Q+ ngMod = getBModularity clusters $ b+ getIdxs val = VS.ifoldr' (\ !i !v !acc -> bool acc (i:acc) $ v == val) []+ leftIdxs = getIdxs 0 $ clusters+ rightIdxs = getIdxs 1 $ clusters+ left = B $ (unB b) H.? leftIdxs+ right = B $ (unB b) H.? rightIdxs++-- | Generates a tree through divisive hierarchical clustering using -- Newman-Girvan modularity as a stopping criteria. Can also use minimum number -- of observations in a cluster as the stopping criteria.-hierarchicalSpectralCluster :: (Show a) => EigenGroup+hierarchicalSpectralClusterAdj :: (Show a) => EigenGroup -> Maybe NumEigen -> Maybe Int -> Maybe Q -> Items a -> AdjacencyMatrix -> ClusteringTree a-hierarchicalSpectralCluster !eigenGroup !numEigenMay !minSizeMay !minModMay !items !adjMat =+hierarchicalSpectralClusterAdj !eigenGroup !numEigenMay !minSizeMay !minModMay !items !adjMat = if H.rows adjMat > 1 && hasMultipleClusters clusters && ngMod > minMod@@ -56,14 +116,14 @@ then Node { rootLabel = vertex , subForest =- [ hierarchicalSpectralCluster+ [ hierarchicalSpectralClusterAdj eigenGroup numEigenMay minSizeMay minModMay (subsetVector items leftIdxs) left- , hierarchicalSpectralCluster+ , hierarchicalSpectralClusterAdj eigenGroup numEigenMay minSizeMay
src/Math/Clustering/Hierarchical/Spectral/Test.hs view
@@ -125,21 +125,45 @@ . S.toListSM $ adjacencyExample +denseFeatureExample :: H.Matrix Double+denseFeatureExample = H.assoc (S.dimSM (exampleMatrix 3 exampleData)) 0+ . fmap (\(!x, !y, !z) -> ((x, y), z))+ . S.toListSM+ $ exampleMatrix 3 exampleData++denseClusterAdjExample = Dense.hierarchicalSpectralClusterAdj+ SignGroup+ Nothing+ Nothing+ Nothing+ exampleItems+ denseAdjacencyExample++denseClusterAdjKExample = Dense.hierarchicalSpectralClusterAdj+ KMeansGroup+ (Just 2)+ Nothing+ Nothing+ exampleItems+ denseAdjacencyExample+ denseClusterExample = Dense.hierarchicalSpectralCluster SignGroup+ True Nothing Nothing Nothing exampleItems- denseAdjacencyExample+ (Left denseFeatureExample) denseClusterKExample = Dense.hierarchicalSpectralCluster KMeansGroup+ True (Just 2) Nothing Nothing exampleItems- denseAdjacencyExample+ (Left denseFeatureExample) -- | Generate the matrix of qgrams from a list of records and qgram length. exampleEigenMatrix :: Int -> [String] -> E.SparseMatrixXd