VB.NET NMF Ordered Connectivity Matrix Example

[TOC]

Imports System.Text

Imports CenterSpace.NMath.Core
Imports CenterSpace.NMath.Stats

Public Class NMFOrderedConnectivityMatrixExample

  ' A .NET example in VB.NET showing how to create an ordered connectivity matrix to display the results of
  ' NMF clustering.
  '
  ' An ordered connectivity matrix is created by taking a connectivity matrix
  ' and reodering the rows and columns so that the most affilitated elements
  ' appear as clustered values along the diagonal. The reodering is determined
  ' as follows:
  ' 
  ' First a hierarchical cluster analysis is performed on the elements 
  ' represented in the connectivity matrix. For the purpose of clustering 
  ' the elements represented in the connectivity matrix are labeled 0, 1,
  ' 2,...,n-1, where n is the number of the elements. 
  ' 
  ' Given two integers, i and j, the provided distance function should return
  ' the distance between the ith and jth elements. If no distance function is
  ' provided the default distance function returns the value 1.0 - aij for 
  ' the distance between the ith and jth elements, where aij is the i, jth 
  ' element of the connectivity matrix A. 
  ' 
  ' After the hierarchical clustering process, the leaf nodes of the
  ' dendrogram produced from the results are traversed in order to produce a
  ' permutation vector. This permutation vector is used to reorder the rows
  ' and columns of the input connectivity matrix, causing the most affiliated 
  ' elements to appear as clusters of higher values along the diagonal.
  ' 
  ' The connectivity matrix used in this example is an NMFConsensusMatrix which
  ' is the result of using a Nonnegative Matrix Factorization (NMF) to cluster a set
  ' of samples.  The display in the example is a "heat map" with tightly clustered 
  ' elements colored in darker "hotter" colors (red, orange, yellow) which "cooler" 
  ' colors (green and blue) being used for the more loosly affiliated elements.

  Private HeatMap As Bitmap
  ' Colors to use in the bitmap.

  Private Colors As New List(Of Color)()
  ' The heat map.

  Sub Painting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    If (HeatMap Is Nothing) Then
      Initialize()
    End If
    Dim BmpUpperLeftRow As Integer = 10
    Dim BmpUpperLeftCol As Integer = 10
    e.Graphics.DrawImage(HeatMap, BmpUpperLeftCol, BmpUpperLeftRow)
  End Sub

  Private Sub Initialize()

    Height = 650
    Width = 630

    ' Colors to use in the heat map. The colors range from
    ' reds and oranges, for highly affiliated elements, to
    ' greens and blues for loosely affilitated elements.
    Colors.Add(Color.DarkRed)
    Colors.Add(Color.OrangeRed)
    Colors.Add(Color.Orange)
    Colors.Add(Color.Yellow)
    Colors.Add(Color.GreenYellow)
    Colors.Add(Color.MediumSeaGreen)
    Colors.Add(Color.Green)
    Colors.Add(Color.LightGreen)
    Colors.Add(Color.LightBlue)
    Colors.Add(Color.Aqua)

    ' First read in some data to cluster. In this example columns in the
    ' the data frame represent samples to which we will apply a Nonnegative
    ' Matrix Factorization (NMF) to get a connectivity matrix in the form of a
    ' NMFConsensusMatrix.
    Dim Filename As String = "..\\..\\nmf_data.dat"
    Dim Data As DataFrame = Nothing
    Try
      Data = ReadDataFromFile(Filename)
    Catch E As NMathException
      MessageBox.Show("Error loading data: " + E.Message)
    End Try

    ' Order of the NMF.
    Dim K As Integer = 3

    ' Number of factorizations to use in constructing the consensus matrix.
    Dim NumberOfRuns As Integer = 25

    ' Construct the consensus matrix using a Gradiant Descent, Constrained Least
    ' Squares iterative algorithm.
    Dim ConsensusMatrix As New NMFConsensusMatrix(Of NMFGdClsUpdate)(Data, K, NumberOfRuns)

    ' Construct the ordered connectivity matrix from the consensus matrix.
    Dim OrderedConsensusMatrix As New OrderedConnectivityMatrix(ConsensusMatrix)

    ' Construct and display the heat map by displaying the number in the ordered consensus matrix 
    ' a pixels whose colors are "hotter" (red, orange) for higher values (highly affiliated), and 
    ' cooler (green, yellow) for smaller values (less affiliated). Note that all the numbers in the
    ' consensus matrix are between 0 and 1.
    Dim BlockSize As Integer = 600 / OrderedConsensusMatrix.Order
    Dim S As Integer = (BlockSize + 1) * OrderedConsensusMatrix.Order
    HeatMap = New Bitmap(S, S)
    Dim RowOffset As Integer = 0
    Dim ColumnOffset = 0
    Dim I As Integer
    Dim J As Integer
    Dim C As Color
    Dim BI As Integer
    Dim BJ As Integer
    For I = 0 To (OrderedConsensusMatrix.Order - 1)
      For J = 0 To (OrderedConsensusMatrix.Order - 1)
        C = GetColor(OrderedConsensusMatrix(I, J))
        For BI = RowOffset To (RowOffset + BlockSize - 1)
          For BJ = ColumnOffset To (ColumnOffset + BlockSize - 1)
            HeatMap.SetPixel(BI, BJ, C)
          Next
        Next
        ColumnOffset += BlockSize
      Next
      ColumnOffset = 0
      RowOffset += BlockSize
    Next

  End Sub


  Private Function GetColor(ByVal P As Double) As Color

    If (P = 1.0) Then
      Return Colors(0)
    End If
    If (P >= 0.9) Then
      Return Colors(1)
    End If
    If (P >= 0.8) Then
      Return Colors(2)
    End If
    If (P >= 0.7) Then
      Return Colors(3)
    End If
    If (P >= 0.6) Then
      Return Colors(4)
    End If
    If (P >= 0.5) Then
      Return Colors(5)
    End If
    If (P >= 0.4) Then
      Return Colors(6)
    End If
    If (P >= 0.3) Then
      Return Colors(7)
    End If
    If (P >= 0.2) Then
      Return Colors(8)
    End If
    If (P >= 0.1) Then
      Return Colors(9)
    End If
    Return Color.MidnightBlue

  End Function

  Function ReadDataFromFile(ByVal FileName As String) As DataFrame
    Dim Data As DataFrame
    Try
      ' Load the example data into a DataFrame
      Data = DataFrame.Load(FileName, True, True, ControlChars.Tab, True)
    Catch E As NMathException
      Dim Msg As New StringBuilder(String.Format("Could not find data file {0}.", FileName))
      Msg.Append(Environment.NewLine)
      Msg.Append(E.Message)
      Msg.Append(Environment.NewLine)
      Msg.Append("Data file must have the same name as the example source ")
      Msg.Append(Environment.NewLine)
      Msg.Append("file and be located three directories up from where the ")
      Msg.Append(Environment.NewLine)
      Msg.Append("executable is running.")
      Console.WriteLine(Msg)
      Console.WriteLine()
      Return Nothing
    End Try
    Return Data

  End Function

End Class

[TOC]