如何生成可运行K-means且展示全量数据的DataFrame?
代码修正与K-means聚类实现
原代码存在的问题
group_by(NEIGHBORHOOD_NAME=="BRONXDALE")写法错误:这种写法会把数据强行分成「是BRONXDALE」和「不是BRONXDALE」两组,最终只会得到2行数据。想要获取全部社区的聚合结果,应该直接按NEIGHBORHOOD_NAME分组。- 管道符拼写错误:
group_by行末尾的%>缺少一个%,正确写法是%>%。 - 指标计算逻辑不合理:
PricePerSQFT=sum(SALE_PRICE/GROSS_SQUARE_FEET)是把每笔交易的单价简单相加,并非社区整体的平方英尺均价,正确逻辑应该是总销售额除以总平方英尺:sum(SALE_PRICE)/sum(GROSS_SQUARE_FEET)。SALES_NUMBERS=sum(SALE_PRICE)计算的是总销售额,而非交易数量,统计交易笔数应该用n()。
修正后的df_Q7代码
# 构建初始数据框 df <- NYC_TRANSACTION_DATA %>% left_join(NEIGHBORHOOD, by = "NEIGHBORHOOD_ID") %>% left_join(BUILDING_CLASS, by = "BUILDING_CLASS") %>% left_join(BOROUGH, by = "BOROUGH_ID") %>% mutate(YEAR = as.integer(format(SALE_DATE, "%Y"))) # 无需重复引用原数据集,直接调用SALE_DATE即可 # 生成用于聚类的全量社区聚合数据框 df_Q7 <- df %>% filter(TYPE == "RESIDENTIAL") %>% group_by(NEIGHBORHOOD_NAME) %>% # 按每个社区单独分组 summarize( MedianSalePrice = median(SALE_PRICE, na.rm = TRUE), # 加入na.rm处理缺失值 PricePerSQFT = sum(SALE_PRICE, na.rm = TRUE)/sum(GROSS_SQUARE_FEET, na.rm = TRUE), # 社区整体平方英尺均价 sdResidential = sd(SALE_PRICE, na.rm = TRUE), # 售价标准差 SALES_NUMBERS = n() # 统计交易总笔数 ) %>% mutate(PROPORTION_RESIDENTIAL = SALES_NUMBERS/sum(SALES_NUMBERS)) # 交易数量占比
基于df_Q7运行K-means聚类
K-means对变量尺度敏感,需要先标准化数值变量,再执行聚类:
# 提取聚类用的数值型变量,排除社区名称列 cluster_features <- df_Q7 %>% select(-NEIGHBORHOOD_NAME) # 标准化变量(将变量转为均值0、标准差1的格式) scaled_features <- scale(cluster_features) # 运行K-means,假设分为3类(可根据业务需求调整k值) set.seed(123) # 设置随机种子保证结果可复现 kmeans_result <- kmeans(scaled_features, centers = 3, nstart = 20) # 将聚类标签合并回原数据框 df_Q7_clustered <- df_Q7 %>% mutate(Cluster = kmeans_result$cluster) # 查看全部数据(n=Inf表示展示所有行) print(df_Q7_clustered, n = Inf)
额外实操建议
- 先检查缺失值:用
summary(df_Q7)查看各指标的缺失情况,必要时用na.omit()删除缺失行,或用均值/中位数填充。 - 确定最优聚类数:可以用肘部法则(绘制k值与总平方和的折线图)或轮廓系数来选择最合适的k值。
内容的提问来源于stack exchange,提问作者Thanos of Siberia
相关产品推荐
相关产品推荐

