---
title: "Introduction to Clustering"
output:
  ioslides_presentation: 
    smaller: true
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Outline
- Discuss fundamentals of clustering
- Apply knowledge to simple problems

## What is Cluster Analysis?

A simple way of describing cluster analysis is dividing data into groups (clusters) that are meaningful and useful based upon properties of your data. The end goal being the objects within each group are similar and distinct from other clusters. The greater the homogeneity (similarity) within a cluster the greater the difference between other groups

As an example, given any sports team you can cluster teams based upon their skill level. For instance, teams with higher overall skill will be in one cluster while teams with lower overall skill will be in another cluster.

## Cluster Analysis

An overarching question to clustering is, how do you find *similar* groups? Since the task of clustering is somewhat subjective, there are many different ways of accomplishing this goal. Two of the most common types of clustering algorithms are:

- K-Means Clustering

- Hierarchical Clustering

## K-Means Clustering

This algorithm is a partitional clustering technique that attempts to find a user input, *k*, number of clusters. In short, the algorithm computes a **centroid** for the *k* clusters and then computes distances from each point to determine if a centroid is a reasonable point for a cluster. 

## Pre-Processing Data
When doing clustering it is important to **center** and **scale** your data. This is a consequence of the distance metric being used. For example, in the NFL is 1 unit of rushing yards equivalent to 1 unit of touchdown? No of course not! 1 touchdown is much for valuable than 1 rushing yard. Hence when we scale and center our data, we create a good measure of distance between all variables.

## Example

Here we are going to perform cluster analysis on the NFL Running Backs 2016 data set. This data contain the seasonal statistics of each starting running back (32 total) for the 2016 - 2017 NFL season.

Let's see if using K-Means clustering can identify meaning groups within this data set. The structure of K-Means is as follows:
`kmeans(data set,centers = k)`. There are many more arguments that can be viewed in the help menu using `?kmeans`.

##

**Note**: K-Means clustering can only be applied with numerical values, so you will have to remove all categorical variables in any data set where you want to apply cluster analysis.

```{r}
# Load data
nfl <- read.csv("NFL Running Backs 2016.csv")

# Remove categorical variables
nfl.rb <- subset(nfl, select = -c(Player,Year,Team,Pos))

# Give our data frame row names for use of use
rownames(nfl.rb) <- nfl$Player

# Scale data. This is important!!
nfl.rb <- scale(nfl.rb)

# K-means algorithm with 2 clusters
nfl.rb.cluster <- kmeans(nfl.rb,centers = 2)
```

##

```{r}
# Output results
nfl.rb.cluster
```

##

```{r}
# See cluster
nfl.rb.cluster$cluster
```
##

Create a data frame with the cluster as a column
```{r}
# Create data frame joining cluster data to NFL data
df <- data.frame(nfl,as.factor(nfl.rb.cluster$cluster))

# Rename last column "Cluster"
names(df)[ncol(df)] <- "Cluster"

head(df)
```

## Plotting Clusters

```{r, fig.height=3, fig.width=7}
# Load relevant libraries
library(ggplot2)
library(ggrepel)

# ggplot of df with x: RushYds, y: RushTD with coloring by cluster
ggplot(df, aes(RushYds, RushTD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Rushing Touchdowns vs. Rushing Yards K = 2")

```

## Changing K

K = 3
```{r, fig.height=2, fig.width=7}
nfl.rb.cluster <- kmeans(nfl.rb,centers = 3)

# Create data frame joining cluster data to NFL data
df <- data.frame(nfl,as.factor(nfl.rb.cluster$cluster))
# Rename last column "Cluster"
names(df)[ncol(df)] <- "Cluster"

# ggplot of df with x: RushYds, y: RushTD with coloring by cluster
ggplot(df, aes(RushYds, RushTD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Rushing Touchdowns vs. Rushing Yards K = 3")
```

##

K = 4
```{r, fig.height=3, fig.width=7}
nfl.rb.cluster <- kmeans(nfl.rb,centers = 4)

# Create data frame joining cluster data to NFL data
df <- data.frame(nfl,as.factor(nfl.rb.cluster$cluster))
# Rename last column "Cluster"
names(df)[ncol(df)] <- "Cluster"

# ggplot of df with x: RushYds, y: RushTD with coloring by cluster
ggplot(df, aes(RushYds, RushTD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Rushing Touchdowns vs. Rushing Yards K = 4")
```

##

K = 5
```{r, fig.height=3, fig.width=7}
nfl.rb.cluster <- kmeans(nfl.rb,centers = 5)

df <- data.frame(nfl,as.factor(nfl.rb.cluster$cluster))
names(df)[ncol(df)] <- "Cluster"

ggplot(df, aes(RushYds, RushTD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Rushing Touchdowns vs. Rushing Yards K = 5")
```

## Discussion

By printing out `nfl.rb.cluster$cluster` in any of the code above, you can see which cluster group each player is in. Moreover, in our plots, we chose to model rushing touchdowns vs. rushing yards. We will notice that some colors groups (clusters) are consistently near the top corner, while others are near the bottom corner. Moreover, by doing clustering we can get a sense of the different *tiers* and *types* of players.

## Your Turn

Using the NFL Wide Receivers 2016.csv data set, complete the following:

1. Center and scale your data and subset your data frame to remove: *Player*,*Year*,*Team*,*Pos*.

2. Reconstruct the 4 graphs above using k = 2,3,4,5. However, this time put touchdowns (TD) on the *y*-axis and receptions (Rec) on the *x*-axis.



## Answers

### 1.
```{r}
# Load WR data set
nfl <- read.csv("NFL Wide Receivers 2016.csv") 

# Subset data to remove categorical variables
nfl.wr <- subset(nfl, select = -c(Player,Year,Team,Pos))

# Name rows of data set
rownames(nfl.wr) <- nfl$Player

# Center and scale data
nfl.wr <- scale(nfl.wr)
```
##

### 2.
```{r, fig.height=2.5, fig.width=7}
# K means with 2 clusters
nfl.wr.cluster <- kmeans(nfl.wr,centers = 2)
# Data frame of original data plus cluster assignments
df <- data.frame(nfl,as.factor(nfl.wr.cluster$cluster))
# Rename last column
names(df)[ncol(df)] <- "Cluster"
# Plotting TD vs. Rec
ggplot(df, aes(Rec, TD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Receiving Touchdowns vs. Receptions K = 2")
```

##

K = 3
```{r, fig.height=3, fig.width=7}
# K means with 3 clusters
nfl.wr.cluster <- kmeans(nfl.wr,centers = 3)
# Data frame of original data plus cluster assignments
df <- data.frame(nfl,as.factor(nfl.wr.cluster$cluster))
# Rename last column
names(df)[ncol(df)] <- "Cluster"
# Plotting TD vs. Rec
ggplot(df, aes(Rec, TD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Receiving Touchdowns vs. Receptions K = 3")
```

##

K = 4
```{r, fig.height=3, fig.width=7}
nfl.wr.cluster <- kmeans(nfl.wr,centers = 4)

df <- data.frame(nfl,as.factor(nfl.wr.cluster$cluster))
names(df)[ncol(df)] <- "Cluster"

ggplot(df, aes(Rec, TD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Receiving Touchdowns vs. Receptions K = 4")
```

##

K = 5
```{r, fig.height=3, fig.width=7}
nfl.wr.cluster <- kmeans(nfl.wr,centers = 5)

df <- data.frame(nfl,as.factor(nfl.wr.cluster$cluster))
names(df)[ncol(df)] <- "Cluster"

ggplot(df, aes(Rec, TD,colour = df$Cluster)) + 
  geom_text_repel(aes(label=Player))+
  theme(legend.position="none") +
  ggtitle("Visualization of Clusters for Receiving Touchdowns vs. Receptions K = 5")
```

