if(!require(morpheus)) install.packages('morpheus.R')
pacman::p_load(dplyr, d3heatmap)
cols = colorRamp(c('seagreen','lightyellow','red'))
SP RJ MG RS PR SC BA DF ES GO PE CE PA MT MA
0.42 0.55 0.67 0.72 0.77 0.81 0.84 0.86 0.88 0.90 0.92 0.93 0.94 0.95 0.96
超過80%的顧客都集中在前6州
C$customer_state
into I$state
via O
I = left_join(O[,1:2], C[,c(1,5)])[-2] %>% # merge state into `O`
rename(state=customer_state) %>% # use a shoter name
right_join(I) # then merge to `I`
Joining, by = "customer_id"
Joining, by = "order_id"
TPC$product_category_name_english
into I$category
via O
I = left_join(P, TPC)[,c(1,10)] %>% # merge name into `P``
rename(category = product_category_name_english) %>% # use a shorter name
right_join(I) %>% data.frame # merge into `I`
Joining, by = "product_category_name"
Joining, by = "product_id"
state
*category
MatrixX = xtabs(price ~ state + category, I) # sum(price) per cat., per st.
X = X[order(-rowSums(X)),] # arrange rows and ...
X = X[,order(-colSums(X))] # columns in decending order
[1] 15
[1] 32
X = as(X[1:15, 1:32], "matrix") # keep 15 states & 32 categorie
colnames(X) = substr(colnames(X),1,12) # use shorter names
由於我們事先已經將X
矩陣的行列次序依降冪排列,我們可以以原有的次序畫出熱圖
SP
)和賣得最好的幾個品類。
[1] 49.99 478284.52
因為log(0) = -Inf
,所以取對數之前我們常需要先加進去一個數值,通常我們會選用矩陣中最小的數字
熱圖工具通常都會對矩陣的行與列分別作集群分析,在這個例子裡面,「購買行為相似的州」和「顧客地理分布相似的產品」會被檢在一起,以方便我們做觀察。
由於各州的顧客數量相差很多,州間並沒有相互比較的基礎,在熱圖裡面我們也很難觀察前三大州以外的地區;為了克服這個問題,我們可以用正規化(Normalization)的方式讓每一州的總營收都等於100,也就是說,我們讓矩陣之中的每一格都代表某一品類佔某一州總購買金額的百分比,這樣我們才能夠比較各州在品類購買比重上的異同。
當然我們也可以做縱向正規化,藉以比較品類在各州間的銷售分佈
💡 學習重點:
■ 注意一下縱向正規化的做法,它需要做兩次轉置 t()
■ 通常熱圖的集群分析只會做在正規化的方向(因為通常另一個方向的相似性沒有實質意義)
■ 正規化似乎並沒有解決顏色只會集中在少數幾個品類或少數幾州的問題
矩陣數值的分布很不均勻的時候,有時候可以加上一些遮罩把極端值遮去,可能會比較容易找到結構。
X[4:15,!colnames(X) %in% c("fixed_teleph","agro_industr")] %>%
t %>% {100*./rowSums(.)} %>% t %>% d3heatmap(Rowv=F, Colv=T, col=cols)
X[, !colnames(X) %in% c("health_beaut","watches_gift")] %>%
{100*./rowSums(.)} %>% d3heatmap(Rowv=T, Colv=F, col=cols)
前面說過,單方向的正規化有一個缺點,我們對一個方向(州)做正規化之後,另外一個方向(品類)的數值就失去了比較的基礎;如果我們想要在兩個方向上同時做分類和比較,我們可以把矩陣的「標準化殘差(standardized residuals)」畫成熱圖
標準化殘差 (standardized residuals):在列連表的兩個方向同時做標準化
\[r_{i,j} = \frac{x_{i,j} - E_{i.j}}{\sqrt{E_{i,j}}}\]
表格期望值:
\(E_{i,j} = P_i \times P_j \times R, \quad P_i = R_i/R, \quad P_j = R_j/R\)
E = (rowSums(X) %o% colSums(X))/sum(X) # cells' expected value
r = (X - E)/sqrt(E) # standerdized residuals
r[r > 100] = 100 # adjust the outlier
hist(r) # check distribution
💡 學習重點:
■ 熱圖不只是用顏色代表數值而已
■ 它可以對矩陣的欄與列做集群分析,分別將兩個類別變數之中相似的分類撿在一起
■ 對數轉換可以降低極端(離群))值的影響,讓熱圖的顏色更有區辨效果
■ 為了建立比較基礎,有時我們需要對矩陣的欄、列或整個矩陣做基準化(normalization)
■ 基準化有兩種:
§ 正規化(Normalization)比較重視比例,它的值是單向的(從0到1);
§ 常態化(Standardization)比較重視變異,它的值是雙向的,以0為基準、標準差
🗿 討論問題:
■ 基準化的目的是什麼?
■ 正規化和常態化的目的有什麼異同?