Cara Kerja Correspondence Analysis

CA membentuk suatu plot yang terdiri dari titik baris dan titik kolom. Posisi titik ini dihitung dengan mengatur koordinatnya sedemikian sehingga didapatkan hubungan antara titik baris dan kolom dalam dua dimensi. Hal ini dilakukan dengan melakukan Singular Value Decomposition (SVD) untuk meminimalkan standardized residual.

Berikut adalah langkah-langkah kerja metode Correspondence Analysis secara matematis:

Step 1: Prepare the data

Seperti dalam analisis apa pun, langkah pertama adalah mempersiapkan data. Dalam CA, data harus berupa tabel kontingensi.

Pada tahap ini, kita akan menggunakan data housetasks yang merupakan tabel kontingensi dari factoextra package. Baris pada housetasks adalah kategori pekerjaan rumah dan kolomnya adalah role keluarga.

# Load the housetasks dataset
data(housetasks, package = "factoextra")
housetasks

Step 2: Calculate the row and column marginals

Dalam CA, margin baris dan kolom digunakan untuk menghitung expected, yang digunakan dalam perhitungan statistik chi-squared. Anda dapat menghitung margin baris dan kolom menggunakan fungsi rowSums() dan colSums().

# Calculate row marginals
row_marginals <- rowSums(housetasks)
row_marginals
#>    Laundry  Main_meal     Dinner Breakfeast    Tidying     Dishes   Shopping 
#>        176        153        108        140        122        113        120 
#>   Official    Driving   Finances  Insurance    Repairs   Holidays 
#>         96        139        113        139        165        160
# Calculate column marginals
col_marginals <- colSums(housetasks)
col_marginals
#>        Wife Alternating     Husband     Jointly 
#>         600         254         381         509

Step 3: Calculate the expected values

Expected values dihitung dengan asumsi independensi antar variabel. Untuk menghitung expected values, Anda dapat menggunakan perkalian dari margin baris dan kolom, dibagi dengan frekuensi total data. Atau dirumuskan juga sebagai berikut:

\[E_i=\frac{row.marginals * col.marginas}{grand.total}\]

# Calculate expected values
n <- sum(housetasks)
expected <- outer(row_marginals, col_marginals) / n
expected
#>                Wife Alternating  Husband  Jointly
#> Laundry    60.55046    25.63303 38.44954 51.36697
#> Main_meal  52.63761    22.28326 33.42489 44.65424
#> Dinner     37.15596    15.72936 23.59404 31.52064
#> Breakfeast 48.16514    20.38991 30.58486 40.86009
#> Tidying    41.97248    17.76835 26.65252 35.60665
#> Dishes     38.87615    16.45757 24.68635 32.97993
#> Shopping   41.28440    17.47706 26.21560 35.02294
#> Official   33.02752    13.98165 20.97248 28.01835
#> Driving    47.82110    20.24427 30.36640 40.56823
#> Finances   38.87615    16.45757 24.68635 32.97993
#> Insurance  47.82110    20.24427 30.36640 40.56823
#> Repairs    56.76606    24.03096 36.04644 48.15654
#> Holidays   55.04587    23.30275 34.95413 46.69725
#math
(176*600)/n
#> [1] 60.55046

Step 4: Calculate the Standardized Residual Matrix

Standardized residual adalah akar dari statistik chi-squared yang dapat diperoleh dengan chisq.test()$residuals. Standadized residual mengukur standar deviasi dari frekuensi yang diamati dengan frekuensi yang diharapkan di bawah asumsi independensi. Formulanya adalah sebagai berikut. \[S = \frac{O - E}{\sqrt{E}}\]

# Calculate the chi-squared matrix
chi_sq <- chisq.test(housetasks)$residuals
chi_sq
#>                 Wife Alternating    Husband   Jointly
#> Laundry    12.266344  -2.2976972 -5.8782288 -6.608968
#> Main_meal   9.836062  -0.4836881 -4.9165873 -6.083794
#> Dinner      6.536557  -1.1924678 -3.4162600 -3.298819
#> Breakfeast  4.875263   3.4569876 -2.8180566 -5.297104
#> Tidying     1.702142  -1.6056807 -4.9689076  3.585198
#> Dishes     -1.102817   1.8592103 -4.1634703  3.486107
#> Shopping   -1.289342   1.3211002 -3.3623444  3.375634
#> Official   -3.658896   8.5628768  0.4427320 -2.459431
#> Driving    -5.469207   6.8355754  8.0996318 -5.898312
#> Finances   -4.150095  -0.8522912 -0.7419395  5.749805
#> Insurance  -5.758422  -4.2771092  4.1073055  5.719883
#> Repairs    -7.534325  -4.2901609 20.6456123 -6.651286
#> Holidays   -7.419291  -4.6201370 -4.8973513 15.556033
#standardized residual manual
Z = ((housetasks-expected)/sqrt(expected))
Z

Step 5: Perform Singular Value Decomposition (SVD)

SVD digunakan untuk mendekomposisi standardized residual untuk merangkum data awal. Dalam CA, matriks input untuk SVD adalah matriks M yaitu matriks proporsi dari standardized residuals.

Formula untuk matriks M adalah \[M = \frac{S}{\sqrt{grand.total}}\] Istilah SVD artinya mencari matriks ortogonal U dan V, bersama dengan matriks diagonal D dari matriks M sedemikian sehingga: \[M = UDV^T\]

Catatan:

Anda dapat melakukan SVD menggunakan fungsi svd().

# Perform Singular Value Decomposition (SVD)
residuals <- chi_sq/sqrt(n)

# Number of dimensions (rule of SVD)
nb.axes <- min(nrow(residuals)-1, ncol(residuals)-1)

# Singular value decomposition
SVD <- svd(residuals, nu = nb.axes, nv = nb.axes)
rownames(SVD$u) = rownames(housetasks)
rownames(SVD$v) = colnames(housetasks)
SVD
#> $d
#> [1] 0.7368102095278515895060 0.6670852727809422066940 0.3564385407465551214301
#> [4] 0.0000000000000001012225
#> 
#> $u
#>                   [,1]        [,2]        [,3]
#> Laundry    -0.42762952 -0.23587902 -0.28228398
#> Main_meal  -0.35197789 -0.21761257 -0.13633376
#> Dinner     -0.23391020 -0.11493572 -0.14480767
#> Breakfeast -0.19557424 -0.19231779  0.17519699
#> Tidying    -0.14136307  0.17221046 -0.06990952
#> Dishes     -0.06528142  0.16864510  0.19063825
#> Shopping   -0.04189568  0.15859251  0.14910925
#> Official    0.07216535 -0.08919754  0.60778606
#> Driving     0.28421536 -0.27652950  0.43123528
#> Finances    0.09354184  0.23576569  0.02484968
#> Insurance   0.24793268  0.20050833 -0.22918636
#> Repairs     0.63820133 -0.39850534 -0.40738669
#> Holidays    0.10379321  0.65156733 -0.11011902
#> 
#> $v
#>                    [,1]       [,2]       [,3]
#> Wife        -0.66679846 -0.3211267 -0.3289692
#> Alternating -0.03220853 -0.1668171  0.9085662
#> Husband      0.73643655 -0.4217418 -0.2476526
#> Jointly      0.10956112  0.8313745 -0.0703917

Menyimpan komponen-komponen yang dihasilkan dari SVD

sv <- SVD$d[1:nb.axes] # singular value
u <- SVD$u #vector eigen baris
v <- SVD$v #vector eigen kolom

Eigenvalues dan eigenvectors dapat dihitung dari SVD. Eigenvalues mewakili variansi yang dijelaskan oleh setiap dimensi, sedangkan eigenvectors mewakili loadings variabel.

# Eigenvalues
eig <- sv^2
eig
#> [1] 0.5428893 0.4450028 0.1270484

Step 6: Visualize the results

Akhirnya, Anda dapat memvisualisasikan hasil CA dengan memplotting koordinat dari variabel pada dua dimensi pertama.

Row Coordinat: \[row.coord = \frac{U * \delta}{\sqrt{row.marginals/grand.total}}\] Kita dapat menggunakan fungsi apply() untuk melakukan operasi sewenang-wenang pada baris dan kolom matriks.

apply(X, MARGIN, FUN, ...)

Keterangan:

# row coord = u * sv /sqrt(row_marginals/n)
cc <- apply(u, 1, '*', sv) # each row X sv
row.coord <- apply(cc, 1, '/', sqrt(row_marginals/n))
rownames(row.coord) <- rownames(housetasks)
colnames(row.coord) <- paste0("Dim.", 1:nb.axes)
round(row.coord,3)
#>             Dim.1  Dim.2  Dim.3
#> Laundry    -0.992 -0.495 -0.317
#> Main_meal  -0.876 -0.490 -0.164
#> Dinner     -0.693 -0.308 -0.207
#> Breakfeast -0.509 -0.453  0.220
#> Tidying    -0.394  0.434 -0.094
#> Dishes     -0.189  0.442  0.267
#> Shopping   -0.118  0.403  0.203
#> Official    0.227 -0.254  0.923
#> Driving     0.742 -0.653  0.544
#> Finances    0.271  0.618  0.035
#> Insurance   0.647  0.474 -0.289
#> Repairs     1.529 -0.864 -0.472
#> Holidays    0.252  1.435 -0.130

Column Coordinat: \[col.coord = \frac{V * \delta}{\sqrt{col.marginals/grand.total}}\]

# coordinates sv * v /sqrt(col_marginals/n)
cc <- apply(v, 1, '*', sv)
col.coord <- apply(cc, 1, '/', sqrt(col_marginals/n))
rownames(col.coord) <- colnames(housetasks)
colnames(col.coord) <- paste0("Dim", 1:nb.axes)
head(col.coord)
#>                    Dim1       Dim2        Dim3
#> Wife        -0.83762154 -0.3652207 -0.19991139
#> Alternating -0.06218462 -0.2915938  0.84858939
#> Husband      1.16091847 -0.6019199 -0.18885924
#> Jointly      0.14942609  1.0265791 -0.04644302

Untuk membuat biploy CA, Anda dapat membuat scatter plot menggunakan fungsi plot() dan memberi label pada titik menggunakan fungsi text().

#limit axis x dan y
xlim <- range(c(row.coord[,1], col.coord[,1]))*1.1
ylim <- range(c(row.coord[,2], col.coord[,2]))*1.1

# Plot of rows
plot(row.coord, pch=19, col = "blue", xlim = xlim, ylim = ylim)
text(row.coord, labels = rownames(row.coord), pos = 3, col ="blue")

# plot of columns
points(col.coord, pch=17, col = "red")
text(col.coord, labels = rownames(col.coord), pos = 3, col ="red")
abline(v=0, h=0, lty = 2)