Activity 3.3 - PCA implementation

SUBMISSION INSTRUCTIONS

  1. Render to html
  2. Publish your html to RPubs
  3. Submit a link to your published solutions
library(tidyverse)
Warning: package 'ggplot2' was built under R version 4.4.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   4.0.0     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Problem 1

Consider the following 6 eigenvalues from a \(6\times 6\) correlation matrix:

\[\lambda_1 = 3.5, \lambda_2 = 1.0, \lambda_3 = 0.7, \lambda_4 = 0.4, \lambda_5 = 0.25, \lambda_6 = 0.15\]

If you want to retain enough principal components to explain at least 90% of the variability inherent in the data set, how many should you keep?

3.5/6 + 1/6 + 0.7/6 + 0.4/6
[1] 0.9333333

We need to keep 4 principal components to explain at least 90% of the variability in the data set. If we only keep 3 we will preserve 86.6%, but if we go to 4, we will keep 93.3%.

Problem 2

The iris data set is a classic data set often used to demonstrate PCA. Each iris in the data set contained a measurement of its sepal length, sepal width, petal length, and petal width. Consider the five irises below, following mean-centering and scaling:

library(tidyverse)
five_irises <- data.frame(
  row.names = 1:5,
  Sepal.Length = c(0.189, 0.551, -0.415, 0.310, -0.898),
  Sepal.Width  = c(-1.97, 0.786, 2.62, -0.590, 1.70),
  Petal.Length = c(0.137, 1.04, -1.34, 0.534, -1.05),
  Petal.Width  = c(-0.262, 1.58, -1.31, 0.000875, -1.05)
) %>% as.matrix

Consider also the loadings for the first two principal components:

# Create the data frame
pc_loadings <- data.frame(
  PC1 = c(0.5210659, -0.2693474, 0.5804131, 0.5648565),
  PC2 = c(-0.37741762, -0.92329566, -0.02449161, -0.06694199),
  row.names = c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
) %>% as.matrix

A plot of the first two PC scores for these five irises is shown in the plot below.

Match the ID of each iris (1-5) to the correct letter of its score coordinates on the plot.

five_irises %*% pc_loadings
         PC1        PC2
1  0.5606200  1.7617440
2  1.5715031 -1.0649071
3 -2.4396481 -2.1418936
4  0.6308802  0.4146079
5 -2.1283408 -1.1346763

Iris Matches:

Iris 1: B - Large PC2 and PC1 slightly above 0.5

Iris 2: D - PC1 greater than 1 and negative PC2

Iris 3: A - Very negative PC1 and PC2

Iris 4: C - Small PC1 and PC2 both positive as well

Iris 5: E - Negative 2 for PC1 and Negative 1 for PC2

Problem 3

These data are taken from the Places Rated Almanac, by Richard Boyer and David Savageau, copyrighted and published by Rand McNally. The nine rating criteria used by Places Rated Almanac are:

  • Climate & Terrain
  • Housing
  • Health Care & Environment
  • Crime
  • Transportation
  • Education
  • The Arts
  • Recreation
  • Economics

For all but two of the above criteria, the higher the score, the better. For Housing and Crime, the lower the score the better. The scores are computed using the following component statistics for each criterion (see the Places Rated Almanac for details):

  • Climate & Terrain: very hot and very cold months, seasonal temperature variation, heating- and cooling-degree days, freezing days, zero-degree days, ninety-degree days.
  • Housing: utility bills, property taxes, mortgage payments.
  • Health Care & Environment: per capita physicians, teaching hospitals, medical schools, cardiac rehabilitation centers, comprehensive cancer treatment centers, hospices, insurance/hospitalization costs index, flouridation of drinking water, air pollution.
  • Crime: violent crime rate, property crime rate.
  • Transportation: daily commute, public transportation, Interstate highways, air service, passenger rail service.
  • Education: pupil/teacher ratio in the public K-12 system, effort index in K-12, accademic options in higher education.
  • The Arts: museums, fine arts and public radio stations, public television stations, universities offering a degree or degrees in the arts, symphony orchestras, theatres, opera companies, dance companies, public libraries.
  • Recreation: good restaurants, public golf courses, certified lanes for tenpin bowling, movie theatres, zoos, aquariums, family theme parks, sanctioned automobile race tracks, pari-mutuel betting attractions, major- and minor- league professional sports teams, NCAA Division I football and basketball teams, miles of ocean or Great Lakes coastline, inland water, national forests, national parks, or national wildlife refuges, Consolidated Metropolitan Statistical Area access.
  • Economics: average household income adjusted for taxes and living costs, income growth, job growth.

In addition to these, latitude and longitude, population and state are also given, but should not be included in the PCA.

Use PCA to identify the major components of variation in the ratings among cities.

places <- read.csv('./Data/Places.csv')
head(places)
                       City Climate Housing HlthCare Crime Transp Educ Arts
1                 AbileneTX     521    6200      237   923   4031 2757  996
2                   AkronOH     575    8138     1656   886   4883 2438 5564
3                  AlbanyGA     468    7339      618   970   2531 2560  237
4 Albany-Schenectady-TroyNY     476    7908     1431   610   6883 3399 4655
5             AlbuquerqueNM     659    8393     1853  1483   6558 3026 4496
6              AlexandriaLA     520    5819      640   727   2444 2972  334
  Recreat Econ      Long     Lat    Pop
1    1405 7633  -99.6890 32.5590 110932
2    2632 4350  -81.5180 41.0850 660328
3     859 5250  -84.1580 31.5750 112402
4    1617 5864  -73.7983 42.7327 835880
5    2612 5727 -106.6500 35.0830 419700
6    1018 5254  -92.4530 31.3020 135282
library(factoextra)
Warning: package 'factoextra' was built under R version 4.4.3
Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa

A.

If you want to explore this data set in lower dimensional space using the first \(k\) principal components, how many would you use, and what percent of the total variability would these retained PCs explain? Use a scree plot to help you answer this question.

places_df <- (places %>% select(-City, -Long:-Pop))

places_pca <- (
  places_df
  %>% prcomp(scale. = TRUE)
)

summary(places_pca)
Importance of components:
                          PC1    PC2    PC3    PC4    PC5     PC6     PC7
Standard deviation     1.8462 1.1018 1.0684 0.9596 0.8679 0.79408 0.70217
Proportion of Variance 0.3787 0.1349 0.1268 0.1023 0.0837 0.07006 0.05478
Cumulative Proportion  0.3787 0.5136 0.6404 0.7427 0.8264 0.89650 0.95128
                           PC8     PC9
Standard deviation     0.56395 0.34699
Proportion of Variance 0.03534 0.01338
Cumulative Proportion  0.98662 1.00000
fviz_eig(places_pca)
Warning in geom_bar(stat = "identity", fill = barfill, color = barcolor, :
Ignoring empty aesthetic: `width`.

I will use the first 2 principal components to explore this data set in lower dimensions we can see a large drop off in the variability explained after the first principal components. Thus, we will only use the first two components to explore this data set. The first two components explain 51.36% of the variability in our data set.

B.

Interpret the retained principal components by examining the loadings (plot(s) of the loadings may be helpful). Which variables will be used to separate cities along the first and second principal axes, and how? Make sure to discuss the signs of the loadings, not just their contributions!

loadings_places <- data.frame(places_pca$rotation) %>% 
  rownames_to_column('Variable')


base_plot <- ggplot(loadings_places) + 
  theme_classic(base_size = 12) +
  theme(axis.text.x = element_text(angle = 45,hjust=1,vjust=1)) + 
  labs(x = 'Variable') + 
  geom_hline(aes(yintercept= 0), linetype=2)
library(patchwork)
Warning: package 'patchwork' was built under R version 4.4.3
l1 <- base_plot + 
  geom_col(aes(x = reorder(Variable,PC1, decreasing=TRUE), y = PC1))
l2 <- base_plot+
  geom_col(aes(x = reorder(Variable,PC2, decreasing=TRUE), y = PC2))  

(l1+l2) +
  plot_annotation(title = 'Loadings plots for PCA on Places Rated',
                  theme=theme(plot.title = element_text(hjust = 0.5)))

Loadings for PC1: After looking at the loadings for PC1, we can see that each variable is positive. Meaning that cities that have a high score in each variable will have a high PC1. Notably, the two largest loadings are Arts and Healthcare/Environment. This tells us that these are the most important variables that will lead to a large PC1. Notably Economics and Climate are the two smallest loadings. This means that while a high climate score and economics score will contribute to a high PC1, they will have the smallest contribution.

Loadings for PC2: After looking at the loadings for PC2, we can see that half of the loadings are positive and half are negative. This means that high scores for economics, recreate, crime, housing and climate will contribute to a large PC2. However, a high score in transportation, arts, healthcare, or education will contribute a low PC2. The most important positive PCS are economics, recreation and climate. The most important negative PCs are education and health care.

C.

Add the first two PC scores to the places data set. Create a biplot of the first 2 PCs, using repelled labeling to identify the cities. Which are the outlying cities and what characteristics make them unique?

library(ggrepel)
Warning: package 'ggrepel' was built under R version 4.4.3
places_pc_df <- (
  cbind(places, places_pca$x[,1:2])
)

fviz_pca_biplot(places_pca, label = 'var') + 
  geom_text_repel(data = places_pc_df, aes(x = PC1, y = PC2, label = City))
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
ℹ The deprecated feature was likely used in the ggpubr package.
  Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
Warning: ggrepel: 314 unlabeled data points (too many overlaps). Consider
increasing max.overlaps

From this plot we can see that the cities that are far away from the others are San Francisco, Long Beach/LA, and New York City. New York City has a higher score for transportation and arts then pretty much every other city. New York is much further in the direction those arrows are pointing then any other point. San Francisco and Long Beach/LA are closer to each other, but they are far away from every other point. They are in between the Housing arrow and the Arts and Transportation arrows. This tells us that they have a high arts and transportation score, but they also have a large housing price.

Problem 4

The data we will look at here come from a study of malignant and benign breast cancer cells using fine needle aspiration conducted at the University of Wisconsin-Madison. The goal was determine if malignancy of a tumor could be established by using shape characteristics of cells obtained via fine needle aspiration (FNA) and digitized scanning of the cells.

The variables in the data file you will be using are:

  • ID - patient identification number (not used in PCA)
  • Diagnosis determined by biopsy - B = benign or M = malignant
  • Radius: mean of distances from center to points on the perimeter
  • Texture: standard deviation of gray-scale values
  • Smoothness: local variation in radius lengths
  • Compactness: perimeter^2 / area - 1.0
  • Concavity: severity of concave portions of the contour
  • Concavepts: number of concave portions of the contour
  • Symmetry: measure of symmetry of the cell nucleus
  • FracDim: fractal dimension; “coastline approximation” - 1
bc_cells <- read.csv('./Data/BreastDiag.csv')
head(bc_cells)
  Diagnosis Radius Texture Smoothness Compactness Concavity ConcavePts Symmetry
1         M  17.99   10.38    0.11840     0.27760    0.3001    0.14710   0.2419
2         M  20.57   17.77    0.08474     0.07864    0.0869    0.07017   0.1812
3         M  19.69   21.25    0.10960     0.15990    0.1974    0.12790   0.2069
4         M  11.42   20.38    0.14250     0.28390    0.2414    0.10520   0.2597
5         M  20.29   14.34    0.10030     0.13280    0.1980    0.10430   0.1809
6         M  12.45   15.70    0.12780     0.17000    0.1578    0.08089   0.2087
  FracDim
1 0.07871
2 0.05667
3 0.05999
4 0.09744
5 0.05883
6 0.07613

A.

My analysis suggests 3 PCs should be retained. Support or refute this suggestion. What percent of variability is explained by the first 3 PCs?

cells_pca <- prcomp(bc_cells %>% select(-Diagnosis), scale. = TRUE)

summary(cells_pca)
Importance of components:
                          PC1    PC2    PC3     PC4     PC5     PC6    PC7
Standard deviation     2.0705 1.3504 0.9087 0.70614 0.61016 0.30355 0.2623
Proportion of Variance 0.5359 0.2279 0.1032 0.06233 0.04654 0.01152 0.0086
Cumulative Proportion  0.5359 0.7638 0.8670 0.92937 0.97591 0.98743 0.9960
                           PC8
Standard deviation     0.17837
Proportion of Variance 0.00398
Cumulative Proportion  1.00000

The first 3 PCs explain 86.70% of the variability in cell shape features. We can see a drop in variability explained by each PC once we go from 2 to 3 PCs. That tells us that we can use 3 PCs moving forward.

B.

Interpret the first 3 principal components by examining the eigenvectors/loadings. Discuss.

cells_pca$rotation[,1:3]
                   PC1         PC2         PC3
Radius      -0.3003952  0.52850910  0.27751200
Texture     -0.1432175  0.35378530 -0.89839046
Smoothness  -0.3482386 -0.32661945  0.12684205
Compactness -0.4584098 -0.07219238 -0.02956419
Concavity   -0.4508935  0.12707085  0.04245883
ConcavePts  -0.4459288  0.22823091  0.17458320
Symmetry    -0.3240333 -0.28112508 -0.08456832
FracDim     -0.2251375 -0.57996072 -0.24389523

By looking at the loadings for PC1, we can see that all of them are negative. That tells us that cells that have a large values for each measurement will have a low PC1. The largest loadings are the loadings for Compactness, Concavity, and Concave points. Meaning that cells that have low values for each of these are going to have a very high PC1.

Next, we can look into PC2 and see how it differs. We can see that a good portionof the loadings for PC2 are positive. The negatives are fractal dimension, symmetry, compactness, and concavity. The largest loadings for PC2 are radius and fractal dimension. Cells with a large radius will have a large PC2 and the points with a large fractal dimension will have a small PC2.

Lastly, lets look into PC3. PC3 has a lot of loadings that are close to 0, which makes sense because a lot fo the variability has already been explained in the other PCs. Notably, texture was a very negative loading. The loading for texture is -0.898, which is the largest individual loading in absolute value for any of the PCs. This tells us that cells with a large standard deviation in texture are going to have a small PC3.

C.

Examine a biplot of the first two PCs. Incorporate the third PC by sizing the points by this variable. (Hint: use fviz_pca to set up a biplot, but set col.ind='white'. Then use geom_point() to maintain full control over the point mapping.) Color-code by whether the cells are benign or malignant. Answer the following:

  • What characteristics distinguish malignant from benign cells?
  • Of the 3 PCs, which does the best job of differentiating malignant from benign cells?
cells_pc_df <- (
  cbind(bc_cells, cells_pca$x[,1:4])
)

fviz_pca_biplot(cells_pca,
                col.ind='white') +
  geom_point(data = cells_pc_df, aes(x = PC1, y = PC2, size = PC3, color = Diagnosis))

The characteristics that do the best job of differentiating between benign and malignant cells are concavity, concave points, compactness, and radius. There are two large clouds of points, one is mostly malignant points and the other is mostly benign points. Most of the arrows are pointing in the direction of the malignant cloud, but those four arrows specifically have no benign points in those directions. The PC that is best at differentiating between the cells is PC1. On one end of the PC1 axis, we have almost all malignant cells (the left side). The other side is almost entirely the benign cells. Additionally, the most important factors for PC1 are Compactness, concavity, and concave points. Cells with large values of these have low PC1s. Each of these arrows is pointing towards the malignant cells.