dhclust {lazy.cluster}R Documentation

Divisive Hierarchical Cluster Analysis

Description

Divisive Hierarchical Cluster Analysis

Usage

dhclust(df, id = NULL, ndiv = 2, maxclustersize = 0, nolarge = 0,
  method = "LS", maxiter = 100, eps = 1e-04, nstart = 0,
  init_method = "ward.D2", plot = 1, useid = 0, print = 1, pplot = 0,
  bplot = 0, debug = 0)

Arguments

df

Input data frame. Numeric part will be used.

id

A vector containing observation id

ndiv

# of clusters to be created at each divide: 2 or 3.

maxclustersize

Maximum # of observations in a cluster which will NOT be divided.

nolarge

= 1 to skip the creation of large (full) tree when maxclustersize > 1.

method

= "LS", "ML"
where LS uses kmenas and ML uses mxnormal.

maxiter

Maximum # of iterations for method = ML

eps

convergence criterion for method = ML

nstart

= 0 to use hclust as the initial of each division
= n to try n random initial by kmeans and pick up the best.

init_method

Method of hclust for initial

plot

= 0 to surpress the tree

useid

= 1 to use id in the tree plot

print

= 0 to surpress the printing result

pplot

= A vector consisting of the number of clusters with which the profile plots are created.

bplot

= A vector consisting of the number of clusters with which the two dimensional plots are created.

debug

= 1 to print intermediate result

Details

Use nolarge=1 and maxclustersize=nn where nn is about 1/4 of the number of observations
when the data frame to be analyzed contains large # of observations.

This function performs a divisive hierarchical cluster analysis using a recursive function "divide":


The outline of the functions are shown below:

*******************

dhclust <- function( df, id, maxclustersize=1, method="LS" ){
 # Divisive Hierarchical Cluster Analysis

 # global variables

 # recursion level
 recursion_level <<- 1

 # fission history
 # (cl3 and size_cl3 are used when ndiv=3.)
 fissionhistory <<- matrix(1:9,1)
 colnames(fissionhistory)=
    c( "divide","parent","cl1","size_cl1","cl2","size_cl2"
     , "cl3","size_cl3","SS" )
 bottom cluster info
 bottom=matrix(1:6,1)
 colnames(bottom)=c( "divide", "cname", "size",  "id1", "ss", "newname")
 bottoml=NULL

 # call to divide: fusion history will be created
 temp=divide( df, 1, ndiv=ndiv, maxclustersize=maxclustersize )

 # remove all NULL record
 fissionhistory=fissionhistory[-1,]

 # rename parent clusters and convert fissionhistory to fusionhistory.
 # take care of the case with ndiv=3.
 # take care of the bottom clusters with n > 1.

 # create hclust object
 res_dhclust=convert2hclust( fusionhhistory, maxclustersize, bottom, bottoml
  , ndiv )

 return( res_dhclust )

} # end of dhclust



divide <- function( df, dfnum, id, maxclustersize=1, method="LS" ){
  # This function divides a dataset df into df1 and df2
  and name them as cn1 and cn2, resp.
  # The recursion level is used as cn1 and cn2.

  # df           input data frame to be divided.
  # dfnum        name of the df.
  # id           a vector consisting of the names of observations in df.
  # maxclustersize  max # of objects in a cluster not to be divided.

  # # of obs in df
  nobs=nrow(df)

  # # of divisions so far performed
  ndivide=nrow(fissionhistory)

  # update recursion level and new cluster names to be created
  cn1=recursion_level+1; cn2=recursion_level+2
  recursion_level <<- recursion_level+2

  # can we stop here?
  if( nobs <= maxclustersize ){
   # store the bottom level info in bottom and bottom_l.
   return()
  }

  # if nobs > maxclustersize divide df into ndiv clusters
  # by LS or ML clustering.
  if( method == "LS" ){
   res_clust=ls_clust( df, ndiv )
  }
  else if( method == "ML" ){
   res_clust=ml_clust( df, ndiv )
  }

  # record the result
  loc=which(res_clust\$cluster==1)
  df1=df[loc,,drop=0]; id1=id[loc]
  loc=which(res_clust\$cluster==2)
  df2=df[loc,,drop=0]; id2=id[loc]
  size_cl1=nrow(df1); size_cl2=nrow(df2)
  SS=res_clust\$totss

  # mark the bottom level clusters by negative id
  if( size_cl1 <= maxclustersize ) cn1=-id1[1]
  if( size_cl2 <= maxclustersize ) cn2=-id2[1]

  # update fission history
  fissionhistory <<- rbind( fissionhistory
                      , c(ndivide, dfnum, cn1, size_cl1, cn2, size_cl2
                      , cn3, size_cl3, SS) )

  # Divide the just created two data sets recursively.
  temp=divide( df1, cn1, id1, 2, maxclustersize )
  temp=divide( df2, cn2, id2, 2, maxclustersize )

  # return nothing
  return()

} # end of divide

*******************

Value

If maxclustersize=1, a class "hclust" object.
If maxclustersize>1, a list of two class "hclust" objects,
tree_s, for he abbreviated tree, and tree_l, for large full tree.

Each class hclust object has additional information called fissonhistory and fusionhistory, and if maxclustersize > 1,
fusionhistory_l.
When nolarge=1 is specified, even if maxclustersize>1, large tree will not be created.

Use method = "LS" with maxclustersize > 1 and nolarge = 1 when analyzing large dataset.

Examples


# very small test data
resdhc <- dhclust( unidimdata, id=unidimdata$idN, useid=1, plot=1, print=3 )
plot_tree( resdhc, height="step", useid=1 )

resdhc <- dhclust( unidimdata, ndiv=2, maxclustersize=2
                  , method="LS", plot=0, print=1 )
plot( resdhc$tree_s, hang=-1, main="LS" )
plot( resdhc$tree_l, hang=-1, main="LS" )

# very small test data with ndiv=3
resdhc <- dhclust( unidimdata, ndiv=3, maxclustersize=2
                  , method="LS", plot=1, print=1 )


# small test data 1
resdhc <- dhclust( circle1, ndiv=2, plot=1, print=1, maxclustersize=20
              , method="ML", bplot=4:5 )
resdhc <- dhclust( circle1, ndiv=2, plot=1, print=1, maxclustersize=20
              , method="LS", bplot=4:5 )

# small test data 1 with ndiv=3
resdhc <- dhclust( circle1, ndiv=3, plot=1, print=1, maxclustersize=20
           , method="ML", bplot=4:5 )
resdhc <- dhclust( circle1, ndiv=3, plot=1, print=1, maxclustersize=20
             , method="LS", bplot=4:5 )


# small test data 2
resdhc <- dhclust( circle2, ndiv=2, plot=1, print=1, maxclustersize=30
              , method="ML", bplot=4:5 )
resdhc <- dhclust( circle2, ndiv=2, plot=1, print=1, maxclustersize=30
              , method="LS", bplot=4:5 )

# small test data 2 with nolarge option
resdhc <- dhclust( circle2, ndiv=2, plot=1, print=1, maxclustersize=30
              , method="ML",nolarge=1, bplot=4:5 )



# medium size test data
set.seed(1701); testdat <- matrix( rnorm(30000*2), , 2 )
resdhc <- dhclust( testdat, ndiv=2, plot=1, maxclustersize=3000
                 , nstar=10,  method="LS", nolarge=1 )

# pplot and bplot
Y <- demodata[,1:8]
set.seed(1701)
resY2 <- dhclust( Y, method="LS", pplot=5)
pplot_tree( Y, resY2, 4)
bplot_tree( Y, resY2, 5, pca=1 )



[Package lazy.cluster version 0.1.2 Index]