← All NMath Code Examples
using System;
using CenterSpace.NMath.Core;
namespace CenterSpace.NMath.Examples.CSharp
{
/// <summary>
/// A .NET example in C# showing how to perform a hierarchical cluster analysis on a data set.
/// </summary>
public class ClusterExample
{
static void Main( string[] args )
{
// Class ClusterAnalysis perform hierarchical cluster analysis. Instances
// are constructed from a matrix of data, where each row represents an object
// to be clustered. This code clusters 8 random vectors of length 3:
var data = new DoubleMatrix( 8, 3, new RandGenUniform() );
Console.WriteLine();
Console.WriteLine( "Data =" );
Console.WriteLine( data.ToTabDelimited( "F5" ) );
var ca = new ClusterAnalysis( data );
// The N property gets the number of objects clustered:
Console.WriteLine( "Number of objects clustered = " + ca.N );
Console.WriteLine();
// Distances between objects are computed using a Distance.Function delegate.
// The default distance delegates is Distance.EuclideanFunction. Property
// Distances gets the vector of distances between all possible object pairs,
// computed using the current distance delegate. For n objects, the distance
// vector is of length (n-1)(n/2), with distances arranged in the order:
// (1,2), (1,3), ..., (1,n), (2,3), ..., (2,n), ..., ..., (n-1,n)
Console.WriteLine( "Results using Euclidean distance and Single linkage..." );
Console.WriteLine();
Console.WriteLine( "Distances: " );
Console.WriteLine( ca.Distances.ToString( "F3" ) );
Console.WriteLine();
// Distances between clusters of objects are computed using a Linkage.Function
// delegate. The default linkage delegate is Linkage.SingleFunction.
// The Linkages property gets the complete hierarchical linkage tree, computed
// from Distances using the current linkage delegate. At each level in the tree,
// Columns 1 and 2 contain the indices of the clusters linked to form the next
// cluster. Column 3 contains the distances between the clusters.
Console.WriteLine( "Linkages: " );
Console.WriteLine( ca.Linkages.ToTabDelimited( "F3" ) );
// The CopheneticDistances property gets the vector of cophenetic distances
// between all possible object pairs. The cophenetic distance between two
// objects is defined to be the intergroup distance when the objects are first
// combined into a single cluster in the linkage tree. The correlation between
// the original Distances and the CopheneticDistances is sometimes taken as a
// measure of appropriateness of a cluster analysis relative to the original data:
double r = StatsFunctions.Correlation( ca.Distances, ca.CopheneticDistances );
Console.WriteLine( "Cophenetic correlation = " + r );
Console.WriteLine();
// Delegates are provided as static variables on class Distance for
// euclidean, squared euclidean, city-block (Manhattan), maximum (Chebychev),
// and power distance functions. Delegates are provided as static variables
// on class Linkage for single, complete, unweighted average, weighted average,
// centroid, median, and Wards linkage functions. You can also easily create
// your own distance or linkage functions. This code repeats the analysis using
// different distance and linkage delegates:
ca.Update( data, Distance.SquaredEuclideanFunction, Linkage.CompleteFunction );
Console.WriteLine( "Results using Squared Euclidean distance and Complete linkage..." );
Console.WriteLine();
Console.WriteLine( "Distances:" );
Console.WriteLine( ca.Distances.ToString( "F3" ) );
Console.WriteLine();
Console.WriteLine( "Linkages: " );
Console.WriteLine( ca.Linkages.ToTabDelimited( "F3" ) );
// The CutTree() method constructs a set of clusters by cutting the
// hierarchical linkage tree either at the specified height, or into the
// specified number of clusters. This code cuts the tree into 3 clusters:
Console.WriteLine( "CutTree() into 3 clusters..." );
ClusterSet cs = ca.CutTree( 3 );
Console.WriteLine( "Cluster each object is assigned to: " + cs );
// The indexer on ClusterSet gets the cluster to which a given object is
// assigned.
Console.WriteLine( "Object 0 is in cluster: " + cs[0] );
Console.WriteLine( "Object 3 is in cluster: " + cs[3] );
// The Cluster() method returns an array of integers identifying the objects
// assigned to a given cluster.
int[] objects = cs.Cluster( 1 );
Console.Write( "Objects in cluster 1: " );
for ( int i = 0; i < objects.Length; i++ )
{
Console.Write( objects[i] + " " );
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine( "Press Enter Key" );
Console.Read();
} // Main
} // class
} // namespace
← All NMath Code Examples