PCA分析店铺综合排名
·
xiebro
在美食推荐应用中,用户对店铺的评价通常有“环境”、“服务”和“味道”等多方面的评分。
那么,如何通过这些评分来计算出一个更能代表整体印象的“综合评分”?本次练习使用主成分分析(PCA)来实现店铺的综合排名。
数据集概览
library(dplyr)
library(plotly)
dat <-
read.csv("data/food.csv") %>%
filter(种类 == "咖啡厅")
# 结构概览
glimpse(dat)
## Rows: 717
## Columns: 5
## $ 店名 <chr> "YECLIP COFFEE 黄色回形针咖啡", "hellopets·猪咖狗咖", "格度猫…
## $ 种类 <chr> "咖啡厅", "咖啡厅", "咖啡厅", "咖啡厅", "咖啡厅", "咖啡厅", "…
## $ 环境评分 <dbl> 4.10, 4.50, 4.74, 4.11, 4.18, 4.14, 4.03, 4.94, 3.92, 4.38, 4…
## $ 服务评分 <dbl> 3.97, 4.17, 4.35, 4.75, 4.57, 4.12, 4.39, 4.60, 4.43, 4.95, 3…
## $ 口味评分 <dbl> 4.16, 4.86, 4.67, 4.92, 4.96, 4.57, 4.93, 4.80, 4.04, 4.04, 3…
# 分布概览
plot_ly(
dat,
x = ~环境评分,
y = ~服务评分,
z = ~口味评分,
type = "scatter3d",
mode = "markers",
marker = list(size = 1)
)
PCA分析
# 标准化
dat_scaled <-
dat %>%
select(环境评分, 服务评分, 口味评分) %>%
scale()
# PCA分析
pca_result <- prcomp(dat_scaled, center = TRUE, scale. = TRUE)
summary(pca_result)
## Importance of components:
## PC1 PC2 PC3
## Standard deviation 1.2076 0.9049 0.8502
## Proportion of Variance 0.4861 0.2729 0.2409
## Cumulative Proportion 0.4861 0.7591 1.0000
# 店铺综合评分结果
pca_scores <-
pca_result$x %>% # 提取主成分得分
as.data.frame() %>%
cbind(dat) %>%
mutate(综合评分 = round(PC1, 1))
# 店铺综合排名
pca_scores %>%
select(店名, contains("评分")) %>%
arrange(desc(综合评分)) %>%
mutate(综合排名 = 1:n()) %>%
head(10) %>%
knitr::kable()
店名 | 环境评分 | 服务评分 | 口味评分 | 综合评分 | 综合排名 |
---|---|---|---|---|---|
果徕咖啡庄园 | 4.95 | 4.94 | 4.76 | 2.2 | 1 |
博物馆咖啡厅 | 4.80 | 4.96 | 4.80 | 2.1 | 2 |
羊驼来了Young for you | 4.95 | 4.76 | 4.84 | 2.0 | 3 |
MOJOC CAFE | 4.95 | 4.96 | 4.63 | 2.0 | 4 |
农夫和兔 cafe | 4.88 | 4.65 | 4.98 | 2.0 | 5 |
luckin coffee瑞幸咖啡(第一城店) | 4.66 | 4.99 | 4.84 | 2.0 | 6 |
EN SPACE ·恩空间 | 4.68 | 4.93 | 4.80 | 1.9 | 7 |
墨閑山房 | 4.85 | 4.62 | 4.94 | 1.9 | 8 |
Sunrise大安正街店 | 4.90 | 4.71 | 4.82 | 1.9 | 9 |
CK柴犬柯基狗咖·猪咖(春熙路IFS店) | 4.77 | 4.96 | 4.68 | 1.9 | 10 |
# 可视化PCA结果
pca_scores %>%
ggplot(aes(x = PC1, y = PC2)) +
geom_point(alpha = .5) +
geom_vline(xintercept = 0) +
geom_hline(yintercept = 0) +
theme_minimal()

plot_ly(
pca_scores,
x = ~PC1,
y = ~PC2,
z = ~PC3,
type = "scatter3d",
mode = "markers",
marker = list(size = 1)
)