Phylogeny Clustering

PortfolioOptimisers.clusteriseMethod
clusterise(nte::NetworkClustersEstimator{<:NetworkEstimator{<:Any, <:Any,
                                                            <:AbstractTreeType,
                                                            <:HopCount}},
           X::MatNum; dims::Int = 1, branchorder::Symbol = :optimal, kwargs...)

Cluster assets using a minimum spanning tree (MST) network structure and return a Clusters result.

Builds the MST from the distance matrix, accumulates a symmetric pseudo-distance matrix P over the configured network depth n as $\sum_{i=0}^{n}(\mathbf{D}^i - \mathbf{A}^i)$, and dispatches to _clusterise to perform the actual clustering and select the optimal number of clusters.

$\mathbf{A}$ is calc_weighted_adjacency's matrix, read off calc_weighted_adjacency_graph's graph through its one-argument form, so this method reads the same structure as every other consumer of a network and carries weights, not 0/1 — the tree branch's polarity is the distance, which is what $\mathbf{D}^i - \mathbf{A}^i$ subtracts a like quantity from. The two-argument entry point is the one used, because D is already in hand, and the graph is kept rather than discarded so that a budget rule is answered over it instead of re-deriving the distance.

Only a hop count is admitted

The fourth type parameter is narrowed to HopCount, so a PathLength separation fails at dispatch. The power sum is indexed by nte.nte.sep.n, and a matrix power counts edges: there is no radius analogue of $\mathbf{D}^i - \mathbf{A}^i$, so the refusal is the honest answer rather than a gap. phylogeny_matrix does have a radius method, so the two consumers of a network differ here on purpose.

Algorithm

  1. Derive the correlation matrix S and the distance matrix D from X with nte.nte.de and nte.nte.ce.
  2. Build the tree over D with calc_weighted_adjacency_graph's two-argument entry point, giving the structure G, and read its weighted adjacency matrix A with calc_weighted_adjacency.
  3. Resolve nte.nte.sep against G with resolve_separation, and read the hop count n off the resolved separation.
  4. Accumulate the pseudo-distance matrix P as the sum of D^i - A^i over i in 0:n.
  5. Clear the diagonal of P, and hand the symmetric matrix to _clusterise together with S and D.

Arguments

  • nte: Network clustering estimator configured with an MST-based NetworkEstimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × observations when dims = 2.
  • dims: Dimension along which to perform the computation.
  • branchorder: Branch ordering strategy for hierarchical clustering.
  • kwargs...: Additional keyword arguments passed to the underlying estimators.

Returns

  • clr::Clusters: Clustering result containing the clustering object, similarity matrix, distance matrix, pseudo-distance matrix, and optimal number of clusters.

Related

source
PortfolioOptimisers.clusteriseMethod
clusterise(nte::NetworkClustersEstimator{<:NetworkEstimator{<:Any, <:Any,
                                                            <:AbstractNonNegativeSimilarityMatrixAlgorithm,
                                                            <:HopCount}},
           X::MatNum; dims::Int = 1, branchorder::Symbol = :optimal, kwargs...)

Cluster assets using a Planar Maximally Filtered Graph (PMFG) network structure and return a Clusters result.

Builds the PMFG from the similarity matrix via PMFG_T2s, accumulates a symmetric pseudo-distance matrix P over the configured network depth n as $\sum_{i=0}^{n}(\mathbf{S}^i - \mathbf{A}^i)$, and dispatches to _clusterise to perform the actual clustering and select the optimal number of clusters.

$\mathbf{A}$ is calc_weighted_adjacency's matrix, read off the graph as on the tree method, and this branch's polarity is the similarity — so $\mathbf{S}^i - \mathbf{A}^i$ again subtracts a like quantity. The two-argument entry point is the one used, because S is already in hand, and the graph is kept for the same reason.

Only a hop count is admitted

The fourth type parameter is narrowed to HopCount, so a PathLength separation fails at dispatch. See the tree method: a matrix power counts edges, and there is no radius analogue of the power sum.

Algorithm

  1. Derive the correlation matrix and the distance matrix D from X with nte.nte.de and nte.nte.ce, and check D against nte.nte.alg's domain with assert_similarity_domain.
  2. Convert the pair to the similarity matrix S with distance_to_similarity.
  3. Build the triangulated maximally filtered graph over S with calc_weighted_adjacency_graph's two-argument entry point, giving the structure G, and read its weighted adjacency matrix Rpm with calc_weighted_adjacency.
  4. Resolve nte.nte.sep against G with resolve_separation, and read the hop count n off the resolved separation.
  5. Accumulate the pseudo-distance matrix P as the sum of S^i - Rpm^i over i in 0:n.
  6. Clear the diagonal of P, and hand the symmetric matrix to _clusterise together with S and D.

Arguments

  • nte: Network clustering estimator configured with a similarity-matrix-based NetworkEstimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × observations when dims = 2.
  • dims: Dimension along which to perform the computation.
  • branchorder: Branch ordering strategy for hierarchical clustering.
  • kwargs...: Additional keyword arguments passed to the underlying estimators.

Validation

Returns

  • clr::Clusters: Clustering result containing the clustering object, similarity matrix, distance matrix, pseudo-distance matrix, and optimal number of clusters.

Related

source