Fused Lasso on Trees
This is the documentation of the Julia part. For other languages, have a look at
TreeLas.TreeLas — ModuleFused Lasso Solver for tree graphs, i.e. we aim to minimize the following objective function
Hereby is
- $y_i$ the input signal for node $i$,
- $\mu_i \geq 0$ is the node weight for node $i$,
- $E$ the edges of a tree, and
- $\lambda_{ij} > 0$ is the edge weight for $(i,j)$.
Exact Tree Solver
The exact solver is found in the module TreeLas.TreeDP.
General Graphs
Furtheron, we presend a general graph solver that iteratively picks a subtree and block-optimizes it.
TreeLas.MGT — ModuleMaximum Gap Tree
Also called Gap Tree Lasso (GapLas).
In the central function gaplas, a tree having the largest gap values (computed by gap_vec!) is selected. The non-tree edge-flows are forwarded into the input y. Then the tree solver is used and the tree-edges are updated.
Graph Indexes
For the different steps, several indexes are necessary
Dual.gap_vec!needs to access every edge once.Prim's minimum spanning tree:
IncidenceIndexproviding outgoing edges for a node (i.e. every edge is included in two node's adjacency lists)Once the tree has been determined we need to have a
ChildrenIndexfrom theparent(e.g. fordfs_walk); also needed for computing theQueueslayout (parenthesis tree representation) and the processing order.
TreeLas.MGT.duality_check — MethodEnsure that the alpha is dually feasible, i.e. componentwise absolutely not greater than lambda.
TreeLas.MGT.enumerate_typed_edges — Methodtraverse_edges(func, edges, π)Call for every edge (u, v) enumerated by i the function
func(istree, i, u, v)whereby istree tells whether the edge is a tree edge. If it is a tree edge, u is the child of v.
TreeLas.MGT.extract_non_tree! — Methodextract_non_tree!(graph, y, λt, π, α, λ)Iterate over all edges of grapy (weighted by λ) and do the following: If the edge e is a tree edge, store the corresponding λ[e] in tree order. If the edge e is not part of the tree, compute the flow α[e] into the node input y.
TreeLas.MGT.gaplas! — Methodgaplas!(...)Perform one iteration. Premises:
x = y + D'*ααdually feasible,abs(α[e]) ≤ λ[e]for all edgese.
TreeLas.MGT.gaplas — Methodgaplas(...)Graph has to implement several methods:
iter_edges(::Function, ::Graph)IncidenceIndex(::Graph)
TreeLas.MGT.gaplas — Methodgaplas(y, graph, λ; learn=1.0, max_iter=3, ...)Optimize in each iteration along a tree.
The learn parameter controls how much of the new tree solution should be taken (should be between $0$ and $1.0$).
TreeLas.MGT.update_tree! — Methodupdate_tree!(α, αt, selected, graph, parent)Update the global dual α by a tree dual αt.
Utility Functions
TreeLas.Utils.primal_objective — Methodprimal_objective(x, y, graph [, mu])Compute the objective function, i.e.
Hereby the edges (and edge weights $λ_{ij}$) are obtained via enumerate_edges(graph).
TreeLas.Utils.sum2 — Methodsum2(x)Sum of squares.
julia> TreeLas.Utils.sum2([1, 11])
122