Skip to contents
library(biplotEZ)
#> Welcome to biplotEZ! 
#> This package is used to construct biplots 
#> Run ?biplot or vignette() for more information
#> 
#> Attaching package: 'biplotEZ'
#> The following object is masked from 'package:stats':
#> 
#>     biplot

This vignette deals with biplots for separating classes. Topics discussed are

  • CVA (Canonical variate analysis) biplots
  • AoD (Analysis of Distance) biplots
  • Classification biplots

What is a CVA biplot

Consider a data matrix ๐‘ฟ:nร—p\mathbf{X}:n \times p containing data on nn objects and pp variables. In addition, a vector ๐’ˆ:nร—1\mathbf{g}:n \times 1 contains information on class membership of each observation. Let GG indicate the total number of classes. CVA is closely related to linear discriminant anlaysis, in that the pp variables are transformed to pp new variables, called canonical variates, such that the classes are optimally separated in the canonical space. By optimally separated, we mean maximising the between class variance, relative to the within class variance. This can be formulated as follows:

Let ๐‘ฎ:nร—G\mathbf{G}:n \times G be an indicator matrix with gij=0g_{ij} = 0 unless observation ii belongs to class jj and then gij=1g_{ij} = 1. The matrix ๐‘ฎโ€ฒ๐‘ฎ\mathbf{G'G} is a diagonal matrix containing the number of observations per class on the diagonal. We can form the matrix of class means ๐‘ฟโ€พ:Gร—p=(๐‘ฎโ€ฒ๐‘ฎ)โˆ’1๐‘ฎโ€ฒ๐‘ฟ\bar{\mathbf{X}}:G \times p = (\mathbf{G'G})^{-1} \mathbf{G'X}. With the usual analysis of variance the total variance can be decomposed into a between class variance and within class variance:

๐‘ป=๐‘ฉ+๐‘พ \mathbf{T} = \mathbf{B} + \mathbf{W}

๐‘ฟโ€ฒ๐‘ฟ=๐‘ฟโ€พโ€ฒ๐‘ช๐‘ฟโ€พ+๐‘ฟโ€ฒ[๐‘ฐโˆ’๐‘ฎ(๐‘ฎโ€ฒ๐‘ฎ)โˆ’๐Ÿ๐‘ช(๐‘ฎโ€ฒ๐‘ฎ)โˆ’๐Ÿ๐‘ฎโ€ฒ]๐‘ฟ \mathbf{X'X} = \mathbf{\bar{\mathbf{X}}'C \bar{\mathbf{X}}} + \mathbf{X' [I - G(G'G)^{-1}C(G'G)^{-1}G'] X}

The default choice for the centring matrix ๐‘ช=๐‘ฎโ€ฒ๐‘ฎ\mathbf{C = G'G} leads to the simplification

๐‘ฟโ€ฒ๐‘ฟ=๐‘ฟโ€พโ€ฒ๐‘ฎโ€ฒ๐‘ฎ๐‘ฟโ€พ+๐‘ฟโ€ฒ[๐‘ฐโˆ’๐‘ฎ(๐‘ฎโ€ฒ๐‘ฎ)โˆ’๐Ÿ๐‘ฎโ€ฒ]๐‘ฟ. \mathbf{X'X} = \mathbf{\bar{\mathbf{X}}'G'G \bar{\mathbf{X}}} + \mathbf{X' [I - G(G'G)^{-1}G'] X}.

Other options are ๐‘ช=๐‘ฐ\mathbf{C = I} and ๐‘ช=(๐‘ฐGโˆ’1G๐Ÿ๐Ÿโ€ฒ)\mathbf{C} = (\mathbf{I}_G - \frac{1}{G}\mathbf{11'}). To find the canonical variates we want to maximise the ratio

๐’Žโ€ฒ๐‘ฉ๐’Ž๐’Žโ€ฒ๐‘พ๐’Ž \frac{\mathbf{m'Bm}}{\mathbf{m'Wm}}

subject to ๐’Žโ€ฒ๐‘พ๐’Ž=1\mathbf{m'Wm} = 1. It can be shown that this leads to the following equivalent eigen equations:

๐‘พโˆ’1๐‘ฉ๐‘ด=๐‘ด๐šฒ \mathbf{W}^{-1}\mathbf{BM} = \mathbf{M \Lambda} \tag{1}

๐‘ฉ๐‘ด=๐‘พ๐‘ด๐šฒ \mathbf{BM} = \mathbf{WM \Lambda}

(๐‘พโˆ’12๐‘ฉ๐‘พโˆ’12)๐‘ด=(๐‘พโˆ’12๐‘ด)๐šฒ (\mathbf{W}^{-\frac{1}{2}} \mathbf{B} \mathbf{W}^{-\frac{1}{2}}) \mathbf{M} = (\mathbf{W}^{-\frac{1}{2}} \mathbf{M}) \mathbf{\Lambda}

with ๐‘ดโ€ฒ๐‘ฉ๐‘ด=๐šฒ\mathbf{M'BM}= \mathbf{\Lambda} and ๐‘ดโ€ฒ๐‘พ๐‘ด=๐‘ฐ\mathbf{M'WM}= \mathbf{I}.

Since the matrix ๐‘พโˆ’12๐‘ฉ๐‘พโˆ’12\mathbf{W}^{-\frac{1}{2}} \mathbf{B} \mathbf{W}^{-\frac{1}{2}} is symmetric and positive semi-definite the eigenvalues in the matrix ๐šฒ\mathbf{\Lambda} are positive and ordered. The rank of ๐‘ฉ=min(p,Gโˆ’1)\mathbf{B} = min(p, G-1) so that only the first rank(๐‘ฉ)rank(\mathbf{B}) eigenvalues are non-zero. We form the canonical variates with the transformation

๐’€โ€พ=๐‘ฟโ€พ๐‘ด. \bar{\mathbf{Y}} = \bar{\mathbf{X}}\mathbf{M}.

To construct a 2D biplot, we plot the first two canonical variates ๐’โ€พ=๐‘ฟโ€พ๐‘ด๐‘ฑ2\bar{\mathbf{Z}} = \bar{\mathbf{X}}\mathbf{MJ}_2 where ๐‘ฑ2โ€ฒ=[๐‘ฐ2๐ŸŽ]\mathbf{J}_2' = \begin{bmatrix} \mathbf{I}_2 & \mathbf{0} \end{bmatrix}. We add the individual sample points with the same transformation

๐’=๐‘ฟ๐‘ด๐‘ฑ2 \mathbf{Z} = \mathbf{X}\mathbf{MJ}_2 where ๐‘ฑ2=[๐‘ฐ2๐ŸŽ]. \mathbf{J}_2 = \begin{bmatrix} \mathbf{I}_2\\ \mathbf{0} \end{bmatrix}. Interpolation of a new sample ๐’™*:pร—1\mathbf{x}^*:p \times 1 follows as ๐’›*โ€ฒ:2ร—1=๐’™*โ€ฒ๐‘ด๐‘ฑ2{\mathbf{z}^*}':2 \times 1 ={\mathbf{x}^*}' \mathbf{MJ}_2. Using the inverse transformation ๐’™โ€ฒ=๐’šโ€ฒ๐‘ดโˆ’1\mathbf{x}' = \mathbf{y}'\mathbf{M}^{-1}, all the points that will predict ฮผ\mu for variable jj will have the form

ฮผ=๐’šโ€ฒ๐‘ดโˆ’1๐’†j \mu = \mathbf{y}'\mathbf{M}^{-1} \mathbf{e}_j

where ๐’†j\mathbf{e}_j is a vector of zeros with a one in position jj. All the points in the 2D biplot that predict the value ฮผ\mu will have

ฮผ=[z1z20โ€ฆ0]๐‘ดโˆ’1๐’†j \mu = \begin{bmatrix} z_1 & z_2 & 0 & \dots & 0\end{bmatrix}\mathbf{M}^{-1} \mathbf{e}_j

defining the prediction line as

ฮผ=๐’›ฮผโ€ฒ๐‘ฑ2๐‘ดโˆ’1๐’†j. \mu = \mathbf{z}_{\mu}' \mathbf{J}_2 \mathbf{M}^{-1} \mathbf{e}_j.

Writing ๐’‰(j)=๐‘ฑ2๐‘ดโˆ’1๐’†j\mathbf{h}_{(j)} = \mathbf{J}_2 \mathbf{M}^{-1} \mathbf{e}_j the construction of biplot axes is similar to the discussion in the biplotEZ vignette for PCA biplots. The direction of the axis is given by ๐’‰(j)\mathbf{h}_{(j)}. To find the intersection of the prediction line with ๐’‰(j)\mathbf{h}_{(j)} we note that ๐’›(ฮผ)โ€ฒ๐’‰(j)=โˆฅ๐’›(ฮผ)โˆฅ2โˆฅ๐’‰(j)โˆฅ2cos(๐’›(ฮผ),๐’‰(j))=โˆฅ๐’‘โˆฅ2โˆฅ๐’‰(j)โˆฅ2 \mathbf{z}'_{(\mu)}\mathbf{h}_{(j)} = \| \mathbf{z}_{(\mu)} \|^2 \| \mathbf{h}_{(j)} \|^2 cos(\mathbf{z}_{(\mu)},\mathbf{h}_{(j)}) = \| \mathbf{p} \|^2 \| \mathbf{h}_{(j)} \|^2 where ๐’‘\mathbf{p} is the length of the orthogonal projection of ๐’›(ฮผ)\mathbf{z}_{(\mu)} on ๐’‰(j)\mathbf{h}_{(j)}.

Since ๐’‘\mathbf{p} is along ๐’‰(j)\mathbf{h}_{(j)} we can write ๐’‘=c๐’‰(j)\mathbf{p} = c\mathbf{h}_{(j)} and all points on the prediction line ฮผ=๐’›ฮผโ€ฒ๐’‰(j)\mu = \mathbf{z}'_{\mu}\mathbf{h}_{(j)} project on the same point cฮผ๐’‰(j)c_{\mu}\mathbf{h}_{(j)}. We solve for cฮผc_{\mu} from ฮผ=๐’›ฮผโ€ฒ๐’‰(j)=โˆฅ๐’‘โˆฅ2โˆฅ๐’‰(j)โˆฅ2=โˆฅcฮผ๐’‰(j)โˆฅ2โˆฅ๐’‰(j)โˆฅ2 \mu = \mathbf{z}'_{\mu}\mathbf{h}_{(j)}=\| \mathbf{p} \|^2 \| \mathbf{h}_{(j)} \|^2 = \| c_{\mu}\mathbf{h}_{(j)} \|^2 \| \mathbf{h}_{(j)} \|^2

cฮผ=ฮผ๐’‰(j)โ€ฒ๐’‰(j). c_{\mu} = \frac{\mu}{\mathbf{h}_{(j)}'\mathbf{h}_{(j)}}. If we select โ€˜niceโ€™ scale markers ฯ„1,ฯ„2,โ‹ฏฯ„k\tau_{1}, \tau_{2}, \cdots \tau_{k} for variable jj, then ฯ„hโˆ’xโ€พj=ฮผh\tau_{h}-\bar{x}_j = \mu_{h} and positions of these scale markers on ๐’‰(j)\mathbf{h}_{(j)} are given by pฮผ1,pฮผ2,โ‹ฏpฮผkp_{\mu_{1}}, p_{\mu_{2}}, \cdots p_{\mu_{k}} with pฮผh=cฮผh๐’‰(j)=ฮผh๐’‰(j)โ€ฒ๐’‰(j)๐’‰(j) p_{\mu_h} = c_{\mu_h}\mathbf{h}_{(j)} = \frac{\mu_h}{\mathbf{h}_{(j)}'\mathbf{h}_{(j)}}\mathbf{h}_{(j)}

=ฮผh๐’†(j)โ€ฒ๐‘ดโ€ฒโˆ’1๐‘ฑ๐‘ดโˆ’1๐’†(j)๐‘ฑ2๐‘ดโˆ’1๐’†(j) = \frac{\mu_h}{\mathbf{e}_{(j)}' \mathbf{M'}^{-1} \mathbf{J} \mathbf{M}^{-1} \mathbf{e}_{(j)}}\ \mathbf{J}_2 \mathbf{M}^{-1} \mathbf{e}_{(j)}

with ๐‘ฑ=[๐‘ฐ2๐ŸŽ๐ŸŽ๐ŸŽ]. \mathbf{J} = \begin{bmatrix} \mathbf{I}_2 & \mathbf{0}\\ \mathbf{0} & \mathbf{0} \end{bmatrix}.

The function CVA()

To obtain a CVA biplot of the state.x77 data set, optimally separating the classes according to state.region we call

biplot(state.x77) |> 
  CVA(classes = state.region) |> 
  plot()

Fitting ฮฑ\alpha-bags to the classes makes it easier to compare class overlap and separation. For a detailed discussion on ฮฑ\alpha-bags, see the biplotEZ vignette.

biplot(state.x77) |> CVA(classes = state.region) |> alpha.bags() |> 
  legend.type (bags = TRUE) |> 
  plot()
#> Computing 0.95 -bag for Northeast 
#> Computing 0.95 -bag for South 
#> Computing 0.95 -bag for North Central 
#> Computing 0.95 -bag for West

The function means()

This function controls the aesthetics of the class means in the biplot. The function accepts as first argument an object of class biplot where the aesthetics should be applied. Let us first construct a CVA biplot of the state.x77 data with samples optimally separated according to state.division.

biplot(state.x77, scaled = TRUE) |> 
  CVA(classes = state.division) |> 
  legend.type(means = TRUE) |> 
  plot()

Instead of adding a legend, we can choose to label the class means. Furthermore, the colour of each class mean defaults to the colour of the samples. We wish to select a different colour and plotting character for the class means.

biplot(state.x77, scaled = TRUE) |> 
  CVA(classes = state.division) |> 
  means(label = TRUE, col = "olivedrab", pch = 15) |> 
  plot()

If we choose to only show the class means for the central states, the argument which is used either indicating the number(s) in the sequence of levels (which = 4:7), or as shown below, the levels themselves:

biplot(state.x77, scaled = TRUE) |> 
  CVA(classes = state.division) |> 
  means (which = c("West North Central", "West South Central", "East South Central", 
                     "East North Central"), label = TRUE) |>
  plot()

The size of the labels is controlled with label.cex which can be specified either as a single value (for all class means) or a vector indicating size values for each individual sample. The colour of the labels defaults to the colour(s) of the class means. However, individual label colours can be spesified with label.col, similar to label.cex as either a single value of a vector of length equal to the number of classes.

biplot(state.x77, scaled = TRUE) |> 
  CVA(classes = state.division) |> 
  means (col = "olivedrab", pch = 15, cex = 1.5,
         label = TRUE, label.col = c("blue","green","gold","cyan","magenta",
                                     "black","red","grey","purple")) |>
  plot()

We can also make use of the functionality of the ggrepel package to place the labels.

biplot(state.x77, scaled = TRUE) |> 
  CVA(classes = state.division) |> 
  samples (label = "ggrepel", label.cex=0.65) |> 
  means (label = "ggrepel", label.cex=0.8) |> plot()

The function classify()

Classification regions can be added to the CVA biplot with the function classify(). The argument classify.regions must be set equal to TRUE to render the regions in the plot. Other arguments such as col, opacity and borders allows to change the aesthetics of the regions.

biplot(state.x77, scaled = TRUE) |> 
  CVA(classes = state.division) |>
  classify(classify.regions = TRUE,opacity = 0.2) |> 
  plot()

The functions fit.measures() and summary()

There is a number of fit measures that are specific to CVA biplots. The measures are computed with the function fit.measures() and the results are displayed by the function summary().

Canonical variate analysis can be considered as a transformation of the original variables to the canonical space followed by constructing a PCA biplot of canonical variables. The matrix of class means ๐‘ฟโ€พ=(๐‘ฎโ€ฒ๐‘ฎ)โˆ’1๐‘ฎโ€ฒ๐‘ฟ\bar{\mathbf{X}} = (\mathbf{G'G})^{-1} \mathbf{G'X} is transformed to ๐‘ฟโ€พ๐‘ณ\mathbf{\bar{X}L} where ๐‘ณ\mathbf{L} is a non-singular matrix such that ๐‘ณ๐‘ณโ€ฒ=๐‘พโˆ’1\mathbf{LL'=W}^{-1}. Pricipal component analysis finds the orthogonal matrix ๐‘ฝ\mathbf{V} such that

(๐‘ณโ€ฒ๐‘ฟโ€พโ€ฒ๐‘ช๐‘ฟโ€พ๐‘ณ)๐‘ฝ=๐‘ฝ๐šฒ \mathbf{(L'\bar{X}'C\bar{X}L)V=V \Lambda}

where ๐‘ด=๐‘ณ๐‘ฝ\mathbf{M = LV} as defined in section 1. The predicted values for the class means is given by

๐‘ฟโ€พฬ‚=๐‘ฟโ€พ๐‘ด๐‘ฑ๐‘ดโˆ’1. \mathbf{\hat{\bar{X}}} = \mathbf{\bar{X}MJ}\mathbf{M}^{-1}.

Overall quality of fit

Based on the two-step process described above, there are two measures of quality of fit. The quality of the approximation of the canonical variables ๐‘ฟโ€พ๐‘ณ\mathbf{\bar{X}L} in the 22-dimensional display is given by

Quality(canonicalvariables)=tr(๐šฒ๐‘ฑ)tr(๐šฒ) Quality (canonical \: variables) = \frac{tr(\mathbf{\Lambda J})}{tr(\mathbf{\Lambda)}} and the quality of the approximation of the original variables ๐‘ฟโ€พ\mathbf{\bar{X}} in the 2D CVA biplot is given by

Quality(originalvariables)=tr(๐šฒ๐‘ฑ)tr(๐šฒ) Quality (original \: variables) = \frac{tr(\mathbf{\Lambda J})}{tr(\mathbf{\Lambda)}}

Adequacy of representation of variables

The adequacy with which each of the variables is represented in the biplot is given by the elementwise ratios

Adequacy=diag(๐‘ด๐‘ฑ๐‘ดโ€ฒ)diag(๐‘ด๐‘ดโ€ฒ). Adequacy = \frac{diag(\mathbf{MJM'})}{diag(\mathbf{MM'})}.

Predictivity

Between class predictivity

The axis and class mean predictivities are defined in terms of the weighted class means.

Axis predictivity

The elementwise ratios for the predictivity of each of the axes are given by

axispredictivity=diag(๐‘ฟโ€พฬ‚โ€ฒ๐‘ช๐‘ฟโ€พฬ‚)diag(๐‘ฟโ€พโ€ฒ๐‘ช๐‘ฟโ€พ). axis \: predictivity = \frac{diag(\mathbf{\hat{\bar{X}}}'\mathbf{C\hat{\bar{X}}})}{diag(\mathbf{\bar{X}}'\mathbf{C\bar{X}})}.

Class predictivity

Similarly for each of the class means the elementwise ratio is computed from

classpredictivity=diag(๐‘ช12๐‘ฟโ€พฬ‚โ€ฒ๐‘พโˆ’๐Ÿ๐‘ฟโ€พฬ‚๐‘ช12)diag(๐‘ช12๐‘ฟโ€พโ€ฒ๐‘พโˆ’๐Ÿ๐‘ฟโ€พ๐‘ช12). class \: predictivity = \frac{diag(\mathbf{C}^{\frac{1}{2}}\mathbf{\hat{\bar{X}}}'\mathbf{W^{-1}}\mathbf{\hat{\bar{X}}}\mathbf{C}^{\frac{1}{2}})}{diag(\mathbf{C}^{\frac{1}{2}}\mathbf{\bar{X}}'\mathbf{W^{-1}}\mathbf{\bar{X}}\mathbf{C}^{\frac{1}{2}})}.

Within class predictivity

We define the matrix of samples as deviations from their class means as

(๐‘ฐโˆ’๐‘ฏ)๐‘ฟ=(๐‘ฐnโˆ’๐‘ฎ(๐‘ฎโ€ฒ๐‘ฎ)โˆ’1๐‘ฎโ€ฒ)๐‘ฟ (\mathbf{I-H})\mathbf{X}=(\mathbf{I}_n-\mathbf{G}(\mathbf{G'G})^{-1}\mathbf{G}')\mathbf{X}

where ๐‘ฏ=๐‘ฎ(๐‘ฎโ€ฒ๐‘ฎ)โˆ’1๐‘ฎโ€ฒ\mathbf{H} = \mathbf{G}(\mathbf{G'G})^{-1}\mathbf{G}'.

Within class axis predictivity

The within class axis predictivity is computed as the elementwise ratios

withinclassaxispredictivity=diag(๐‘ฟฬ‚โ€ฒ(๐‘ฐโˆ’๐‘ฏ)๐‘ฟฬ‚)diag(๐‘ฟโ€ฒ(๐‘ฐโˆ’๐‘ฏ)๐‘ฟ). within \: class \: axis \: predictivity = \frac{diag(\mathbf{\hat{X}}'(\mathbf{I-H)\hat{X}})}{diag(\mathbf{X}'(\mathbf{I-H)X})}.

Within class sample predictivity

Unlike PCA biplots, sample predictivity for CVA biplots are computed for the observations expressed as deviations from their class means. The elementwise ratios is obtained from

withinclassaxispredictivity=diag((๐‘ฐโˆ’๐‘ฏ)๐‘ฟฬ‚๐‘พโˆ’1๐‘ฟฬ‚โ€ฒ(๐‘ฐโˆ’๐‘ฏ))diag((๐‘ฐโˆ’๐‘ฏ)๐‘ฟ๐‘พโˆ’1๐‘ฟโ€ฒ(๐‘ฐโˆ’๐‘ฏ)). within \: class \: axis \: predictivity = \frac{diag(\mathbf{(I-H)\hat{X}}\mathbf{W}^{-1}\mathbf{\hat{X}'(I-H)})}{diag(\mathbf{(I-H)X}\mathbf{W}^{-1}\mathbf{X'(I-H)})}. To display the fit measures, we create a biplot object with the measures added by the function fit.measures() and call summary().

obj <- biplot(state.x77, scaled = TRUE) |> 
       CVA(classes = state.division) |> 
       fit.measures() |>
       plot()

summary (obj)
#> Object of class biplot, based on 50 samples and 8 variables.
#> 8 numeric variables.
#> 9 classes: New England Middle Atlantic South Atlantic East South Central West South Central East North Central West North Central Mountain Pacific 
#> 
#> Quality of fit of canonical variables in 2 dimension(s) = 70.7% 
#> Quality of fit of original variables in 2 dimension(s) = 70.5% 
#> Adequacy of variables in 2 dimension(s):
#> Population     Income Illiteracy   Life Exp     Murder    HS Grad      Frost 
#> 0.41716176 0.15621549 0.16136381 0.09759664 0.19426796 0.55332679 0.50497634 
#>       Area 
#> 0.40661470 
#> Axis predictivity in 2 dimension(s):
#> Population     Income Illiteracy   Life Exp     Murder    HS Grad      Frost 
#>  0.1859124  0.4019427  0.8195756  0.6925389  0.7685373  0.9506355  0.7819324 
#>       Area 
#>  0.8458143 
#> Class predictivity in 2 dimension(s):
#>        New England    Middle Atlantic     South Atlantic East South Central 
#>          0.7922047          0.6570417          0.8191791          0.8777759 
#> West South Central East North Central West North Central           Mountain 
#>          0.7416085          0.6370315          0.3265978          0.6825966 
#>            Pacific 
#>          0.6700194 
#> Within class axis predictivity in 2 dimension(s):
#> Population     Income Illiteracy   Life Exp     Murder    HS Grad      Frost 
#> 0.04212318 0.09357501 0.25675620 0.19900223 0.29474972 0.75215233 0.31027358 
#>       Area 
#> 0.12741853 
#> Within class sample predictivity in 2 dimension(s):
#>        Alabama         Alaska        Arizona       Arkansas     California 
#>    0.722548912    0.163442379    0.333341120    0.268976273    0.229139828 
#>       Colorado    Connecticut       Delaware        Florida        Georgia 
#>    0.264963758    0.082284385    0.593415987    0.461070888    0.636531435 
#>         Hawaii          Idaho       Illinois        Indiana           Iowa 
#>    0.015640188    0.113711473    0.338612599    0.389208196    0.507060148 
#>         Kansas       Kentucky      Louisiana          Maine       Maryland 
#>    0.784831952    0.314119027    0.078465054    0.008388471    0.306141816 
#>  Massachusetts       Michigan      Minnesota    Mississippi       Missouri 
#>    0.076563044    0.218470793    0.645446212    0.046129058    0.710971640 
#>        Montana       Nebraska         Nevada  New Hampshire     New Jersey 
#>    0.086279776    0.810374638    0.090490164    0.298187909    0.003496353 
#>     New Mexico       New York North Carolina   North Dakota           Ohio 
#>    0.007134343    0.024268121    0.422776032    0.446240464    0.277262145 
#>       Oklahoma         Oregon   Pennsylvania   Rhode Island South Carolina 
#>    0.450104680    0.108636860    0.033945796    0.415029328    0.261568299 
#>   South Dakota      Tennessee          Texas           Utah        Vermont 
#>    0.134881180    0.247921823    0.110537439    0.500454605    0.159941068 
#>       Virginia     Washington  West Virginia      Wisconsin        Wyoming 
#>    0.310439564    0.030877305    0.066303623    0.295499472    0.474458397

The call to biplot(), CVA() and fit.measures() is required to (a) create an object of class biplot, (b) extend the object to class CVA and (c) compute the fit measures. The call to the function plot() is optional. It is further possible to select which fit measures to display in the summary() function where all measures default to TRUE.

obj <- biplot(state.x77, scaled = TRUE) |> 
       CVA(classes = state.region) |> 
       fit.measures()
summary (obj, adequacy = FALSE, within.class.axis.predictivity = FALSE,
         within.class.sample.predictivity = FALSE)
#> Object of class biplot, based on 50 samples and 8 variables.
#> 8 numeric variables.
#> 4 classes: Northeast South North Central West 
#> 
#> Quality of fit of canonical variables in 2 dimension(s) = 91.9% 
#> Quality of fit of original variables in 2 dimension(s) = 95.3% 
#> Axis predictivity in 2 dimension(s):
#> Population     Income Illiteracy   Life Exp     Murder    HS Grad      Frost 
#>  0.9873763  0.9848608  0.8757913  0.9050208  0.9955088  0.9970346  0.9558192 
#>       Area 
#>  0.9344651 
#> Class predictivity in 2 dimension(s):
#>     Northeast         South North Central          West 
#>     0.8031465     0.9985089     0.6449906     0.9988469

Additional CVA dimensions

It was mentioned that the eigen equation (1) has min(p,Gโˆ’1)min(p, G-1) non-zero eigenvalues. This implies that the CVA biplot for G=2G=2 groups, reduces to a single dimension. If we write

๐‘ด=[๐’Ž1๐‘ด*] \mathbf{M} = \begin{bmatrix} \mathbf{m}_1 & \mathbf{M}^* \end{bmatrix} the columns of ๐‘ด*\mathbf{M}^* forms a basis for the orthogonal complement of the canonical space defined by ๐’Ž\mathbf{m}_1. The argument low.dim determines how to uniquely define the second and third dimensions. By default low.dim = "sample.opt" which selects the dimensions by minimising total squared reconstruction error for samples.

The representation of the canonical variates ๐’โ€พ=๐‘ฟโ€พ๐’Ž1\bar{\mathbf{Z}} = \bar{\mathbf{X}}\mathbf{m}_1 are exact in the first dimension, but not the representation of the individual samples ๐’=๐‘ฟ๐’Ž1{\mathbf{Z}} = {\mathbf{X}}\mathbf{m}_1. If we define ๐‘ฟฬ‚=๐‘ฟ๐‘ด๐‘ฑ๐‘ดโˆ’1\mathbf{\hat{X}} = \mathbf{XMJ}\mathbf{M}^{-1} with ๐‘ฑ\mathbf{J} a square matrix of zeros except for a 11 in the first diagonal position, then the total square reconstruction error for samples is given by

TSRES=tr(๐‘ฟโˆ’๐‘ฟฬ‚)โ€ฒ(๐‘ฟโˆ’๐‘ฟฬ‚). TSRES = tr{(\mathbf{X}-\mathbf{\hat{X}})'(\mathbf{X}-\mathbf{\hat{X}})}. Define ๐‘ดโˆ’1=[๐‘ด(1):(Gโˆ’1)ร—p๐‘ด(2):(pโˆ’G+1)ร—p] \mathbf{M}^{-1} = \begin{bmatrix} \mathbf{M}^{(1)}:(G-1) \times p \\ \mathbf{M}^{(2)}: (p-G+1) \times p \end{bmatrix}

then TSRESTSRES is minimised when

๐‘ดopt=[๐‘ด1๐‘ด*๐‘ฝ] \mathbf{M}^{opt} = \begin{bmatrix} \mathbf{M}_1 & \mathbf{M}^*\mathbf{V} \end{bmatrix}

where where ๐‘ฝ\mathbf{V} is the matrix of right singular vectors of ๐‘ด(2)๐‘ด(2)โ€ฒ\mathbf{M}^{(2)}\mathbf{M}^{(2)'}.

state.2group <- ifelse(state.division == "New England" | 
                       state.division == "Middle Atlantic"  |
                       state.division == "South Atlantic" |
                       state.division == "Pacific",
                       "Coastal", "Central")
biplot (state.x77) |> CVA (state.2group) |> legend.type(means=TRUE) |> plot()
#> Warning in CVA.biplot(biplot(state.x77), state.2group): The dimension of the
#> canonical space < dim.biplot sample.opt method used for additional
#> dimension(s).

le Roux and Gardner-Lubbe (2024) discuss an alternative method for obtaining additional dimensions. When assuming underlying normal distributions, the Bhattacharyya distance can be optimised. This method is specific to the two class case and cannot be utilised to find a third dimension in a 3D CVA biplot with three classes.

biplot (state.x77) |> CVA (state.2group, low.dim="Bha") |> legend.type(means=TRUE) |> plot()
#> Warning in CVA.biplot(biplot(state.x77), state.2group, low.dim = "Bha"): The
#> dimension of the canonical space < dim.biplot Bhattacharyya.dist method used
#> for additional dimension(s).

Analysis of Distance (AoD)

Similar to the variance decomposition in CVA, analysis of distance decomposes the total sum of squared distances into a sum of squared distances between class means component and a sum of squared distances within classes component.

Consider any Euclidean embeddable distance metric ฯˆij=ฯˆ(๐’™i,๐’™j)\psi_{ij}=\psi(\mathbf{x}_i,\mathbf{x}_j). For a Euclidean embeddable metric it is possible to find high dimensional coordinates ๐’ši\mathbf{y}_i and ๐’šj\mathbf{y}_j such that the Euclidean distance between ๐’ši\mathbf{y}_i and ๐’šj\mathbf{y}_j is equal to ฯˆij\psi_{ij}. Let the matrix ๐šฟฬƒ\mathbf{\tilde\Psi} contain the values โˆ’12ฯˆij2-\frac{1}2{}\psi_{ij}^2 and similarly ๐šซฬƒ\mathbf{\tilde\Delta} the values โˆ’12ฮดhk2-\frac{1}2{}\delta_{hk}^2 where ฮดhk\delta_{hk} represent the distance between class means hh and kk.

๐‘ป=๐‘ฉ+๐‘พ \mathbf{T} = \mathbf{B} + \mathbf{W}

๐Ÿโ€ฒ๐šฟฬƒ๐Ÿ=๐’โ€ฒ๐šซฬƒ๐’+โˆ‘k=1Gnnk๐’ˆkโ€ฒ๐šฟฬƒ๐’ˆk \mathbf{1'\tilde\Psi1} = \mathbf{n'\tilde\Delta n} + \sum_{k=1}^{G} \frac{n}{n_k} \mathbf{g}_k'\mathbf{\tilde\Psi}\mathbf{g}_k where ๐’=(๐‘ฎโ€ฒ๐‘ฎ)๐Ÿ\mathbf{n}=\mathbf{(G'G)1}. Thus, AoD differs from CVA in allowing any Euclidean embeddable measure of inter-class distance. As with CVA, these distances may be represented in maps with point representing the class means, supplemented by additional points representing the within-group variation. Principal coordinate analysis is performed, only on the Gร—GG \times G matrix ๐šซฬƒ\mathbf{\tilde\Delta}.

biplot(state.x77, scaled = TRUE) |> AoD(classes = state.region) |> plot()

By default linear regression biplot axes are fitted to the plot. Alternatively, spline axes can be constructed.

biplot(state.x77, scaled = TRUE) |> AoD(classes = state.region, axes = "splines") |> plot()
#> Warning: The ggplot2 engine does not yet support spline axes; falling back to
#> base graphics.

#> Calculating spline axis for variable 1 
#> Calculating spline axis for variable 2 
#> Calculating spline axis for variable 3 
#> Calculating spline axis for variable 4 
#> Calculating spline axis for variable 5 
#> Calculating spline axis for variable 6 
#> Calculating spline axis for variable 7 
#> Calculating spline axis for variable 8

As an illustration of a Euclidean embeddable distance metric, other than Euclidean distance itself, we can construct an AoD biplot with the square root of the Manhattan distance.

biplot(state.x77, scaled = TRUE) |> 
  AoD(classes = state.region, axes = "splines", dist.func=sqrtManhattan) |> plot()
#> Warning: The ggplot2 engine does not yet support spline axes; falling back to
#> base graphics.

#> Calculating spline axis for variable 1 
#> Calculating spline axis for variable 2 
#> Calculating spline axis for variable 3 
#> Calculating spline axis for variable 4 
#> Calculating spline axis for variable 5 
#> Calculating spline axis for variable 6 
#> Calculating spline axis for variable 7 
#> Calculating spline axis for variable 8

References

le Roux, N. J, and S. Gardner-Lubbe. 2024. โ€œA Two-Group Canonical Variate Analysis Biplot for an Optimal Display of Bothmeans and Cases.โ€ Advances in Data Analysis and Classification.