-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGMLDM-Cluster-FullStack.R
More file actions
227 lines (187 loc) · 10.1 KB
/
GMLDM-Cluster-FullStack.R
File metadata and controls
227 lines (187 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# GMLDM/MEQ Cluster Analysis
# Author: Jess Strait for CROPP Cooperative
# Clear environment and load packages
rm(list = ls())
setwd("~/")
library(data.table)
library(Rtsne)
library(ggplot2)
library(caret)
library(ClusterR)
library(cluster)
library(mlr)
library(factoextra)
library(NbClust)
library(FeatureImpCluster)
library(attempt)
library(flexclust)
library(RColorBrewer)
# Intake data
data <- fread("ChannelMEQ.csv")
data <- na.omit(data)
# Drop outliers seen in analysis
data <- data %>% filter(`Milk Equivalents` < 50000000)
data <- data %>% filter(`Discounts & Allowances` > -1500000)
data <- data %>% filter(`GMLDM $` < 2000000)
# Create dummy variables
dummies <- dummyVars(~ ., data = data)
numdummies <- predict(dummies, newdata = data)
# Run tSNE
set.seed(3)
perplexityvalue <- 50
tsne <- Rtsne(numdummies, pca = F, perplexityvalue=perplexityvalue, theta = 0.4, check_duplicates = F)
# Obtain tSNE coordinates and visually observe clustering
tsne_dt <- data.table(tsne$Y)
# Elbow method
fviz_nbclust(tsne_dt, kmeans, method = "wss", k.max=25) +
geom_vline(xintercept = 4, linetype = 2)+
labs(subtitle = "Elbow method")
# Suggests optimal number of clusters is 4
# Silhouette method
fviz_nbclust(tsne_dt, kmeans, method = "silhouette", k.max=25)+
labs(subtitle = "Silhouette method")
# Suggests optimal number of clusters is 3
# Run kmeans with tSNE dataframe
kmeantsne <- kmeans(tsne_dt, centers = 4, nstart = 100, algorithm=c("Hartigan-Wong", "Lloyd", "Forgy", "MacQueen"), trace=FALSE)
# KCCA family object for feature importance vis
res <- kcca(tsne_dt, family=kccaFamily("kmeans"), k=4)
# Visualize the clusters in color
fviz_cluster(kmeantsne, tsne_dt, palette = c("pink1", "violet", "mediumpurple1", "slateblue1", "purple", "forestgreen",
"turquoise2", "skyblue", "yellow", "blue2", "navyblue",
"orange", "tomato", "black", "palevioletred", "violetred", "red2",
"springgreen2", "yellowgreen", "palegreen4",
"wheat2", "tan3", "brown3",
"grey70"), ggtheme = theme_minimal())
# Save cluster predictions as dataframe columns
tsne_dt$kmeanPred <- kmeantsne$cluster
data$kmeanPred <- as.factor(kmeantsne$cluster)
# Compute group means
commeans <- data %>% group_by(Commodity) %>% mutate(`GMLDM $` = mean(`GMLDM $`))
commeans <- commeans %>% select(`GMLDM $`, `Milk Equivalents`, `Commodity`, `kmeanPred`)
commeans$kmeanPred <- 0
chanmeans <- data %>% group_by(`Sales Channel`) %>% mutate(`GMLDM $` = mean(`GMLDM $`))
chanmeans <- chanmeans %>% select(`GMLDM $`, `Milk Equivalents`, `kmeanPred`, `Sales Channel`)
chanmeans$kmeanPred <- 0
ggplot(data, aes(x=`Milk Equivalents`, y=`Discounts & Allowances`, color=kmeanPred)) + geom_point()
# Clust 2: Higher milk equivalents; no clear D&A
# Clust 1: Midrange milk equivalents; no clear D&A
# Clust 4: Low milk equivalents; no clear D&A
# Clust 3: Very low milk equivalents; almost zero D&A
ggplot(data, aes(x=`Milk Equivalents`, y=`GMLDM $`, color=kmeanPred)) + geom_point()
# Clust 4 and somewhat 3: NEGATIVE GMLDM
ggplot(data, aes(x=`GMLDM $`, y=Commodity, color=kmeanPred)) + geom_point()
# Clust 2: mostly bulk milk with high GMLDM; a couple UHT, spreads, powder (range), HTST (high GMLDM), cheese
# Clust 4: mostly sour cream, butter, aseptic (where we see low GMLDM)
# Clust 3: UHT, powder, cheese- all almost 0 GMLDM
ggplot(data, aes(x=`Discounts & Allowances`, y=Commodity, color=kmeanPred)) + geom_point()
ggplot(data, aes(x=`Milk Equivalents`, y=Commodity, color=kmeanPred)) + geom_point()
ggplot(data, aes(x=`GMLDM $`, y=`Sales Channel`, color=kmeanPred)) + geom_point()
ggplot(data, aes(x=`Discounts & Allowances`, y=`Sales Channel`, color=kmeanPred)) + geom_point()
ggplot(data, aes(x=`Milk Equivalents`, y=`Sales Channel`, color=kmeanPred)) + geom_point()
# Clust 4: manufacturing ops division, food service division, global ingredients; all low GMLDM
# Clust 3: small format
# Clust 1: Retail grocery, ingredient, food service
# Clust 2: Mostly retailer grocery, some ingredient and high GMLDM VP
# Clust 3: VP and Sales Operations
# Clust 4: Mostly VP and some ingredient
# Manufacturing, small format, VP divisions -> all 0 GMLDM
ggplot(data, aes(x=`GMLDM $`, y=reorder(`Commodity`, `GMLDM $`), color=kmeanPred, size=`Milk Equivalents`)) + geom_point() + geom_point(data=commeans, aes(color='Mean GMLDM', size=100)) + ylab("Commodity")
ggplot(data, aes(x=`GMLDM $`, y=reorder(`Sales Channel`, `GMLDM $`), color=kmeanPred, size=`Milk Equivalents`)) + geom_point() + geom_point(data=chanmeans, aes(color='Mean GMLDM', size=300)) + ylab("Sales Channel")
ggplot(data, aes(x=`Milk Equivalents`, y=`GMLDM $`, color=Commodity)) + geom_point()
ggplot(data, aes(x=`Milk Equivalents`, y=`GMLDM $`, color=`Sales Channel`)) + geom_point()
# Divs with higher GMLDM: domestic ingredient division
# Cmdty with higher GMLDM: Bulk milk, powder
# Cmdty with lower GMLDM: Spreads, sour cream, cottage cheese, some butter
gmm_data <- GMM(tsne_dt[,.(V1,V2)], 4)
# Convert log-likelihood into probability of cluster occurrence
l_clust <- gmm_data$Log_likelihood^10
l_clust <- data.table(l_clust)
net_lh <- apply(l_clust,1,FUN=function(x){sum(1/x)})
cluster_prob <- 1/l_clust/net_lh
tsne_dt$Cluster_1_prob <- cluster_prob$V1
tsne_dt$Cluster_2_prob <- cluster_prob$V2
tsne_dt$Cluster_3_prob <- cluster_prob$V3
tsne_dt$Cluster_4_prob <- cluster_prob$V4
# Visualize cluster probabilities - did not find this method useful
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_1_prob)) + geom_point()
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_2_prob)) + geom_point()
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_3_prob)) + geom_point()
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_4_prob)) + geom_point()
# Write data with cluster predictions to a CSV
write.csv(data, "TsneProductFourClusterAnalysis.csv")
# Clustering for meat & egg pools
rm(list = ls())
meat <- fread("Meat&Egg.csv")
meat <- na.omit(meat)
meat <- meat %>% filter(`GMLDM $` < 100000)
meatdummies <- dummyVars(~ ., data = meat)
meatnumdummies <- predict(meatdummies, newdata = meat)
# Run tSNE
set.seed(3)
perplexityvalue <- 50
tsne <- Rtsne(meatnumdummies, pca = F, perplexityvalue=perplexityvalue, theta = 0.4, check_duplicates = F)
# Obtain tSNE coordinates and visually observe clustering
tsne_dt <- data.table(tsne$Y)
# Run kmeans again with tSNE dataframe
kmeantsne <- kmeans(tsne_dt, centers = 4, nstart = 100, algorithm=c("Hartigan-Wong", "Lloyd", "Forgy", "MacQueen"), trace=FALSE)
# KCCA family object for feature importance vis
res <- kcca(tsne_dt, family=kccaFamily("kmeans"), k=4)
# Elbow method
fviz_nbclust(tsne_dt, kmeans, method = "wss", k.max=25) +
geom_vline(xintercept = 4, linetype = 2)+
labs(subtitle = "Elbow method")
# Suggests optimal number of clusters is 4
# Silhouette method
fviz_nbclust(tsne_dt, kmeans, method = "silhouette", k.max=25)+
labs(subtitle = "Silhouette method")
# Suggests optimal number of clusters is 2
# Visualize the clusters in color
fviz_cluster(kmeantsne, tsne_dt, palette = c("pink1", "violet", "mediumpurple1", "slateblue1", "purple", "forestgreen",
"turquoise2", "skyblue", "yellow", "blue2", "navyblue",
"orange", "tomato", "black", "palevioletred", "violetred", "red2",
"springgreen2", "yellowgreen", "palegreen4",
"wheat2", "tan3", "brown3",
"grey70"), ggtheme = theme_minimal())
# Save cluster predictions as dataframe columns
tsne_dt$kmeanPred <- kmeantsne$cluster
meat$kmeanPred <- as.factor(kmeantsne$cluster)
# Compute group means
commeans <- meat %>% group_by(Commodity) %>% mutate(`GMLDM $` = mean(`GMLDM $`))
commeans <- commeans %>% select(`GMLDM $`, `Commodity`, `kmeanPred`)
commeans$kmeanPred <- 0
chanmeans <- meat %>% group_by(`Sales Channel`) %>% mutate(`GMLDM $` = mean(`GMLDM $`))
chanmeans <- chanmeans %>% select(`GMLDM $`, `kmeanPred`, `Sales Channel`)
chanmeans$kmeanPred <- 0
ggplot(meat, aes(x=`GMLDM $`, y=Commodity, color=kmeanPred)) + geom_point()
# Clust 4: Ranging all commodities, both high and low outliers- most eggs
# Eggs have higher average GMLDM
# Chicken and turkey tend towards zero GMLDM
# Clust 1: Almost zero GMLDM
# Clust 3: Exactly zero
ggplot(meat, aes(x=`Discounts & Allowances`, y=Commodity, color=kmeanPred)) + geom_point()
# Clust 4: Has almost all D&A, all other clusters tend towards zero
ggplot(meat, aes(x=`GMLDM $`, y=`Sales Channel`, color=kmeanPred)) + geom_point()
# Retail grocery has trending positive GMLDM
# Ingredient and VP less extreme but also trending positive
# Sales Operations exactly zero, foodservice trending towards zero
ggplot(meat, aes(x=`Discounts & Allowances`, y=`Sales Channel`, color=kmeanPred)) + geom_point()
# Retail grocery has almost all D&A, with some VP
ggplot(meat, aes(x=`GMLDM $`, y=reorder(`Commodity`, `GMLDM $`), color=kmeanPred)) + geom_point() + geom_point(data=commeans, aes(color='Mean GMLDM')) + ylab("Commodity")
ggplot(meat, aes(x=`GMLDM $`, y=reorder(`Sales Channel`, `GMLDM $`), color=kmeanPred)) + geom_point() + geom_point(data=chanmeans, aes(color='Mean GMLDM')) + ylab("Sales Channel")
gmm_data <- GMM(tsne_dt[,.(V1,V2)], 4)
# Convert log-likelihood into probability of cluster occurrence
l_clust <- gmm_data$Log_likelihood^10
l_clust <- data.table(l_clust)
net_lh <- apply(l_clust,1,FUN=function(x){sum(1/x)})
cluster_prob <- 1/l_clust/net_lh
tsne_dt$Cluster_1_prob <- cluster_prob$V1
tsne_dt$Cluster_2_prob <- cluster_prob$V2
tsne_dt$Cluster_3_prob <- cluster_prob$V3
tsne_dt$Cluster_4_prob <- cluster_prob$V4
# Visualize cluster probabilities - did not find this method useful
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_1_prob)) + geom_point()
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_2_prob)) + geom_point()
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_3_prob)) + geom_point()
ggplot(tsne_dt,aes(x=V1,y=V2,col=Cluster_4_prob)) + geom_point()
# Write data with cluster predictions to a CSV
write.csv(data, "TsneMeatFourClusterAnalysis.csv")